6.5 Fehler beheben
Sehr viele Fehler können durch Beachtung der folgenden Punkte vermieden bzw. behoben werden.
6.5.1 Code kompilieren
Nach jeder Code-Änderung sollte vor der nächsten Ausführung der Code kompiliert werden, um evtl. versteckte Fehler ausfindig zu machen. Dazu muss man im VBA-Editor Debuggen/Kompilieren von Datenbankname (ALT+G, anschliessend K) aufrufen.
6.5.2 Explizites Deklarieren von Variablen durch Option Explicit
In jedem Deklarationsteil eines Moduls sollte als 2. Zeile die Anweisung Option
Explicit zu finden sein (s. auch Screenshot unter 6.4). Dadurch wird man
gezwungen, die verwendeten Variablen vorher zu deklarieren und erspart sich so manche Fehlersuche wg.
Buchstabendrehern in Variablennamen. Man kann diese Zeile in jedem neuen Modul
erzwingen, indem man im VBA-Editor Extras/Optionen (ALT+X, dann O) aufruft und dort im Register
Editor einen Haken bei Variablendeklaration
erforderlich setzt. Bereits bestehende Module müssen manuell ergänzt werden.
6.5.3 Richtiges Deklarieren der Variablen
Werden Variablen innerhalb einer Zeile deklariert, so muss der Typ hinter jede Variable gesetzt werden. Das folgende Beispiel ist falsch, da so nur die letzte Variable als String und die ersten zwei Variablen als Variant deklariert werden:
Dim strVariable1, strVariable2, strVariable3 As String
So ist es richtig:
Dim strVariable1 As String, strVariable2 As String, strVariable3 As String
Zudem sollte bei möglichen Überschneidungen von Variablentypen zwischen unterschiedlichen Verweisen
explizit die betreffende Bibliothek davor gesetzt werden. Der letztgenannte Punkt trifft vor allem ab Access
2000 und dort speziell bei der Deklaration von Recordsets zu, da der Typ
Recordset in ADO und DAO vorhanden ist (s. auch FAQ 7.11):
Dim rs As DAO.Recordset 'ist besser als nur: 'Dim rs As Recordset
6.5.4 Verwenden von Debug.Print
Immer wieder kommt man in die Verlegenheit, Datenherkünfte oder dgl. dynamisch zu erstellen. Wenn es
nicht wie erwartet funktioniert, ist es ratsam, den SQL-String oder andere Werte zur Kontrolle mit
Debug.Print auszugeben. Danach taucht der zugewiesene Wert im Direktfenster auf und
lässt sich somit besser als mit einer Msgbox oder mittels Haltepunkt kontrollieren. Man muss also
folgendermassen vorgehen: Bei der Code-Erstellung lässt man sich im VBA-Editor das Direktfenster
über Ansicht/Direktfenster anzeigen (oder durch den Tastenschlüssel
STRG+G). Der zuzuweisende String (oder was auch immer) wird in einer Variablen gespeichert und vor der
Zuweisung zur Eigenschaft mittels Debug.Print ausgegeben. Startet man nun die
Prozedur und es treten Fehler auf, wechselt man in den VBA-Editor und schaut sich das Ergebnis im
Direktfenster an. Speziell SQL-Anweisungen lassen sich durch Kopieren
des im Direktfenster erhaltenen Strings und Einfügen in die SQL-Ansicht einer neuen Abfrage sehr gut kontrollieren.
Weiteres zum Direktfenster findet man auch auf DBWiki.
Hier nun endlich ein Beispiel:
Private Sub lstZeitraeume_AfterUpdate() 'Dieser Beispiel-Code wertet den Wert eines 'Listenfeldes aus und ändert die Datenherkunft 'eines Formulares zur Laufzeit. Dim strSQL As String 'nimmt den SQL-String der neuen Datenherkunft auf strSQL = "SELECT TagDerVerbindung, PrK_IDdesTages, FrK_AbrechnungsID" _ & " FROM tblTage WHERE FrK_Abrechnungsid=" & Me!lstZeitraeume _ & " ORDER BY TagDerVerbindung;" 'Ausgabe der zuzuweisenden Datenherkunft im Direktfenster. 'Wenn alles funktioniert, sollte die Zeile wieder entfernt 'werden: Debug.Print strSQL 'Zuweisen der neuen Datenherkunft: Me.Recordsource = strSQL End Sub
6.5.5 Einzelschrittmodus und Haltepunkte
Um den Ablauf in einer Prozedur zu verfolgen, kann man Haltepunkte festlegen. Dazu geht man im VBA-Editor in die gewünschte Zeile, in der das möglich ist (im Deklarationsteil z.B. ist diese Option nicht gegeben) und legt über Debuggen/Haltepunkt ein/aus den Überwachungspunkt an. Schneller geht es sicherlich mit dem Hotkey F9 oder mit einem Klick auf den grauen Bereich neben dem VBA-Code. Wenn die Routine nun gestartet wird, wartet sie dort so lange, bis sie mittels F8 (oder Debuggen/Einzelschritt) fortgesetzt wird.
6.5.6 Abfangen von Fehlern
Speziell bei Anwendungen, die in einer Runtime-Umgebung laufen sollen, müssen z.T. unvermeidliche Laufzeitfehler abgefangen werden. Dazu kann man sich einfach mal einen durch den Schaltflächen-Assistenten generierten Code anschauen und diesen ggf. anpassen. Wenn beispielsweise ein leerer Bericht nach der Variante #2 unter FAQ 5.8 nicht gedruckt werden soll, müsste der Code ungefähr so ausschauen (bei anderen Anweisungen muss die Fehlernummer sicherlich angepasst werden - 2501 gilt nur für diesen speziellen Fall):
Private Sub repBerichtsNameDrucken_Click() On Error GoTo Err_repBerichtsNameDrucken_Click DoCmd.OpenReport "Berichtsname" Exit_repBerichtsNameDrucken_Click: Exit Sub Err_repBerichtsNameDrucken_Click: If Err.Number <> 2501 Then MsgBox Err.Description, vbCritical, "Fehler# " & Err.Number End If Resume Exit_repBerichtsNameDrucken_Click End Sub
6.5.7 Code-Gestaltung und -Tools
Der Code sollte so gestaltet oder eingerückt werden, dass daraus schon der Ablauf einigermassen
ersichtlich wird. Dies erleichtert das Auffinden von fehlenden abschliessenden Zeilen wie beispielsweise
End If bei einer IF-Klausel oder Next bei einer
For-Next-Schleife. Erweiterungen des Codes sind dann auch nicht mehr so schwierig. Für das
Einrücken bietet sich der Smart Indenter
an. Ein weiteres praktisches Add-In sind die MZ-Tools, die eine Bibliothek für immer
wiederkehrende Code-Fragmente enthalten. Zeilen können nummeriert, Prozedurköpfe in Kommentarform
angelegt werden usw. Unbedingt anschauen!
