8 debugging excel vba excel-vba expression-evaluation
嗨,欢迎来到Evaluate()之谜
使用方括号(例如,"[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)
在我看来,执行代码的不同方式的不同之处在于它运行的线程 - 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"),不会发生延迟.