Home > Artikel > Ausgabe 2/2019 > Auflistungen mit dem Dictionary-Objekt

Auflistungen mit dem Dictionary-Objekt

Achtung: Sie sind nicht angemeldet. Wenn Sie Abonnent sind und sich anmelden, lesen Sie den kompletten Artikel, laden das PDF herunter oder probieren die Beispieldatenbank aus (sofern vorhanden).

Die Bibliothek Microsoft Scripting Runtime liefert neben den Objekten für den Umgang mit Laufwerken, Verzeichnissen, Dateien und Textstreams noch ein weiteres Objekt an, nämlich das Dictionary-Objekt. Dabei handelt es sich um eine Alternative zur Collection-Auflistung der VBA-Bibliothek. Das Dictionary-Objekt liefert allerdings ein paar zusätzliche Features. Dieser Artikel zeigt, wie Sie mit dem Dictionary-Objekt programmieren und wozu Sie es nutzen können.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1902_Dictionary.accdb.

Andere Auflistungsarten

Es gibt neben dem Dictionary-Objekt andere Möglichkeiten, um Auflistungen von Elementen oder Informationen unterzubringen. Da wäre zum Beispiel das Array, über das wir beispielsweise im Artikel Programmieren mit Arrays berichtet haben. Und die ebenfalls in VBA eingebaute Collectioon haben wir im Artikel Programmieren mit Collections ausführlich beschrieben.

Verweis auf die Microsoft Scripting Runtime

Wenn Sie das Dictionary-Objekt der Bibliothek Microsoft Scripting Runtime nutzen wollen, können Sie dieses per Late Binding oder Early Binding tun. Wenn Sie die Early Binding-Variante verwenden wollen, gehen Sie wie folgt vor: Fügen wir dem VBA-Projekt der Datenbank einen Verweis auf die entsprechende Bibliothek hinzu, und zwar im Verweise-Dialog (VBA-Editor, Menüpunkt Extras|Verweise) – siehe Bild 1. Dann können Sie die Variable für das Dictionary-Objekt mit dem entsprechenden Typ deklarieren und auch mit dem Schlüsselwort New eine neue Instanz dieser Klasse erstellen:

Verweis auf die Bibliothek Microsoft Scripting Runtime

Bild 1: Verweis auf die Bibliothek Microsoft Scripting Runtime

Dim objDictionary As Dictionary

Set objDictionary = New Dictionary

Wenn Sie aus irgendwelchen Gründen keinen Verweis setzen wollen, können Sie auch mit Late Binding arbeiten. In diesem Fall verwenden Sie die folgenden Anweisungen statt der oben verwendeten:

Dim objDictionary As Object

Set objDictionary = CreateObject("Scripting.Dictionary")

Das Dictionary-Objekt

Das Dictionary-Objekt enthält die folgenden Elemente:

  • Add: Fügt ein neues Element hinzu. Erwartet den Schlüssel und den Wert für das neue Element als Parameter.
  • CompareMode: Modus für das Vergleichen der Schlüsselwerte. Es gibt die Werte vbTextCompare (unterscheidet nicht zwischen Groß- und Kleinschreibung) und vbBinaryCompare (unterscheidet zwischen Groß- und Kleinschreibung).
  • Count: Liefert die Anzahl der Einträge im Dictionary-Objekt.
  • Exists: Prüft, ob das Element mit dem angegebenen Schlüssel existiert.
  • Item: Erlaubt den Zugriff über den Schlüssel des jeweiligen Elements.
  • Items: Auflistung aller Werte, die über den Index angesteuert werden kann.
  • Key: Dient zum Zuweisen eines neuen Schlüssels für ein vorhandenes Element.
  • Keys: Auflistung aller Schlüssel, die über den Index angesteuert werden kann.
  • Remove: Entfernt den Eintrag mit dem angegebenen Schlüssel aus dem Dictionary-Objekt.
  • RemoveAll: Entfernt alle Einträge aus dem Dictionary-Objekt.

Erstellen und Füllen eines Dictionary-Objekts

