【问题标题】:Why can't I use Call infront of DoEvents?为什么我不能在 DoEvents 前面使用 Call?
【发布时间】:2016-12-19 13:31:59
【问题描述】:

在 VBA 中,您可以在调用方法/函数之前加上 Call,以明确告诉编译器您不想使用返回值(如果有的话)。

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

当我输入时:

Call DoEvents

编译时它只是说“语法错误”。

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


在 Excel 2016、IIRC 中使用 VBE 中的 VBA,它在 2013 年、2010 年等中也不起作用。

【问题讨论】:

  • 我认为你不能调用 VBA 交互类的任何成员(Environ、MsgBox 等)
  • @JiminyCricket Call MsgBox("Test", vbOKOnly) 绝对有效。 DoEvents 是第一个(功能?)我偶然发现它不允许我 Call
  • 啊,我尝试将其用作子 Call MsgBox "Test" 不起作用。最好不要使用 Call 而只是使用 DoEvents。我将其用作所有 Subs 和 Functions 的一般做法,因为它减少了代码/视觉混乱
  • @JiminyCricket 我公司的指导方针是尽可能使用 call,由于它与 vb.net 代码相似,它使非 vba 编码器的代码更具可读性。我只想知道为什么我不能使用它,而不是如何。过去几年只写 DoEvents 效果很好

标签: excel vba call doevents


【解决方案1】:

tldr;可以Call它,但只能从 VBA 模块中明确显示。

正如@Gary'sStudent (see the application agnostic version here) 链接的文档指出的那样,DoEvents 实际上是Function 而不是Sub,它在VBA 中总是返回0。在未托管的 Visual Basic(即 VB6)中,它返回打开窗口的总数。对于为什么它返回零,我完全没有根据的猜测是,在 VBA 中,代码正在运行的进程的顶级窗口不属于您正在执行的代码。

函数本身位于VBA.Interaction 模块中,如您在对象浏览器中所见:

也就是说,您应该注意,您可以使用DoEvents 前面带有Call 关键字的函数 - 但您需要明确引用VBA 程序集:

Sub Example()
    'This is perfectly fine.
    Call VBA.DoEvents
End Sub

同样,这只是猜测,但我怀疑原因与内部实现有关。通常这将调用SwitchToThread 函数(vbe7.dll 确实导入了该函数)。但返回值的性质指向枚举产生的窗口,因此它可能只需要VBA 的句柄即可运行。 typelib 中没有任何内容表明它与 Interaction 模块中的任何其他函数不同(尽管我可能在某处遗漏了一个标志):

[entry(598), helpcontext(0x000f7900)]
short _stdcall DoEvents();

编译错误“Expected: identifier”的性质表明存在某种内部事物“隐藏”DoEvents 对全局可访问的 VBA 函数。


最后一点:Call Foo 语法完全是多余的——它所做的只是显式地丢弃函数的返回值。不分配返回值的作用完全相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 2020-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多