Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Excel VBA type mismatch - Public Object

I am trying to read a global public Object foo. I declared it in one module and want to read it in every other module. Why do I get a type mismatch error?

Modul1:

Public Sub Test()
    If foo Is Nothing Then MsgBox "Foo is not initialized", vbOKOnly
End Sub

foo:

Public foo As Object

VBA Screenshot

like image 712
Tom Stevens Avatar asked Jan 01 '23 01:01

Tom Stevens


1 Answers

What's happening is a phenomenon called identifier shadowing: the public variable foo exists in the same scope as the module foo.

And since Sub Test doesn't exist in the same module as the foo variable, the identifier foo in Modul1 resolves to the module foo, because it syntactically can: the syntax does not differentiate between a standard module and a class module with a VB_PredeclaredId attribute, so this:

If Foo Is Nothing Then

Is syntactically no different than:

If UserForm1 Is Nothing Then

Or:

If ThisWorkbook Is Nothing Then

VBA will always try to resolve an in-scope identifier to a module if a module exists by that name... unless it's a class module without a VB_PredeclaredId attribute, in which case it knows you can't possibly be referring to the class itself (a class is a type, not an object). Arguably VBA should be smart enough to also know that a standard module isn't an object either, but I wouldn't hold my breath for a fix ;-)


Rubberduck (disclaimer: I'm heavily involved in this open-source project) can shed more light about what's resolving to what:

context-sensitive selection shows what 'Foo' is resolving to

You can use the Foo (the module) as a qualifier for Foo (the variable) to fix the compile error:

If Foo.Foo Is Nothing Then

This is now unambiguous, because now Foo.Foo is clearly referring to the member Foo of the module Foo.

Another (perhaps better) solution, would be to rename either the module or the variable.

like image 68
Mathieu Guindon Avatar answered Feb 28 '23 01:02

Mathieu Guindon