在VBA中评估()

8 debugging excel vba excel-vba expression-evaluation

嗨,欢迎来到Evaluate()之谜


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

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


因此,我运行了一个非常简单的代码来查看Microsoft的Evaluate()方法文档的准确性.
毫不奇怪,我得到了一个奇怪但一致的结果.
注意: 执行Immediate Window CTRL+ 中的4个命令中的每一个G.查看每个呼叫的差异.注意内置错误,它显示每个MsgBox两次.请记住这一点,不要混淆......
将此代码粘贴在一个模块中

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

然后在立即窗口中执行这4个命令(每次1个)

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

前2个立即执行代码; 对我来说意味着他们已经评估了代码.第三个(根据文档)应该是,Evaluating但它的行为方式与模块正文中的行为不同.然后立即窗口给出了Error 2023一个模块体内相同的调用执行它,就好像你正在调用一个sub.It等等,20 seconds如果它是一个正常Call SleepESub()的4号调用.

任何人都能解释我在这里缺少的东西吗?第3行不是正确的Evaluation电话吗?或者它是否评估对sub本身的调用(如果这是有道理的)


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

' 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
Run Code Online (Sandbox Code Playgroud)

Mon*_*ild 6

在我看来,执行代码的不同方式的不同之处在于它运行的线程 - UI线程或后台线程,以及解析器. Evaluate对于明确定义的函数,执行函数的处理方式不同,从立即窗口调用的函数的处理方式也略有不同.

在:

Sub ModuleBody()
    Evaluate ("SleepESub()")
    [SleepESub()]
    [SleepESub]
    SleepESub
End Sub
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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