Letzte Änderung am 29. Juli 2021 by Christoph Jüngling
Es gibt ja nicht nur die großen Themen, bei denen man viele Worte machen muss, um alles auch nur halbwegs auf die Reihe zu kriegen. Nein, auch die kleinen Tipps sind unter Umständen sehr hilfreich. Und manchmal fragt man sich, wieso man nicht selbst längst auf diese Idee gekommen ist.
Heute geht es um Collections. Das ist eigentlich ein ziemlich einfaches Thema, bei dem mich anfangs nur eine Kleinigkeit gestört hat. Also fangen wir vorn an.
Die Collection
ist ein vordefinierter Datentyp in VBA, der beliebig viele Objekte aufnehmen kann. Diese werden in einer Liste verwaltet und lassen sich dann mittels “For-Each-Next”-Schleife sehr einfach durchgehen.
Was ich daran als störend empfunden habe, war die Einschränkung auf den Datentyp “Object”, den jedes Element der Liste haben muss. Anders als beispielsweise in Python sind aber Strings oder numerische Datentypen in VBA keine Objekte. Es schien also zunächst so, als würde es nicht gehen.
Doch der Trick ist wirklich simpel:
Public Sub test()
Dim col As New Collection
Dim s As str
Set s = New str
s = "eins"
col.Add s
Set s = New str
s = "zwei"
col.Add s
Debug.Print col.Count; " Elemente"
For Each s In col
Debug.Print s
Next s
End Sub
Und was ist nun dieses “str”? Im einfachsten Fall ein Klassenmodul mit einer öffentlichen Deklaration einer String-Variablen:
Option Compare Database
Option Explicit
Public text As String
Der Nachteil dabei ist jedoch, dass wir dann immer die Eigenschaft .text
mit angeben müssen. Im obigen Beispiel müsste also statt s = "eins"
dort stehen s.text = "eins"
.
Um auf dieses Standardelement verzichten zu können, müssen wir den Weg über Properties gehen. Das ist in der Programmierung des Klassenmoduls ein klein wenig aufwändiger, aber es lohnt sich. Das Prinzip sollte hinlänglich bekannt sein:
Option Compare Database
Option Explicit
Private m_text As String
Public Property Get text() As String
text = m_text
End Property
Public Property Let text(ByVal NewValue As String)
m_text = NewValue
End Property
Abgesehen davon eröffnet das Property Let
dann auch die Möglichkeit, bei der Zuweisung gleich eine Werteprüfung vorzunehmen.
Nun muss das Klassenmodul gespeichert und in eine Textdatei exportiert werden. Diese öffnen wir dann mit einem Texteditor und suchen darin das Property. Hierin ergänzen wir mindestens die Zeile Attribute text.VB_UserMemId = 0
. Wenn das Element auch noch eine Beschriftung bekommen soll, so ist das auch einfach möglich:
Public Property Get text() As String
Attribute text.VB_UserMemId = 0
Attribute text.VB_Description = "Contains the assigned string"
text = m_text
End Property
Diese Datei wird nun gespeichert. Zurück im Access-VBA-Editor löschen wir zunächst das Klassenmodul und importieren es dann erneut. Das Löschen ist wichtig, da sonst ein Duplikat mit Namen “Modul1” entsteht, was nicht gewünscht ist. Wer mit OASIS arbeitet, kann auch dessen Importfunktion verwenden und muss dann das Modul vorher nicht löschen, da das OASIS selbst übernimmt.
Überraschend ist nun allerdings, dass die beiden hinzugefügten Zeilen nicht im VBA-Editor sichtbar sind. Zur Überprüfung öffnen wir den Objektkatalog und selektieren unsere Klasse. Wie im nachfolgenden Screenshot zu erkennen ist, ist das Element “text” mit einem anderen Icon versehen als zum Beispiel “m_text”. Klicken wir dort drauf, dann sehen wir im unteren Bereich des Objektkatalogs den Hinweis, dass es sich um das Standardelement handelt. Ebenso wird der Texthinweis dort dargestellt.
Nun sollte die obige “Sub test” funktionieren.
Die Änderung bleibt übrigens erhalten und wird von OASIS auch beim nächsten Export ebenfalls exportiert. Die Änderung wird also auch über die Quellcodeverwaltung archiviert.
Neueste Kommentare