🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Err-Objekt in Excel — Number, Description & eigene Fehler auslösen

|

VBA Err-Objekt in Excel — Number, Description & eigene Fehler auslösen

Getestet in: Excel 365 v2509 · Excel 2021 · Excel 2019 · zuletzt geprüft am 08.06.2026

Kurz gesagt — Wenn ein Laufzeitfehler auftritt, füllt VBA ein einziges globales Objekt — Err — mit allem, was es über den Absturz weiß. Du liest es in einer Fehlerbehandlungsroutine, um zu entscheiden, was zu tun ist; du kannst es mit Err.Raise aber auch beschreiben, um einen eigenen Fehler auszulösen:

Sub PreisLesen()
    On Error Resume Next
    Dim preis As Double
    preis = CDbl(Range("A1").Value)          ' scheitert, wenn A1 nicht numerisch ist
    If Err.Number <> 0 Then
        MsgBox "Fehler " & Err.Number & ": " & Err.Description
        Err.Clear                            ' zurücksetzen, damit die nächste Prüfung sauber ist
    End If
    On Error GoTo 0
End Sub

Das ganze Objekt an einem Ort:

Err.Number        ' der Fehlercode — 0 bedeutet "kein Fehler"
Err.Description   ' die für Menschen lesbare Meldung
Err.Source        ' wer ihn ausgelöst hat (Projekt-/Objektname)
Err.Raise 513     ' selbst einen Fehler AUSLÖSEN
Err.Clear         ' Err wieder in einen sauberen Zustand zurücksetzen

Das Denkmodell: Err ist die Blackbox des letzten Absturzes

Err ist ein einziges, immer vorhandenes, globales Objekt. Stell es dir als Flugschreiber deines Makros vor: In dem Moment, in dem ein Laufzeitfehler auftritt, schreibt VBA drei Fakten hinein, bevor die Steuerung zu deiner Routine springt —

  • Err.Number — der numerische Code (1004, 13, 9 …). 0 heißt „nichts ist schiefgegangen".
  • Err.Description — derselbe Text, den du im roten Dialog sähst („Typen unverträglich", „Index außerhalb des gültigen Bereichs").
  • Err.Source — welches Projekt oder Objekt ihn ausgelöst hat.

Es gibt nur ein Err-Objekt für die ganze Sitzung, und es hält den jüngsten Fehler. Deshalb zählt das Wann du es liest genauso viel wie das Was du liest — und deshalb wird es automatisch gelöscht (mehr dazu gleich).

Die eine Regel: Err.Number ist das einzig verlässliche „ist es wirklich gescheitert?"

Nach On Error Resume Next läuft dein Code weiter, egal ob die Zeile funktioniert hat oder nicht. Der einzige Weg zu wissen, was von beidem passierte, ist, Err.Number zu lesen:

On Error Resume Next
Set wb = Workbooks("Budget.xlsx")     ' ist diese Mappe schon offen?
If Err.Number = 0 Then
    MsgBox "Bereits geöffnet."
Else
    Err.Clear
    Set wb = Workbooks.Open("C:\Daten\Budget.xlsx")
End If
On Error GoTo 0

Resume Next ohne Err.Number-Prüfung ist vergeudet: Du hast VBA gesagt, es solle Fehlschläge ignorieren, erfährst aber nie, dass einer passiert ist. Die Prüfung ist die Behandlung. Das ist die Begleitregel zu On Error Resume Next — die beiden funktionieren nur als Paar.

Du kannst auch nach dem konkreten Code verzweigen, denn verschiedene Nummern bedeuten verschiedene Probleme:

Select Case Err.Number
    Case 0:    ' kein Fehler
    Case 9:    MsgBox "Dieses Blatt oder dieser Index existiert nicht."   ' Index außerhalb des Bereichs
    Case 13:   MsgBox "Dieser Wert hat nicht den richtigen Typ."          ' Typen unverträglich
    Case 1004: MsgBox "Excel hat diesen Vorgang verweigert."              ' allgemeiner Automatisierungsfehler
    Case Else: MsgBox "Unerwarteter Fehler " & Err.Number & ": " & Err.Description
End Select

Die Falle: Err löscht sich, wenn du es am wenigsten erwartest

Err bleibt nicht gefüllt, bis du damit fertig bist. VBA setzt es bei jedem dieser Ereignisse automatisch auf Number = 0 zurück:

  • eine On Error-Anweisung jeder Art (einschließlich On Error GoTo 0)
  • ein Resume oder Resume Next
  • Exit Sub / Exit Function
  • der nächste Laufzeitfehler (er wird überschrieben, nicht angehängt)

Wenn du also Nummer oder Beschreibung nach einem dieser Ereignisse brauchst — um sie zu protokollieren, später zu zeigen, nach oben weiterzureichen —, sichere sie in eigene Variablen, sobald deine Routine startet:

Fehlerbehandlung:
    Dim fehlerNum As Long, fehlerMsg As String
    fehlerNum = Err.Number                   ' JETZT greifen
    fehlerMsg = Err.Description
    On Error Resume Next                      ' ← diese Zeile würde Err löschen ...
    Application.ScreenUpdating = True         ' ... das Aufräumen kann Err danach nicht mehr lesen
    InsBlattProtokollieren fehlerNum, fehlerMsg  ' die gesicherten Kopien nutzen, nicht Err.*

Dieser eine Stolperstein steckt hinter den meisten Bug-Meldungen „mein Fehlerprotokoll zeigt Fehler 0".

Eigene Fehler mit Err.Raise auslösen

Err zu lesen ist die halbe Miete. Die andere Hälfte ist, es zu beschreiben — gezielt einen Fehler auszulösen, wenn deine Regeln verletzt werden, nicht nur die von VBA:

