为什么我不能在DoEvents前面使用Call?

5

在VBA中,您可以在方法/函数前面加上Call,明确告诉编译器如果有返回值,则不想使用它。

现在,应该也可以通过Call调用DoEvents函数,但我无法实现它。

当我输入:

Call DoEvents

编译时会简单地提示“语法错误”。

为什么我不能在DoEvents前使用Call


使用来自Excel 2016中VBE的VBA,据我所知,它也无法在2013、2010等版本中工作。


我认为您不能调用VBA交互类的任何成员(Environ、MsgBox等)。 - Jiminy Cricket
@JiminyCricket,Call MsgBox("Test", vbOKOnly) 肯定可以工作。DoEvents 是我遇到的第一个(函数?),它不允许我进行调用。 - Mafii
啊,我尝试将它作为子程序调用,但是MsgBox“测试”不起作用。最好不要使用Call,而是直接使用DoEvents。我将其用作所有Sub和Function的通用做法,因为它可以减少代码/视觉混乱。 - Jiminy Cricket
1
@JiminyCricket,我们公司的指导方针是尽可能使用Call,因为它与vb.net代码相似,使得非VBA编程人员更容易阅读代码。我只是想知道为什么我不能使用它,而不是如何使用它。在过去的几年中,仅编写DoEvents就可以正常工作。 - Mafii
1个回答

3

tldr;可以从VBA模块明确地调用它。

正如@Gary'sStudent链接的文档(请参阅此处的应用程序无关版本)所指出的,在VBA中,DoEvents实际上是一个Function而不是Sub,并且它总是返回0。在未托管的Visual Basic(即VB6)中,它返回打开窗口的总数。我完全没有根据的猜测是它为什么会返回零,因为在VBA中,代码正在运行的进程的顶级窗口不是由你执行的代码拥有。

该函数本身位于VBA.Interaction模块中,正如你可以在对象浏览器中看到的:

DoEvents in the Object Browser

请注意,您可以在使用Call关键字之前使用DoEvents函数,但需要明确引用VBA程序集。
Sub Example()
    'This is perfectly fine.
    Call VBA.DoEvents
End Sub

再次强调,这只是猜测,但我怀疑原因与内部实现有关。通常情况下会调用SwitchToThread函数(vbe7.dll导入的函数)。但返回值的性质指向了枚举产生的窗口,所以可能只需要一个VBA句柄来运行。在类型库中没有任何提示表明它与Interaction模块中的任何其他函数不同(虽然可能有我错过的标志):

[entry(598), helpcontext(0x000f7900)]
short _stdcall DoEvents();
编译错误“预期:标识符”的本质表明,有些内部因素正在将DoEvents隐藏在全局可访问的VBA函数之外。请注意保留HTML标签。
最后说明: Call Foo 语法完全是多余的 - 它只是显式地丢弃函数的返回值。不 分配 返回值也会产生完全相同的效果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接