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
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With