在VBA中评估()

您好,欢迎来到Evaluate()的神秘面纱


MSDN Office开发人员参考(2013年)文档说:

使用方括号(例如,“[A1:C5]”)与使用字符串参数调用Evaluate方法相同。


因此,我运行了一个非常简单的代码,以了解Microsoft的Evaluate()方法的文档的准确性。
毫不奇怪,我得到了一个奇怪的,但一致的结果。
注意:Immediate Window CTRL + G中执行4个命令中的每一个。 查看每个调用的区别。 注意显示每个MsgBox两次的内置错误 。 请记住这一点,不要感到困惑......
将此代码粘贴到模块中

Private Sub SleepESub()
    Application.Wait Now + TimeValue("0:00:20")
    MsgBox "w8'd "
End Sub

然后在即时窗口中执行这4个命令(一次一个)

? Evaluate ("SleepESub()")
? [SleepESub()]
? [SleepESub]
? SleepESub

前两个代码立即执行; 对我来说意味着他们评估了代码。 第三个(根据文档)应该是Evaluating但它不像它在模块的主体中​​那样行事。 即时窗口给出了一个Error 2023然而,来自模块内部的相同调用执行它,就好像你正在调用一个sub.It一样等待20 seconds好像它是一个正常的Call SleepESub() ,这是4号呼叫。

任何人都可以解释我在这里失踪了吗? 第3行是不是一个适当的Evaluation电话? 还是它评估调用本身(如果这是有道理的)


更新:
我认为有些人误解我在这里评估的内容 - 不要担心这是一个高级话题,我不是一个书作家,你不介意读者。 (原谅我...)
为了获得更好的想法,您可以比较即时窗口与模块正文的结果。 试试这个代码:

' Run each of the calls separately
' in a module's body and compare it with 
' the previous calls from the Immediate Window
    Sub ModuleBody()
        Evaluate ("SleepESub()")
        '[SleepESub()]
        '[SleepESub]
        'SleepESub
    End Sub

在我看来,执行代码的不同方式会有什么不同,它会运行的线程 - UI线程或后台线程以及解析器。 Evaluate执行的函数的处理方式与明确定义的函数的处理方式不同,并且从即时窗口调用的函数也会稍有不同。

在:

Sub ModuleBody()
    Evaluate ("SleepESub()")
    [SleepESub()]
    [SleepESub]
    SleepESub
End Sub

Evaluate ("SleepESub()")[SleepESub()]似乎期望一个公式,并且Private Sub SleepESub()根本没有被执行。

根据解析器如何处理过程,每个命令可以在单个线程中按顺序执行,从而导致Application.Wait的延迟,或者Application.Wait可能被认为仅在UI线程上有效,并且被跳过当在后台线程上运行时。

这可以通过以下代码进行确认,由立即窗口中的?[SleepESub()]?Evaluate("SleepESub()")执行:

Private Declare PtrSafe Sub sapiSleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
Private Sub SleepESub()
    'Application.Wait Now + TimeValue("0:00:05")
    sapiSleep 5000
    MsgBox "w8'd "
End Sub

当使用sapiSleep 5000 API调用时,发生等待(两次! - 提到的错误),但是当使用Application.Wait Now + TimeValue("0:00:05") ,不会发生延迟。


我认为说第三个调用不是评估是错误的:它确实评估提供的对象,并返回它的值(如记录)。

我稍微修改了Sub来说明:

Private Function SleepESub()
    Debug.Print Application.Wait(Now + TimeValue("0:00:02"))
    MsgBox "w8'd "
    SleepESub = 42
End Function

如预期的那样,4个评估呼叫中的每一个确实将返回42。

有什么不同是:

  • 应用程序上下文(在一种情况下,对Application.Wait的调用成功,在另一种情况下失败 - 注意调试输出返回true或false)
  • 对例程的调用次数(一次或两次调用)
  • 不过,我没有解释这些差异。

    链接地址: http://www.djcxy.com/p/72637.html

    上一篇: Evaluate() in VBA

    下一篇: Dart language support async/await programming style, or similar?