Search This Blog

Monday, October 15, 2012

Strongly typed dictionary collection in VBA

In this post, I will show you how to build a strongly type dictionary and how to loop through its elements with a For Each Loop.

The Generic Dictionary Object can be found in the "Microsoft Scripting Runtime" library.
This can be used to store any type of variables or object. However, it is usually very useful to wrap it up so that you can create your own strongly typed dictionary.
As you will see from the code below, a very simple way to loop through the collection of elements in a dictionary is to loop through its keys. The variable key must be variant type.
For Each key In emps.Keys
   Set emp = emps(key)
   Debug.Print emp.Name
Next

The first class is a strongly typed dictionary of Employee object, called Employees.
A usual to make the .Item property to be the default property you need to add the

Attribute Item.VB_UserMmeId = 0

just below the definition of the Get Item property

Option Explicit

Private Const cMODULE_NAME As String = "Employees"Private mDic As Dictionary


Private Sub Class_Initialize()
  Set mDic = New Dictionary
End Sub
Private Sub Class_Terminate()
  Set mDic = Nothing
End Sub

Public Sub Add(key As Variant, Item As Employee)
  
    Call mDic.Add(key, Item)
  
End Sub

Public Property Get Item(key As Variant) As Employee
   'Attribute Item.VB_UserMemId = 0
   'This Attribute makes Item the default property
   'In VBA, uncomment the first line. Export, Remove and import the file again. To make it work

   Set Item = mDic.Item(key)
       
End Property

Public Function count() As Long
   count = mDic.count
End Function

Public Function Exists(key As Variant) As Boolean
  Exists = mDic.Exists(key)
End Function

Public Function items() As Variant
 items = mDic.items
End Function

Public Function Remove(key As Variant)
  mDic.Remove (key)
End Function

Public Function RemoveAll()
  mDic.RemoveAll
End Function

Public Function Keys() As Variant
  Keys = mDic.Keys
End Function


This is the the Employee Class


Option Explicit

Private Const cMODULE_NAME As String = "Employee"
Private mIdentifier As Long
Private mName As String
Private mAge As Long

Public Property Get Identifier() As Long
  Identifier = mIdentifier
End Property

Public Property Let Identifier(value As Long)
    mIdentifier = value
End Property

Public Property Get Name() As String
   Name = mName
End Property

Public Property Let Name(value As String)
   mName = value
End Property

Public Property Get Age() As Long
  Age = mAge
End Property

Public Property Let Age(value As Long)
  mAge = value
End Property

This is the Sub to test the Code


Sub TestCollection()

Dim emp As Employee
Dim emps As Employees
Dim key As VariantSet emps = New Employees
Set emp = New Employee
emp.Identifier = 1
emp.Name = "Mario"
emp.Age = 34
Call emps.Add(emp.Identifier, emp)

Set emp = New Employee
emp.Identifier = 2
emp.Name = "Gino"
emp.Age = 12
Call emps.Add(emp.Identifier, emp)

For Each key In emps.Keys
   Set emp = emps(key)
   Debug.Print emp.Name
NextEnd Sub

3 comments:

  1. hi, i was going trough your example code of employee and employees classes and test code - "For Each key In emps.keys" loop gives error '438' - object doesn't support this property or method. Tried to evaluate the reason for this error but failed. Any idea what is causing this error? I really like the method you have posted but this error is blocking me with going ahead with my code.

    ReplyDelete
  2. Make sure you do this in vba

    'Attribute Item.VB_UserMemId = 0
    'This Attribute makes Item the default property
    'In VBA, uncomment the first line. Export, Remove and import the file again. To make it work

    ReplyDelete
  3. If you don't do it you will need to call explicitly the item property

    ReplyDelete