Parameterized Constructors in VBA

VBA does not allow for parameterized constructors. We can work around that, though, using the Factory pattern and a strong naming convention.

Parameterized Constructors in VBA

If you are familiar with other object-oriented programming languages, you are likely familiar with the concept of constructors:

In class-based object-oriented programming, a constructor (abbreviation: ctor) is a special type of subroutine called to create an object. It prepares the new object for use, often accepting arguments that the constructor uses to set required member variables.

A constructor that accepts arguments is known as a parameterized constructor.  A constructor that does not require arguments is known as a default constructor.

The VBA language specification does not allow for parameterized constructors.

VBA does support default constructors, in the form of the Class_Initialize lifecycle handler:

"If a class defines a Class_Initialize lifecycle handler, that subroutine will be invoked as a method each time an instance of that class is created..."

Unfortunately, there is no way to pass parameters to the Class_Initialize handler.  Thus, it is impossible in VBA to require calling code to provide arguments when creating a class.  This differs from almost every other object-oriented programming language, as most OOP languages support parameterized constructors.

"In object-oriented programming (OOP), a factory is an object for creating other objects..." (Wikipedia)

To work around this shortcoming in VBA, I create a standard module that holds all the parameterized constructors for each of my applications.  I name this module, "xxFactory," where the "xx" is an application-specific prefix that distinguishes the module from other modules that I import from my standard code library.  For example, in my TaxColl2k application, I have a StringFunctions module that I keep in sync with my code library and a tcFactory module whose code has no value outside of the TaxColl2k application.

Here is an example of one of my factory functions:

Function NewSchoolObject(SchoolDist As String, _
                         DistrictID As String) As oSchool
    Set NewSchoolObject = New oSchool
    NewSchoolObject.Init SchoolDist, DistrictID
End Function

There are some naming conventions I want to point out in the above code.  Since there is nothing in VBA itself that requires the use of these functions, a strong and consistent naming convention greatly improves code quality.

The underlying object is named oSchool.  I use a variety of prefixes when naming my class modules.  The "o" prefix is reserved for classes that represent real-world objects.  These kinds of objects in my applications frequently have a one-to-one relationship with database tables, too.

The name of the factory function comprises three parts:

  • "New": a literal string that prefixes every one of my factory function names
  • "School": the underlying object name stripped of its prefix
  • "Object": a literal string that I append to each factory function name

Thus, every factory function name follows this format: New{class name}Object.

Finally, the underlying class has a public method named Init that takes the same parameters as the factory function.  The Init method must be public, but it should only ever be called from a factory function.

Here's how the code looks without using the factory function:

Dim School As oSchool
Set School = New oSchool
School.SchoolDist = "X"
School.DistrictID = 42

Here's the same code with the factory function:

Dim School As oSchool
Set School = NewSchoolObject("X", 42)

Image by LEEROY Agency from Pixabay

Your Commento.io account has been suspended. Go to the Commento dashboard to resolve this.

All original code samples by Mike Wolfe are licensed under CC BY 4.0