If I know the ordinal position of an element in a collection, how can I retrieve the key associated with it?
I want to get the MyCollection.Items(2).Key ... What to do?
Is this possible in VB or with the help of some API?
Printable View
If I know the ordinal position of an element in a collection, how can I retrieve the key associated with it?
I want to get the MyCollection.Items(2).Key ... What to do?
Is this possible in VB or with the help of some API?
You can do this if you use the Dictionary Class. It is available if you have the references loaded for FSO.
Dictionarys work slightly quicker than Collections and they have methods for exporting the items and the keys into one dimentional arrays.
Quote:
Originally Posted by Pradeep1210
Default Collection object doesn't have one..
you can create your own colleciton class for this purpose..
Or you could use something like this:
..it can cause problems though. I'm not sure I've done it correctly. But it will return the keys you want.VB Code:
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (A As _ Any, b As Any, ByVal C As Long) Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Any) As _ Long Public Type CollectionData Unk0(0 To 2) As Long Unk1 As Long ElementCount As Long Unk2 As Long PtrFirstElement As Long PtrLastElement As Long Unk3 As Long Unk4 As Long Unk5 As Long End Type Public Type CollectionElement Data As Variant Key As Long PtrPrev As Long PtrNext As Long Unk0 As Long Unk1 As Long Unk2 As Long End Type Function CollectionGetKeys(ByVal Col As Collection) As String() Dim asKeys() As String Dim lIdx As Long Dim tColl As CollectionData Dim tColElem As CollectionElement If Col.Count > 0 Then ReDim asKeys(1 To Col.Count) MoveMemory tColl, ByVal ObjPtr(Col), LenB(tColl) tColElem.PtrNext = tColl.PtrFirstElement For lIdx = 1 To tColl.ElementCount MoveMemory tColElem, ByVal tColElem.PtrNext, LenB(tColElem) asKeys(lIdx) = pvPtr2Str(tColElem.Key) Next End If CollectionGetKeys = asKeys End Function Function pvPtr2Str(lpszA As Long) As String pvPtr2Str = String$(lstrlenW(lpszA), 0) MoveMemory ByVal StrPtr(pvPtr2Str), ByVal lpszA, lstrlenW(lpszA) * 2 End Function
chem
Chem.. y would one want to use this way as there are a lot of easier options (like creating custom class or using Dictionary object)Quote:
Originally Posted by chemicalNova
When I needed it, I didn't want to create a custom class, as I only needed it for a short time to check something in my code. I was just posting this so he could use it, should the need arise.
chem
Yes I should use the Dictionary Object. I think I m using a Collection Object wrongly in this situation.
But as it will require major changes inmy program, I can't switch over.
I have just built my own collection class by now (as moinkhan advised)
Thanks Everyone :thumb:
Here is the code for needy people like me:
This is just the general method I followed. You may wrap it into a class.
VB Code:
Dim MyCollection As New Collection Dim sCollectionData(2) ''To add elements sCollectionData(1) = sKey sCollectionData(2) = sValue MyCollection.Add sCollectionData, sKey ''To retrieve it 'Retrieve by ordinal sKey = MyCollection(AnyIndex)(1) ''Key retrieved sValue = MyCollection(AnyIndex)(2) ''value retrieved 'retrieve by key sKey = MyCollection(AnyKey)(1) ''Key retrieved sValue = MyCollection(AnyKey)(2) ''value retrieved
Public Type CollectionElement
'Data As Variant <--- don't use thisData(0 to 15) <---- use thisKey As LongPtrPrev As LongPtrNext As Long
'these can be omitted since you are just reading the linked list
Unk0 As LongUnk1 As LongUnk2 As LongEnd Type
VB initializes the variant with the automation functions for variant management. Once you write over the struct when traversing the collection's linked list, a leak at best or a crash is probable when VB calls VariantClear.
Do you know that you are reviving a 6 year old thread, and that too which is marked "Resolved"? :eek:
And this means bugging everyone who has participated in this thread...
Then quit listening to this (erronously marked as resolved) thread after 6 years already, sir. Do you need help finding the off switch? I could start a how-to thread on that if anyone is interested.
Nothing is marked erroneously. I was the thread starter and after coming up to a good solution for my problem, I marked it resolved.
And that was 6 years ago. Now there is no problem and no solution. Organization changed, language changed, everything changed. In fact VB6 became obsolete.
If you are in a similar problem and anything already posted in this thread helps, that's good.
Otherwise you can start your own new thread for that and many people will reply there. Why spoil a thread unnecessarily like this which contains the solution to a problem in specific situation?