Поиск…
замечания
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