您好,欢迎来到Evaluate()谜团
<小时/>Using square brackets (for example, "[A1:C5]") is identical to calling the Evaluate method with a string argument.
所以,我运行了一个非常简单的代码来查看 Microsoft's Documentation of the Evaluate() 的准确度。方法是。
毫不奇怪,我得到了一个奇怪但一致的结果。
注意: 在立即窗口
中执行 4 个命令中的每一个 CTRL+G。查看每个调用的差异。请注意内置的错误,它将每个 MsgBox 显示两次。请记住这一点,不要混淆......
将此代码粘贴到模块中
Private Sub SleepESub()
Application.Wait Now + TimeValue("0:00:20")
MsgBox "w8'd "
End Sub
然后在立即窗口中执行这 4 个命令(一次 1 个)
?评估(“SleepESub()”)
? [SleepESub()]
? [SleepESub]
? SleepESub
前 2 个立即执行代码;对我来说意味着他们已经评估了代码。第三个(根据文档)应该是评估
,但它的行为方式与在模块的主体。立即窗口给出错误 2023
,但是来自模块体内的相同调用会像调用子程序一样执行它。它会等待 20 秒
就好像这是一个普通的 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
最佳答案
在我看来,执行代码的不同方式的不同之处在于它运行的线程 - 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")
,不会出现延迟。
关于vba - VBA 中的评估(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17484571/