5

In VBA, you can call your methods/functions with Call ahead of them, to tell the compiler explicitly that you don't want to use the return value if there is any.

Now the DoEvents function should also be possible to be called via Call, but I can't make it happen.

When I type:

Call DoEvents

it simply says "syntax error" when compiling.

Why can't I use Call infront of DoEvents?


Using VBA from the VBE in Excel 2016, IIRC it also didn't work in 2013, 2010, etc.

Mafii
  • 6,538
  • 1
  • 33
  • 52
  • I don't think you can call any member of the VBA Interaction Class (Environ, MsgBox etc) – Jiminy Cricket Dec 19 '16 at 13:44
  • @JiminyCricket `Call MsgBox("Test", vbOKOnly)` definitely works. `DoEvents` is the first (function?) I stumbeled upon that didn't allow me to `Call` it – Mafii Dec 19 '16 at 13:46
  • Ahh, I tried using it as a sub Call MsgBox "Test" doesn't work. Best off just not using Call and simply using DoEvents. I used that as general practice for all Subs and Functions as it cuts down on code/visual clutter – Jiminy Cricket Dec 19 '16 at 13:58
  • 1
    @JiminyCricket my companies guidelines are to use call whenever possible, it makes the code more readable for non vba coders due to its similarity to vb.net Code. I Just want to know why I cant use it, not how. Just writing DoEvents has worked fine the last years – Mafii Dec 19 '16 at 14:24

1 Answers1

3

tldr; You can Call it, but only explicitly from the VBA module.

As the documentation linked by @Gary'sStudent (see the application agnostic version here) points out, DoEvents is actually a Function not a Sub, and it will always return 0 in VBA. In unhosted Visual Basic (i.e. VB6) it returns the total number of open windows. My completely unsubstantiated guess as to why it returns zero is that in VBA the top level window of the process that the code is running isn't owned by the code you're executing.

The function itself is in the VBA.Interaction module, as you can see in the Object Browser:

DoEvents in the Object Browser

That said, you should note that you can use the DoEvents function preceded by the Call keyword - but you need to explicitly reference the VBA assembly:

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

Again, this is just speculation, but I suspect the reason has to do with the internal implementation. Typically that would be calling the SwitchToThread function (which the vbe7.dll does import). But the nature of the return value points to enumerating the windows that are yielded to, so it probably just needs a handle to VBA to run. There isn't anything in the typelib that suggests it's different from any of the other functions in the Interaction module (although there may be a flag that I missed somewhere):

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

The nature of the compile error "Expected: identifier" indicates that there is something internal that is "hiding" DoEvents from the globally accessible VBA functions.


Final note: The Call Foo syntax is completely superfluous - all it does is explicitly discard the return value of a function. Not assigning the return value does exactly the same thing.

Comintern
  • 20,878
  • 5
  • 30
  • 73