Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VBA中的Evaluate()_Vba_Excel_Debugging_Expression Evaluation - Fatal编程技术网

VBA中的Evaluate()

VBA中的Evaluate(),vba,excel,debugging,expression-evaluation,Vba,Excel,Debugging,Expression Evaluation,大家好,欢迎来到神秘世界 MSDN Office Developer Reference(2013)文档说明: 使用方括号(例如,“[A1:C5]”)与调用 带有字符串参数的求值方法 所以,我运行了一个非常简单的代码,看看这个方法有多精确 毫不奇怪,我得到了一个奇怪但一致的结果。 注意:执行即时窗口中的4个命令中的每一个CTRL+G。查看每个调用中的差异。请注意内置的bug,它将每个MsgBox显示两次。记住这一点,不要感到困惑…… 将此代码粘贴到模块中 Private Sub SleepE

大家好,欢迎来到神秘世界

MSDN Office Developer Reference(2013)文档说明:

使用方括号(例如,“[A1:C5]”)与调用 带有字符串参数的求值方法


所以,我运行了一个非常简单的代码,看看这个方法有多精确
毫不奇怪,我得到了一个奇怪但一致的结果。
注意:执行
即时窗口中的4个命令中的每一个
CTRL+G。查看每个调用中的差异。请注意内置的bug,它将每个MsgBox显示两次。记住这一点,不要感到困惑……
将此代码粘贴到模块中

Private Sub SleepESub()
    Application.Wait Now + TimeValue("0:00:20")
    MsgBox "w8'd "
End Sub
然后在即时窗口中执行这4个命令(每次1个)

?评估(“SleepESub()”

?[SleepESub()]

?[SleepESub]

?SleepESub

前2个立即执行代码;对我来说意味着他们已经评估了代码。第三个(根据文档)应该是
评估
,但它的作用方式与模块主体中的不同。即时窗口给出了一个
错误2023
,但是来自模块主体内的同一调用执行该错误,就像您正在调用sub一样。它等待
20秒
,就像它是一个正常的
调用SleepESub()
,这是第4个调用一样

有人能解释我在这里遗漏了什么吗?3号线是否不是正确的
评估
呼叫?或者它是否评估对sub本身的调用(如果有意义的话)


更新:
我想有些人误解了我在这里的评价——别担心这是一个高级话题,我不是一个作家,你们也不是读心术的人。(原谅我…)
为了获得更好的想法,您可以比较即时窗口和模块主体的结果。请尝试以下代码:


我认为说第三个调用没有计算是错误的:它确实计算提供的对象,并返回其值(如文档所示)

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

不过,我对这两种差异都没有解释。

在我看来,执行代码的不同方式的不同之处在于它所运行的线程—UI线程或后台线程,以及解析器<代码>求值执行的函数的处理方式与显式定义的函数不同,从即时窗口调用的函数的处理方式也略有不同

在:

Evaluate(“SleepESub()”)
[SleepESub()]
似乎需要一个公式,并且根本没有执行
私有子SleepESub()

根据解析器处理过程的方式,每个命令可能在单个线程中按顺序执行,从而导致
应用程序的延迟。Wait
,或
应用程序的延迟。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”)
时,不会发生延迟。

有趣。我需要删除最后两个的
Run(“SleepESub”)
Run(“SleepESub()”
类似,但
Evaluate(“SleepESub”)
不起作用。发生什么事?!使用Excel 2010(评估文档与2013相同),
?评估(“SleepESub”)
返回
错误2029
;与
相同?[SleepESub]
。我认为2010年是“干净的”(与文档相符)@d-stroyer
?[SleepESub]
(从即时窗口调用)确实会返回一个
错误2029
,但是如果您在模块主体内进行相同的调用,它确实会工作,虽然没有计算,但它只是像调用sub一样执行。我开始怀疑,在这种情况下,方括号是否只是被忽略了,因为编译器认为
[SleepESub]=SleepyESub
。另一方面,如果即时窗口给出错误,那么来自模块主体的同一调用是如何工作的?如果更改SleepESub的声明使其成为公共的,那么
[SleepESub]
将从即时窗口工作。与模块主体的结果相同(无明显的计算)。
预期的函数或变量。
即使在Excel 2010中未将其设置为私有,也会出现错误。我不认为这是可见度的问题。另外,我不知道为什么我会出错,但这对你是有效的:你是对的!我错了,假设前两个调用已被评估,但它们没有-它们已部分执行。
应用程序.Wait
被省略,即使msgbox显示它没有正确执行
SleepESub
。从模块调用
ModuleBody
与从即时窗口调用
ModuleBody确实有区别。值得一提的是,
[SleepESub]=SleepESub
。实际上,在Evaluate(“SleepESub()”)和[SleepESub()]中,根本没有执行Private Sub SleepESub()——请尝试在Sub ModuleBody()和Private Sub SleepESub()行上设置断点,当您单步执行代码时,您将看到Private Sub SleepESub SleepESub())在ModuleBody()中的这两行中没有命中。
Sub ModuleBody()
    Evaluate ("SleepESub()")
    [SleepESub()]
    [SleepESub]
    SleepESub
End Sub
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