Zum Hinzufügen eines Eintrags zu einem Dictionary-Objekts verwenden Sie standardmäßig die Add-Methode. Diese gibt über die zur Verfügung stehenden Parameter, die Sie nach Eingabe der Add-Methode etwa per IntelliSense einsehen können, die Struktur eines Eintrags vor (siehe Bild 2).

Nutzen von IntelliSense mit dem Dictionary-Objekt

Bild 2: Nutzen von IntelliSense mit dem Dictionary-Objekt

Dieser enthält also ein Key- und ein Item-Element. Für Key geben Sie einen Namen oder einen Wert an, über den Sie den Eintrag später referenzieren wollen.

Wenn Sie also etwa eine Reihe von Informationen über einen Benutzer in einem Dictionary-Objekt speichern wollen, beginnen Sie mit dem Key mit der Bezeichnung Vorname und weisen dem Element mit diesem Key den entsprechenden Wert zu, beispielsweise André:

Dim objDictionary As Dictionary

Set objDictionary = New Dictionary

With objDictionary

.Add "Vorname", "André"

End With

Öffentliches Dictionary-Objekt deklarieren

Damit wir mit dem Dictionary, dessen Daten gegebenenfalls für die komplette Sitzung mit der Access-Anwendung zur Verfügung stehen sollen, experimentieren können, deklarieren wir es außerhalb einer Prozedur in einem Standardmodul als öffentliche Variable:

Public objDictionary As Dictionary

Dann erstellen wir eine Instanz der Dictionary-Klasse und weisen diese unserer Objektvariablen zu:

Set objDictionary = New Dictionary

Dies können Sie in einer Prozedur erledigen, aber auch etwa über den Direktbereich des VBA-Editors.

Eintrag hinzufügen mit der Add-Methode

Danach fügen wir dort den ersten Eintrag hinzu:

objDictionary.Add "Vorname", "André"

Damit können wir nun schon einmal die Count-Eigenschaft nutzen, um die Anzahl der Elemente zu ermitteln – ebenfalls im Direktbereich:

Debug.Print objDictionary.Count

1

Wir fügen ein weiteres Element hinzu:

objDictionary.Add "Nachname", "Minhorst"

Danach liefert Count logischerweise diesen Wert:

Debug.Print objDictionary.Count

2

Wenn wir allerdings versuchen, ein Element zum Dictionary-Objekt hinzuzufügen, dessen Schlüssel bereits vorhanden ist, löst dies den Fehler mit der Nummer 457 aus (Dieser Schlüssel ist bereits einem Wert dieser Auflistung zugeordnet.). Auch dies können wir leicht umgehen, indem wir zuvor mit der Exists-Funktion prüfen, ob das entsprechende Element bereits vorhanden ist:

Public Sub ElementNurHinzufuegenWennNochNichtVorhanden()

If Not objDictionary.Exists("Vorname") Then

objDictionary.Add "Vorname", "Klaus"

Else

MsgBox "Element 'Vorname' bereits vorhanden."

End If

End Sub

Auf Elemente per Key zugreifen

Wie greifen wir nun auf die einzelnen Elemente des Dictionary-Elements zu? Dazu verwenden wir beispielsweise die Item-Eigenschaft:

objDictionary.Item("Vorname")

André

objDictionary.Item("Nachname")

Minhorst

Anderen Wert zuweisen

Wenn Sie den Wert eines Dictionary-Eintrags mit einem bestimmten Schlüssel ändern wollen, referenzieren Sie das Element über den Schlüssel als Parameter der Eigenschaft Item und weisen diesem dann den neuen Wert zu:

objDictionary.Item("Vorname") = "Andreas"

Danach ist der Wert geändert:

objDictionary.Item("Vorname")

Andreas

Was aber geschieht, wenn wir einen Wert zu einem Element zuweisen wollen, das noch gar nicht existiert – wie in folgendem Beispiel?

objDictionary.Item("Strasse") = "Borkhofer Str. 17"

Dann wird automatisch ein neuer Eintrag mit dem angegebenen Schlüssel angelegt und diesem der nachfolgende Wert zugewiesen. Das können Sie leicht an der Anzahl der Einträge prüfen:

