Ricerca…


Osservazioni

Una Collection è un oggetto contenitore incluso nel runtime VBA. Non sono necessari ulteriori riferimenti per poterlo utilizzare. È possibile utilizzare una Collection per memorizzare elementi di qualsiasi tipo di dati e consentirne il recupero tramite l'indice ordinale dell'articolo o utilizzando una chiave univoca opzionale.


Confronto delle funzionalità con array e dizionari

Collezione schieramento Dizionario
Può essere ridimensionato A volte 1
Gli articoli sono ordinati 2
Gli articoli sono fortemente tipizzati No No
Gli oggetti possono essere recuperati per ordinale No
Nuovi oggetti possono essere inseriti in ordinale No No
Come determinare se esiste un oggetto Iterare tutti gli elementi Iterare tutti gli elementi Iterare tutti gli elementi
Gli articoli possono essere recuperati con la chiave No
Le chiavi sono sensibili al maiuscolo / minuscolo No N / A Opzionale 3
Come determinare se esiste una chiave Gestore degli errori N / A .Exists funzione
Rimuovi tutti gli oggetti .Remove e. .Remove Erase , ReDim .RemoveAll funzione

1 Solo gli array dinamici possono essere ridimensionati e solo l'ultima dimensione di array multidimensionali.

2 I .Keys e .Items sottostanti sono ordinati.

3 Determinato dalla proprietà .CompareMode .

Aggiunta di elementi a una raccolta

Gli oggetti vengono aggiunti a una Collection chiamando il suo metodo .Add :

Sintassi:

.Add(item, [key], [before, after])
Parametro Descrizione
articolo L'oggetto da conservare nella Collection . Questo può essere essenzialmente qualsiasi valore a cui può essere assegnata una variabile, inclusi tipi primitivi, matrici, oggetti e Nothing .
chiave Opzionale. Una String che funge da identificatore univoco per il recupero di elementi dalla Collection . Se la chiave specificata esiste già nella Collection , verrà generato un errore di runtime 457: "Questa chiave è già associata a un elemento di questa raccolta".
prima Opzionale. Una chiave esistente (valore String ) o indice (valore numerico) per inserire l'elemento nella Collection . Se viene fornito un valore, il parametro after deve essere vuoto o un errore run-time 5: "Risulterà una chiamata o un argomento di procedura non valida". Se viene passata una chiave String che non esiste nella Collection , verrà generato un errore 5 in fase di esecuzione: "Chiamata o argomento procedura non valida". Se viene passato un indice numerico che non esiste nella Collection , verrà generato un errore 9 in fase di esecuzione: "Sottoscritto fuori intervallo".
dopo Opzionale. Una chiave esistente (valore String ) o indice (valore numerico) per inserire l'elemento dopo nella Collection . Se viene fornito un valore, il parametro before deve essere vuoto. Gli errori generati sono identici al parametro precedente .

Gli appunti:

  • Le chiavi non sono sensibili al maiuscolo / minuscolo. .Add "Bar", "Foo" e. .Add "Baz", "foo" provocherà una collisione tra chiavi.

  • Se nessuno dei due parametri opzionali prima o dopo viene assegnato, l'elemento verrà aggiunto dopo l'ultimo elemento nella Collection .

  • Gli inserimenti effettuati specificando un parametro before o after modificheranno gli indici numerici dei membri esistenti per adattarli alla nuova posizione. Ciò significa che è necessario prestare attenzione quando si effettuano inserimenti nei loop utilizzando indici numerici.


Esempio di utilizzo:

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

Rimozione di elementi da una raccolta

Gli elementi vengono rimossi da una Collection chiamando il suo metodo .Remove :

Sintassi:

