How to use comparison methods between class object modules in VBA in a similar manner as VB.NET?
Due to new project in VBA I moved from VB.NET, to be honest don't really know how to deal between objects classes here. What I want to reach is comparing objects between different class object modules.
e.g
class Employee
properties: Name
, Age
point is: compare Name
s between two Employees
classes: Employee and Manager
point is: compare Name
from Employee with Name
of Manager
I know how to in VB.NET, but how do I compare properties of different class module objects in VBA?
VBA doesn't support class polymorphism so I recommend to change the way you're thinking about the Employee
and Manager
classes.
You can't have an Employee
class as a base class and then a separate Manager
class that derives from Employee
. They could be 2 separate classes implementing a common interface.
I will talk about it in detail in a bit. Let's now go through a few examples...
↓ Easy approach ↓
A
base
class (Person
) and child classes which derive from the base class. (applies to C#, VB.NET, etc)
but in VBA you have to think of it like this:
A base class which exposes an enum property describing the position.
Something like
This is the easiest way to have a class exposing some properties. It allows you to add your Person
objects into a collection and iterate over using the easy for each
loop with Intellisense!
Properties comparison system would be very very easy
note: same applies to enum as its implicitly converted to a number
↓ More complex approach ↓
Two separate classes which both expose public properties. For instance you have an Employee
and Manager
classes which both implement a Person
Interface and an additional Comparer
class exposing a Compare()
method
In your VBA Project you need 4 class modules and a standard module
Person
(this is your Interface)
Public Property Get Name() As String
End Property
Public Property Get Age() As Long
End Property
this class is the interface which both the Employee
and Manager
both need to implement to share some common functions (getters for Names and Ages). Having the interface allows you to do the for each loop using the interface type variable as the enumerator. You will see in a minute.
Employee
and Manager
are identical. Obviously you may modify them to suit your real life solution.
Implements Person
Private name_ As String
Private age_ As Long
Public Property Get Name() As String
Name = name_
End Property
Public Property Let Name(ByVal Value As String)
name_ = Value
End Property
Public Property Get Age() As Long
Age = age_
End Property
Public Property Let Age(ByVal Value As Long)
age_ = Value
End Property
Private Property Get Person_Name() As String
Person_Name = Name
End Property
Private Property Get Person_Age() As Long
Person_Age = Age
End Property
ComparerCls
you will use an instance of this class to compare two objects properties or references. You do not necessarily need to have a class for this but I prefer it that way.
Public Enum ComparisonMethod
Names = 0 ' default
Ages = 1
References = 2
End Enum
' makes names the default comparison method
Public Function Compare(ByRef obj1 As Person, _
ByRef obj2 As Person, _
Optional method As ComparisonMethod = 0) _
As Boolean
Select Case method
Case Ages
Compare = IIf(obj1.Age = obj2.Age, True, False)
Case References
Compare = IIf(obj1 Is obj2, True, False)
Case Else
Compare = IIf(obj1.Name = obj2.Name, True, False)
End Select
End Function
And your Module1
code
Option Explicit
Sub Main()
Dim emp As New Employee
emp.Name = "person"
emp.Age = 25
Dim man As New Manager
man.Name = "manager"
man.Age = 25
Dim People As New Collection
People.Add emp
People.Add man
Dim individual As Person
For Each individual In People
Debug.Print TypeName(individual), individual.Name, individual.Age
Next
End Sub
run the Main()
sub and check out the results in the Immediate Window
The best part of the above code is the fact that you are creating a reference variable of the Person
interface. It allows you to loop through all items in the collection that implement the interface. Also, you can use the Intellisense which is great if you have had many more properties and functions.
Comparison
Take a look again at the code in the ComparerCls
class
I hope you see now why I have separated this to be a class. Its purpose is just to take care of the way the objects are being compared. You can specify the Enum order and modify the Compare()
method itself to compare differently. Note the Optional parameter which allows you to call the Compare method without the method of comparison.
Now you can play around passing different parameters to the compare function. See what the results are like.
Try combinations:
emp.Name = "name"
man.Name = "name"
Comparer.Compare(emp, name, Names)
Comparer.Compare(emp, name, References)
Comparer.Compare(emp, emp, References)
If something is still unclear refer to this answer about the Implements
keyword in VBA