Retrieve the index of an object stored in a collection using its key (VBA)

后端 未结 4 825
一整个雨季
一整个雨季 2020-12-11 11:01

I have a collection with several elements in VBA, each of these elements has a key assigned.

I would like to know the position of a given element in the collection u

相关标签:
4条回答
  • 2020-12-11 11:28

    I liked Sil's answer above. I think he short changed himself by saying 'Its not pretty but it works'. In my experience it is way faster when doing a large number of lookups. Here is another example

    Sub UseCollectionWithKey()
    Dim Col As New Collection
    Dim I As Integer
    
    ' create a new collection that is keyed
    For I = 1 To ActiveWorkbook.Styles.Count
      Col.Add I, ActiveWorkbook.Styles(I)   ' where "ActiveWorkbook.Styles(I)" is the key
    Next I
    
    MsgBox Col(ActiveCell.Style)    ' this gives the index of the style for the active cell
    
    End Sub
    

    See also "Adding Items Using a Key" at this link https://excelmacromastery.com/excel-vba-collections/

    0 讨论(0)
  • 2020-12-11 11:30

    Essentially, no. There's not a faster way. Not using a collection at least. Here's the fastest way I know to find the index of an item in a collection.

    ' returns index of item if found, returns 0 if not found
    Public Function IndexOf(ByVal coll As Collection, ByVal item As Variant) As Long
        Dim i As Long
        For i = 1 To coll.Count
            If coll(i) = item Then
                IndexOf = i
                Exit Function
            End If
        Next
    End Function
    

    Note that we exit the function as soon as we've found the first matching item. This algorithm has an average and worst case of O(n) where n is the number of items in the collection.

    I think there may be another reason you want to be able to find the index though, so I'm going to suggest also taking a look at the Scripting.Dictionary in the Microsoft Scripting Runtime library. While, there is also no way to get an item's index via it's key value (other than looping), you can actually retrieve the key values from the dictionary, not just it's items. I suspect that you may be asking this question because of the lack of this ability in the built in Collection object.

    0 讨论(0)
  • 2020-12-11 11:32

    I recently had the same "issue" and used this workaround:

    Create two collections: one containing the actual strings of interest and one containing numbers from 1 to n with the actuals strings as keys. This way you can retrieve the index since it's a value in the second collection.

    Sub example()
    
        'imagine we are reading out following excel column
    
        'one
        'two
        'three
    
        Dim textcol, numcol As New Collection
        Dim i, index As Integer
        Dim str As String
    
        For i = 1 To Range.Rows.Count
            textcol.Add Range.Cells(i, 1)       'value, no key
            numcol.Add i, Range.Cells(i, 1)     'i, value as key
        Next i
    
        'textcol: "one", "two", "three"
        'numcol: 1 ["one"], 2 ["two"], 3 ["three"]
    
        str = "two"
        index = numcol(str) '~> 2
    
    End Sub
    

    It's not pretty but it worked for me.

    0 讨论(0)
  • 2020-12-11 11:49

    There is no way that I have found to return the index, however if you have a collection of user defined objects that will only be stored in a single collection you can add an index property to the object and set it when the object is added to the collection.

    0 讨论(0)
提交回复
热议问题