Function NettoPreis(brutto As Double, steuerSatz As Double) As Double
    If steuerSatz < 0 Or steuerSatz > 1 Then
        Err.Raise vbObjectError + 513, "NettoPreis", _
                  "steuerSatz muss zwischen 0 und 1 liegen, war aber " & steuerSatz
    End If
    NettoPreis = brutto / (1 + steuerSatz)
End Function

Err.Raise Number, Source, Description erzeugt einen echten Laufzeitfehler — die On Error-Routine des Aufrufers fängt ihn genauso ab wie einen eingebauten. Nimm vbObjectError + n (mit n von 513 bis 65535) für eigene Fehler; diese Konstante versetzt dich sauber jenseits des Bereichs 0–512, den VBA für Systemcodes reserviert, sodass du nie mit einem echten kollidierst.

Die Meinung: einen Fehlercode zurückzugeben ist Hoffnung; einen auszulösen ist Durchsetzung

Viel VBA „validiert", indem es einen Platzhalter zurückgibt — -1, False, eine leere Zeichenfolge — und darauf vertraut, dass jeder Aufrufer daran denkt, ihn zu prüfen. Werden sie nicht. Sechs Monate später ruft jemand deine Funktion auf, ignoriert die -1 und dividiert durch sie.

Err.Raise nimmt die Wahl weg. Ein ausgelöster Fehler kann nicht stillschweigend ignoriert werden — er trifft entweder eine Routine oder stoppt das Makro. Genau das ist der Sinn. Err.Number zu lesen macht dich kompetent in der Fehlerbehandlung; eigene Fehler für falsche Eingaben und Geschäftsregeln auszulösen ist das, was deinen Code defensiv statt nur höflich macht. Wenn ein Wert das Ergebnis weiter unten zerstören würde, gib kein Flag zurück und hoffe — löse einen Fehler aus.

Häufige Err-Fehler (und die Lösung)

Symptom Ursache Lösung
Protokoll zeigt immer „Fehler 0" Err gelesen, nachdem Resume/On Error/Aufräumen es löschte Err.Number/Err.Description zuerst in Variablen sichern
Resume Next „fängt" nichts Err.Number nach der riskanten Zeile nie geprüft If Err.Number <> 0 Then … ergänzen
eigener Fehler kollidiert mit einem System-Fehler rohe kleine Nummer wie Err.Raise 5 verwendet Err.Raise vbObjectError + 513 aufwärts nehmen
zweite Prüfung feuert auf einem alten Fehler Err.Clear nach der ersten Behandlung vergessen Err.Clear aufrufen, sobald er erledigt ist
Err.Description ist leer nach Err.Clear oder einem Reset gelesen Beschreibung vor dem Löschen lesen

Schluss mit handgeschriebener Fehler-Leitungsverlegung — beschreib die Regel einfach

Die Hälfte von robustem VBA ist genau das: Err.Number lesen, die Beschreibung sichern, eigene Fehler für falsche Daten auslösen, löschen, wiederholen. Es ist nötig und es ist mühsam. ExcelMaster Agent lässt dich „prüfe, dass der Steuersatz zwischen 0 und 1 liegt, und stopp mit einer klaren Meldung, falls nicht" in Klartext-Deutsch sagen — und das erzeugte Python löst den Fehler aus und meldet ihn für dich, mit zuvor gesicherter Datei. Kostenlos testen →

Verwandte Anleitungen

FAQ

Was ist das Err-Objekt in VBA? Err ist ein globales Objekt, das Informationen über den jüngsten Laufzeitfehler hält. Seine wichtigsten Eigenschaften sind Err.Number (der Fehlercode, 0 = kein Fehler), Err.Description (die Meldung) und Err.Source (wer ihn auslöste). Du liest es in einer Fehlerbehandlungsroutine, um zu entscheiden, was zu tun ist.

Wie prüfe ich die Fehlernummer in VBA? Lies Err.Number. Nach On Error Resume Next testest du mit If Err.Number <> 0 Then, ob die vorige Zeile gescheitert ist. Der Wert 0 bedeutet, dass kein Fehler auftrat. Mit Select Case Err.Number kannst du auf bestimmte Codes wie 9 (Index außerhalb des Bereichs) oder 13 (Typen unverträglich) unterschiedlich reagieren.

Wann wird das Err-Objekt zurückgesetzt? Automatisch bei jeder On Error-Anweisung, bei Resume/Resume Next, bei Exit Sub/Exit Function und wenn der nächste Fehler es überschreibt. Brauchst du die Werte danach noch, kopiere Err.Number und Err.Description sofort in eigene Variablen. Manuell zurücksetzen kannst du es mit Err.Clear.

Wie löse ich einen eigenen Fehler in VBA aus? Mit Err.Raise Number, Source, Description. Für eigene Fehler nimm vbObjectError + n, wobei n zwischen 513 und 65535 liegt, z. B. Err.Raise vbObjectError + 513, "MeineFunktion", "Ungültige Eingabe". Das vermeidet den für Systemfehler reservierten Bereich 0–512 und lässt die Routine des Aufrufers ihn wie jeden eingebauten Fehler abfangen.

Was ist der Unterschied zwischen Err.Clear und On Error GoTo 0? Err.Clear setzt die Eigenschaften des Err-Objekts in einen sauberen Zustand zurück, lässt deinen Fehlerüberwachungs-Modus aber unverändert. On Error GoTo 0 setzt den Überwachungs-Modus auf den Standard (bei Fehler anhalten) zurück — und löscht als Nebeneffekt auch Err. Nimm Err.Clear, um Err innerhalb derselben Routine wiederzuverwenden; nimm On Error GoTo 0, um das Ignorieren von Fehlern zu beenden.