2010-08-27 3 views

ответ

5

Если вы использовали ключ при добавлении элемента в коллекцию, увидеть, если со ссылкой на этот ключ дает ошибку:

on error goto no_item 
col.Item "key" 
msgbox "Item exists" 

exit sub 

no_item:  
msgbox "Item does not exist" 

В противном случае вам придется перебрать все пункты, чтобы увидеть, если есть тот, который вы необходимость.

4

Коллекция основана на индексе. Следовательно, вам придется перебирать коллекцию для поиска элемента.

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 
3

Я использую простую функцию инструмента, которая выполняет итерацию через коллекцию. Он не имеет прямого доступа к индексам и использует функции языка 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 
+0

Я не понимаю, что случилось с этим ответом. – schmijos

+0

возможно, потому что вопрос был сформулирован * поиск через *, как итерация, на которую вы ответили, как было задано. однако строки имеют хешированный собственный поиск, не требуется петли. ваш не является недопустимым, и это способ без необходимости взломать условие ошибки, и я не думаю, что это должно было быть отклонено и, конечно, не было отрицательным. Там используется ошибка использования, а также встроенный индексный цикл, а также использование встроенного итератора. – Celess

2

@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