3 Ways to Create Class Instances in VBA
Before you can use a class, you need to create an instance of the class and assign it to an object variable. ... Or do you?
You can't directly call the functions and procedures of a class module the way you can a standard module.
Instead, you create an instance of the class module and then call the class's functions and procedures from that instance. Consider the following class,
Option Explicit Dim mCreatedAt As Date Private Sub Class_Initialize() mCreatedAt = VBA.Now() End Sub Public Property Get CreatedAt() As Date CreatedAt = mCreatedAt End Property
With explicit instantiation, you create a new instance of the class using the
Sub Explicit() Dim MyClass As clsMyClass Set MyClass = New clsMyClass Debug.Print MyClass.CreatedAt End Sub
With implicit instantiation, you declare the object variable
As New. An instance of the object is automatically created the first time it gets used. The
Set statement is not required:
Sub Implicit() Dim MyClass As New clsMyClass Debug.Print MyClass.CreatedAt End Sub
With predeclared instantiation, you set the hidden class module attribute
VB_PredeclaredID equal to
True (see the HOW-TO section below). VBA creates a default instance of the class with the same name as the class. As with implicit instantiation, the default instance gets created the first time it is used.
With predeclared instantiation, you don't need to declare an object variable at all:
Sub Predeclared() Debug.Print clsMyClass.CreatedAt End Sub
Notes, Caveats, and How-Tos
CAVEAT: A warning about implicit instantiation
There is one very important thing to know about implicit instantiation: the
Is Nothing conditional will always return False for an object variable declared
As New. Even if the object has not been created, the simple act of checking it to see if it exists is enough for VBA to automatically create a new instance if needed.
Sub Implicit_IsNothingTest() Dim MyClass As New clsMyClass Debug.Print MyClass.CreatedAt Set MyClass = Nothing Debug.Print MyClass Is Nothing 'Returns False End Sub
HOW-TO: Setting the PredeclaredID Attribute
The PredeclaredID attribute is completely hidden in the VBA IDE.
I know of only two ways to set it.
The Manual Method: Export - Import Cycle
The traditional way this has been done in VBA is as follows:
- Export the class module to a text file: File > Export File (Ctrl + E)
- Open the exported text file in a text editor
- Change the VB_PredeclaredID value from False to True
- Save and close the text file
- Delete the clsMyClass class module
- Import the text file: File > Import File (Ctrl + M)
The Automatic Method: Rubberduck VBA
This method requires that you first install the Rubberduck VBA Add-in.
Once that is done, you can use the Rubberduck PredeclaredID attribute to set this value directly in your source code:
VB_PredeclaredID = True Still Allows for Other Instances
Even if the VB_PredeclaredID attribute is set to True, you can still create other instances of the class. For example:
Option Explicit Private Declare PtrSafe Sub Sleep Lib "kernel32" _ (ByVal dwMilliseconds As Long) Sub Predeclared_MultiInstance() Debug.Print "A: "; clsMyClass.CreatedAt Sleep 2000 Dim AnotherInstance As clsMyClass Set AnotherInstance = New clsMyClass Debug.Print "B: "; AnotherInstance.CreatedAt Sleep 3000 Debug.Print "A: "; clsMyClass.CreatedAt End Sub