3 hilfreiche VBA Datenstrukturen (Array, Collection und Dictionary)

Im Gegensatz zu anderen Programmiersprachen, wie C# oder Java, verfügt VBA über relativ wenige Datenstrukturen zur Verwaltung großer Datenmengen. In diesem Beitrag möchte ich die verfügbaren VBA Datenstrukturen gerne vorstellen und anhand von Beispielen erklären, für welche Zwecke ich sie einsetze.

VBA Arrays

Das gute alte Array nutze ich immer wieder gerne, wenn es um die Verwaltung von Daten gleichen Typs geht und es absehbar ist, dass die Anzahl der Elemente während der Verarbeitung konstant bleibt. Ist die Anzahl der Elemente gleich zu Beginn der Verarbeitung klar, (zum Beispiel bei einem Array für die Verwaltung der Monatsnamen), so gebe ich die Anzahl der Arrayelemente gleich bei der Deklaration mit.

Dim monatsbezeichnungen(1 To 12) As String

Ich finde es übrigens gut, dass VBA dem Entwickler die Freiheit lässt, den Arrayindex mit 0 oder 1 beginnen zu lassen. Man beginnt mit 0, wie es die meisten Programmiersprachen vorleben oder mit 1, wie es den meisten Menschen logischer erscheint:-). Ich kann es immer noch nicht verstehen, warum sich 0 als Arraystartindex in den meisten modernen Sprachen durchgesetzt hat. Mittlerweile habe ich in Erfahrung gebracht, dass die Programmiersprachen, bei denen Array-Indizies mit 0 beginnen, diese intern nicht als Indizes, sondern eher als Offsets nutzen. So verschiebt sich beispielsweise beim Index (also Offset) von 0 der interne Zeiger nicht und bleibt auf dem ersten Element stehen. Der Index (also Offset) von 1 lässt den internen Zeiger um eins weiterwandern und zeigt somit auf das nächste (in diesem Fall zweite) Arrayelement.

Mit dem Befehl ReDim stellt VBA einen Befehl zur Verfügung, mit dem die Anzahl der Arrayelemente nachträglich verändert werden kann. Dabei sorgt das Schlüsselwort Preserve dafür, dass bei der Redimensionierung die bisher enthaltenen Elemente nicht gelöscht werden. Sollten wir irgendwann eine Kalenderreform und dadurch einen zusätzlichen Monat bekommen, würde diese Anweisung dafür sorgen, dass das Array monatsbezeichnungen um ein weiteres Element erweitert wird:-). Die Funktion UBound liefert dabei den letzten Index des Arrays. Der Gegenspieler dazu ist die LBound-Funktion.

ReDim Preserve monatsbezeichnungen(1 to UBound(monatsbezeichnungen) + 1)

Trotz dieser beschriebenen Möglichkeit stoße ich mit Arrays des Öfteren an Ihre Grenzen – und zwar immer dann, wenn ich ein neues Element nicht einfach ans Ende, sondern mitten in ein Array einsetzen oder ein Element aus dem Array löschen möchte. In beiden Fällen muss ich als Entwickler dafür sorgen, dass dabei alle nachfolgenden Elemente entweder alle um eins nach vorne (beim Löschen) oder um eins nach hinten (beim Einfügen) zu verschieben.

Ich bin da ehrlich – auf solches Verschieben von Elementen habe ich wirklich keine Lust, zumal diese nachgebaute Funktionalität auch die Fehlerwahrscheinlichkeit erhöht. Da kommen nun Collections ins Spiel.

VBA Collections

Die beiden eben beschriebenen Konstellationen lassen sich mit Collections deutlich einfacher und ganz ohne Programmieraufwand abbilden. So muss bei der Deklaration der Collection nicht angegeben werden, aus wie vielen Elementen diese bestehen wird. Um ein neues Element einzufügen, nutzt man einfach eine Add-Methode.

Dim aufstellung As New Collection
Dim personenObject As New Person
aufstellung.Add Item:=personenObject, After:=78

Dabei kann man festlegen, dass das neue Element an eine bestimmte Stelle einzufügen ist. Alle anderen Elemente, die darauf folgen, rutschen einfach automatisch eine Position weiter nach hinten.

Verglichen mit Arrays und Dictionaries, auf die ich später zu sprechen komme, haben Collections einen Nachteil, den ich persönlich jedoch nicht gravierend finde. So ist es bei Arrays sehr einfach, einem Element einen neuen Wert zuzuweisen. Bei Collection hingegen, ist es nicht ohne Weiteres möglich. Zuerst muss das zu ändernde Element gelöscht und ein neues Element mit dem neuen Wert an die Position des alten Elementes hinzugefügt werden.

