VBA Grundlagen: Verwendung des !-Operators

Aus DBWiki
Wechseln zu: Navigation, Suche

Der !-Operator – umgangssprachlich im englichen oft auch als Bang–Operator bezeichnet – wird in Beschreibungen und Erklärungen zu Access und VBA oft vergessen oder falsch erklärt. Er fehlt z. B. in Microsofts Operatorentabelle, obwohl er in Microsoft Access in Ausdrücken und in VBA-Code häufig verwendet wird. Ein kleiner Code-Auschnitt soll das zeigen:

   Dim rs As DAO.Recordset
 
   Set rs = CurrentDb.OpenRecordset("SELECT Vorname, Nachname, Geburtstag " & _
                                    "FROM   Freunde WHERE FreundID = 4711")
   If Not rs.EOF Then
      Me!txtVorname = rs!Vorname
      Me!txtNachname = rs!Nachname
      Me!txtGeburtstag = rs!Geburtstag
   End If
   rs.Close
Was passiert nun in den Code-Zeilen mit dem !-Operator? 
Der Bang-Operator erlaubt late-bound (späten oder verzögerten) Zugriff auf die Standardeigenschaft eines Objekts, indem er den literalen Namen hinter dem !-Operator als String-Argument an diese Standardeigenschaft übergibt.

Um die Aussage zu verstehen, muss man natürlich wissen, was eine Standardeigenschaft eines Objekts (Klasseninstanz) ist.

Standardeigenschaft 
Eine Standardeigenschaft eines Objekts ist jene, deren Name in Ausdrücken nicht aufgeführt werden muss. Ein Objekt kann demzufolge auch immer nur eine Standardeigenschaft besitzen.
Untersuchung des Code-Fragments 
Zerlegen wir zuerst die erste uns interessierende Anweisung aus dem vorstehenden Code:
Me!txtVorname = rs!Vorname
Das Me bezieht sich dabei auf die aktuelle Instanz des Klassenmoduls, in dem der Code ausgeführt wird (es sei hier ein Formular unterstellt); die Angabe ist optional, wird aber gerne zur Unterscheidung von Variablen im Klassenmodul oder in Methoden verwendet. Me macht den Code auch verständlicher.


Der nachfolgende ! erfordert nun, herauszufinden, was denn die Standardeigenschaft des Formulars ist. Beim Blick in den VBA-Objektkatalog unter der Klasse Form (gute Augen vorausgesetzt) findet man dann die Standard-Eigenschaft Controls, die an dem kleinen hellblauen Punkt über dem Symbol in den Eigenschaften von Form zu erkennen ist.
FormDefaultProperty.png


Klickt man nun unten in der Beschreibung auf das hellgrüne Control gelangt man zu dessen Klassennbeschreibung. Dort lässt sich wiederum eine Standard-Eigenschaft ausmachen: Item. Diese ist vom Datentyp Object - also nicht näher spezifiziert, weil sie ja verschiedene Objekte aufnehmen muss – wie z. B. ein Textfeld-, eine Kombobox, ein Listenfeld, usw.. Weiterhin ist ersichtlich, dass die Eigenschaft Item ein Argument Index erwartet, welches vom nicht angegebenen Standard-Datentyp Variant ist. Der Index kann demzufolge auch eine Zahl sein, die man jedoch meistens nicht kennt. Deshalb wird man üblicherweise stattdessen den bekannten Namen des Steuerelements einsetzen.


Damit ist die Anweisung links vom Gleichheitszeichen nun erklärt, und es können alternativ mehrere alsolut gleichwertige Ausdrücke dafür verwendet werden.
Me.Controls.Item("txtNachname") = ...
Me.Controls("txtNachname") = ...
Me.Controls!txtNachname = ...
Me("txtNachname") = ...


Zu erwähnen bleibt noch, dass das Textfeldsteuerelement auch eine Standard-Eigenschaft besitzt, die bisher unterschlagen wurde. Es handelt sich um die Eigenschaft Value, die optional an jede der vorstehenden Varianten – z. B. Me.Controls.Item("txtNachname").Value – angehangen werden kann.


Den Ausdruck auf der rechten Seite des Gleichheitszeichen erkläre ich nun nicht mehr ganz so aufwendig.
Für das Recordsetobjekt lässt sich die Standardeigenschaft Fields mit der versteckten Standard-Eigenschaft Item vom Datentyp DAO.Field finden. Item erwartet auch wieder ein Variant-Argument, welches im Objektkatalog ebenso Item genannt ist. Hierfür wird man die 0-basierte Feldposition im Recordset oder den Feldnamen als String angeben.
Bei Field angekommen kann man Value als Standard-Eigenschaft herausfinden.
Daraus ergeben sich dann folgende vollkommen gleichwertige Schreibweisen:
... = rs.Fields.Item(1).Value 'Nachname ist das 2. Feld
... = rs.Fields(1).Value
... = rs(1).Value
... = rs.Fields.Item("Nachname").Value
... = rs.Fields.!Nachname.Value
... = rs!Nachname.Value
... = rs("Nachname").Value
Die Angabe der Standard-Eigenschaft Value ist dabei natürlich optional - die Angabe von z. B. ... = rs(1) wäre also auch gültig.

Weblinks