Get the key of an item on a Collection object

28,420

The simple approach would be to use a Dictionary instead of a Collection. The Dictionary is essentially an associative array of key, item pairs and support retrieval of its keys as an array. To use the Dictionary you will need to add a reference to the Microsoft Scripting Runtime. The drawback to using the dictionary is that it is not enumerable in the same way as the collection. A more elaborate solution would be to wrap the collection and dictionary to create an enumerable dictionary as outlined below.

NB To get NewEnum to work properly in VBA the class module has to be exported and manually edited as follows and then re-imported.

Public Property Get NewEnum() As IUnknown
Attribute NewEnum.VB_UserMemId = -4
   Set NewEnum = someKeys.[_NewEnum]
End Property

example

Option Explicit
Private someKeys As Dictionary
Private someCols As Collection
Public Function Add(o As Object, Key As String) As Object
    someKeys.Add Key, o
    someCols.Add o, Key
End Function
Public Property Get Count() As Long
    Count = someCols.Count
End Property
Public Property Get Item(vKey As Variant) As Object
    Set Item = someCols.Item(vKey)
End Property
Public Sub Remove(vKey As Variant)
    someKeys.Remove vKey
    someCols.Remove vKey
End Sub
Public Property Get NewEnum() As IUnknown
   Set NewEnum = someCols.[_NewEnum]
End Property
Public Property Get Keys() As Variant
    Keys = someKeys.Keys
End Property
Private Sub Class_Initialize()
    Set someKeys = New Dictionary
    Set someCols = New Collection
End Sub
Share:
28,420
Lumen
Author by

Lumen

Embedded C, occasional C++, daily simple-problem-killer VBA programmer. Electronics teacher, EE engineer.

Updated on August 08, 2020

Comments

  • Lumen
    Lumen over 3 years

    The environment is that the members I'm pushing into the Collection are nameless, un-identifiable (to avoid bad abstractions, and please, don't freak out: members are actually other Collection instances). In order to be able to make fast searches, I'm creating a meaningfull hash name for each new member, and provide it as the Key string, on the Add method of the "topmost" Collection.

    When I have a key to seach with, everything's dandy... Problem is I'd like to iterate the members of the collection and get the Key that was provided on Add (the generated Hash, that unfortunetely is not possible to reverse-Hash).

    I'm moving on by defining that the first member of the inserted sub-collection instance is a string, containing the mentioned hash, but if anyone cracks this, I'll be much obliged.