I\'m trying to decide whether to use Excel VBA Collection or Dictionary for my project. For several reasons, I lean toward dictionary, but I keep reading that when using a <
No one can provide an example of a Scripting.Dictionary object returning keys/items in a different order than they were added because a Scripting.Dictionary does not do that. Never. If you add the following key/item pairs in a progressive order then that is the ways they are returned.
key item
1 A
2 B
3 C
4 D
'enumerate by key
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
dict.Add Key:=1, Item:="A"
dict.Add Key:=2, Item:="B"
dict.Add Key:=3, Item:="C"
dict.Add Key:=4, Item:="D"
Dim k As Variant
For Each k In dict.Keys
Debug.Print k & " - " & dict.Item(k)
Next k
You might be referring to the shorthand 'overwrite' method of adding keys without checking to see it they exist. If you try to .Add a key that exists error 457 is thrown. However, if you simply write Keys and Items into the dictionary a new key and item will be created if the key does not exist but if the key exists the key remains the same and the item is overwritten.
key item
1 A
2 B
3 C
4 D
2 E
'enumerate by key
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
dict.Item(1) = "A"
dict.Item(2) = "B"
dict.Item(3) = "C"
dict.Item(4) = "D"
dict.Item(2) = "E" 'the second entry's item is overwritten
Dim k As Variant
For Each k In dict.Keys
Debug.Print k & " - " & dict.Item(k)
Next k
The overwrite method is a little faster than checking if a key .Exists but the behavior should be understood. I've used the overwrite to intentionally retrieve the last item for any key in a list with duplicate keys but that was a special case. Note that the 2 .Key is not out of original order; it has merely had its .Item replaced with the later one.
If you have added the Microsoft Scripting Runtime reference library you can use Early Binding in your variable declaration. This has the benefit of creating a slightly faster dictionary object and exposing other methods of indexed enumeration.
Dim dict As New Scripting.Dictionary
'enumerate by index position (zero-based index)
Dim i As Long
For i = 0 To dict.Count - 1
Debug.Print dict.Keys(i) & " - " & dict.Items(i)
Next i
'enumerate as elements of an array
Dim a As Long
For a = LBound(dict.Keys) To UBound(dict.Keys)
Debug.Print dict.Keys(a) & " - " & dict.Items(a)
Next a
fwiw, I've found this indexed enumeration unreliable when the dictionary's .Count exceeds a signed integer (32,767).
Finally, key/item pairs can be removed one at a time or all at once.
dict.Remove 2 'remove by key
dict.Remove dict.Keys(0) 'remove first key/item by index position
dict.Remove dict.Keys(UBound(dict.Keys)) 'remove last key/item by index position
dict.RemoveAll 'remove all