【问题标题】:vba - Macro producing incorrect results when run, but when stepping into results are correctvba - 宏在运行时产生不正确的结果,但在进入结果时是正确的
【发布时间】:2017-05-06 20:41:10
【问题描述】:

我有一个将VLOOKUP 插入列的宏。该宏必须将一个数字存储为文本并将其转换为一个数字,然后再在另一张表中查找该数字。

宏总是产生相同的结果,例如在开始产生错误结果之前到达第 43 行,但是当使用F8 单步执行代码时,不会产生这些错误结果。

错误的结果是放入 col 13 的值不等于存储为文本的数字。大多数情况下,似乎上下行的值,有时下面的 2 行被插入到 col 13。在我看来,好像 2 个不同的线程以 2 个不同的速度运行或其他什么?

如果有人可以查看导致错误的循环,我将不胜感激,谢谢。

For counter = 2 To NumRowsList
  checker = CInt(Sheets("Sheet2").Cells(counter, 3)    
  Sheets("Sheet2").Cells(counter, 13).Value = checker

  'Call WaitFor(0.5)
  If checker < 4000 Then
    Sheets("Sheet2").Cells(counter, 14) = "=VLOOKUP(M" & counter & ",Sheet4!E2:F126,2,FALSE)"
  Else
    Sheets("Sheet2").Cells(counter, 14) = "=VLOOKUP(M" & counter & ",Sheet5!B2:C200,2,FALSE)"
  End If        
Next counter

我已经尝试了此代码的一些类似变体,例如直接使用存储在 col 13 中的值而不是使用 VLOOKUP 中的单元格引用,总是产生相同的结果。

我什至使用 waitfor 函数尝试创建延迟,希望它可以同步操作,但它没有帮助,使用超过 0.5 的延迟会导致宏的运行时间太大。

更新: 我没有找到一个完美的解决方案,只有一个长手工作。我只是将 Vlookups 合并到一张纸上,并将作为文本存储的数字转换为 vba 例程之外的数字。这使错误远离了数字计算(只是 col C * 1),然后 vlookups 正在查找正确的值。感谢您的帮助,无论如何。

【问题讨论】:

  • VBA 不支持多线程。我是否认为这是问题所在:Sheets("Sheet2").Cells(counter, 13).Value = checker?它从 Sheet2 第 3 列获取数据。该列是否包含公式或值?
  • 是的,我只是在猜测。没有 col 3 将数字存储为文本。无论是否有 .value,它都会产生相同的结果。
  • C列中的任何值是否> 32,767?
  • 不,它们在 1000 到 5000 之间。我完全被这个问题难住了,因为一次进入一行时它运行正常。

标签: vba excel macros vlookup


【解决方案1】:

你可以避免循环,checker 和所有那些If-Then-Else,如下所示

编辑以说明 VlookUp 范围取决于 VlookUp

With Worksheets("Sheet2")
    .Range("N2", .Cells(NumRowsList, 14)).FormulaR1C1 = "=VLOOKUP(Value(RC3),IF(Value(RC3)<4000,Sheet4!R2C5:R126C6,Sheet4!R2C2:R200C3),2,FALSE)"
End With

【讨论】:

  • 范围变化不依赖于行号,而是依赖于行中的值,所以这种方法行不通。
  • 什么意思?你测试过吗?
  • FormulaR1C1 表示法,RC3 表示“当前行 - 第 3 列”,因此书面公式将始终引用它们所在单元格的行索引
  • @Flephal,我最后的两个 cmets 是给你的
  • 为输入的家伙干杯,我会看看我是否可以实现这个解决方案。到目前为止,我想出了一个有点长但完成了我想要的工作。
【解决方案2】:

以下内容适用于我的测试数据,但您需要查看它是否适用于您...(您是否要关闭计算或事件?我不知道这是否有问题? )

我发现最好设置对要使用的工作表的引用而不是直接访问它,这可能会有所帮助吗?

Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet2")
Dim VLURange As String, checker As Long

For counter = 2 To 200 ' NumRowsList
    checker = CLng(ws.Cells(counter, 3).Value)
    ws.Cells(counter, 13) = checker
    VLURange = IIf(checker < 4000, "Sheet4!E2:F126", "Sheet5!B2:C200")
    ws.Cells(counter, 14) = "=VLOOKUP(M" & counter & ", " & VLURange & ", 2, FALSE)"
Next counter

【讨论】:

    猜你喜欢
    • 2020-12-14
    • 2015-10-12
    • 2015-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    • 2017-04-06
    相关资源
    最近更新 更多