Schlagwort-Archiv: Error

Errorhandling in VBA. Teil 1.

Grundlagen 1/2

VBA bringt mit „On Error“ ein eigenes Konstrukt zur Fehlerbehandlung mit. Grundsätzlich gibt es zwei Arten wie man in VBA auf einen Fehler reagieren kann.
1. Ignorieren
2. Reagieren

Während im ersten Teil das Thema „ignorieren“ behandelt wird, wird sich der zweite Teil mit dem Thema „reagieren“ auseinandersetzen.

Der Standardfall.
Nehmen wir als Anschauungsobjekt eine einfache Prozedur. Nennen wir sie kreativerweise mal „RaisingError“. Diese Funktion kann erstmal recht wenig und sieht wie folgt aus:

Public Sub RaisingError
	debug.print 1 / 0
End Sub

Führen wir diese Funktion aus, erhalten wir eine Fehlermeldung in Form einer Dialogbox in wir die Ausführung beenden können, oder in die Debug-Umgebung springen können.
Für einen Entwickler ist das sicherlich noch kein Beinbruch, aber für einen Anwender ist das schnell die totale Überforderung. Erstens weiß dieser im Zweifel nichts mit „Debuggen“ anzufangen, und erst recht wird er im VBA-Editor nicht seine zweite Heimat haben, am wichtigsten aber ist, dass er keine Ahnung von dem Code haben wird, den ihr geschrieben habt. Also, was soll der arme Mensch dann in der Debug-Umgebung…

Fehler ignorieren. On Error Resume Next
Setzen wir bei der obigen Prozedur mal ein “On Error Resume Next” vor die 1. Zeile und starten die Prozedur erneut. Die Dialogbox, die uns darauf aufmerksam macht, dass eine Division durch Null ein Fehler ist, taucht nun nicht auf. Der Fehler wird schlicht ignoriert. Das ist auch gut so, jedenfalls in dem hier vorliegenden Fall.

Public Sub RaisingError
	On Error Resume Next

	debug.print 1 / 0
End Sub

Der ausgelöste Fehler wird zwar ignoriert, dennoch lässt er sich anzeigen. Hierfür können wir das Err-Objekt abfragen. Das Err-Objekt hat, neben ein paar anderen, zwei zentrale Eigenschaften: Number und Description. In Number wird der als letztes aufgetretene Fehlercode festgehalten, in Description eine manchmal mehr, manchmal weniger aussagekräftige Fehloerbeschreibung. Ein Fehler mit dem Fehlercode 0 ist dabei ein „Kein Fehler aufgetreten“-Antifehler.
Für unser obiges Beispiel heißt das, dass wir nach der 2.Zeile prüfen könnten, ob bei der geplanten Debug-Ausgabe ein Fehler aufgetreten ist. Wenn das der Fall ist, dann müsste der Fehlercode im Err-Objekt ungleich 0 sein.

Public Sub RaisingError
	On Error Resume Next

	debug.print 1 / 0

	If Err.Number <> 0 Then
		Debug.Print “Hier ist ein Fehler aufgetreten.”
		Debug.Print „Genauer: Fehlercode „ & Err.Number & „ Beschreibung: „ & Err.Description
	End If
End Sub

Nun muss man hier aber noch eine Anmerkung unterbringen. Sehen wir uns die folgende Prozedur an:

Public Sub RaisingError
	On Error Resume Next

	debug.print 1 / 0

	debug.print 1 + 2

	If Err.Number <> 0 Then
		Debug.Print “Hier ist ein Fehler aufgetreten.”
		Debug.Print „Genauer: Fehlercode „ & Err.Number & „ Beschreibung: „ & Err.Description
	End If
End Sub

Hier ist in der uns wohl bekannten Zeile der „übliche“ Fehler aufgetreten, in der folgenden Zeile wird eine einfache Addition ausgeführt bei der kein Fehler auftreten sollte. Dennoch finden wir in der folgenden Zeile bei der Fehlercode-Abfrage einen Fehler der ungleich 0 ist. Sprich: der letzte vorkommende Fehler muss zurückgesetzt werden um ein wirklich verlässliches Ergebnis zu erhalten. Hierfür kommt die Methode „Clear“ des Err-Objekts zum Einsatz.

Public Sub RaisingError
	On Error Resume Next

	debug.print 1 / 0
	Err.Clear

	debug.print 1 + 2

	If Err.Number <> 0 Then
		Debug.Print “Hier ist ein Fehler aufgetreten.”
		Debug.Print „Genauer: Fehlercode „ & Err.Number & „ Beschreibung: „ & Err.Description
	End If
End Sub

Damit sind wir mit diesem Teil schon am Ende. Wir haben gesehen dass es ein Möglichkeit gibt, die Standard-Fehlerbehandlung auszuschalten und damit die Interaktion zu unterbinden. Mit dem „On Error Resume Next“-Statement wird ein linearer Errorhandler initiiert, welche grundsätzlich einen auftretenden Fehler ignoriert und die Fehlerbehandlung in die Hände des Entwicklers legt.
Das hat den Vorteil dass sehr punktuell auf Fehler reagiert werden kann, aber auch den Nachteil dass man im Prinzip wissen muss, wann und wo ein Fehler auftreten kann. Zudem ist darauf zu achten, dass sich Fehler nach Auftreten nur mit einem Err.Clear zurücksetzt.
Bis zum nächsten Teil.

Errorhandling in VBA

Ich möchte hier mal ein Fass aufmachen und das Thema Errorhandling in VBA an Hand von Access genauer unter die Lupe nehmen. Das ist sicherlich ein komplexes Thema aber auch ein elementares da ohne ein vernünftiges Errorhandling Probleme nicht nur schwerer zu finden sind sondern vor allem weil es den negativen Seiteneffekt hat, dass Programme bei Problemen einen Runtime-Error produzieren. Das kann zu vielerlei Szenarien führen, die dann nicht mehr kontrolliert abgefangen werden können. Bsw dass Werte auf Grund des ad hoc Programmausstiegs verloren gehen, der User das aber gar nicht mitbekommt und daher in Situationen gerät, in der das Programm im freien Fall ist. Wenn all diese Unwägbarkeiten im Sourcecode kontrolliert werden sollen, kann man sich einfach vorstellen, dass sich das Programm dadurch ungeheuer aufblähen kann. Warum also nicht einfach eine funktionierende Fehlerbehandlung einsetzen und so eine Menge Probleme einfach gar nicht erst entstehen lassen.
Die Beiträge zum Thema Errorhandling werden sich auf mehrere Posts verteilen. Angefangen von den Basics bis letztendlich zu einem komplexen Errorhandler der Momentaufnahmen der Anwendung zur Fehlerzeit aufzeichnet und so auch im Nachhinein nachvollziehbar macht.

Beginnen werden wir also mit dem ersten Posting zu dem Thema, den Grundlagen. mehr dazu im Posting „Errorhandling in VBA. Teil 1: Grundlagen.“