.Remove(index)
Parametro Descrizione
indice L'elemento da rimuovere dalla Collection . Se il valore passato è un tipo numerico o Variant con un sottotipo numerico, verrà interpretato come indice numerico. Se il valore passato è una String o Variant contenente una stringa, verrà interpretata come una chiave. Se viene passata una chiave stringa che non esiste nella Collection , verrà generato un errore 5 in fase di esecuzione: "Chiamata o argomento procedura non valida". Se viene passato un indice numerico che non esiste nella Collection , verrà generato un errore 9 in fase di esecuzione: "Sottoscritto fuori intervallo".

Gli appunti:

  • La rimozione di un oggetto da una Collection cambierà gli indici numerici di tutti gli elementi dopo di essa nella Collection . For cicli che utilizzano indici numerici e rimuovi elementi, è necessario eseguire l'operazione all'indietro ( Step -1 ) per evitare eccezioni degli indici e articoli saltati.
  • Articoli non dovrebbero generalmente essere rimossi da una Collection all'interno di un For Each ciclo come può dare risultati imprevedibili.

Esempio di utilizzo:

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

Ottenere il numero di oggetti di una collezione

Il numero di elementi in una Collection può essere ottenuto chiamando la sua funzione .Count :

Sintassi:

.Count()

Esempio di utilizzo:

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

Recupero di oggetti da una collezione

Gli oggetti possono essere recuperati da una Collection chiamando la funzione .Item .

Sintassi:

.Item(index)
Parametro Descrizione
indice L'oggetto da recuperare dalla Collection . Se il valore passato è un tipo numerico o Variant con un sottotipo numerico, verrà interpretato come indice numerico. Se il valore passato è una String o Variant contenente una stringa, verrà interpretata come una chiave. Se viene passata una chiave stringa che non esiste nella Collection , verrà generato un errore 5 in fase di esecuzione: "Chiamata o argomento procedura non valida". Se viene passato un indice numerico che non esiste nella Collection , verrà generato un errore 9 in fase di esecuzione: "Sottoscritto fuori intervallo".

Gli appunti:

  • .Item è il membro predefinito di Collection . Ciò consente flessibilità nella sintassi come dimostrato nell'uso di esempio riportato di seguito.
  • Gli indici numerici sono basati su 1.
  • Le chiavi non sono sensibili al maiuscolo / minuscolo. .Item("Foo") e .Item("foo") riferiscono alla stessa chiave.
  • Il parametro index non viene convertito implicitamente in un numero da String o viceversa. È del tutto possibile che .Item(1) e .Item("1") facciano riferimento a diversi elementi della Collection .

Esempio di utilizzo (indici):

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

Esempio di utilizzo (chiavi):

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

Esempio di utilizzo (sintassi 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

Si noti che la sintassi bang ( ! ) È consentita perché .Item è il membro predefinito e può accettare un singolo argomento String . L'utilità di questa sintassi è discutibile.

Determinazione della presenza di una chiave o di un oggetto in una raccolta

chiavi

A differenza di Scripting.Dictionary , una Collection non ha un metodo per determinare se esiste una determinata chiave o un modo per recuperare le chiavi che sono presenti nella Collection . L'unico metodo per determinare se una chiave è presente è utilizzare il gestore degli errori:

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

Elementi

L'unico modo per determinare se un elemento è contenuto in una Collection è iterare sulla Collection fino a quando l'elemento non si trova. Tieni presente che poiché una Collection può contenere primitive o oggetti, è necessaria una gestione aggiuntiva per evitare errori di runtime durante i confronti:

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

Cancellare tutti gli oggetti da una collezione

Il modo più semplice per cancellare tutti gli elementi da una Collection è semplicemente sostituirlo con una nuova Collection e lasciare che quello vecchio vada fuori ambito:

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

Tuttavia, se sono presenti più riferimenti alla Collection , questo metodo fornirà solo una Collection vuota per la variabile che viene assegnata .

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

In questo caso, il modo più semplice per cancellare i contenuti consiste nel ripetere il numero di elementi nella Collection e rimuovere ripetutamente l'elemento più basso:

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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow