Are there any pitfalls in using class modules as namespaces in VBA
oop, vba
Solution
No other answers so far...
The pitfalls I've come up with myself are more limitations and gotchas:
- You need to set the Instancing property of each class to "2 - PublicNotCreatable". Otherwise if the project is compiled and then referenced from another project, the members will not appear in the Object Browser (though they will still be useable)
- You cannot declare external API declarations in a class module as Public. In order to expose them to code outside the class you must do the `Declare` as private and then make a public wrapper method.
- This still does not allow you to organize types in namespaces -- only collections of static methods.
- From queries and macros you can only call global methods defined in a standard module. So to use any functions wrapped up in namespace classes you'll have to define wrappers in a standard module, reflattening the heirarchy.
Problem
VBA does not support namespaces (packages for Java poeple). Namespaces in other languages help avoid ambiguity and supplement tools like autocompletion of member names. One way to simulate namespaces in VBA is to declare what are defacto static methods in a Class module and then declare a default instance of that class in a standard module. This is even the pattern followed in some Microsoft documentation. You can use this approach to nest pseudo-namespaces as well. Do you, my peers, anticipate any technical problems with using this approach? This is not a poll question; I'm not asking about the orthodoxy or aesthetic appeal. I'm asking, "will this cause problems? If so, what?" Example: ``` ' Class module called clsIOText Public Function ReadAllText(ByVal FileName As String) As String With New FileSystemObject With .OpenTextFile(FileName, ForReading) ReadAllText = .ReadAll .Close End With End With End Function ' Class module call clsIO Public Text As New clsIOText ' In a standard module somewhere Public IO As New clsIO ' Usage like a namespace ' 1. Fully qualified Debug.Print IO.Text.ReadAllText("C:\temp\example.txt") ' 2. With a namespace alias-like object Dim Text As clsIOText Text = IO.Text Debug.Print Text.ReadAllText("C:\temp\example.txt") ```