vbaclassoopconstructorfactory

Pass arguments to Constructor in VBA


How can you construct objects passing arguments directly to your own classes?

Something like this:

Dim this_employee as Employee
Set this_employee = new Employee(name:="Johnny", age:=69)

Not being able to do this is very annoying, and you end up with dirty solutions to work this around.


Solution

  • Here's a little trick I'm using lately and brings good results. I would like to share with those who have to fight often with VBA.

    1.- Implement a public initiation subroutine in each of your custom classes. I call it InitiateProperties throughout all my classes. This method has to accept the arguments you would like to send to the constructor.

    2.- Create a module called factory, and create a public function with the word "Create" plus the same name as the class, and the same incoming arguments as the constructor needs. This function has to instantiate your class, and call the initiation subroutine explained in point (1), passing the received arguments. Finally returned the instantiated and initiated method.

    Example:

    Let's say we have the custom class Employee. As the previous example, is has to be instantiated with name and age.

    This is the InitiateProperties method. m_name and m_age are our private properties to be set.

    Public Sub InitiateProperties(name as String, age as Integer)
    
        m_name = name
        m_age = age
    
    End Sub
    

    And now in the factory module:

    Public Function CreateEmployee(name as String, age as Integer) as Employee
    
        Dim employee_obj As Employee
        Set employee_obj = new Employee
    
        employee_obj.InitiateProperties name:=name, age:=age
        set CreateEmployee = employee_obj
    
    End Function
    

    And finally when you want to instantiate an employee

    Dim this_employee as Employee
    Set this_employee = factory.CreateEmployee(name:="Johnny", age:=89)
    

    Especially useful when you have several classes. Just place a function for each in the module factory and instantiate just by calling factory.CreateClassA(arguments), factory.CreateClassB(other_arguments), etc.

    EDIT

    As stenci pointed out, you can do the same thing with a terser syntax by avoiding to create a local variable in the constructor functions. For instance the CreateEmployee function could be written like this:

    Public Function CreateEmployee(name as String, age as Integer) as Employee
    
        Set CreateEmployee = new Employee
        CreateEmployee.InitiateProperties name:=name, age:=age
    
    End Function
    

    Which is nicer.