Я ищу конкретный элемент в коллекции. как узнать, существует ли в коллекции?vba: как мне искать коллекцию?
ответ
Если вы использовали ключ при добавлении элемента в коллекцию, увидеть, если со ссылкой на этот ключ дает ошибку:
on error goto no_item
col.Item "key"
msgbox "Item exists"
exit sub
no_item:
msgbox "Item does not exist"
В противном случае вам придется перебрать все пункты, чтобы увидеть, если есть тот, который вы необходимость.
Коллекция основана на индексе. Следовательно, вам придется перебирать коллекцию для поиска элемента.
Sub test()
Dim iCtr As Integer
Dim itemCount As Integer
Dim myData As Collection
Set myData = New Collection
Dim searchFor As String
myData.Add "MS", "11"
myData.Add "Oracle", "22"
myData.Add "Google", "33"
'** Searching based on value
searchFor = "Google"
itemCount = myData.Count
For iCtr = 1 To itemCount
If myData(iCtr) = searchFor Then
MsgBox myData(iCtr)
Exit For
End If
Next
'** Searching by key
MsgBox myData.Item("22")
End Sub
Я использую простую функцию инструмента, которая выполняет итерацию через коллекцию. Он не имеет прямого доступа к индексам и использует функции языка VBA, такие как они должны использоваться (Сравнение вариантов и каждый -Loop).
Public Function ExistsIn(item As Variant, lots As Collection)
Dim e As Variant
ExistsIn = False
For Each e In lots
If item = e Then
ExistsIn = True
Exit For
End If
Next
End Function
Я не понимаю, что случилось с этим ответом. – schmijos
возможно, потому что вопрос был сформулирован * поиск через *, как итерация, на которую вы ответили, как было задано. однако строки имеют хешированный собственный поиск, не требуется петли. ваш не является недопустимым, и это способ без необходимости взломать условие ошибки, и я не думаю, что это должно было быть отклонено и, конечно, не было отрицательным. Там используется ошибка использования, а также встроенный индексный цикл, а также использование встроенного итератора. – Celess
@Josua Schmid:
Я думаю, что код в ваш ответ может быть правильным, но может быть не исправить, а также. Ваша функция имеет пареметр типа Variant и затем сравнивается с каждым мензуром коллекции. Но что на самом деле сравнивается? В этом случае сравнивается элемент по умолчанию. Таким образом, проблема может возникнуть, если коллекция будет содержать члены какого-либо пользовательского класса, который не имеет указанного члена по умолчанию. В таком случае объект 438 ошибки времени выполнения не поддерживает это свойство или метод будет поднят. Ну, вы можете добавить участника по умолчанию, но даже тогда он будет работать так, как вам может быть не нравится, я боюсь.
Пример с диапазонами (для Range-Class Value используется элемент по умолчанию, поэтому значения будут сравниваться). Возможно, это именно то, что вы хотели, но, возможно, нет. Поэтому, с моей точки зрения, лучше использовать «Ключ» для каждого элемента, добавленного в коллекцию, а затем попытаться получить этот элемент по его ключу.
Debug.Print col.item(r1.Address) ' A1 Value
Или индекса, если не использовались никакие клавиши:
Debug.Print col.item(1) ' A1 Value
Sub test()
Dim col As New VBA.Collection
Dim r1 As Range
Dim r2 As Range
Dim r3 As Range
Set r1 = Range("a1")
Set r2 = Range("b1")
Set r3 = Range("c1")
r1 = "A1 Value"
r2 = "B1 Value"
r3 = "C1 Value"
col.Add r1, r1.Address
col.Add r2, r2.Address
col.Add r3, r3.Address
Debug.Print ExistsIn(r1, col)
Debug.Print ExistsIn(r2, col)
Debug.Print ExistsIn(r3, col)
Dim r4 As Range
Set r4 = Range("d1")
r4 = "A1 Value"
Debug.Print ExistsIn(r4, col)
End Sub
Output:
True
True
True
True
Это дубликатом вопрос; см. http://stackoverflow.com/questions/137845/determining-whether-an-object-is-a-member-of-a-collection-in-vba –