我在VBA中有一个包含多个元素的集合,每个元素都分配了一个键。
我想知道使用其键在集合中给定元素的位置。我能想到的唯一方法是在我收到我想要的项目之前循环收集,是否有更快的方法?
由于
答案 0 :(得分:3)
基本上,没有。这不是一个更快的方式。至少不使用集合。这是我知道找到集合中项目索引的最快方法。
' 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
请注意,我们会在找到第一个匹配项后立即退出该功能。此算法的平均值和最差情况为 O(n),其中 n 是集合中的项目数。
我认为您希望能够找到索引的原因可能还有另外一个原因,因此我还建议您查看Microsoft Scripting Runtime库中的Scripting.Dictionary
。虽然,也无法通过它的键值(循环除外)来获取项目索引,但可以实际从字典中检索键值,而不仅仅是它的物品。我怀疑你可能会问这个问题,因为内置的Collection
对象缺乏这种能力。
答案 1 :(得分:0)
我最近遇到了相同的“问题”并使用了此解决方法:
创建两个集合:一个包含感兴趣的实际字符串,另一个包含从1到n的数字,其中实际字符串作为键。这样您就可以检索索引,因为它是第二个集合中的值。
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
它不漂亮,但它对我有用。
答案 2 :(得分:0)
我喜欢Sil的答案。我认为他简短地改变了自己说'它不漂亮但它有效'。根据我的经验,在进行大量查找时会更快。 这是另一个例子
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
另请参阅此链接中的“使用密钥添加项目” https://excelmacromastery.com/excel-vba-collections/
答案 3 :(得分:-2)
我找不到返回索引的方法,但是如果你有一组用户定义的对象只存储在一个集合中,你可以向对象添加一个索引属性并在对象时设置它被添加到集合中。