VBA collection: list of keys
After I add some values to the VBA collection, is there any way to retain the list of all keys?
For example
Dim coll as new Collection
Dim str1, str2, str3
str1="first string"
str2="second string"
str3="third string"
coll.add str1, "first key"
coll.add str2, "second key"
coll.add str3, "third key"
I know how to retain the list of strings:
first string
second string
third string
Once again: is there any way to retain the keys?
first key
second key
third key
Note: I'm using VBA through AutoCAD 2007
Solution 1:
If you intend to use the default VB6 Collection
, then the easiest you can do is:
col1.add array("first key", "first string"), "first key"
col1.add array("second key", "second string"), "second key"
col1.add array("third key", "third string"), "third key"
Then you can list all values:
Dim i As Variant
For Each i In col1
Debug.Print i(1)
Next
Or all keys:
Dim i As Variant
For Each i In col1
Debug.Print i(0)
Next
Solution 2:
I don't thinks that possible with a vanilla collection without storing the key values in an independent array.
The easiest alternative to do this is to add a reference to the Microsoft Scripting Runtime & use a more capable Dictionary instead:
Dim dict As Dictionary
Set dict = New Dictionary
dict.Add "key1", "value1"
dict.Add "key2", "value2"
Dim key As Variant
For Each key In dict.Keys
Debug.Print "Key: " & key, "Value: " & dict.Item(key)
Next
Solution 3:
You can create a small class to hold the key and value, and then store objects of that class in the collection.
Class KeyValue:
Public key As String
Public value As String
Public Sub Init(k As String, v As String)
key = k
value = v
End Sub
Then to use it:
Public Sub Test()
Dim col As Collection, kv As KeyValue
Set col = New Collection
Store col, "first key", "first string"
Store col, "second key", "second string"
Store col, "third key", "third string"
For Each kv In col
Debug.Print kv.key, kv.value
Next kv
End Sub
Private Sub Store(col As Collection, k As String, v As String)
If (Contains(col, k)) Then
Set kv = col(k)
kv.value = v
Else
Set kv = New KeyValue
kv.Init k, v
col.Add kv, k
End If
End Sub
Private Function Contains(col As Collection, key As String) As Boolean
On Error GoTo NotFound
Dim itm As Object
Set itm = col(key)
Contains = True
MyExit:
Exit Function
NotFound:
Contains = False
Resume MyExit
End Function
This is of course similar to the Dictionary suggestion, except without any external dependencies. The class can be made more complex as needed if you want to store more information.
Solution 4:
An alternative solution is to store the keys in a separate Collection:
'Initialise these somewhere.
Dim Keys As Collection, Values As Collection
'Add types for K and V as necessary.
Sub Add(K, V)
Keys.Add K
Values.Add V, K
End Sub
You can maintain a separate sort order for the keys and the values, which can be useful sometimes.