Nun möchte ich ein paar Wörter zum Thema Zugriff auf Elemente verlieren. Beide Strukturen (sowohl Array als auch Collections) erlauben Zugriff auf einzelne Elemente mit Hilfe des Indexes, der die Position des Elementes innerhalb der jeweiligen Datenstruktur repräsentiert. In einigen Anwendungsfällen jedoch möchte man den Zugriff nicht anhand eines Indexes durchführen, sondern anhand eines fachlichen Attributes, zum Beispiel mit einer PersonenID. Im Falle von Arrays ist kein direkter Zugriff möglich – man braucht eine Schleife, um das das Array Element für Element anhand der PersonenID zu durchsuchen (im schlechtesten Fall befinden sich das gesuchte Element ganz am Ende). Bei Collections ist der direkte Zugriff auch so eine Sache… Denn leider (ich habe wirklich keine Ahnung, warum das so ist) stellen sie keine Methode bereit, mit der man das Vorhandensein eines Elementes mit einem bestimmten Schlüssel prüfen kann. Diese Prüfung ist absolut essenziel, sowohl beim Auslesen als auch beim Hinzufügen von Elementen. Natürlich könnte man sich dabei behelfen, indem man abfragt, ob beim Zugriff auf eine ID ein Fehler gemeldet wird und richtet darauf hin dann die weitere Verarbeitung aus. Ich persönlich verwende On Error Resume Next / On Error GoTo 0 in meinen Programmen jedoch ausschließlich zu Ausnahmebehandlung, nie zur Programmsteuerung. Zum Glück gibt es Dictionaries 🙂

    On Error Resume Next
        objPersonalstamm.Item ("Y123")
        If Err.Number > 0 Then
            MsgBox "ist nicht vorhanden"
            Err.Clear
        Else
            MsgBox "ist vorhanden"
        End If
    On Error GoTo 0

VBA Dictionary

Der selbe Anwendungsfall sieht bei Dictionaries deutlich eleganter aus, einfach weil es hier von Hause aus eine Prüfmethode exists zur Verfügung steht, die wir sowohl vor dem Einfügen als auch vor dem Auslesen von Einträgen heranziehen können.

Dim objPersonalstamm As Object

Set objPersonalstamm = CreateObject("Scripting.Dictionary")

If objPersonalstamm.Exists("Y123") Then
    MsgBox "ist vorhanden."
Else
    MsgBox "ist nicht vorhanden"
End If

Fazit

Ich hoffe, ich habe es rüberbringen können, dass es keine eierlegende Wollmilchsau (schade eigentlich) unter den Datenstrukturen gibt :-). Gerade als Einsteiger, ist es von Vorteil, nicht die Struktur zu verwenden, die man am besten kennt, sondern sich Zeit zu nehmen, die Struktur zu finden, die für den jeweiligen Anwendungsfall an besten geeignet ist – das richtige Werkzeug zahlt sich nämlich immer aus.

2 thoughts on “3 hilfreiche VBA Datenstrukturen (Array, Collection und Dictionary)

  1. Endlich einer der sehen kann. Ich habe unser Warenwirtschaftssystem in Foxpro geschrieben und suche genau nach Ihrem Programm um auf der Rechnung den QR-Code zu installieren. Kann man dieses Programm QR-Code auf Rechnung bei Ihnen kaufen?
    Ich versuche mich gegen paypal und visa zu wehren wegen der Gebühren und sehe für junge Leute zahlen per Giro-Code als Alternative.
    Unser Magento-Shop sollte auch bei der Bestellung den QR-Code anzeigen um leichter Vorauskasse zu ermöglichen. Vielleicht können wir das mit diesem Programm auch irgendwie handeln.

    1. Hallo Herr Hofmann, ich muss sagen, von Foxpro als Technologie habe ich noch nie gehört. Ich melde mich bei Ihnen, wir können dann gerne schauen, ob sich die Bibliothek an Ihr Warenwirtschaftssystem anbinden lässt. Was Ihr Megento-Shot angeht, so würde ich Ihnen in diesem Fall eher eine QRCode-Bibliothek auf PHP oder JS-Basis empfehlen, die sich deutlich einfacher integrieren lässt. Mit Sicherheit gibt es bei Magento fertige QR-Plugins.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert