简体   繁体   English

在VBA中进行Evaluate()

[英]Evaluate() in VBA

Hi and welcome to the Evaluate() mystery 嗨,欢迎来到Evaluate()之谜


The MSDN Office Developer Reference (2013) Documentation says: MSDN Office开发人员参考(2013)文档说:

Using square brackets (for example, "[A1:C5]") is identical to calling the Evaluate method with a string argument. 使用方括号(例如,“ [A1:C5]”)与使用字符串参数调用Evaluate方法相同。


So, I have ran a very simple code to see how accurate the Microsoft's Documentation of the Evaluate() method is. 因此,我运行了一个非常简单的代码,以查看Microsoft的Evaluate()方法的文档的准确性。
Not surprisingly, I am getting a strange albeit consistent result. 毫不奇怪,尽管得到了一致的结果,但我得到了一个奇怪的结果。
note: execute each of the 4 commands in the Immediate Window CTRL + G . 注意: Immediate Window CTRL + G中执行这4条命令。 See the difference in each of the calls . 查看每个调用的区别 Notice the built-in bug which shows each MsgBox twice . 注意内置错误 ,该错误每个MsgBox两次显示 Just keep that in mind and do not get confused... 请记住这一点,不要感到困惑...
Stick this code in a module 将此代码粘贴到模块中

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

then execute these 4 commands ( 1 at a time ) in the Immediate Window 然后在立即窗口中执行这4条命令(一次1条)

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

The first 2 execute the code right away; 前两个立即执行代码。 means to me they have evaluated the code. 对我来说意味着他们已经评估了代码。 The third one (according to the documentation) should be Evaluating but it doesn't act the same way as it does in a module's body . 第三篇文章(根据文档)应该是Evaluating但其作用方式与模块主体中的方式不同 The Immediate Window is giving an Error 2023 however the same call from within a module's body executes it as if you were calling a sub.It waits the 20 seconds like if it was a normal Call SleepESub() which is the number 4 call. 即时窗口显示Error 2023但是从模块主体内部执行的相同调用就像执行子调用一样执行,它等待20 seconds就像它是普通的Call SleepESub()即4号调用)一样。

Can anyone explain what I am missing here? 谁能解释我在这里缺少什么? Is the line number 3 not a proper Evaluation call? 3号线不是正确的Evaluation电话吗? or does it evaluate the call to sub itself (if that makes sense) 还是评估对sub本身的调用(如果有意义)


Update: 更新:
I think some people are misunderstanding what I am evaluating here - don't worry it is an advanced topic and I am not a book writer and you are not mind readers. 我认为有些人误会了我在这里评估的内容-不用担心这是一个高级话题,我不是读书作家,而且您不是介意读者。 ( forgive me... ) 原谅我...
To get a better idea you can compare results from the immediate window vs. module's body. 为了获得更好的主意,您可以比较即时窗口与模块主体的结果。 Try this code: 试试这个代码:

 ' 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 

It would appear to me that what differs in the different ways of executing the code would be the thread that it runs on - the UI thread or a background thread, and the parser. 在我看来,执行代码的不同方式不同之处在于它运行的线程-UI线程或后台线程,以及解析器。 Evaluate executed functions would be handled differently to explicitly defined functions, and functions called from the Immediate window would be handled slightly differently also. Evaluate执行的函数将与显式定义的函数进行不同的处理,并且从“即时”窗口调用的函数的处理也将稍有不同。

In: 在:

Sub ModuleBody()
    Evaluate ("SleepESub()")
    [SleepESub()]
    [SleepESub]
    SleepESub
End Sub

Evaluate ("SleepESub()") and [SleepESub()] appear to be expecting a formula, and Private Sub SleepESub() is not being executed at all. Evaluate ("SleepESub()")[SleepESub()]似乎期望公式,并且完全不执行Private Sub SleepESub()

Depending on how the parser handles the procedure, each command may be executed in sequence in a single thread, resulting in the delay from the Application.Wait , or the Application.Wait may be considered to be valid only on the UI thread, and skipped when run on a background thread. 根据解析器处理该过程的方式,每个命令可能会在单个线程中按顺序执行,从而导致Application.WaitApplication.Wait的延迟仅在UI线程上才有效,因此被跳过在后台线程上运行时。

This can be confirmed by the following code, executed by ?[SleepESub()] or ?Evaluate("SleepESub()") in the Immediate window: 这可以通过以下代码来确认,该代码由?Evaluate("SleepESub()")立即”窗口中的?[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

When using the sapiSleep 5000 API call, the wait occurs (twice! - that bug that was mentioned), but when using Application.Wait Now + TimeValue("0:00:05") , no delay occurs. 使用sapiSleep 5000 API调用时,会发生等待(两次!-提到的那个错误),但是使用Application.Wait Now + TimeValue("0:00:05") ,不会发生延迟。

I think that it is wrong to state that the 3rd call is not evaluating : it does indeed evaluate the provided object, and return its value (as documented). 我认为声明第三个调用没有评估是错误的:它确实评估了提供的对象并返回其值(如文档所示)。

I have slightly modified the Sub to illustrate: 我稍微修改了Sub来说明:

Private Function SleepESub()
    Debug.Print Application.Wait(Now + TimeValue("0:00:02"))
    MsgBox "w8'd "
    SleepESub = 42
End Function

Each of the 4 evaluation calls will indeed return 42 as expected. 4个评估调用中的每一个确实将按预期返回42。

What is different is: 不同的是:

  • the application context (in one case the call to Application.Wait succeeds, in the other it fails - notice the debug output which returns either true or false) 应用程序上下文(在一种情况下,对Application.Wait的调用成功,而在另一种情况下,则失败-请注意调试输出,返回true或false)
  • the number of calls to the routine (one or two calls) 例程的调用次数(一次或两次调用)

I have no explanation for either of these differences, though. 不过,我没有任何解释。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM