VBA Collections

The Collection object stores a collection of items in an ordered sequence. Collections can store any type of data and objects except user-defined types. Collections start at index 1 unlike arrays which start at index 0 by default. The Option Base statement has no effect on collections as they always start at index 1. The Collection object is designed to be simple and easy to use with a minimalist set of methods that allow for adding, removing, retrieving, and counting items. Items in a collection cannot be reassigned once they are added. Objects in a collection can still be mutated but the object reference variable cannot be reassigned.

Collection Methods

Collections have four simple methods: Add, Remove, Count, and Item. Item is the default method of the Collection class which retrieves an item at a given index and does not need to be explicitly written. To clear a Collection just set the Collection to a New Collection.

Public Sub Example()

    'Create Collection
    Dim Coll As Collection
    Set Coll = New Collection

    'Add items
    Coll.Add 1
    Coll.Add 2
    Coll.Add 3

    'Count items
    Debug.Print Coll.Count

    'Remove item at index 1
    Coll.Remove 1

    'Retrieve item from Collection
    Debug.Print Coll(1) 
   'Debug.Print Coll.Item(1) 'Same as above

    'Cannot reassign an item in a Collection
    'Coll(1) = 4  'Causes an error. 

    'Clear Collection
    Set Coll = New Collection

End Sub

Keys and Values

Items can be given a Key and a Value and can be accessed either by their index or by their key. A Key needs to be a unique string value.

Public Sub Example()

    Dim Coll As Collection
    Set Coll = New Collection

    Coll.Add 1, "Key1"
    Coll.Add 2, "Key2"
    Coll.Add 3, "Key3"

    Debug.Print Coll("Key2") 'Prints: 2

End Sub

Collections Vs Arrays

The Collection and the array both store a sequential list of data, however the array has a predefined size and data type whereas the Collection does not. A Collection should be used in place of an array when items need to be added or removed frequently from the list and items do not need to be reassigned once added.

Array

  • Predetermined size
  • Predetermined data type
  • Elements can be reassigned
  • Adding and removing items can be inefficient and requires more code

Collection

  • No predetermined size
  • Can store any type of data
  • Items cannot be reassigned
  • Items can be easily and efficiently added and removed

Jagged Collections

A Jagged Collection is a Collection of Collection Objects.

Public Sub Example()

    Dim Coll As Collection
    Set Coll = New Collection

    Coll.Add New Collection
    Coll.Add New Collection
    Coll.Add New Collection

    Coll(1).Add "Test"

    Debug.Print Coll(1)(1) 'Prints: Test

End Sub

Looping Over Collections

While it is possible to use any type of loop to iterate over a Collection, it is most efficient to use a For Each loop. Accessing items via the Item method is inefficient when looping. When using a For Each loop, each item in the Collection is accessed via the control variable so Item does not need to be called for each iteration.

Note: In general, a For Each loop should always be used to iterate over a Collection object.

For Each Loop

When a Collection contains data types that are not objects, the control variable for a For Each loop when iterating over the items in a Collection must be type Variant.

Public Sub Example()

    Dim Coll As Collection
    Set Coll = New Collection

    Coll.Add 1
    Coll.Add 2
    Coll.Add 3

    Dim i As Variant
    For Each i In Coll
        Debug.Print i
    Next i

End Sub

When a Collection contains objects, the control variable can be of type Variant, Object, or the specific type of object the Collection contains.

Public Sub Example()

    Dim Coll As Collection
    Set Coll = New Collection

    Coll.Add New Collection
    Coll.Add New Collection
    Coll.Add New Collection

    Dim C As Collection
    For Each C In Coll
        Debug.Print C.Count
    Next C

End Sub

For Loop

To use a For loop to iterate over the items in a Collection, start the incrementor at 1 and increment to the Collection's Count property. Items of a collection can be accessed by their index using the Item method. The Item method is the default member of the Collection object and can be omitted by simply using parentheses after the Collection name.

Note: It is inefficient to iteratively access items in a Collection object via the Item method.

Public Sub Example()

    'INEFFICIENT

    Dim Coll As Collection
    Set Coll = New Collection

    Coll.Add 1
    Coll.Add 2
    Coll.Add 3

    Dim i As Long
    For i = 1 To Coll.Count
        Debug.Print Coll(i) 'Same as Coll.Item(i)
    Next i

End Sub

Collections And Objects

Collections work very well for storing objects. Collections can be used to store instances of user-defined classes which makes storing and manipulating data in VBA much easier.

'Class Module: clsPerson

Option Explicit

Public FirstName  As String
Public Birthday   As Date
Public Hometown   As String

Public Sub PrintDetails()
    Debug.Print Me.FirstName, Me.Birthday, Me.Hometown
End Sub
'Standard Module: modExample

Option Explicit

Public Sub Example()

    Dim PersonCollection As Collection
    Set PersonCollection = New Collection

    Dim P As clsPerson

    'Add person
    Set P = New clsPerson
    P.FirstName = "Johnnie"
    P.Birthday = #1/1/1990#
    P.Hometown = "New York"
    PersonCollection.Add P

    'Add person
    Set P = New clsPerson
    P.FirstName = "Sally"
    P.Birthday = #1/1/1991#
    P.Hometown = "Chicago"
    PersonCollection.Add P

    'Add person
    Set P = New clsPerson
    P.FirstName = "Susie"
    P.Birthday = #1/1/1992#
    P.Hometown = "Los Angeles"
    PersonCollection.Add P

    'Print each person's details
    For Each P In PersonCollection
        P.PrintDetails
    Next P

    'Cleanup
    Set PersonCollection = Nothing

End Sub