Collection: Unterschied zwischen den Versionen

Aus VBA-wiki
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: „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…“)
 
 
(7 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
[[Category:vba-wiki]]
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.
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.


Zeile 45: Zeile 46:
  Next 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.
<span style="Color:blue">Private Sub </span>OverwriteItem<span style="Color:gray">()</span>
    <span style="Color:blue"> Dim </span>colTest<span style="Color:blue"> As </span>Collection
   
    <span style="Color:blue"> Set </span>colTest <span style="Color:gray">=</span><span style="Color:blue"> New </span>Collection
    colTest<span style="Color:gray">.</span>Add <span style="Color:gray">"First Item"</span>
    colTest<span style="Color:gray">.</span>Add <span style="Color:gray">"Item 2"</span>
   
    colTest<span style="Color:gray">.</span>Item<span style="Color:gray">(2)</span> <span style="Color:gray">=</span> <span style="Color:gray">"Second Item"</span>    <span style="Color:green">' Fehler 424: Objekt erforderlich</span>
<span style="Color:blue">End Sub</span>
''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:
<span style="Color:blue">Public Function </span>ReplaceItemInCollection<span style="Color:gray">(</span><span style="Color:blue">ByVal </span>colInCollection<span style="Color:blue"> As </span>Collection<span style="Color:gray">,</span><span style="Color:blue"> ByVal </span>strNewItem<span style="Color:blue"> As String</span><span style="Color:gray">,</span><span style="Color:blue"> ByVal </span>lngItemIndex<span style="Color:blue"> As Long</span><span style="Color:gray">)</span><span style="Color:blue"> As </span>Collection
    <span style="Color:blue"> Dim </span>lngCount<span style="Color:blue"> As Long</span>
   
    <span style="Color:blue"> Set </span>ReplaceItemInCollection <span style="Color:gray">=</span> colInCollection
    <span style="Color:blue"> If </span>lngItemIndex <span style="Color:gray"><</span> <span style="Color:gray">1</span><span style="Color:blue"> Then Exit Function</span>
    lngCount <span style="Color:gray">=</span> ReplaceItemInCollection<span style="Color:gray">.</span>Count
    <span style="Color:blue"> If </span>lngItemIndex <span style="Color:gray">></span> lngCount<span style="Color:blue"> Then Exit Function</span>
    ReplaceItemInCollection<span style="Color:gray">.</span>Remove lngItemIndex
    <span style="Color:blue"> Select Case </span>lngItemIndex
        <span style="Color:blue"> Case </span><span style="Color:gray">1</span>
            <span style="Color:blue"> Select Case </span>lngCount
                <span style="Color:blue"> Case </span><span style="Color:gray">1</span>
                    ReplaceItemInCollection<span style="Color:gray">.</span>Add strNewItem
                <span style="Color:blue"> Case Else</span>
                    ReplaceItemInCollection<span style="Color:gray">.</span>Add strNewItem<span style="Color:gray">,</span> <span style="Color:gray">,</span> <span style="Color:gray">1</span>
            <span style="Color:blue"> End Select</span>
        <span style="Color:blue"> Case Else</span>
            ReplaceItemInCollection<span style="Color:gray">.</span>Add strNewItem<span style="Color:gray">,</span> <span style="Color:gray">,</span> <span style="Color:gray">,</span> lngItemIndex <span style="Color:gray">-</span> <span style="Color:gray">1</span>
    <span style="Color:blue"> End Select
End Function</span>
<span style="Color:blue">Private Sub </span>OverwriteItem<span style="Color:gray">()</span>
    <span style="Color:blue"> Dim </span>colTest<span style="Color:blue"> As </span>Collection
   
    <span style="Color:blue"> Set </span>colTest <span style="Color:gray">=</span><span style="Color:blue"> New </span>Collection
    colTest<span style="Color:gray">.</span>Add <span style="Color:gray">"First Item"</span>
    colTest<span style="Color:gray">.</span>Add <span style="Color:gray">"Item 2"</span>
   
    Debug<span style="Color:gray">.</span>Print colTest<span style="Color:gray">.</span>Item<span style="Color:gray">(2)</span>            <span style="Color:green">'  Item 2</span>
    <span style="Color:blue"> Set </span>colTest <span style="Color:gray">=</span> Tools<span style="Color:gray">.</span>CollectionTools<span style="Color:gray">.</span>ReplaceItemInCollection<span style="Color:gray">(</span>colTest<span style="Color:gray">,</span> <span style="Color:gray">"Second Item",</span> <span style="Color:gray">2)</span>
    Debug<span style="Color:gray">.</span>Print colTest<span style="Color:gray">.</span>Item<span style="Color:gray">(2)</span>            <span style="Color:green">'  Second Item</span>
<span style="Color:blue">End Sub</span>
'''Beachte:''' Der Schlüssel eines Eintrags kann nicht verwendet werden, um seinen Index zu finden (siehe [[#Schlüssel_('Key')]])


==== Als Rückgabewert einer Funktion ====
==== Als Rückgabewert einer Funktion ====
Zeile 90: Zeile 142:
'''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'.
'''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.
'''Wichtig:''' Der Schlüssel kann zwar verwendet werden, um ein Element direkt anzusprechen, aber es ist nicht möglich, den Index eines Elementes mithilfe des Schlüssels zu ermitteln. Dies bedeutet auch, dass man nicht ein Element der Auflistung nur mithilfe des Schlüssels entfernen kann!


== Beispiele ==
== Beispiele ==
Zeile 116: Zeile 168:
Hier wird eine Collection in eine Liste umgewandelt:
Hier wird eine Collection in eine Liste umgewandelt:


  Public Function CollectionToList(ByVal colCollection As Collection, ByVal strDelimiter As String) As String
  <span style="Color:blue">Public Function </span>CollectionToList<span style="Color:gray">(</span><span style="Color:blue">ByVal </span>colCollection<span style="Color:blue"> As </span>Collection<span style="Color:gray">,</span><span style="Color:blue"> ByVal </span>strDelimiter<span style="Color:blue"> As String</span><span style="Color:gray">)</span><span style="Color:blue"> As String</span>
    Dim lngIndex As Long
    <span style="Color:blue"> Dim </span>lngIndex<span style="Color:blue"> As Long</span>
      
      
    If colCollection Is Nothing Then
    <span style="Color:blue"> If </span>colCollection<span style="Color:blue"> Is </span>Nothing<span style="Color:blue"> Then</span>
        Exit Function
        <span style="Color:blue"> Exit Function</span>
    End If
    <span style="Color:blue"> End If</span>
    If colCollection.Count < 1 Then
    <span style="Color:blue"> If </span>colCollection<span style="Color:gray">.</span>Count <span style="Color:gray"><</span> <span style="Color:gray">1</span><span style="Color:blue"> Then</span>
        Exit Function
        <span style="Color:blue"> Exit Function</span>
    End If
    <span style="Color:blue"> End If</span>
     CollectionToList = colCollection.Item(1)        <span style="color:green">' Erstes Element wird ohne Trennzeichen hinzugefügt</span>
     CollectionToList <span style="Color:gray">=</span> colCollection<span style="Color:gray">.</span>Item<span style="Color:gray">(1)</span>       <span style="Color:green">' Erstes Element wird ohne Trennzeichen hinzugefügt</span>
    For lngIndex = 2 To colCollection.Count
    <span style="Color:blue"> For </span>lngIndex <span style="Color:gray">=</span> <span style="Color:gray">2</span><span style="Color:blue"> To </span>colCollection<span style="Color:gray">.</span>Count
         CollectionToList = CollectionToList & strDelimiter & colCollection.Item(lngIndex)
         CollectionToList <span style="Color:gray">=</span> CollectionToList & strDelimiter & colCollection<span style="Color:gray">.</span>Item<span style="Color:gray">(</span>lngIndex<span style="Color:gray">)</span>
    Next lngIndex
    <span style="Color:blue"> Next </span>lngIndex<span style="Color:blue">
  End Function
  End Function</span>


== Alternativen ==
== Alternativen ==

Aktuelle Version vom 10. Februar 2023, 10:10 Uhr

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

Beachte: Der Schlüssel eines Eintrags kann nicht verwendet werden, um seinen Index zu finden (siehe #Schlüssel_('Key'))

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'.

Wichtig: Der Schlüssel kann zwar verwendet werden, um ein Element direkt anzusprechen, aber es ist nicht möglich, den Index eines Elementes mithilfe des Schlüssels zu ermitteln. Dies bedeutet auch, dass man nicht ein Element der Auflistung nur mithilfe des Schlüssels entfernen kann!

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