8

嗨,欢迎来到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

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

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

前 2 个立即执行代码;对我来说意味着他们已经评估了代码。第三个(根据文档)应该是Evaluating,但它的行为方式与在模块的 body 中的行为方式不同。立即窗口正在给出一个Error 2023但是来自模块主体内的相同调用执行它,就好像您正在调用一个子程序一样。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
4

2 回答 2

6

在我看来,执行代码的不同方式的不同之处在于它运行的线程——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 5000API 调用时,会发生等待(两次!- 提到的那个错误),但使用 时Application.Wait Now + TimeValue("0:00:05"),不会发生延迟。

于 2013-07-23T00:18:15.103 回答
-1

我认为说第三次调用没有评估是错误的:它确实评估了提供的对象,并返回它的值(如文档所述)。

我稍微修改了 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 的调试输出)
  • 例程的调用次数(一次或两次调用)

不过,我对这些差异中的任何一个都没有解释。

于 2013-07-09T08:27:17.393 回答