VBA Error Handling – Robuste Makros die nicht abstürzen
Strukturierte Fehlerbehandlung mit On Error GoTo, Cleanup, Logging und den häufigsten Laufzeitfehlern: So werden Ihre Makros robust und absturzsicher.
Ein Makro läuft wochenlang problemlos – bis ein Kollege eine Spalte löscht, eine Datei umbenannt wird oder ein Netzlaufwerk nicht erreichbar ist. Ohne Error Handling bricht das Makro kommentarlos ab. Schlimmer noch: Excel bleibt in einem kaputten Zustand zurück – ScreenUpdating auf False, Berechnung auf Manual, Events deaktiviert. Der Benutzer sieht einen eingefrorenen Bildschirm und verliert das Vertrauen in die gesamte Automatisierung.
Sauberes Error Handling verhindert das. Es fängt Fehler ab, gibt verständliche Meldungen aus und stellt den Systemzustand zuverlässig wieder her – egal was schiefgeht.
Fehler im Code? Der VBA Debug Assistant analysiert Ihren Code, findet Laufzeitfehler und liefert korrigierten Code mit Erklärung.
Warum Error Handling unverzichtbar ist
Ohne Fehlerbehandlung passiert bei einem Laufzeitfehler Folgendes:
- Das Makro bricht sofort ab – mitten in der Verarbeitung, ohne Hinweis was passiert ist.
- Excel-Zustände bleiben verändert – wenn Sie vorher
Application.ScreenUpdating = Falsegesetzt haben, bleibt der Bildschirm eingefroren.Application.Calculation = xlCalculationManualbleibt auf manuell. Events sind deaktiviert. - Daten sind inkonsistent – wenn das Makro nach 500 von 1000 Zeilen abbricht, ist die Tabelle halb verarbeitet.
- Benutzer verlieren Vertrauen – nach dem dritten Absturz verwendet niemand mehr Ihre Makros.
Das alles lässt sich mit wenigen Zeilen Code verhindern.
Die drei Error-Handling-Strategien in VBA
On Error GoTo — Der Standardansatz
Dies ist die wichtigste und häufigste Strategie. Sie leitet den Programmfluss bei einem Fehler zu einer Sprungmarke um, wo Sie den Fehler behandeln können:
Sub DatenVerarbeiten() On Error GoTo ErrHandler ' --- Hauptcode --- Dim ws As Worksheet Set ws = ThisWorkbook.Worksheets("Daten") Dim lastRow As Long lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row Dim i As Long For i = 2 To lastRow ws.Cells(i, 3).Value = ws.Cells(i, 1).Value * ws.Cells(i, 2).Value Next i MsgBox "Verarbeitung abgeschlossen.", vbInformation Exit Sub ErrHandler: MsgBox "Fehler " & Err.Number & ": " & Err.Description & vbCrLf & _ "In Prozedur: DatenVerarbeiten", vbCritical, "Fehler" End Sub
Die wichtigsten Err-Eigenschaften:
Err.Number– Die Fehlernummer (z.B. 9, 13, 1004)Err.Description– Beschreibung des Fehlers als TextErr.Source– Quelle des Fehlers (Modul/Klasse)Err.Clear– Setzt das Err-Objekt zurück (wichtig nachResume Next)
On Error Resume Next — Gezielt einsetzen
Diese Strategie überspringt Fehler und macht mit der nächsten Zeile weiter. Achtung: Das ist kein Freibrief zum Ignorieren von Fehlern! Verwenden Sie Resume Next nur in zwei Situationen:
Sinnvoll: Prüfen ob ein Objekt existiert:
Function WorksheetExists(ByVal name As String) As Boolean Dim ws As Worksheet On Error Resume Next Set ws = ThisWorkbook.Worksheets(name) On Error GoTo 0 WorksheetExists = Not ws Is Nothing End Function
Sinnvoll: Prüfen ob eine Datei vorhanden ist:
Function DateiExistiert(ByVal pfad As String) As Boolean On Error Resume Next DateiExistiert = (Dir(pfad) <> "") On Error GoTo 0 End Function
NICHT sinnvoll: Fehler pauschal ignorieren – das verschleiert Bugs und macht Debugging unmöglich:
' SCHLECHT – niemals so verwenden! Sub SchlechterCode() On Error Resume Next ' 200 Zeilen Code... ' Fehler werden stillschweigend geschluckt End Sub
On Error GoTo 0 — Error Handling zurücksetzen
Diese Anweisung deaktiviert die aktive Fehlerbehandlung und stellt das Standardverhalten wieder her (Fehler erzeugen einen Laufzeitfehler-Dialog). Verwenden Sie sie nach einem Resume Next-Block, um wieder normal auf Fehler zu reagieren:
Sub GemischterAnsatz() On Error GoTo ErrHandler ' Normaler Code mit Error Handling... ' Kurzer Block mit Resume Next: On Error Resume Next Dim ws As Worksheet Set ws = ThisWorkbook.Worksheets("Optional") On Error GoTo 0 ' Wieder zurück zum normalen Handling ' Ab hier werden Fehler wieder normal behandelt ' ... Exit Sub ErrHandler: MsgBox "Fehler: " & Err.Description, vbCritical End Sub
Das perfekte Error-Handling-Template
Dieses Template können Sie in jede Prozedur kopieren. Es sichert die Excel-Zustände, führt den Hauptcode aus und stellt bei Erfolg oder Fehler alles zuverlässig wieder her:
Sub MeinRobusterProzess() ' --- Zustände sichern --- Dim oldCalc As XlCalculation oldCalc = Application.Calculation Dim oldScreen As Boolean oldScreen = Application.ScreenUpdating Dim oldEvents As Boolean oldEvents = Application.EnableEvents On Error GoTo ErrHandler ' --- Performance-Optimierung --- Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Application.EnableEvents = False ' ===================== ' HAUPTCODE HIER ' ===================== ' ... Ihr Code ... ' ===================== Cleanup: ' --- Zustände IMMER wiederherstellen --- Application.EnableEvents = oldEvents Application.Calculation = oldCalc Application.ScreenUpdating = oldScreen Exit Sub ErrHandler: MsgBox "Fehler " & Err.Number & ": " & Err.Description & vbCrLf & _ "Prozedur: MeinRobusterProzess", vbCritical, "Fehler" Resume Cleanup End Sub
Warum dieses Muster funktioniert:
- Die Original-Zustände werden vor jeder Änderung gesichert.
- Das
Cleanup-Label wird bei Erfolg und bei Fehler durchlaufen (Resume Cleanup). Exit Subvor demErrHandlerverhindert, dass der Fehlercode bei fehlerfreiem Ablauf ausgeführt wird.
Die häufigsten VBA-Laufzeitfehler und ihre Lösungen
Laufzeitfehler 9 – Subscript out of Range
Ursache: Sie greifen auf ein Worksheet, Array-Element oder Collection-Item zu, das nicht existiert.
' FEHLER: Blatt "Daten2024" existiert nicht Dim ws As Worksheet Set ws = ThisWorkbook.Worksheets("Daten2024") ' Fehler 9! ' LÖSUNG: Existenz vorher prüfen If WorksheetExists("Daten2024") Then Set ws = ThisWorkbook.Worksheets("Daten2024") Else MsgBox "Das Blatt 'Daten2024' wurde nicht gefunden.", vbExclamation Exit Sub End If
Mehr Details und Lösungen finden Sie auf der Seite VBA Fehler 9 – Subscript out of Range.
Laufzeitfehler 13 – Type Mismatch
Ursache: Ein Wert hat den falschen Datentyp – z.B. Text in einer Zelle, die als Zahl erwartet wird.
' FEHLER: Zelle enthält Text statt Zahl Dim betrag As Double betrag = ws.Cells(i, 1).Value ' Fehler 13 wenn Zelle "abc" enthält! ' LÖSUNG: Typ vorher prüfen If IsNumeric(ws.Cells(i, 1).Value) Then betrag = CDbl(ws.Cells(i, 1).Value) Else MsgBox "Zeile " & i & ": Kein gültiger Zahlenwert.", vbExclamation End If
Mehr dazu: VBA Type Mismatch Fehler beheben.
Laufzeitfehler 1004 – Application/Object-defined Error
Ursache: Ungültige Range-Referenz, geschütztes Blatt, oder eine Methode die in diesem Kontext nicht erlaubt ist.
' FEHLER: Blatt ist geschützt ws.Cells(1, 1).Value = "Test" ' Fehler 1004 bei geschütztem Blatt! ' LÖSUNG: Schutz prüfen und temporär aufheben If ws.ProtectContents Then ws.Unprotect Password:="meinPasswort" End If ws.Cells(1, 1).Value = "Test" ws.Protect Password:="meinPasswort"
Ausführliche Informationen: VBA Fehler 1004 – Ursachen und Lösungen.
Laufzeitfehler 91 – Object Variable Not Set
Ursache: Sie verwenden eine Objektvariable, ohne sie vorher mit Set zuzuweisen, oder das Objekt ist Nothing.
' FEHLER: Set vergessen Dim ws As Worksheet ws = ThisWorkbook.Worksheets("Daten") ' Fehler 91! Set fehlt ' LÖSUNG: Immer Set verwenden Set ws = ThisWorkbook.Worksheets("Daten") ' FEHLER: Nothing-Referenz verwenden Dim rng As Range Set rng = ws.Range("A1").Find("Suchbegriff") rng.Interior.Color = vbYellow ' Fehler 91 wenn Find nichts findet! ' LÖSUNG: Nothing-Prüfung Set rng = ws.Range("A:A").Find("Suchbegriff") If Not rng Is Nothing Then rng.Interior.Color = vbYellow Else MsgBox "Suchbegriff nicht gefunden.", vbInformation End If
Error Logging – Fehler protokollieren
Fehlermeldungen per MsgBox reichen für Entwicklung, aber in Produktionsmakros brauchen Sie ein Log. Hier zwei Ansätze:
Variante 1: Fehler in eine Textdatei schreiben
Sub LogToFile(ByVal prozedur As String, ByVal errNum As Long, _ ByVal errDesc As String) Dim logPath As String logPath = ThisWorkbook.Path & "\fehlerlog.txt" Dim f As Integer f = FreeFile Open logPath For Append As #f Print #f, Format(Now, "yyyy-mm-dd hh:nn:ss") & " | " & _ prozedur & " | Fehler " & errNum & ": " & errDesc Close #f End Sub
Variante 2: Fehler in ein verstecktes Worksheet loggen
Sub LogToSheet(ByVal prozedur As String, ByVal errNum As Long, _ ByVal errDesc As String, Optional ByVal kontext As String = "") Dim ws As Worksheet On Error Resume Next Set ws = ThisWorkbook.Worksheets("_ErrorLog") On Error GoTo 0 If ws Is Nothing Then Set ws = ThisWorkbook.Worksheets.Add ws.name = "_ErrorLog" ws.Visible = xlSheetVeryHidden ws.Range("A1:E1").Value = Array("Zeitpunkt", "Prozedur", _ "Fehlernr", "Beschreibung", "Kontext") End If Dim r As Long r = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1 ws.Cells(r, 1).Value = Now ws.Cells(r, 2).Value = prozedur ws.Cells(r, 3).Value = errNum ws.Cells(r, 4).Value = errDesc ws.Cells(r, 5).Value = kontext End Sub
Best Practices
1. Immer Cleanup-Code verwenden: Jede Prozedur, die ScreenUpdating, Calculation oder EnableEvents ändert, braucht ein Cleanup-Label. Ohne Cleanup bleibt Excel bei einem Fehler in einem unbrauchbaren Zustand.
2. Err.Clear nach Resume Next: Nach einem On Error Resume Next-Block immer Err.Clear aufrufen oder On Error GoTo 0 setzen, sonst schleppen Sie alte Fehler mit.
3. Spezifische Fehlermeldungen: Statt MsgBox Err.Description lieber konkreten Kontext nennen: welche Datei, welche Zeile, welcher Schritt. Das spart Stunden beim Debugging.
4. Error Handling nicht als Kontrollfluss missbrauchen: Verwenden Sie If...Then oder Select Case statt absichtlich Fehler auszulösen und per Resume Next abzufangen. Error Handling ist für unerwartete Situationen.
5. Einheitliches Muster verwenden: Standardisieren Sie Ihr Error-Handling-Template über alle Module hinweg. Der VBA Code Generator kann das automatisch einbauen.
FAQ
Soll ich On Error Resume Next oder On Error GoTo verwenden?
In 95% der Fälle ist On Error GoTo die richtige Wahl. Resume Next sollten Sie nur für kurze, gezielte Prüfungen verwenden – z.B. ob ein Worksheet existiert oder ob Find ein Ergebnis liefert. Für den Hauptcode einer Prozedur verwenden Sie immer On Error GoTo mit einem Cleanup-Label.
Wie finde ich heraus welche Zeile den Fehler verursacht?
Verwenden Sie Erl (Error Line) zusammen mit Zeilennummern, oder nutzen Sie den VBA Debugger mit Breakpoints und dem Direktfenster. In Produktionscode hilft ein Log mit dem Prozedurnamen und dem aktuellen Verarbeitungsschritt (z.B. Zeilennummer der Schleife).
Kann ich eigene Fehlernummern definieren?
Ja, mit Err.Raise. Eigene Fehlernummern sollten ab vbObjectError + 512 beginnen, um Konflikte mit VBA-internen Nummern zu vermeiden: Err.Raise vbObjectError + 1001, "MeinModul", "Ungültiger Datumsbereich".
Was ist der Unterschied zwischen Err.Raise und Error?
Err.Raise ist die moderne Methode und erlaubt benutzerdefinierte Fehlernummern, Source und Description. Error ist die alte Syntax und akzeptiert nur eine Fehlernummer. Verwenden Sie immer Err.Raise.
Wie teste ich mein Error Handling?
Erstellen Sie kleine Testprozeduren, die gezielt Fehler auslösen: ungültige Ranges ansprechen, Division durch Null, nicht existierende Dateien öffnen. Prüfen Sie ob der Cleanup-Code korrekt ausgeführt wird und die Fehlermeldung verständlich ist.
Fehler automatisch finden und beheben
Der VBA Debug Assistant analysiert Ihren Code, findet Laufzeitfehler und liefert korrigierten Code mit Erklärung. Auch das VBA Fehler-Nachschlagewerk hilft bei der schnellen Lösung häufiger Fehlermeldungen.
Kostenlos testen – 10 Anfragen inklusive, keine Registrierung nötig.
Code-Generierung
Automatische VBA-Code-Erstellung durch natürliche Sprache
Code-Analyse
Code verstehen und dokumentieren
Debugging
Intelligente Fehlerfindung und -behebung
Code-Verbesserung
Optimierung und Fehlerbehandlung
UI-Design
UserForms über natürliche Sprache erzeugen
Snippet-Verwaltung
Über 100 vorgefertigte Code-Bausteine
Fehler automatisch finden und beheben
Der VBA Debug Assistant analysiert Ihren Code, findet Laufzeitfehler und liefert korrigierten Code mit Erklärung.
