Поиск…


замечания

Collection представляет собой контейнерный объект, который включен в среду выполнения VBA. Никаких дополнительных ссылок для его использования не требуется. Collection может использоваться для хранения элементов любого типа данных и позволяет извлекать либо порядковый индекс элемента, либо с помощью необязательного уникального ключа.


Сравнение функций с массивами и словарями

Коллекция массив толковый словарь
Могут быть изменены да Иногда 1 да
Элементы заказаны да да Да 2
Элементы строго типизированы нет да нет
Элементы могут быть получены по порядковым номерам да да нет
Новые элементы могут быть вставлены по порядковому номеру да нет нет
Как определить, существует ли элемент Итерировать все элементы Итерировать все элементы Итерировать все элементы
Элементы могут быть получены ключом да нет да
Ключи чувствительны к регистру нет N / A Дополнительно 3
Как определить, существует ли ключ Обработчик ошибок N / A .Exists функция
Удалить все элементы Итерация и .Remove Erase , ReDim .RemoveAll функция

1 Могут быть изменены только динамические массивы и только последнее измерение многомерных массивов.

2 , лежащие в основе .Keys и .Items упорядочены.

3 Определяется свойством .CompareMode .

Добавление элементов в коллекцию

Элементы добавляются в Collection , вызывая метод .Add :

Синтаксис:

.Add(item, [key], [before, after])
параметр Описание
вещь Элемент для хранения в Collection . Это может быть практически любое значение, которому может быть присвоена переменная, включая примитивные типы, массивы, объекты и Nothing .
ключ Необязательный. String которая служит уникальным идентификатором для извлечения элементов из Collection . Если указанный ключ уже существует в Collection , это приведет к ошибке времени выполнения 457: «Этот ключ уже связан с элементом этой коллекции».
до Необязательный. Существующий ключ ( String value) или индекс (числовое значение) для вставки элемента в Collection . Если задано значение, параметр after должен быть пустым или ошибка времени выполнения 5: «Неверный вызов или аргумент процедуры». Если передан String ключ, который не существует в Collection , это приведет к ошибке времени выполнения 5: «Неверный вызов или аргумент процедуры». Если числовой индекс передан, который не существует в Collection , это приведет к ошибке времени выполнения 9: «Подзаголовок вне диапазона».
после Необязательный. Существующий ключ ( String value) или индекс (числовое значение) для вставки элемента после в Collection . Если задано значение, параметр before должен быть пустым. Исправленные ошибки идентичны параметру before .

Заметки:

  • Ключи не чувствительны к регистру. .Add "Bar", "Foo" и .Add "Baz", "foo" приведет к столкновению клавиш.

  • Если ни один из необязательных параметров до или после не задан, элемент будет добавлен после последнего элемента Collection .

  • Вставки, заданные параметром до или после , изменят числовые индексы существующих элементов, чтобы они соответствовали новой позиции. Это означает, что при вставках в циклы следует соблюдать осторожность, используя числовые индексы.


Пример использования:

Public Sub Example()
    Dim foo As New Collection
    
    With foo
        .Add "One"            'No key. This item can only be retrieved by index.
        .Add "Two", "Second"  'Key given. Can be retrieved by key or index.
        .Add "Three", , 1     'Inserted at the start of the collection.
        .Add "Four", , , 1    'Inserted at index 2.
    End With
    
    Dim member As Variant
    For Each member In foo
        Debug.Print member    'Prints "Three, Four, One, Two"
    Next
End Sub

Удаление элементов из коллекции

Элементы удаляются из Collection , вызывая ее метод .Remove :

Синтаксис:

.Remove(index)
параметр Описание
индекс Элемент для удаления из Collection . Если переданное значение является числовым или Variant с числовым подтипом, оно будет интерпретироваться как числовой индекс. Если переданное значение представляет собой String или Variant содержащий строку, это будет интерпретироваться как ключ a. Если передан String-ключ, который не существует в Collection , это приведет к ошибке времени выполнения 5: «Неверный вызов или аргумент процедуры». Если числовой индекс передан, который не существует в Collection , это приведет к ошибке времени выполнения 9: «Подзаголовок вне диапазона».

Заметки:

  • Удаление элемента из Collection изменит числовые индексы всех элементов после него в Collection . For циклов, которые используют числовые индексы и удаляющие элементы, должны работать в обратном направлении ( Step -1 ), чтобы исключить исключения в индексе и пропущенные элементы.
  • Элементы обычно не должны удаляться из Collection изнутри цикла For Each поскольку это может дать непредсказуемые результаты.

Пример использования:

Public Sub Example()
    Dim foo As New Collection
    
    With foo
        .Add "One"
        .Add "Two", "Second"
        .Add "Three"
        .Add "Four"
    End With
     
    foo.Remove 1            'Removes the first item.
    foo.Remove "Second"     'Removes the item with key "Second".
    foo.Remove foo.Count    'Removes the last item.
    
    Dim member As Variant
    For Each member In foo
        Debug.Print member  'Prints "Three"
    Next
End Sub

Получение количества предметов коллекции

Количество элементов в Collection можно получить, вызвав ее функцию .Count :

Синтаксис:

.Count()

Пример использования:

Public Sub Example()
    Dim foo As New Collection
    
    With foo
        .Add "One"
        .Add "Two"
        .Add "Three"
        .Add "Four"
    End With
     
    Debug.Print foo.Count   'Prints 4
