VBA Collections and Dictionaries: Unique Lists, Counts and Fast Lookups

📎 This article includes 1 downloadable practice file ↓

⏱ 4 min read

Arrays (lesson 9) are great when you know where things are: row 5, column 3. But many everyday questions are about keys instead: “what’s the total for customer C-104?”, “which product codes appear more than once?”, “give me each region only once”. For those, VBA has two containers that store values under a name: the Collection and the Dictionary.

In this article
  1. Collection: a simple growing list
  2. Dictionary: key → value, and it can answer “do you have this?”
  3. 1. Unique list in one pass
  4. 2. Total and count by key (a pivot in code)
  5. 3. Look-ups without VLOOKUP
  6. 4. Find duplicates
  7. Collection or Dictionary?
  8. Where people go wrong
  9. Practice

Collection: a simple growing list

Dim names As New Collection
names.Add "Asha"
names.Add "Ravi"
names.Add "Meena"
Debug.Print names.Count       ' 3
Debug.Print names(2)          ' Ravi (Collections start at 1)

Dim n As Variant
For Each n In names
    Debug.Print n
Next n

Collections grow without ReDim, which makes them handy for “collect everything that matches”. Their limits: you can’t easily check whether a key exists, you can’t change an item in place, and you can’t list the keys.

Dictionary: key → value, and it can answer “do you have this?”

Dim d As Object
Set d = CreateObject("Scripting.Dictionary")
d.CompareMode = vbTextCompare        ' "delhi" and "Delhi" are the same key

d("Delhi") = 120
d("Mumbai") = 95
Debug.Print d("Delhi")               ' 120
Debug.Print d.Exists("Pune")         ' False
Debug.Print d.Count                  ' 2

Assigning d(key) = value adds the key if it’s new and overwrites it if it exists. That one behaviour powers almost every trick below.

💡 CreateObject("Scripting.Dictionary") works without setting any reference. If you’d like IntelliSense, add Tools › References › Microsoft Scripting Runtime and declare Dim d As New Scripting.Dictionary. Dictionaries are Windows-only — they don’t exist in Excel for Mac.

1. Unique list in one pass

Sub UniqueRegions()
    Dim d As Object, data As Variant, r As Long
    Set d = CreateObject("Scripting.Dictionary"): d.CompareMode = vbTextCompare
    data = Worksheets("Sales").Range("B2:B50001").Value
    For r = 1 To UBound(data, 1)
        If Len(data(r, 1)) > 0 Then d(Trim$(data(r, 1))) = Empty
    Next r
    Worksheets("Out").Range("A2").Resize(d.Count, 1).Value = Application.Transpose(d.Keys)
End Sub

50,000 rows, under a second. d.Keys returns a 1-D array, so Transpose turns it into a column for writing back.

⚠️ Application.Transpose fails on arrays with more than 65,536 items in some Excel versions. For very large outputs, copy the keys into a 2-D array with a loop instead.

2. Total and count by key (a pivot in code)

Sub TotalsByCustomer()
    Dim tot As Object, cnt As Object, data As Variant, r As Long, k As Variant, out() As Variant, i As Long
    Set tot = CreateObject("Scripting.Dictionary"): Set cnt = CreateObject("Scripting.Dictionary")
    data = Worksheets("Sales").Range("A2:E50001").Value          ' A = customer, E = amount
    For r = 1 To UBound(data, 1)
        k = data(r, 1)
        If Len(k) > 0 Then
            tot(k) = tot(k) + data(r, 5)                          ' missing key starts as Empty = 0
            cnt(k) = cnt(k) + 1
        End If
    Next r
    ReDim out(1 To tot.Count, 1 To 3)
    For Each k In tot.Keys
        i = i + 1: out(i, 1) = k: out(i, 2) = cnt(k): out(i, 3) = tot(k)
    Next k
    Worksheets("Out").Range("D2").Resize(tot.Count, 3).Value = out
End Sub

3. Look-ups without VLOOKUP

Load the price list into a dictionary once, then look up 50,000 order lines from memory:

Set price = CreateObject("Scripting.Dictionary")
pl = Worksheets("Prices").Range("A2:B500").Value
For r = 1 To UBound(pl, 1): price(pl(r, 1)) = pl(r, 2): Next r

For r = 1 To UBound(orders, 1)
    If price.Exists(orders(r, 2)) Then
        result(r, 1) = orders(r, 3) * price(orders(r, 2))
    Else
        result(r, 1) = "No price"
    End If
Next r

4. Find duplicates

For r = 1 To UBound(data, 1)
    k = data(r, 1)
    If seen.Exists(k) Then
        dupes(k) = dupes(k) & ", " & (r + 1)          ' remember the sheet rows
    Else
        seen(k) = r + 1
    End If
Next r

Collection or Dictionary?

Need Use
Just collect items in order Collection
Check whether a key exists Dictionary (.Exists)
Update a value for a key (totals, counts) Dictionary
Get all keys back as a list Dictionary (.Keys)
Must work on a Mac Collection (or a sorted array)

Where people go wrong

  • “Delhi” and “Delhi ” counted separately: trim keys before adding.
  • Numbers vs text keys: 101 (number) and "101" (text) are different keys. Convert with CStr() when codes come from different sources.
  • CompareMode error: it can only be set while the dictionary is empty — set it straight after creating it.

Practice

The workbook has 50,000 sales rows and buttons for unique lists, totals by customer, a price look-up, a duplicate finder and a Collection example — each with a timer so you can compare against formulas.

Last lesson: files and folders, and a final project that pulls the whole course together.

📎 Practice files for this article

  • 📄
    Collections & Dictionaries workbook (.xlsb, macros)Unique lists, totals by customer, a price look-up and a Collection demo on 50,000 rows.
    ⬇ XLSB · 1 MB

Free to use for learning. Files with macros (.bas) are plain text — import them with Alt+F11 → File → Import File, and always test on a copy.

✨ Ask AI about this article

Stuck on a step? Ask a question and the AI answers using this article.

Free · AI can be wrong

Leave a Reply

Your email address will not be published. Required fields are marked *