Zusammenfassung
Lernen Sie die Lösung zu den häufigsten VBA-Problemen kennen.
Techniken
VBA, DAO, ADO, SQL
Voraussetzungen
Access 97 und höher
Beispieldateien
FAQ12_A97.mdb (Access 97)FAQ12_A00.mdb (Access 2000 und höher)
Karl Donaubauer, Wien
In der Access-FAQ von Karl Donaubauer (www.donkarl.com) finden Sie die meistgestellten Fragen und Anworten zum Thema Microsoft Access. In dieser Beitragsreihe stellt Karl Donaubauer die wichtigsten Einträge im Detail vor und zeigt Ihnen entsprechende Lösungen anhand praxisnaher Beispiele. Im zwölften Teil werden Lösungen für die häufigsten Probleme in VBA vorgestellt.
Jahrelang war eine der häufigsten Fragen zum Thema Access-Programmierung, ob nun DAO oder ADO als Datenzugriffstechnik zu lernen und zu verwenden sei. Heute kommt die Frage etwas seltener, auch, weil das Match inzwischen entschieden ist. Microsoft hat von cirka 1999 bis 2001/2002, das heißt, ab der Veröffentlichung von Access 2000 bis in die Zeit von Access XP hinein, versucht, das althergebrachte DAO loszuwerden und durch ADO und ADOX zu ersetzen. Viele Buchautoren sind dem MS-Marketingwirbel erlegen und haben dieses Anliegen freudig weiterpropagiert. Allein, die überwältigende Mehrheit der Access-Programmierer ist MS hier nicht gefolgt, sondern bei DAO geblieben. ADO konnte sich nur in Nischen durchsetzen, etwa bei ADPs und beim Zugriff auf JET-Dateien im klassischen ASP.
Bei der reinen Entwicklungsarbeit mit Access, JET und MDBs hatte ADO keine Chance, weil DAO und JET als Duo gewachsen, besser integriert und meist performanter sind und waren. Da half es auch nichts, dass der Zugriff auf manche Erweiterungen in JET 4.0 nur für ADO ermöglicht wurde, während DAO von MS bewusst vernachlässigt wurde. Bei der täglichen Brotarbeit war und ist DAO einfach beliebter. Microsoft hat diese Realität spät, aber doch akzeptiert. Wenn man in Access 2000 oder XP eine neue Datenbank anlegt, ist standardmäßig nur der Verweis auf ADO vorhanden. Das führte zu millionenfachen Verweisproblemen und ebenso vielen Fragen in Access-Foren. Bei einer neuen Datenbank in Access 2003 hingegen ist nicht nur der DAO-Verweis wieder vorhanden, sondern er steht in der Reihenfolge über dem ADO-Verweis. In der nächsten Version von Access gibt es sogar zum ersten Mal nach vielen Jahren wieder Anpassungen und Neuerungen in DAO.
Das ist nicht nur die Konsequenz der Beharrlichkeit der Access-Gemeinde. Das MS-Marketing konzentriert sich seit Jahren ausschließlich auf .NET und damit ADO.NET. Der Name ist mehr oder weniger eine Finte, denn diese Zugriffstechnologie hat nicht sehr viel mit dem klassischen ADO zu tun. ADO ist also auch aus Marketingsicht bereits wieder veraltet. Fazit der jahrelangen Schlacht:
Eines der ersten Probleme jedes Access-VBA-Programmierers ist ebenso ein beliebtes Streitthema unter erfahrenen Programmierern: Wann ist bei Bezügen der Punkt, wann das Ausrufezeichen als Trennzeichen voranzusetzen oder ist die Verwendung der String-Schreibweise generell vorzuziehen
Eine einfache Grundregel ist: vor Objekten ein Ausrufezeichen, vor Auflistungen und Eigenschaften ein Punkt. Eine andere bekannte Merkregel lautet: Wenn nach dem Trennzeichen ein Element folgt, das fix in Access eingebaut ist, dann gehört der Punkt dorthin. Wenn das Element benutzerdefiniert ist, dann verwendet man das Ausrufezeichen. Ein Beispiel (in einer Zeile):
Application.Forms!frmKunden.Controls!Nachname.Visible
Die Forms-Auflistung ist von Access vorgegeben, deshalb wird hier der Punkt vorangestellt. Das Formular frmKunden wurde vom Entwickler erstellt, deshalb kommt hier das Ausrufezeichen zum Zuge. Die Controls-Auflistung ist wieder ein eingebautes Element von Access. Nachname ist ein benutzerdefinierter Steuerelementname. Die Eigenschaft Visible stammt wiederum von Access.
Diese Regel gilt auch für die meistangewandte Kurzform:
Forms!frmKunden!Nachname.Visible
So einfach diese Grundregeln sind, so diffizil wird es im Detail, weil VBA sehr variabel ist und oft mehrere Varianten zulässt. Eine Quelle der Unsicherheit und der häufigste Streitpunkt ist dabei Punkt oder Ausrufezeichen nach dem Schlüsselwort Me. Mit Me bezieht man sich auf das Objekt, das heißt die Instanz der Klasse, in der der aktuelle Code ausgeführt wird. In Access ist das meist ein Formular oder ein Bericht. Nach den oben angeführten Regeln müsste man sich auf Steuerelemente mit Ausrufezeichen beziehen, also: Me!MeinSteuerelement.
Steuerelemente sind in VB und VBA aber nicht nur Objekte, sondern auch Eigenschaften von Formularen. Deshalb funktioniert ebenso: Me.MeinSteuerelement.
Manche Programmierer bevorzugen diese Schreibweise, weil sie damit im VBA-Editor Intellisense nutzen können, ihnen also automatisch die Liste der im jeweiligen Kontext verfügbaren Objekte und Eigenschaften angezeigt wird (siehe Bild 1).
Bild 1: Punkt bringt Intellisense im Kontext.
Bei Verwendung des Ausrufezeichens tritt Intellisense nicht in Aktion. Sie können zwar mit der Tastenkombination STRG + Leertaste die Auswahlliste erzwingen, diese zeigt dann aber nicht die in diesem Kontext verfügbaren Einträge, sondern alle für den VBA-Code in der aktuellen Anwendung verfügbaren Schlüsselworte und Objekte an (siehe Bild 2).
Bild 2: Auswahlliste ohne Kontext
Die Punkt-Schreibweise hat also einen unbestreitbaren Vorteil. Der Nachteil ist jedoch, dass manchmal unvorhersehbare und von Microsoft nicht dokumentierte Probleme damit auftauchen. So kommt es vor, dass nach einer Konvertierung in eine höhere Access-Version oder auch einfach nach einer Neukompilierung die Bezüge nicht mehr funktionieren. Oft passiert diese Art Korruption, wenn für die Steuerelemente dieselben Namen wie für die Felder der Datenquelle verwendet werden. Das scheint aber nur eine der möglichen Mitverursacher zu sein. Jedenfalls treten derartige Probleme mit Ausrufezeichen nicht auf. Deshalb ist es sicherer, auch hier das Ausrufezeichen zu verwenden, oder die ebenfalls zuverlässige String-Schreibweise mit Klammern:
Me("MeinSteuerelement")
oder
Me.Controls("MeinSteuerelement")
Für viele Aufgaben in der VBA-Programmieung ist es von Vorteil oder unbedingt notwendig, statt fixer Objektnamen Variablen verwenden zu können. Das betrifft sowohl Steuerelemente in Formularen und Berichten als auch Felder in Recordsets von DAO oder ADO. Die Lösung für diese Anforderung ist die Schreibweise mit runden Klammern.
Ein Steuerelement können Sie zum Beispiel so ansprechen:
Forms("Formularname")(StringVariable)
Ebenso funktioniert es mit einem Feld in einem Recordset:
rs(StringVariable)
Die häufigste Verwendung findet die eben behandelte Klammer-Schreibweise in Schleifen zum Durchlaufen von Controls- oder Fields-Auflistungen. Meistens geht es darum, per Code mehrere oder alle Steuerelemente eines Formulares oder Berichtes zu durchlaufen, um eine bestimmte Eigenschaft für diese Elemente in einem Rutsch zu prüfen oder zu ändern.
Eine beliebte Lösungsvariante dafür ist, gleichartige Steuerelemente mit denselben Namen und einer fortlaufenden Nummer zu benennen: Liste1, Liste2, Liste3… oder Combo1, Combo2…
Mit dieser Voraussetzung ist es dann einfach, zum Beispiel die Eigenschaft Sichtbar der Steuerelemente zu ändern:
Dim i As Integer For i = 1 To 5 Me("Liste" & i).Visible = False Next
Eine andere Variante, um bestimmte Steuerelemente zu kennzeichnen, ist die Verwendung ihrer Eigenschaft Marke (Tag).
Die Eigenschaft ist genau für diesen Zweck vorhanden, also eine kennzeichnende Information oder irgendeinen Memo-Text für Objekte zu hinterlegen, der ansonsten keine Auswirkungen auf die Funktionalität oder die Eigenschaften des Objektes hat.
Um sie für Steuerelemente zu nützen, können Sie sie per Code durch die Controls-Auflistung von Formularen und Berichten schleifen und Tag prüfen:
Dim ctl As Control For Each ctl In Me.Controls If ctl.Tag = "Suchtext" Then ctl.Visible = False Next ctl
Wenn Sie ein Meldungsfenster öffnen, so wird der Code angehalten, bis die Box wieder geschlossen wird. Damit können Sie im Code nach dem Aufruf des Meldungsfensters sofort auf die im Meldungsfenster gewählte Schaltfläche reagieren. Bild 3 zeigt eine solche Anordnung.
Bild 3: Meldungsfenster als Dialogformular
Im Formular frmDialogAufruf wird per Schaltfläche ein Meldungsfenster aufgerufen. Im Meldungsfenster klickt der Benutzer auf Ja oder Nein. Danach erst läuft der Code im aufrufenden Formular weiter und zeigt dabei das Ergebnis der MsgBox-Funktion an. Der Code hinter der Schaltfläche zum Aufruf des Meldungsfensters sieht dabei so aus:
Dim intAntwort As Integer intAntwort = MsgBox("Bitte klicken " _ "Sie auf Ja oder Nein.", vbYesNo Or _ vbQuestion, "Msgbox als Dialog") Select Case intAntwort Case vbYes Me!txtErgebnis = "Ja" Case vbNo Me!txtErgebnis = "Nein" End Select
Der Grund für das Anhalten des Codes ist, dass das Meldungsfenster modal ist. Es muss zuerst geschlossen werden, bevor Access die aufrufende Prozedur fortführt und wieder Anwenderaktionen in anderen Objekten zulässt.
Die Möglichkeiten eines Meldungsfensters sind auf wenige, fix vorgegebene Schaltflächen begrenzt. Sie können die Dialog-Funktionalität aber auch mit einem selbst definierten modalen Formular programmieren (siehe Bild 4)
Bild 4: Modales Formular als Dialog
Das Dialogformular ist dabei im Vergleich zum Meldungsfenster um weitere Schaltflächen ergänzt. Es könnte aber auch Eingabefelder und so weiter enthalten. Der Code hinter den Schaltflächen im Dialogformular besteht nur aus einer schlanken Anweisung:
Me.Visible = False
Das Dialogformular wird also unsichtbar gemacht. Damit hat das aufrufende Formular wieder den Fokus, sein Code läuft weiter und kann auf die Benutzereingaben im Dialogformular zugreifen. Der entsprechende aufrufende und reagierende Code lautet:
DoCmd.OpenForm "frmDialog", , , , , _ acDialog txtErgebnis = _ Forms!frmDialog.ActiveControl.Caption DoCmd.Close acForm, "frmDialog"
Das Dialogformular wird mit dem Wert acDialog im Parameter Fenstermodus geöffnet. Damit hält der Code an, bis das Dialogformular entweder geschlossen oder unsichtbar gemacht wird. Danach läuft der Code weiter und es wird ein Textfeld im aufrufenden Formular mit der Beschriftung der im Dialogformular gewählten Schaltfläche versorgt. Am Ende wird das Dialogformular geschlossen, damit es nicht dauerhaft unsichtbar geöffnet bleibt.
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
den kompletten Artikel im PDF-Format mit Beispieldatenbank
diesen und alle anderen Artikel mit dem Jahresabo