End Sub

Извлечение предметов из коллекции

Элементы можно получить из Collection , вызвав функцию .Item .

Синтаксис:

.Item(index)
параметр Описание
индекс Элемент для извлечения из Collection . Если переданное значение является числовым или Variant с числовым подтипом, оно будет интерпретироваться как числовой индекс. Если переданное значение представляет собой String или Variant содержащий строку, это будет интерпретироваться как ключ a. Если передан String-ключ, который не существует в Collection , это приведет к ошибке времени выполнения 5: «Неверный вызов или аргумент процедуры». Если числовой индекс передан, который не существует в Collection , это приведет к ошибке времени выполнения 9: «Подзаголовок вне диапазона».

Заметки:

  • .Item является членом Collection по умолчанию. Это обеспечивает гибкость в синтаксисе, как показано в примере использования ниже.
  • Числовые индексы основаны на 1.
  • Ключи не чувствительны к регистру. .Item("Foo") и .Item("foo") относятся к одному и тому же ключу.
  • Параметр индекс не неявно приводится к числу из String или визы-Versa. Вполне возможно, что .Item(1) и .Item("1") относятся к различным элементам Collection .

Пример использования (индексы):

Public Sub Example()
    Dim foo As New Collection
    
    With foo
        .Add "One"
        .Add "Two"
        .Add "Three"
        .Add "Four"
    End With
     
    Dim index As Long
    For index = 1 To foo.Count
        Debug.Print foo.Item(index) 'Prints One, Two, Three, Four
    Next
End Sub

Пример использования (ключи):

Public Sub Example()
    Dim keys() As String
    keys = Split("Foo,Bar,Baz", ",")
    Dim values() As String
    values = Split("One,Two,Three", ",")
        
    Dim foo As New Collection
    Dim index As Long
    For index = LBound(values) To UBound(values)
        foo.Add values(index), keys(index)
    Next
     
    Debug.Print foo.Item("Bar") 'Prints "Two"
End Sub

Пример использования (альтернативный синтаксис):

Public Sub Example()
    Dim foo As New Collection
    
    With foo
        .Add "One", "Foo"
        .Add "Two", "Bar"
        .Add "Three", "Baz"
    End With
    
    'All lines below print "Two"
    Debug.Print foo.Item("Bar")     'Explicit call syntax.
    Debug.Print foo("Bar")          'Default member call syntax.
    Debug.Print foo!Bar             'Bang syntax.
End Sub

Обратите внимание, что синтаксис bang ( ! ) Разрешен, потому что .Item является членом по умолчанию и может принимать один аргумент String . Утилита этого синтаксиса сомнительна.

Определение наличия ключа или предмета в коллекции

Ключи

В отличие от Scripting.Dictionary , в Collection нет способа определить, существует ли данный ключ или способ получить ключи, которые присутствуют в Collection . Единственный способ определить, присутствует ли ключ, - использовать обработчик ошибок:

Public Function KeyExistsInCollection(ByVal key As String, _
                                      ByRef container As Collection) As Boolean
    With Err
        If container Is Nothing Then .Raise 91
        On Error Resume Next
        Dim temp As Variant
        temp = container.Item(key)
        On Error GoTo 0

        If .Number = 0 Then
            KeyExistsInCollection = True 
        ElseIf .Number <> 5 Then
            .Raise .Number
        End If
    End With
End Function

Предметы

Единственный способ определить, содержится ли элемент в Collection - это перебирать Collection до тех пор, пока элемент не будет расположен. Обратите внимание, что поскольку Collection может содержать как примитивы, так и объекты, требуется дополнительная обработка, чтобы избежать ошибок во время сравнений:

Public Function ItemExistsInCollection(ByRef target As Variant, _
                                       ByRef container As Collection) As Boolean
    Dim candidate As Variant
    Dim found As Boolean
    
    For Each candidate In container
        Select Case True
            Case IsObject(candidate) And IsObject(target)
                found = candidate Is target
            Case IsObject(candidate), IsObject(target)
                found = False
            Case Else
                found = (candidate = target)
        End Select
        If found Then
            ItemExistsInCollection = True
            Exit Function
        End If
    Next
End Function

Очистка всех элементов из коллекции

Самый простой способ очистить все элементы из Collection - просто заменить его на новую Collection а старая - выйти из области видимости:

Public Sub Example()
    Dim foo As New Collection
    
    With foo
        .Add "One"
        .Add "Two"
        .Add "Three"
    End With
     
    Debug.Print foo.Count   'Prints 3
    Set foo = New Collection
    Debug.Print foo.Count   'Prints 0
End Sub

Однако, если имеется несколько ссылок на Collection , этот метод даст вам только пустую Collection для назначенной переменной .

Public Sub Example()
    Dim foo As New Collection
    Dim bar As Collection
    
    With foo
        .Add "One"
        .Add "Two"
        .Add "Three"
    End With
     
    Set bar = foo
    Set foo = New Collection
    
    Debug.Print foo.Count   'Prints 0
    Debug.Print bar.Count   'Prints 3
End Sub

В этом случае самый простой способ очистить содержимое - это перебрать количество элементов в Collection и повторно удалить самый нижний элемент:

Public Sub ClearCollection(ByRef container As Collection)
    Dim index As Long
    For index = 1 To container.Count
        container.Remove 1
    Next
End Sub


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow