Buscar..


Observaciones

Una Collection es un objeto contenedor que se incluye en el tiempo de ejecución de VBA. No se requieren referencias adicionales para usarlo. Una Collection se puede utilizar para almacenar artículos de cualquier tipo de datos y permite la recuperación mediante el índice ordinal del artículo o mediante el uso de una clave única opcional.


Comparación de características con matrices y diccionarios

Colección Formación Diccionario
Puede ser redimensionado A veces 1
Los artículos son ordenados Si 2
Los artículos son fuertemente tipados No No
Los artículos pueden ser recuperados por ordinal No
Nuevos artículos pueden ser insertados en ordinal No No
Cómo determinar si un artículo existe Iterar todos los elementos Iterar todos los elementos Iterar todos los elementos
Los artículos pueden ser recuperados por clave No
Las claves distinguen entre mayúsculas y minúsculas No N / A Opcional 3
Cómo determinar si existe una clave Manejador de errores N / A Función .Exists
Eliminar todos los elementos .Remove y. .Remove Erase , ReDim .RemoveAll función

1 Solo se puede cambiar el tamaño de las matrices dinámicas, y solo la última dimensión de las matrices multidimensionales.

2 Las .Keys y .Items subyacentes están ordenados.

3 Determinado por la propiedad .CompareMode .

Agregar elementos a una colección

Los elementos se agregan a una Collection llamando a su método .Add :

Sintaxis:

.Add(item, [key], [before, after])
Parámetro Descripción
ít El artículo para almacenar en la Collection . Esto puede ser esencialmente cualquier valor al que se pueda asignar una variable, incluidos los tipos primitivos, las matrices, los objetos y Nothing .
llave Opcional. Una String que sirve como un identificador único para recuperar elementos de la Collection . Si la clave especificada ya existe en la Collection , se producirá un error de tiempo de ejecución 457: "Esta clave ya está asociada con un elemento de esta colección".
antes de Opcional. Una clave existente (valor de String ) o índice (valor numérico) para insertar el elemento antes en la Collection . Si se proporciona un valor, el parámetro posterior debe estar vacío o debe aparecer un error de tiempo de ejecución 5: "Llamada o argumento de procedimiento no válido". Si se pasa una clave de String que no existe en la Collection , se generará un error de tiempo de ejecución 5: "Llamada o argumento de procedimiento no válido". Si se pasa un índice numérico que no existe en la Collection , se generará un error de tiempo de ejecución 9: "Subíndice fuera de rango".
después Opcional. Una clave existente (valor de String ) o índice (valor numérico) para insertar el elemento después en la Collection . Si se da un valor, el parámetro anterior debe estar vacío. Los errores planteados son idénticos al parámetro anterior .

Notas:

  • Las claves no distinguen entre mayúsculas y minúsculas. .Add "Bar", "Foo" y .Add "Baz", "foo" resultará en una colisión de teclas.

  • Si no se proporciona ninguno de los parámetros opcionales antes o después , el elemento se agregará después del último elemento de la Collection .

  • Las inserciones realizadas especificando un parámetro antes o después alterarán los índices numéricos de los miembros existentes para que coincidan con su nueva posición. Esto significa que se debe tener cuidado al realizar inserciones en bucles utilizando índices numéricos.


Uso de la muestra:

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

Eliminar elementos de una colección

Los elementos se eliminan de una Collection llamando a su método .Remove :

Sintaxis:

.Remove(index)
Parámetro Descripción
índice El elemento a eliminar de la Collection . Si el valor pasado es un tipo numérico o Variant con un subtipo numérico, se interpretará como un índice numérico. Si el valor pasado es una String o Variant contiene una cadena, se interpretará como una clave. Si se pasa una clave de cadena que no existe en la Collection , se generará un error de tiempo de ejecución 5: "Llamada o argumento de procedimiento no válido". Si se pasa un índice numérico que no existe en la Collection , se generará un error de tiempo de ejecución 9: "Subíndice fuera de rango".

Notas:

  • La eliminación de un elemento de una Collection cambiará los índices numéricos de todos los elementos que se encuentren después de él en la Collection . For bucles que usan índices numéricos y eliminan elementos, deben ejecutarse hacia atrás ( Step -1 ) para evitar excepciones de subíndices y elementos omitidos.
  • Por lo general, los elementos no deben eliminarse de una Collection desde dentro de un bucle For Each ya que puede dar resultados impredecibles.

Uso de la muestra:

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

Obtener el recuento de artículos de una colección

El número de elementos en una Collection se puede obtener llamando a su función .Count :

Sintaxis:

.Count()

Uso de la muestra:

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

Recuperar elementos de una colección

Los elementos se pueden recuperar de una Collection llamando a la función .Item .

Sintaxis:

.Item(index)
Parámetro Descripción
índice El elemento a recuperar de la Collection . Si el valor pasado es un tipo numérico o Variant con un subtipo numérico, se interpretará como un índice numérico. Si el valor pasado es una String o Variant contiene una cadena, se interpretará como una clave. Si se pasa una clave de cadena que no existe en la Collection , se generará un error de tiempo de ejecución 5: "Llamada o argumento de procedimiento no válido". Si se pasa un índice numérico que no existe en la Collection , se generará un error de tiempo de ejecución 9: "Subíndice fuera de rango".

Notas:

  • .Item es el miembro predeterminado de la Collection . Esto permite flexibilidad en la sintaxis como se muestra en el uso de muestra a continuación.
  • Los índices numéricos están basados ​​en 1.
  • Las claves no distinguen entre mayúsculas y minúsculas. .Item("Foo") y .Item("foo") refieren a la misma clave.
  • El parámetro de índice no se convierte implícitamente a un número desde una String o viceversa. Es totalmente posible que .Item(1) y .Item("1") refieran a diferentes elementos de la Collection .

Uso de la muestra (índices):

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

Uso de la muestra (claves):

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

Uso de muestra (sintaxis alternativa):

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

Tenga en cuenta que la sintaxis de bang ( ! ) Está permitida porque .Item es el miembro predeterminado y puede tomar un solo argumento de String . La utilidad de esta sintaxis es cuestionable.

Determinar si una clave o elemento existe en una colección

Llaves

A diferencia de un Scripting.Dictionary , una Collection no tiene un método para determinar si existe una clave determinada o una forma de recuperar las claves que están presentes en la Collection . El único método para determinar si una clave está presente es usar el controlador de errores:

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

Artículos

La única manera de determinar si un artículo está contenido en una Collection es iterar sobre la Collection hasta que se encuentre el artículo. Tenga en cuenta que debido a que una Collection puede contener primitivos u objetos, se necesita un manejo adicional para evitar errores de tiempo de ejecución durante las comparaciones:

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

Borrar todos los artículos de una colección

La forma más fácil de eliminar todos los elementos de una Collection es simplemente reemplazarlo con una nueva Collection y dejar que el anterior quede fuera del alcance:

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

Sin embargo, si hay varias referencias a la Collection retenida, este método solo le dará una Collection vacía para la variable asignada .

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

En este caso, la forma más fácil de borrar el contenido es recorrer la cantidad de elementos en la Collection y eliminar repetidamente el elemento más bajo:

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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow