N · NE · E · SE · S · SW · W · NW
← Magazin 15. Juni 2026
VBA · Fehlerbehandlung

VBA-Fehlerbehandlung — `On Error` richtig einsetzen

Strukturierte Fehlerbehandlung in Access-VBA: `On Error GoTo`, das `Err`-Objekt, Bubble-Pattern und der seltene Sonderfall `Resume Next`.

VBA ist alt, VBA ist eckig, VBA ist in tausenden Access-Anwendungen die Geschäftslogik der Bestandsdaten. Wer dort produktiv Fehler behandelt, kommt um drei Werkzeuge nicht herum: On Error GoTo, das globale Err-Objekt und ein konsequent durchgezogenes Bubble-Pattern. Das vierte Werkzeug — On Error Resume Next — ist ein Spezialwerkzeug, kein Standardansatz.

Das Grundmuster

Jede nicht-triviale Prozedur bekommt einen Fehlerblock am Ende, einen sauberen Exit und einen einzigen On Error GoTo-Aufruf am Anfang:

Public Sub ImportiereCSV(ByVal sPfad As String)
    On Error GoTo Fehler

    Dim db As DAO.Database
    Dim rs As DAO.Recordset

    Set db = CurrentDb
    Set rs = db.OpenRecordset("tbl_Import", dbOpenDynaset)

    ' ... eigentliche Logik ...

ExitProc:
    On Error Resume Next
    If Not rs Is Nothing Then rs.Close
    Set rs = Nothing
    Set db = Nothing
    Exit Sub

Fehler:
    Call LogError("ImportiereCSV", Err.Number, Err.Description, sPfad)
    Resume ExitProc
End Sub

Drei Dinge sind hier wichtig: Der ExitProc-Block räumt Objekte auf, egal ob ein Fehler auftrat oder nicht. Das On Error Resume Next direkt vor dem Aufräumen verhindert, dass ein schon kaputtes rs beim Close einen zweiten Fehler wirft. Der Fehler-Block protokolliert und springt zurück nach ExitProc — niemals direkt Exit Sub, sonst werden Ressourcen leakt.

Das Err-Objekt

Err ist global und enthält im Fehlerfall alle relevanten Informationen: Err.Number, Err.Description, Err.Source. Wer eigene Fehler wirft, nutzt Err.Raise mit einer Nummer ab vbObjectError + 513 (alles darunter ist Microsoft-Reserve):

Public Function PruefeKundennummer(ByVal sNr As String) As Boolean
    Const ERR_FORMAT As Long = vbObjectError + 1001
    Const ERR_LEER   As Long = vbObjectError + 1002

    If Len(sNr) = 0 Then
        Err.Raise ERR_LEER, "PruefeKundennummer", _
                  "Kundennummer darf nicht leer sein."
    End If

    If Not sNr Like "K[0-9][0-9][0-9][0-9][0-9]" Then
        Err.Raise ERR_FORMAT, "PruefeKundennummer", _
                  "Kundennummer entspricht nicht dem Muster Knnnnn."
    End If

    PruefeKundennummer = True
End Function

Der Aufrufer fängt diese Fehler dann gezielt ab und entscheidet, ob er weiterläuft, dem Anwender eine Meldung zeigt oder weiter nach oben durchreicht.

Bubble-Pattern: Fehler nach oben durchreichen

In einer Drei-Schichten-Architektur (Formular → Geschäftslogik → Datenzugriff) sollte der Fehler nicht in der untersten Schicht in einem MsgBox enden. Die Datenzugriffsschicht loggt technisch und reicht weiter; die Geschäftslogik entscheidet, was ein Anwender davon sieht; das Formular zeigt eine verständliche Meldung. Der Fehler-Block einer Zwischenschicht sieht dann so aus:

Fehler:
    Call LogError("BuchungenSpeichern", Err.Number, Err.Description, "")
    Dim lNr As Long, sBeschr As String
    lNr = Err.Number
    sBeschr = Err.Description
    Resume Bubble

Bubble:
    On Error GoTo 0
    Err.Raise lNr, "BuchungenSpeichern", sBeschr

Die Zwischenvariablen sind nötig, weil Err nach Resume zurückgesetzt wird. Der Wechsel auf On Error GoTo 0 vor dem Err.Raise stellt sicher, dass nicht versehentlich der eigene Fehler-Block erneut anspringt — ein Endlosrekursions-Klassiker.

Wann Resume Next legitim ist

On Error Resume Next hat genau zwei berechtigte Einsatzfälle. Erstens das schon gezeigte Aufräumen am Prozedurende. Zweitens „Try-Probe-Patterns”, in denen ein Fehlschlag erwartet und sofort geprüft wird:

On Error Resume Next
Set ws = Application.CurrentProject.AllForms("frmKunde")
If Err.Number <> 0 Then
    Err.Clear
    ' Formular existiert nicht — alternativer Zweig
End If
On Error GoTo Fehler

Wichtig: direkt nach der Probe wieder zurück auf GoTo Fehler schalten und Err.Clear aufrufen. Wer Resume Next über ganze Prozeduren laufen lässt, baut sich eine Anwendung, in der Fehler stumm verschwinden und Datensätze halb geschrieben werden. Das ist der häufigste Grund, warum Access-Anwendungen „manchmal seltsame Daten” enthalten.

Was sich in zehn Jahren Praxis bewährt hat

Eine zentrale LogError-Prozedur mit Tabelle tbl_ErrorLog (Spalten: Zeitpunkt, Modul, Nummer, Beschreibung, Kontext, Benutzer) ist Pflicht. Sie kostet zwei Stunden Initialaufwand und spart drei Tage Fehlersuche pro Jahr. Pro Modul ein Konstantenblock mit den eigenen Fehlernummern, dokumentiert in einer Code-Kommentartabelle. Und: jede Public-Prozedur ohne On Error GoTo ist ein latenter Bug — auch die kurze.

Saubere Fehlerbehandlung in VBA sieht repetitiv aus, weil sie es ist; genau das macht sie verlässlich.


Ressort: VBA