【问题标题】:How does the VBA immediate window differ from the application runtime?VBA 即时窗口与应用程序运行时有何不同?
【发布时间】:2019-06-29 19:00:58
【问题描述】:

我在 VBA 中遇到了一个非常奇怪的错误,想知道是否有人可以解释一下?

我正在调用这样的工作表函数:

Dim lMyRow As Long
lMyRow = WorksheetFunction.Match(vItemID, rngMyRange.Columns(1), 0)

这是为了获取我传入的项目的行。在某些情况下(虽然我无法确定确切的时间),对 Match 函数的调用会发生奇怪的事情。

如果我在即时窗口中执行该行,我会得到以下信息:

lMyRow = WorksheetFunction.Match(vItemID, rngMyRange.Columns(1), 0)
?lMyRow
10

即查找有效,并且 lMyRow 获得分配给它的值。如果我让该语句在实际代码中执行,我 lMyRow 的值为 0。

这看起来很奇怪!我不明白如何在即时窗口中执行某些操作可以成功分配一个值,其中相同的调用,在程序执行的同一点可以在代码中正常运行时给出 0 的值!

我唯一能想到的是这是一些奇怪的转换,但如果我分配的变量是 int、double 甚至是 string,我会得到相同的行为。

我什至不知道从哪里开始 - 帮助!

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    即时窗口和正常代码运行之间的唯一区别是范围。 即时窗口中的代码在当前应用程序范围内运行。 如果当前没有运行,这意味着全局范围。 放入 VBA 函数时的代码仅限于函数范围。

    所以我猜你的变量之一超出了范围。

    我会在该行的函数中设置一个断点并添加监视以找出未设置的变量。

    如果你的 vba 代码模块顶部没有 Option Explicit,你应该添加它。

    【讨论】:

      【解决方案2】:

      您没有分配函数名称,因此该函数将始终返回零(如果您期望一个 Long)。看来你应该有

      makeTheLookup = lMyRow

      在函数结束时。

      【讨论】:

        【解决方案3】:

        我不知道你是否还在看这个,但我会这样写:

        Function makeTheLookup(vItemID As Variant, rngMyRange as Range)as Long
            makeTheLookUp = WorksheetFunction.Match(vItemID, rngMyRange.Columns(1), 0)
        End Function
        

        【讨论】:

          【解决方案4】:

          我无法重现 Excel 2007 的问题。

          这是我使用的代码:

          Sub test()
          
          Dim vItemID As Variant
          Dim lMyRow As Long
          Dim rngMyRange As Range
          
              Set rngMyRange = ActiveWorkbook.Sheets(1).Range("A1:Z256")
          
              vItemID = 8
              lMyRow = WorksheetFunction.Match(vItemID, rngMyRange.Columns(1), 0)
          
              Debug.Print lMyRow
          
          End Sub
          

          这听起来可能很愚蠢,但您确定 Match 函数的所有参数在您的宏和即时窗口中都相同吗?也许范围对象已经改变?

          【讨论】:

          • 是的,这是一个有趣的问题 - 99.9% 的情况下,此调用都有效,但我无法确定失败时的区别!
          【解决方案5】:

          感谢大家的回答 - 我应该在下面拨打电话的方式上稍微具体一点:

          Function makeTheLookup(vItemID As Variant, rngMyRange as Range)
          
          Dim lMyRow As Long
          lMyRow = WorksheetFunction.Match(vItemID, rngMyRange.Columns(1), 0)
          
          End Function
          

          奇怪的是,我将这两个参数传递给函数,所以我看不出它们在函数内部和外部有什么不同。也就是说,我仍然完全不知道是什么原因造成的,特别是因为这是一个非常间歇性的问题

          是否有任何简单的方法可以将函数上下文中的范围对象与即时窗口上下文中的范围对象进行比较并判断它们是否不同?鉴于 range 是一种引用类型,感觉我应该只能比较两个指针,但我不知道如何在 VBA 中做到这一点!

          顺便说一下,我使用的是 Excel 2007,虽然我不确定这是否有什么不同。

          【讨论】:

          • 从即时窗口调用 ?makeTheLookup vItemID, rngMyRange 怎么样?这行得通吗(您应该让函数返回找到的值,而您的示例中不是这种情况)?
          【解决方案6】:

          正如上面提到的,这绝对是一个范围问题。或者一个不起眼的错误。

          我会尝试使用 Debug.print 语句以及 Watch,看看它们是否匹配,然后从那里获取。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-12-24
            • 1970-01-01
            • 1970-01-01
            • 2012-04-29
            • 1970-01-01
            • 2023-03-23
            • 1970-01-01
            相关资源
            最近更新 更多