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, clsMyClass
:
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
Explicit Instantiation
With explicit instantiation, you create a new instance of the class using the Set
statement:
Sub Explicit()
Dim MyClass As clsMyClass
Set MyClass = New clsMyClass
Debug.Print MyClass.CreatedAt
End Sub
Implicit Instantiation
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
Predeclared Instantiation
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:
NOTE: 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