Collection

Aus VBA-wiki
Zur Navigation springen Zur Suche springen

Eine Auflistung (Collection) nimmt eine Liste von Werten entgegen. Diese müssen nicht zwingend den gleichen Datentyp haben, Sie können also z. B. Zahlen und Zeichenketten mischen. Allerdings ist es meistens sinnvoll, eine Liste mit verwandten Elementen zu füllen, welche dann zwangsweise den gleichen Datentyp haben.

Arbeiten mit Collections

Vorbereitungen

Deklaration

Auflistungen erhalten bei der Deklaration den Datentyp 'Collection'.

Dim colList As Collection

Instanziierung

Auflistungen werden mit 'Set' und 'New' instanziiert.

Set colList = New Collection

Verwendung

Elemente hinzufügen

Neue Elemente werden mit der 'Add'-Methode hinzugefügt.

colList.Add "Item 1"
colList.Add "Item 3"

Die Reihenfolge in der Liste entspricht dabei der Reihenfolge, in der die Elemente hinzugefügt wurden. Wenn Sie die Reihenfolge nachträglich beeinflussen möchten, verwenden Sie einen der optionalen Parameter 'Before' bzw. 'After'.

colList.Add "Item 2", , 1        ' Fügt dieses Element nach dem ersten Element ein

Elemente abfragen

Die einzelnen Elemente sind in der 'Item'-Eigenschaft zu finden und können direkt über den Index angesprochen werden.

Dim lngIndex As Long
Dim colList As Collection

Set colList = New Collection
colList.Add "Item 1"
colList.Add "Item 2"

For lngIndex = 1 To colList.Count
    Debug.Print colList.Item(lngIndex)
Next lngIndex

Wert überschreiben

Wenn ein Element einer Collection hinzugefügt wurde, kann man es nicht nachträglich ändern, denn die 'Item'-Eigenschaft ist schreibgeschützt.

Private Sub OverwriteItem()
    Dim colTest As Collection
    
    Set colTest = New Collection
    colTest.Add "First Item"
    colTest.Add "Item 2"
    
    colTest.Item(2) = "Second Item"     ' Fehler 424: Objekt erforderlich
End Sub

Lösung: Folgende Beispielfunktion ersetzt den gewünschten Wert, indem Sie den ursprünglichen Eintrag löscht und an gleicher Stelle den neuen Wert hinzufügt:

Public Function ReplaceItemInCollection(ByVal colInCollection As Collection, ByVal strNewItem As String, ByVal lngItemIndex As Long) As Collection
    Dim lngCount As Long
    
    Set ReplaceItemInCollection = colInCollection
    If lngItemIndex < 1 Then Exit Function
    lngCount = ReplaceItemInCollection.Count
    If lngItemIndex > lngCount Then Exit Function
    ReplaceItemInCollection.Remove lngItemIndex
    Select Case lngItemIndex
        Case 1
            Select Case lngCount
                Case 1
                    ReplaceItemInCollection.Add strNewItem
                Case Else
                    ReplaceItemInCollection.Add strNewItem, , 1
            End Select
        Case Else
            ReplaceItemInCollection.Add strNewItem, , , lngItemIndex - 1
    End Select
End Function


Private Sub OverwriteItem()
    Dim colTest As Collection
    
    Set colTest = New Collection
    colTest.Add "First Item"
    colTest.Add "Item 2"
    
    Debug.Print colTest.Item(2)             '  Item 2
    Set colTest = Tools.CollectionTools.ReplaceItemInCollection(colTest, "Second Item", 2)
    Debug.Print colTest.Item(2)             '  Second Item
End Sub

Als Rückgabewert einer Funktion

Private Function ListOfItems() As Collection
    Dim colList As Collection
    
    Set colList = New Collection
    colList.Add "Item 1"
    colList.Add "Item 2"
    
    ' Die Auflistung in der Prozedur-Variablen wird zum Schluss
    ' über den Funktions-Namen zurückgegeben:
    Set ListOfItems = colList
End Function

Alternativ kann der Funktionsname direkt als Auflistung-Variable verwendet werden. Die Rückgabe erfolgt dann automatisch:

Private Function ListOfItems() As Collection
  
   Set ListOfItems = New Collection
   ListOfItems.Add "Item 1"
   ListOfItems.Add "Item 2"

    ' Die Rückgabe entfällt, weil die Funktions-Variable schon die Auflistung enthält!

End Function

Weitere Möglichkeiten

Schlüssel ('Key')

Die Collection erlaubt beim Hinzufügen von Elementen mit 'Add' über einen optionalen Parameter die Verwendung von Schlüsseln ('Key'). Mithilfe des Schlüssels können Sie anschließend direkt auf ein Element zugreifen, ohne seinen Index kennen zu müssen. Die Groß- bzw. Kleinschreibung wird bei Schlüsseln ignoriert.

   Dim colNames As Collection
   
   Set colNames = New Collection
   colNames.Add "Berta Beispiel", "bb"
   colNames.Add "Max Mustermann", "mm"
   colNames.Add "Maxine Musterfrau", "MF"

' colNames.Add "Maren Ferner", "MF" ' Schlüssel ist schon vergeben, erzeugt Fehler!

   Debug.Print colNames.Item("mf")         ' Maxine Musterfrau

Bitte Beachten: Jeder Schlüssel muss innerhalb einer Auflistung eindeutig sein, sonst erscheint die Fehlermeldung 'Laufzeitfehler 457 - Dieser Schlüssel ist bereits einem Element der Auflistung zugeordnet'.

Allerdings ist die Verwendung von Schlüsseln nur dann sinnvoll, wenn sie aus Elementen aufgebaut ist, die Ihnen zur Programmierzeit schon bekannt sind.

Beispiele

Im folgenden Beispiel wird eine Auflistung mithilfe einer Schleife aufgebaut:

' Diese Funktion soll eine Liste der Textmarken zurückgeben,
' die Firmendaten enthalten
Public Function ListOfCompanyDataBookmarks() As Collection
    Dim bkm As Bookmark
    
    ' Der Name der Funktion gilt als Auflistungs-Variable
    ' und muss daher instanziiert werden:
    Set ListOfCompanyDataBookmarks = New Collection
    
    For Each bkm In ActiveDocument.Bookmarks
        If LCase(bkm.Name) Like "company" Then
            ' Wenn der Textmarken-Name den Text 'company' enthält,
            ' wir der Name der Auflistung hinzugefügt
            ListOfCompanyDataBookmarks.Add bkm.Name
        End If
    Next bkm
End Function

Hier wird eine Collection in eine Liste umgewandelt:

Public Function CollectionToList(ByVal colCollection As Collection, ByVal strDelimiter As String) As String
    Dim lngIndex As Long
    
    If colCollection Is Nothing Then
        Exit Function
    End If
    If colCollection.Count < 1 Then
        Exit Function
    End If
    CollectionToList = colCollection.Item(1)        ' Erstes Element wird ohne Trennzeichen hinzugefügt
    For lngIndex = 2 To colCollection.Count
        CollectionToList = CollectionToList & strDelimiter & colCollection.Item(lngIndex)
    Next lngIndex
End Function

Alternativen

Alternativ zu einer Collection können Sie auch ein eindimensionales Array verwenden. In manchen Fällen ist dieses sogar einer Collection vorzuziehen, weil es zum Beispiel direkt an eine Combobox bzw. einem Listenfeld in einer UserForm übergeben werden kann.

Bitte beachten Sie hierzu den Vergleich zwischen Collection und Array