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.
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
You could wrap your member collections in you own collection call that store the key and the collection. The is just a matter of iterating throw the collection and asking the elements for their key (i.e. you hash).
try to substitute
Public Function NewEnum() As IUnknown
Set NewEnum = m_ObjectCollection.[_NewEnum]
End Function
with
Public Function NewEnum() As Collection
Set NewEnum = m_ObjectCollection
End Function
it worked for me.