Debug.Print objDictionary.Count

3

Elemente des Dictionary-Objekts durchlaufen

Können wir die Elemente des Dictionary-Elements auch per Schleife durchlaufen? Wir probieren es zunächst mit einer einfachen For Next-Schleife über den Index-Wert, wobei wir 1 als untersten Wert annehmen und den obersten Wert mit der Count-Eigenschaft von objDictionary ermitteln:

Public Sub DictionaryDurchlaufen()

Dim i As Integer

For i = 1 To objDictionary.Count

With objDictionary

Debug.Print .Item(i)

End With

Next i

End Sub

Dies gibt allerdings nur leere Zeilen im Direktbereich aus. Wie ist das möglich? Das ist eine Eigenart der Dictionary-Klasse. Diese legt beim Versuch des Zugriffs auf ein Element, das nicht vorhanden ist, einfach ein neues Element mit dem angegebenen Schlüssel an und weist diesem keinen Wert zu.

Wenn wir vor dem Aufruf der obigen Prozedur also drei Elemente zum Dictionary-Objekt hinzugefügt hatten, befinden sich nun sechs Elemente darin. Das belegt auch der Test mit der Count-Eigenschaft:

objDictionary.Count

6

Dictionary durchlaufen per For Each-Schleife

Wie aber können wir die Elemente des Dictionary-Objekts nun durchlaufen? Das gelingt wie folgt:

Public Sub DictionaryDurchlaufenForEach()

Dim varKey As Variant

For Each varKey In objDictionary

Debug.Print varKey, objDictionary.Item(varKey)

Next varKey

End Sub

Wir durchlaufen die Elemente also mit einer For Each-Schleife, wobei die Laufvariable varKey immer den Schlüsselwert des aktuell durchlaufenen Elements erhält. In der Debug.Print-Anweisung geben wir zunächst den Schlüssel aus varKey aus und dann den über die Item-Eigenschaft ermittelten Wert für diesen Schlüssel. Das Ergebnis sieht nach dem Hinzufügen von Vorname, Nachname und Strasse und dem Durchlaufen der For Next-Schleife wie folgt aus:

Vorname Andreas

Nachname Minhorst

Strasse Borkhofer Str. 17

1

2

3

Das ist korrekt, denn die zuletzt hinzugefügten Elemente sind ja leer.

Elemente aus dem Dictionary-Objekt löschen

Zum Löschen eines Elements aus dem Dictionary-Element verwenden Sie die Remove-Methode. In der folgenden Prozedur durchlaufen wir alle Einträge des Dictionary-Objekts und prüfen mit der IsEmpty-Funktion, ob der Wert des jeweiligen Elements leer ist. In diesem Fall entfernen wir das jeweilige Element mit der Remove-Methode, der wir den Schlüssel des zu löschenden Elements als Parameter übergeben:

Public Sub DictionaryEintragEntfernen()

Dim varKey As Variant

For Each varKey In objDictionary

If IsEmpty(objDictionary.Item(varKey)) Then

objDictionary.Remove varKey

End If

Next varKey

End Sub

Danach sind nur noch die zuvor mit Werten versehenen Einträge vorhanden.

For...Next – doch möglich

Wir haben uns weiter oben darauf versteift, über die Item-Auflistung mit einem numerischen Index auf die Elemente zuzugreifen. Das ist nicht gelungen, aber es gibt noch zwei weitere Auflistungen, mit denen wir separat auf die Schlüssel und die Werte zugreifen können. Diese heißen Keys und Items. Die folgende Prozedur durchläuft alle Werte von 0 bis objDictionary.Count - 1 in einer For...Next-Schleife und gibt die Werte der Auflistungen Keys und Items für den entsprechenden Index im Direktbereich aus:

Sie haben das Ende des frei verfügbaren Teil dieses Artikels erreicht!

Wenn Sie mehr lesen und auf viele weitere Artikel zugreifen möchten, melden Sie sich als Abonnent unter Login an. Falls nicht, bestellen Sie doch einfach ein Jahresabonnement!