{"id":55001514,"date":"2024-10-01T00:00:00","date_gmt":"2024-08-27T09:24:58","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1514"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Fehlerbehandlung_per_VBA_hinzufuegen","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/","title":{"rendered":"Fehlerbehandlung per VBA hinzuf&uuml;gen"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg02.met.vgwort.de\/na\/92052a09a2054d54922a3ad4fdb7de70\" width=\"1\" height=\"1\" alt=\"\"><b>Eine Fehlerbehandlung ist Teil einer professionellen Datenbankanwendung auf Basis von Microsoft Access. Sobald wir eine Datenbank an einen Kunden oder Mitarbeiter weitergeben, also an einen anderen Benutzer als uns selbst, ist dies praktisch ein Pflichtprogramm. Die Fehlerbehandlung soll den Benutzer &uuml;ber einen Fehler informieren und diesem die M&ouml;glichkeit geben, dem Entwickler Informationen &uuml;ber den Fehler zukommen zu lassen. In diesem Beitrag wollen wir die Hauptarbeit bei der Implementierung einer Fehlerbehandlung erledigen. Dazu wollen wir eine Prozedur schreiben, die beliebige Routinen, also Sub-, Function- und Property-Prozeduren, mit einer einfachen Fehlerbehandlung ausstattet &#8211; und &uuml;berdies noch mit einer Zeilennummerierung. Diese ist wichtig, wenn wir schnell herausfinden wollen, an welcher Stelle ein Fehler aufgetreten ist. Zusammen mit dem Namen des Moduls, dem Namen der Prozedur, der Fehlernummer und der Fehlerbeschreibung erhalten wir so Informationen, die in der Regel zum Aufdecken des Fehlers f&uuml;hren.<\/b><\/p>\n<p>Wir wollen in diesem Beitrag eine minimale Fehlerbehandlung verwenden, die nur die n&ouml;tigsten Informationen aufnimmt. Dazu geh&ouml;ren die folgenden:<\/p>\n<ul>\n<li>Fehlernummer<\/li>\n<li>Fehlerbeschreibung<\/li>\n<li>Zeile, in welcher der Fehler aufgetreten ist<\/li>\n<li>Prozedur, in welcher der Fehler aufgetreten ist<\/li>\n<li>Modul, in dem der Fehler aufgetreten ist<\/li>\n<\/ul>\n<p>Woher bekommen wir diese Informationen?<\/p>\n<p>Die Fehlernummer und die Fehlerbeschreibung erhalten wir per VBA grunds&auml;tzlich nur, wenn wir die eingebaute Fehlerbehandlung von VBA ausgeschaltet haben. Das erledigen wir mit einer der folgenden Anweisungen:<\/p>\n<pre>On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n<span style=\"color:blue;\">On Error GoTo<\/span> Sprungmarke<\/pre>\n<p>Dabei ist Sprungmarke eine Zeile, die den Namen der Sprungmarke und einen Doppelpunkt enth&auml;lt, zum Beispiel:<\/p>\n<pre>Errorhandling:<\/pre>\n<p>Wenn wir die eingebaute Fehlerbehandlung wieder einschalten wollen, k&ouml;nnen wir dies mit der folgenden Anweisung erledigen:<\/p>\n<pre><span style=\"color:blue;\">On Error GoTo<\/span> 0<\/pre>\n<p>W&auml;hrend die eingebaute Fehlerbehandlung ausgeschaltet ist, werden Fehler entweder einfach ignoriert (<b>On Error Resume Next<\/b>) oder der Code wird an der angegebenen Sprungmarke fortgesetzt, wenn eine angegeben wurde (<b>On Error Goto Errorhandler<\/b>).<\/p>\n<h2>Fehlernummer und Fehlerbeschreibung ermitteln<\/h2>\n<p>In jedem Fall k&ouml;nnen wir in den darauffolgenden Zeilen die Eigenschaften des <b>Err<\/b>-Objekts auslesen. Das k&ouml;nnen wir zwar immer, aber wenn kein unbehandelter Fehler aufgetreten ist, liefert dies auch keine Fehlerinformationen.<\/p>\n<p>Gehen wir jedoch davon aus, dass wir die Informationen nach Auftreten eines Fehlers abfragen, k&ouml;nnen wir dem <b>Err<\/b>-Objekt die folgenden Informationen entnehmen:<\/p>\n<ul>\n<li><b>Err.Number<\/b>: Liefert die Fehlernummer, zum Beispiel <b>11<\/b>.<\/li>\n<li><b>Err.Description<\/b>: Liefert die Fehlerbeschreibung, zum Beispiel <b>Division durch Null<\/b>.<\/li>\n<\/ul>\n<h2>Name des VBA-Projekts ermitteln<\/h2>\n<p>Wir k&ouml;nnten mit der <b>Err<\/b>-Eigenschaft <b>Err.Source <\/b>sogar noch den Namen des VBA-Projekts ermitteln, in dem der Fehler ausgel&ouml;st wurde. Dies ist jedoch nicht unbedingt notwendig, da sich die Fehlerbehandlung meist auf das gleiche VBA-Projekt bezieht, in dem sich diese befindet.<\/p>\n<h2>Zeilennummer ermitteln<\/h2>\n<p>Die Nummer der Zeile, in welcher der Fehler aufgetreten ist, finden wir offiziell gar nicht. Allerdings gibt es eine nicht dokumentierte Funktion namens <b>Erl<\/b>, die uns im Falle eines Fehlers die Nummer der Zeile mit der ausl&ouml;senden Anweisung liefert. Dies geschieht jedoch nur, wenn es auch eine Zeilennummerierung gibt. Diese m&uuml;ssen wir selbst hinzuf&uuml;gen, es gibt keine eingebaute Funktion, um dies einfach zu erledigen.<\/p>\n<p>Wie wir die Zeilennummer hinzuf&uuml;gen, haben wir deshalb ausf&uuml;hrlich beschrieben, und zwar im Beitrag <b>Zeilennummern per VBA hinzuf&uuml;gen <\/b>(<b>www.access-im-unternehmen.de\/1515<\/b>). Hier finden Sie sogar Prozeduren, mit denen Sie die Zeilennummern f&uuml;r eine Prozedur, alle Prozeduren eines Moduls und sogar f&uuml;r alle Module in einem VBA-Projekt per Mausklick anlegen k&ouml;nnen.<\/p>\n<h2>Prozedurname und Modulname ermitteln<\/h2>\n<p>Den Prozedurnamen und den Modulnamen k&ouml;nnen wir ebenfalls nicht automatisch ermitteln. Es ist jedoch dennoch sinnvoll, diesen in einer Fehlerbehandlung auszugeben &#8211; dabei spielt es keine Rolle, ob die Fehlerbehandlung nur eine Meldung anzeigt, die Fehlerinformationen in eine Tabelle schreibt oder direkt eine E-Mail an den Entwickler der Anwendung schickt.<\/p>\n<p>In jedem Fall werden wir in einer Fehlerbehandlung landen, die sich innerhalb der Prozedur befindet, in welcher der Fehler ausgel&ouml;st wurde. Diese befindet sich in der Regel hinter einer Sprungmarke am Ende der jeweiligen Prozedur. Und wenn wir ohnehin f&uuml;r jede Prozedur eine eigene Fehlerbehandlung hinzuf&uuml;gen m&uuml;ssen, dann k&ouml;nnen wir hier auch direkt die Information unterbringen, in welchem Modul und in welcher Prozedur wir uns gerade befinden.<\/p>\n<p>Das gilt auch, wenn sich die Fehlerbehandlungsanweisungen nicht selbst in der Prozedur befinden, sondern in einer eigenen Routine. Dann m&uuml;ssen wir daf&uuml;r sorgen, dass der Modul- und der Prozedurname zur dortigen Routine gelangen und k&ouml;nnen diese im Aufruf der fehlerausl&ouml;senden Prozedur platzieren.<\/p>\n<p>Das sieht beispielsweise wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Test_WriteError()\r\n10    <span style=\"color:blue;\">On Error GoTo<\/span> Errorhandling\r\n20    <span style=\"color:blue;\">Debug.Print<\/span> 1 \/ 0\r\n30    <span style=\"color:blue;\">Exit Sub<\/span>\r\nErrorhandling:\r\n     HandleError Err.Number, Err.Description, Erl, _\r\n         \"Test_WriteError\", \"mdlErrors\"\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die Prozedur hat bereits Zeilennummern und die eingebaute Fehlerbehandlung wird mit <b>On Error Goto Errorhandling <\/b>deaktiviert. Der Fehler durch die Division durch <b>0 <\/b>in Zeile <b>20 <\/b>f&uuml;hrt somit dazu, dass die Prozedur direkt zur Sprungmarke <b>Errorhandling <\/b>springt. Hier rufen wir eine Prozedur namens <b>HandleError <\/b>auf, die unsere Fehlerbehandlungsroutine enth&auml;lt. Dieser &uuml;bergeben wir alle Daten, die wir in der Fehlerbehandlungsroutine verarbeiten wollen &#8211; die Fehlernummer, die Fehlerbeschreibung, die Zeilennummer, den Modulnamen und den Prozedurnamen. An dieser Stelle wird klar: Wenn wir diese Fehlerbehandlung zu vielen Prozeduren hinzuf&uuml;gen wollen, k&ouml;nnen wir zwar mit Copy und Paste arbeiten, aber wir m&uuml;ssen dennoch viele Anpassungen vornehmen. In diesem Fall m&uuml;ssen wir jeweils den Modulnamen und den Prozedurnamen anpassen. Beim Modulnamen muss man dies nur einmal pro Modul erledigen und kann die entsprechenden Zeilen dann kopieren und braucht nur noch den Prozedurnamen anzupassen. Viel Aufwand bleibt es dennoch, und es ist auch nicht wenig fehleranf&auml;llig.<\/p>\n<h2>Fehlerbehandlungsroutine<\/h2>\n<p>Die Routine namens <b>HandleError<\/b>, die wir von allen Prozeduren mit einer Fehlerbehandlung aus aufrufen wollen, finden Sie in Listing 1. In diesem Fall wollen wir aufgetretene Fehler einfach in eine Tabellenamens <b>tblErrors <\/b>schreiben, die sich in der gleichen Datenbank befindet. Diese enth&auml;lt Felder f&uuml;r alle erw&auml;hnten Fehlerinformationen und zuz&uuml;glich noch ein Feld mit Datum und Uhrzeit.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>HandleError(lngNumber<span style=\"color:blue;\"> As Long<\/span>, strMessage<span style=\"color:blue;\"> As String<\/span>, lngLine<span style=\"color:blue;\"> As Long<\/span>, strProcedure<span style=\"color:blue;\"> As String<\/span>, _\r\n         strModule<span style=\"color:blue;\"> As String<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     db.Execute \"INSERT INTO tblErrors(ErrorNumber, ErrorMessage, ErrorLine, ErrorProcedure, ErrorModule) VALUES(\" _\r\n         & lngNumber & \", ''\" & <span style=\"color:blue;\">Replace<\/span>(strMessage, \"''\", \"''''\") & \"'', \" & lngLine & \", ''\" & strProcedure & \"'', ''\" _\r\n         & strModule & \"'')\", dbFailOnError\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Fehlerbehandlungsroutine<\/span><\/b><\/p>\n<p>F&uuml;r dieses legen wir als Standardwert <b>Jetzt() <\/b>fest, damit wir dieses Feld nicht per Code f&uuml;llen m&uuml;ssen (siehe Bild 1).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2024_05\/pic_1514_001.png\" alt=\"Tabelle zum Speichern der Fehlerinformationen\" width=\"574,559\" height=\"453,7493\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Tabelle zum Speichern der Fehlerinformationen<\/span><\/b><\/p>\n<p>Die Fehlerbehandlungsroutine enth&auml;lt im Wesentlichen eine <b>INSERT INTO<\/b>-Anweisung, die einen neuen Datensatz in die Tabelle <b>tblErrors <\/b>schreibt und die mit der <b>Execute<\/b>-Methode des <b>Database<\/b>-Objekts ausgef&uuml;hrt wird.<\/p>\n<p>Wenn wir unsere Fehlerbehandlung einige Male mit der obigen Beispielprozedur ausl&ouml;sen, finden wir Eintr&auml;ge wie in Bild 2 in der Tabelle <b>tblErrors <\/b>vor.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2024_05\/pic_1514_002.png\" alt=\"Tabelle zum Speichern der Fehlerinformationen mit einige Fehlern\" width=\"649,559\" height=\"165,8266\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Tabelle zum Speichern der Fehlerinformationen mit einige Fehlern<\/span><\/b><\/p>\n<h2>Alternativen zum Eintrag in die Fehlertabelle<\/h2>\n<p>Wenn Sie in Ihrer Anwendung einmal alle Prozeduren, bei denen es sinnvoll ist (in der Regel alle), mit einer Fehlerbehandlung ausgestattet haben, k&ouml;nnen Sie die im Falle eines Fehlers durchzuf&uuml;hrenden Aktionen einfach &auml;ndern. Dazu brauchen Sie nur die Anweisungen in der Prozedur <b>HandleError<\/b> anzupassen. Der Fantasie sind hier keine Grenzen gesetzt &#8211; Sie k&ouml;nnen die Daten wir hier in eine Tabelle schreiben, eine E-Mail mit Fehlerinformationen an den Entwickler senden, einfach nur eine Fehlermeldung anzeigen oder auch Fehlermeldungen in eine Textdatei au&szlig;erhalb der Datenbankdatei schreiben.<\/p>\n<p>Sie k&ouml;nnen auch verschiedene dieser Vorschl&auml;ge kombinieren. In der Regel ist es immer von Vorteil, wenn man den Benutzer &uuml;ber einen Fehler informiert, damit dieser gegebenenfalls weitere Schritte durchf&uuml;hren kann &#8211; wie den Entwickler zu informieren.<\/p>\n<h2>Fehlerbehandlung anwendungsweit integrieren<\/h2>\n<p>Nun stehen wir nur noch vor einer Flei&szlig;aufgabe. Wir m&uuml;ssen die Zeilen, die f&uuml;r die Funktion der Fehlerbehandlung n&ouml;tig sind, in jede Prozedur eintragen. <\/p>\n<p>Das sind aus der Beispielprozedur von oben alle Anweisungen au&szlig;er Prozedurkopf, -fu&szlig; und der eigentlichen Anweisung:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Test_WriteError()\r\n10    <span style=\"color:blue;\">On Error GoTo<\/span> Errorhandling\r\n20    <span style=\"color:blue;\">Debug.Print<\/span> 1 \/ 0\r\n30    <span style=\"color:blue;\">Exit Sub<\/span>\r\nErrorhandling:\r\n     HandleError Err.Number, Err.Description, Erl, _\r\n         \"Test_WriteError\", \"mdlErrors\"\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Und wenn wir, wie im Beitrag <b>Zeilennummern per VBA hinzuf&uuml;gen <\/b>(<b>www.access-im-unternehmen.de\/1515<\/b>) beschrieben, auch Zeilennummern automatisiert zu Prozeduren hinzuf&uuml;gen k&ouml;nnen, warum sollten wir dann nicht automatisch die immer wiederkehrenden Zeilen hinzuf&uuml;gen?<\/p>\n<h2>Prozedur zum automatisierten Hinzuf&uuml;gen einer Fehlerbehandlung<\/h2>\n<p>Hier verwenden wir die Prozedur <b>AddErrorHandler<\/b> aus Listing 2. Sie erwartet die folgenden Parameter:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>AddErrorHandler(strModule<span style=\"color:blue;\"> As String<\/span>, strProcedure<span style=\"color:blue;\"> As String<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>objVBProject<span style=\"color:blue;\"> As <\/span>VBIDE.VBProject\r\n     <span style=\"color:blue;\">Dim <\/span>objVBComponent<span style=\"color:blue;\"> As <\/span>VBIDE.VBComponent\r\n     <span style=\"color:blue;\">Dim <\/span>objCodemodule<span style=\"color:blue;\"> As <\/span>VBIDE.CodeModule\r\n     <span style=\"color:blue;\">Dim <\/span>lngCountOfLines<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intProcType<span style=\"color:blue;\"> As <\/span>vbext_ProcKind\r\n     <span style=\"color:blue;\">Dim <\/span>lngProcBodyLine<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strProcBodyLine<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngFirstStatementLineNumber<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngLastStatementLineNumber<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strProcType<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> objVBProject = VBE.ActiveVBProject\r\n     <span style=\"color:blue;\">Set<\/span> objVBComponent = objVBProject.VBComponents(strModule)\r\n     <span style=\"color:blue;\">Set<\/span> objCodemodule = objVBComponent.CodeModule\r\n     lngCountOfLines = objCodemodule.CountOfLines\r\n     lngProcBodyLine = objCodemodule.ProcBodyLine(strProcedure, intProcType)\r\n     lngFirstStatementLineNumber = GetFirstStatementLineNumber(objCodemodule, lngProcBodyLine)\r\n     lngLastStatementLineNumber = GetLastStatementLineNumber(objCodemodule, lngFirstStatementLineNumber)\r\n     strProcBodyLine = GetProcBodyLine(objCodemodule, lngProcBodyLine)\r\n     strProcType = GetProcType(strProcedure, strProcBodyLine)\r\n     objCodemodule.InsertLines lngFirstStatementLineNumber, \"    <span style=\"color:blue;\">On Error GoTo<\/span> Errorhandling\"\r\n     objCodemodule.InsertLines lngLastStatementLineNumber + 2, \"    <span style=\"color:blue;\">Call<\/span> HandleError(Err.Number, Err.Description, _\r\n         Erl, \"\"\" & strProcedure & \"\"\", \"\"\" & strModule & \"\"\")\"\r\n     objCodemodule.InsertLines lngLastStatementLineNumber + 2, \"Errorhandling:\"\r\n     objCodemodule.InsertLines lngLastStatementLineNumber + 2, \"    Exit \" & strProcType\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Prozedur zum Hinzuf&uuml;gen einer Fehlerbehandlung zu einer Prozedur<\/span><\/b><\/p>\n<ul>\n<li><b>strModule<\/b>: Name des Moduls<\/li>\n<li><b>strProcedure<\/b>: Name der Prozedur, in der die Fehlerbehandlung hinzugef&uuml;gt werden soll<\/li>\n<\/ul>\n<p>Die Prozedur f&uuml;llt die Variable <b>objVBProject <\/b>mit einem Verweis auf das aktuelle VBA-Projekt. Dann ermittelt sie das <b>VBComponent<\/b>-Objekt zu dem mit <b>strModule <\/b>angegebenen Modul und referenziert es mit der Variablen <b>objVBComponent<\/b>. &Uuml;ber ihre Eigenschaft <b>CodeModule <\/b>holt sie sich einen Verweis auf das <b>CodeModule<\/b>-Objekt des Moduls.<\/p>\n<p>Nun ermittelt sie einige Zeilennummern:<\/p>\n<ul>\n<li><b>lngCountOfLines<\/b>: Wird mit der Anzahl der Zeilen des Moduls gef&uuml;llt.<\/li>\n<li><b>lngProcBodyLine<\/b>: Wird mit der Nummer der ersten Zeile der Prozedur aus <b>strProcedure <\/b>gef&uuml;llt. F&uuml;r den Pflichtparameter <b>ProcKind <\/b>&uuml;bergeben wir die leere Variable <b>intProcType<\/b>. Diese erh&auml;lt einen Wert f&uuml;r den Typ der Prozedur, den wir aber nicht ben&ouml;tigen.<\/li>\n<li><b>lngFirstStatementLineNumber<\/b>: Hier ermitteln wir mit der Funktion <b>GetFirstStatementLineNumber <\/b>die Nummer der Zeile mit der ersten Anweisung der Prozedur, also die erste Zeile hinter der gegebenenfalls auch aus mehreren Zeilen bestehenden Kopfzeile. Diese Funktion beschreiben wir im Detail im Beitrag <b>Zeilennummern per VBA hinzuf&uuml;gen <\/b>(<b>www.access-im-unternehmen.de\/1515<\/b>).<\/li>\n<li><b>strProcBodyLine<\/b>: Wird &uuml;ber die Funktion <b>GetProcBodyLine<\/b>, die wir ebenfalls im oben genannten Beitrag beschreiben, mit der kompletten Kopfzeile der Prozedur ohne Zeilenumbr&uuml;che gef&uuml;llt. Dieser &uuml;bergeben wir einen Verweis auf das <b>CodeModule<\/b>-Objekt und die erste Zeile der Prozedur.<\/li>\n<li><b>strProcType<\/b>: Hier ermitteln wir mit der Funktion <b>GetProcType<\/b>, die wir ebenfalls im oben genannten Beitrag beschreiben, den Typ der Prozedur, und zwar <b>Sub<\/b>, <b>Function<\/b> oder <b>Property<\/b>.<\/li>\n<li><b>lngLastStatementLineNumber<\/b>: Erh&auml;lt die mit der Funktion <b>GetLastStatementLineNumber <\/b>ermittelte Nummer der letzten Zeile vor der Zeile mit der <b>End &#8230;<\/b>-Anweisung.<\/li>\n<\/ul>\n<p>Danach beginnt die eigentliche Aktion: Die erste <b>InsertLines<\/b>-Methode f&uuml;gt die Zeile <b>On Error Goto Errorhandling <\/b>an Stelle der mit <b>lngFirstStatementLineNumber <\/b>angegebenen ersten Zeile der Prozedur ein. Die n&auml;chste Anweisung beginnt mit dem Einf&uuml;gen der Zeilen am Ende der Prozedur. Damit wir nur die Nummer der Zeile der letzten Anweisung ben&ouml;tigen, f&uuml;gen wir die Anweisungen in umgekehrter Reihenfolge ein. Wir starten also mit der letzten Zeile, die den Aufruf der Fehlerbehandlungsroutine enth&auml;lt. Damit wird die Fu&szlig;zeile um eine Zeile nach unten verdr&auml;ngt.<\/p>\n<p>Danach f&uuml;gen wir die Zeile mit der Sprungmarke ein, was wiederum die beiden letzten Zeilen nach hinten verschiebt.<\/p>\n<p>Schlie&szlig;lich folgt noch die Anweisung <b>Exit Sub<\/b>\/<b>Exit Function<\/b>\/<b>Exit Property<\/b>, damit die Prozedur bei regul&auml;ren Verlauf vor Erreichen der Fehlerbehandlung verlassen wird.<\/p>\n<p>Auf diese Weise k&ouml;nnen wir einer Prozedur in einem Modul die gew&uuml;nschte Fehlerbehandlung hinzuf&uuml;gen.<\/p>\n<h2>Fehlerbehandlungen zu allen Prozeduren eines Moduls hinzuf&uuml;gen<\/h2>\n<p>Mit der Prozedur <b>AddErrorHandlersToModule<\/b>, die den Namen des Moduls als Parameter erwartet, rufen wir die Prozedur <b>AddErrorHandler <\/b>f&uuml;r jede Prozedur des angegebenen Moduls auf (siehe Listing 3).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>AddErrorHandlersToModule(strModule<span style=\"color:blue;\"> As String<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>objVBProject<span style=\"color:blue;\"> As <\/span>VBIDE.VBProject\r\n     <span style=\"color:blue;\">Dim <\/span>objVBComponent<span style=\"color:blue;\"> As <\/span>VBIDE.VBComponent\r\n     <span style=\"color:blue;\">Dim <\/span>objCodemodule<span style=\"color:blue;\"> As <\/span>VBIDE.CodeModule\r\n     <span style=\"color:blue;\">Dim <\/span>intProcType<span style=\"color:blue;\"> As <\/span>vbext_ProcKind\r\n     <span style=\"color:blue;\">Dim <\/span>lngCountOfLines<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngLine<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strProcedure<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> objVBProject = VBE.ActiveVBProject\r\n     <span style=\"color:blue;\">Set<\/span> objVBComponent = objVBProject.VBComponents(strModule)\r\n     <span style=\"color:blue;\">Set<\/span> objCodemodule = objVBComponent.CodeModule\r\n     lngCountOfLines = objCodemodule.CountOfLines\r\n     For lngLine = 1 To lngCountOfLines\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> strProcedure = objCodemodule.ProcOfLine(lngLine, intProcType)<span style=\"color:blue;\"> Then<\/span>\r\n             strProcedure = objCodemodule.ProcOfLine(lngLine, intProcType)\r\n             <span style=\"color:blue;\">Call<\/span> AddErrorHandler(strModule, strProcedure)\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> lngLine\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Prozedur zum Hinzuf&uuml;gen von Fehlerbehandlungen zu allen Prozeduren eines Moduls<\/span><\/b><\/p>\n<p>Die Prozedur ermittelt Verweise auf das aktuelle VBA-Projekt und das betroffenen <b>CodeModule<\/b>-Objekt und ermittelt f&uuml;r die Variable <b>lngCountOfLines <\/b>die Anzahl der Zeilen des Moduls. Dann durchl&auml;uft sie alle Zeilen in einer <b>For&#8230;Next<\/b>-Schleife und pr&uuml;ft bei jedem Durchlauf, ob der Name der aktuellen Prozedur, die mit <b>ProcOfLine <\/b>ermittelt wird, mit der aktuell in der Variablen <b>strProcedure <\/b>gespeicherten Prozedur &uuml;bereinstimmt. Falls nicht, wurde soeben die n&auml;chste Prozedur entdeckt und wir k&ouml;nnen <b>AddErrorHandler <\/b>f&uuml;r diese Prozedur aufrufen.<\/p>\n<p>Danach durchsucht die Prozedur die weiteren Zeilen und stattet die folgenden Prozeduren mit Fehlerbehandlungen aus &#8211; bis die letzte Zeile des Moduls erreicht wurde.<\/p>\n<h2>Alle Module mit Fehlerbehandlungen ausstatten<\/h2>\n<p>Und auch f&uuml;r das Ausstatten aller Prozeduren aller Module haben wir eine Prozedur vorgesehen. Diese durchl&auml;uft lediglich &uuml;ber die Auflistung <b>VBComponents <\/b>des <b>VBProject<\/b>-Objekts alle Module und ruft f&uuml;r jedes einmal die Prozedur <b>AddErrorHandlersToModule<\/b> auf (siehe Listing 4).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>AddErrorHandlersToActiveVBProject()\r\n     <span style=\"color:blue;\">Dim <\/span>objVBProject<span style=\"color:blue;\"> As <\/span>VBIDE.VBProject\r\n     <span style=\"color:blue;\">Dim <\/span>objVBComponent<span style=\"color:blue;\"> As <\/span>VBIDE.VBComponent\r\n     <span style=\"color:blue;\">Set<\/span> objVBProject = VBE.ActiveVBProject\r\n     For Each objVBComponent In objVBProject.VBComponents\r\n         <span style=\"color:blue;\">Call<\/span> AddErrorHandlersToModule(objVBComponent.Name)\r\n     <span style=\"color:blue;\">Next<\/span> objVBComponent\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Prozedur zum Hinzuf&uuml;gen von Fehlerbehandlungen zu allen Prozeduren aller Module eines VBA-Projekts<\/span><\/b><\/p>\n<h2>Fehlerbehandlung wieder entfernen<\/h2>\n<p>Nat&uuml;rlich m&uuml;ssen wir auch hier eine Prozedur vorsehen, mit der wir die Fehlerbehandlung wieder entfernen. Diese hei&szlig;t <b>RemoveErrorHandler <\/b>und erwartet ebenfalls den Namen des Moduls und der zu bearbeitenden Prozedur als Parameter (siehe Listing 5).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>RemoveErrorHandler(strModule<span style=\"color:blue;\"> As String<\/span>, strProcedure<span style=\"color:blue;\"> As String<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>objVBProject<span style=\"color:blue;\"> As <\/span>VBIDE.VBProject\r\n     <span style=\"color:blue;\">Dim <\/span>objVBComponent<span style=\"color:blue;\"> As <\/span>VBIDE.VBComponent\r\n     <span style=\"color:blue;\">Dim <\/span>objCodeModule<span style=\"color:blue;\"> As <\/span>VBIDE.CodeModule\r\n     <span style=\"color:blue;\">Dim <\/span>lngCountOfLines<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intProcType<span style=\"color:blue;\"> As <\/span>vbext_ProcKind\r\n     <span style=\"color:blue;\">Dim <\/span>lngProcBodyLine<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngFirstStatementLineNumber<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngLastStatementLineNumber<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strProcType<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngLine<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strLine<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strProcbodyline<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> objVBProject = VBE.ActiveVBProject\r\n     <span style=\"color:blue;\">Set<\/span> objVBComponent = objVBProject.VBComponents(strModule)\r\n     <span style=\"color:blue;\">Set<\/span> objCodeModule = objVBComponent.CodeModule\r\n     lngCountOfLines = objCodeModule.CountOfLines\r\n     lngProcBodyLine = objCodeModule.ProcBodyLine(strProcedure, intProcType)\r\n     lngFirstStatementLineNumber = GetFirstStatementLineNumber(objCodeModule, lngProcBodyLine)\r\n     lngLastStatementLineNumber = GetLastStatementLineNumber(objCodeModule, lngProcBodyLine)\r\n     strProcbodyline = GetProcBodyLine(objCodeModule, lngProcBodyLine)\r\n     strProcType = GetProcType(strProcedure, strProcbodyline)\r\n     For lngLine = lngFirstStatementLineNumber To lngLastStatementLineNumber\r\n         strLine = <span style=\"color:blue;\">Trim<\/span>(objCodeModule.Lines(lngLine, 1))\r\n         Select Case <span style=\"color:blue;\">True<\/span>\r\n             <span style=\"color:blue;\">Case <\/span>strLine = \"On Error Goto Errorhandling\", strLine = \"\"\r\n                 objCodeModule.DeleteLines lngLine\r\n                 lngLine = lngLine - 1\r\n             <span style=\"color:blue;\">Case <\/span>strLine = \"Exit \" & strProcType & \" ''Errorhandling\", strLine = \"\"\r\n                 objCodeModule.DeleteLines lngLine\r\n                 lngLine = lngLine - 1\r\n             <span style=\"color:blue;\">Case <\/span>strLine = \"Errorhandling:\", strLine = \"\"\r\n                 objCodeModule.DeleteLines lngLine\r\n                 lngLine = lngLine - 1\r\n             <span style=\"color:blue;\">Case <\/span>left(strLine, 17) = \"<span style=\"color:blue;\">Call<\/span> HandleError(\", strLine = \"\"\r\n                 objCodeModule.DeleteLines lngLine\r\n                 lngLine = lngLine - 1\r\n         <span style=\"color:blue;\">End Select<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> lngLine\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Prozedur zum Entfernen von Fehlerbehandlungen aus einer Prozedur<\/span><\/b><\/p>\n<p>Sie referenziert das aktuelle VBA-Projekt und holt sich einen Verweis auf das <b>CodeModule<\/b>-Objekt mit dem zu bearbeitenden Code. Dann ermittelt sie die Gesamtzahl der Zeilen des Moduls und die Startzeile der zu bearbeitenden Prozedur. Au&szlig;erdem ben&ouml;tigen wir die erste und die letzte Zeile innerhalb der Prozedur, also nach der Kopfzeile und vor der Fu&szlig;zeile. Damit ausgestattet holen wir uns noch die Kopfzeile und ermitteln mit der Funktion <b>strProcType <\/b>den Typ der Prozedur.<\/p>\n<p>Nun durchlaufen wir in einer <b>For&#8230;Next<\/b>-Schleife alle Zeilen innerhalb der Prozedur und f&uuml;gen jeweils die aktuelle Zeile in die Variable <b>strLine <\/b>ein. In einer <b>Select Case<\/b>-Anweisung pr&uuml;fen wir im ersten <b>Case<\/b>-Zweig, ob diese Zeile <b>On Error Goto Errorhandling <\/b>lautet. Ist das der Fall, l&ouml;schen wir die Zeile mit der <b>Delete<\/b>-Methode und setzen die Z&auml;hlervariable f&uuml;r die aktuelle Zeile wieder um 1 zur&uuml;ck, denn durch das L&ouml;schen ist die n&auml;chste Zeile ja nun zur aktuellen Zeile geworden, die wir als n&auml;chstes untersuchen wollen.<\/p>\n<p>Der n&auml;chste <b>Case<\/b>-Zweig untersucht, ob die Zeile den Text <b>Exit <\/b>plus Prozedurtyp enth&auml;lt, also <b>Sub<\/b>, <b>Function <\/b>oder <b>Property<\/b>. Auch in diesem Fall soll die Zeile entfernt werden und wir setzen <b>lngLine <\/b>um <b>1 <\/b>zur&uuml;ck.<\/p>\n<p>Auch die Zeile <b>Errorhandling: <\/b>soll auf diese Weise entfernt werden. Eine leicht abgewandelte <b>Case<\/b>-Bedingung verwenden wir nur f&uuml;r die Zeile, welche die Prozedur <b>HandleError <\/b>aufruft &#8211; hier untersuchen wir nur die ersten 17 Zeichen, da wir danach je nach Modul und Prozedur unterschiedliche Texte vorfinden werden.<\/p>\n<p>Auf diese Weise entfernen wir die vier hinzugef&uuml;gten Zeilen recht zuverl&auml;ssig. Aber was bedeutet &#8222;recht zuverl&auml;ssig&#8220; in diesem Zusammenhang? Die meisten Zeilen k&ouml;nnen wir genau ermitteln. Es ist nicht davon auszugehen, dass Zeilen namens <b>Errorhandling:<\/b>, <b>On Error Goto ErrorHandling <\/b>oder beginnend mit <b>Call Handle Error(<\/b> anders als durch unsere Prozedur zum Hinzuf&uuml;gen der Fehlerbehandlung in die Prozedur gelangt sind.<\/p>\n<p>Anders sieht es bei der Zeile <b>Exit Sub<\/b>\/<b>Function<\/b>\/<b>Property <\/b>aus. Diese kann durchaus auch in einem anderen Kontext bereits in der Prozedur vorkommen. Unsere aktuelle Version w&uuml;rde jedoch nun alle Vorkommen dieser Anweisung l&ouml;schen und damit den Code unter Umst&auml;nden fehlerhaft machen.<\/p>\n<p>Also m&uuml;ssen wir uns &uuml;berlegen, wie wir sicherstellen, dass nur die von uns hinzugef&uuml;gte <b>Exit&#8230;<\/b>-Zeile gel&ouml;scht wird. Dazu gibt es folgende M&ouml;glichkeiten:<\/p>\n<ul>\n<li>Wir pr&uuml;fen, ob die n&auml;chste Zeile die Sprungmarke Errorhandling: enth&auml;lt.<\/li>\n<li>Oder wir h&auml;ngen beim Anlegen einen Kommentar an die Zeile an, auf den wir dann pr&uuml;fen.<\/li>\n<\/ul>\n<p>Dazu passen wir die letzte Zeile der Prozedur <b>AddErrorHandler <\/b>wie folgt an:<\/p>\n<pre>bjCodemodule.InsertLines lngLastStatementLineNumber + 1, _\r\n     \"    Exit \" & strProcType & \" ''Errorhandling\"<\/pre>\n<p>In der Prozedur <b>RemoveErrorHandler <\/b>passen wir die entsprechende <b>Case<\/b>-Bedingung so an:<\/p>\n<pre><span style=\"color:blue;\">Case <\/span><span style=\"color:blue;\">Trim<\/span>(strLine) = \"Exit \" & strProcType _\r\n     & \" ''Errorhandling\", <span style=\"color:blue;\">Trim<\/span>(strLine) = \"\"<\/pre>\n<h2>Alle Errorhandler eines Moduls entfernen<\/h2>\n<p>Schlie&szlig;lich wollen wir noch die M&ouml;glichkeit bieten, wenn man alle Prozeduren eines Moduls mit Fehlerbehandlungen versehen hat, diese auch wieder zu entfernen. Das erledigen wir mit der Prozedur aus Listing 6, die genauso aufgebaut ist wie die Prozedur <b>AddErrorHandlersToModule<\/b>.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>RemoveErrorHandlersFromModule(strModule<span style=\"color:blue;\"> As String<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>objVBProject<span style=\"color:blue;\"> As <\/span>VBIDE.VBProject\r\n     <span style=\"color:blue;\">Dim <\/span>objVBComponent<span style=\"color:blue;\"> As <\/span>VBIDE.VBComponent\r\n     <span style=\"color:blue;\">Dim <\/span>objCodemodule<span style=\"color:blue;\"> As <\/span>VBIDE.CodeModule\r\n     <span style=\"color:blue;\">Dim <\/span>intProcType<span style=\"color:blue;\"> As <\/span>vbext_ProcKind\r\n     <span style=\"color:blue;\">Dim <\/span>lngCountOfLines<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngLine<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strProcedure<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> objVBProject = VBE.ActiveVBProject\r\n     <span style=\"color:blue;\">Set<\/span> objVBComponent = objVBProject.VBComponents(strModule)\r\n     <span style=\"color:blue;\">Set<\/span> objCodemodule = objVBComponent.CodeModule\r\n     lngCountOfLines = objCodemodule.CountOfLines\r\n     For lngLine = 1 To lngCountOfLines\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> strProcedure = objCodemodule.ProcOfLine(lngLine, intProcType)<span style=\"color:blue;\"> Then<\/span>\r\n             strProcedure = objCodemodule.ProcOfLine(lngLine, intProcType)\r\n             <span style=\"color:blue;\">Call<\/span> RemoveErrorHandler(strModule, strProcedure)\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> lngLine\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Prozedur zum Entfernen von Fehlerbehandlungen aus allen Prozeduren eines Moduls<\/span><\/b><\/p>\n<h2>Alle Errorhandler des VBA-Projekts entfernen<\/h2>\n<p>Und zu guter Letzt noch eine Prozedur, mit der wir die zuvor genannte Prozedur f&uuml;r jedes Modul des aktuellen VBA-Projekts aufrufen. Diese ist ebenfalls genauso aufgebaut wie die Prozedur <b>AddErrorHandlersToActiveVBProject<\/b> (siehe Listing 7).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>RemoveErrorHandlersFromActiveVBProject()\r\n     <span style=\"color:blue;\">Dim <\/span>objVBProject<span style=\"color:blue;\"> As <\/span>VBIDE.VBProject\r\n     <span style=\"color:blue;\">Dim <\/span>objVBComponent<span style=\"color:blue;\"> As <\/span>VBIDE.VBComponent\r\n     <span style=\"color:blue;\">Set<\/span> objVBProject = VBE.ActiveVBProject\r\n     For Each objVBComponent In objVBProject.VBComponents\r\n         <span style=\"color:blue;\">Call<\/span> RemoveErrorHandlersFromModule(objVBComponent.Name)\r\n     <span style=\"color:blue;\">Next<\/span> objVBComponent\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 7: Prozedur zum Entfernen von Fehlerbehandlungen aus allen Prozeduren aller Module eines VBA-Projekts<\/span><\/b><\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Damit haben wir Routinen, um Fehlerbehandlungen zu Prozeduren, Modulen oder vollst&auml;ndigen VBA-Projekten hinzuf&uuml;gen k&ouml;nnen. Im Beitrag <b>Zeilennummern per VBA hinzuf&uuml;gen <\/b>(<b>www.access-im-unternehmen.de\/1515<\/b>) zeigen wir, wie man die ben&ouml;tigten Zeilennummer ebenfalls automatisiert hinzuf&uuml;gen und wieder entfernen kann. Schlie&szlig;lich verwenden wir beide L&ouml;sungen, um Fehler unter anderem in Runtime-Anwendungen zu finden, wie in <b>Finden von Fehlern in der Access Runtime<\/b> (<b>www.access-im-unternehmen.de\/1513<\/b>) beschrieben.<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>FehlerbehandlungPerVBAHinzufuegen.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/467541E8-4E78-4D33-8393-C4B69B45492A\/aiu_1514.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Eine Fehlerbehandlung ist Teil einer professionellen Datenbankanwendung auf Basis von Microsoft Access. Sobald wir eine Datenbank an einen Kunden oder Mitarbeiter weitergeben, also an einen anderen Benutzer als uns selbst, ist dies praktisch ein Pflichtprogramm. Die Fehlerbehandlung soll den Benutzer &uuml;ber einen Fehler informieren und diesem die M&ouml;glichkeit geben, dem Entwickler Informationen &uuml;ber den Fehler zukommem zu lassen. In diesem Beitrag wollen wir die Hauptarbeit bei der Implementierung einer Fehlerbehandlung erledigen. Dazu wollen wir eine Prozedur schreiben, die beliebige Routinen, also Sub-, Function- und Property-Prozeduren, mit einer einfachen Fehlerbehandlung ausstattet &#8211; und &uuml;berdies noch mit einer Zeilennummerierung. Diese ist wichtig, wenn wir schnell herausfinden wollen, an welcher Stelle ein Fehler aufgetreten ist. Zusammen mit dem Namen des Moduls, dem Namen der Prozedur, der Fehlernummer und der Fehlerbeschreibung erhalten wir so Informationen, die in der Regel zum Aufdecken des Fehlers f&uuml;hren.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662024,66052024,44000025],"tags":[],"class_list":["post-55001514","post","type-post","status-publish","format-standard","hentry","category-662024","category-66052024","category-VBA_und_Programmiertechniken"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Fehlerbehandlung per VBA hinzuf&uuml;gen - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Fehlerbehandlung per VBA hinzuf&uuml;gen\" \/>\n<meta property=\"og:description\" content=\"Eine Fehlerbehandlung ist Teil einer professionellen Datenbankanwendung auf Basis von Microsoft Access. Sobald wir eine Datenbank an einen Kunden oder Mitarbeiter weitergeben, also an einen anderen Benutzer als uns selbst, ist dies praktisch ein Pflichtprogramm. Die Fehlerbehandlung soll den Benutzer &uuml;ber einen Fehler informieren und diesem die M&ouml;glichkeit geben, dem Entwickler Informationen &uuml;ber den Fehler zukommem zu lassen. In diesem Beitrag wollen wir die Hauptarbeit bei der Implementierung einer Fehlerbehandlung erledigen. Dazu wollen wir eine Prozedur schreiben, die beliebige Routinen, also Sub-, Function- und Property-Prozeduren, mit einer einfachen Fehlerbehandlung ausstattet - und &uuml;berdies noch mit einer Zeilennummerierung. Diese ist wichtig, wenn wir schnell herausfinden wollen, an welcher Stelle ein Fehler aufgetreten ist. Zusammen mit dem Namen des Moduls, dem Namen der Prozedur, der Fehlernummer und der Fehlerbeschreibung erhalten wir so Informationen, die in der Regel zum Aufdecken des Fehlers f&uuml;hren.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2024-08-27T09:24:58+00:00\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"17\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlerbehandlung_per_VBA_hinzufuegen\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlerbehandlung_per_VBA_hinzufuegen\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Fehlerbehandlung per VBA hinzuf&uuml;gen\",\"datePublished\":\"2024-08-27T09:24:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlerbehandlung_per_VBA_hinzufuegen\\\/\"},\"wordCount\":2733,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlerbehandlung_per_VBA_hinzufuegen\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg02.met.vgwort.de\\\/na\\\/92052a09a2054d54922a3ad4fdb7de70\",\"articleSection\":[\"2024\",\"5\\\/2024\",\"VBA und Programmiertechniken\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlerbehandlung_per_VBA_hinzufuegen\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlerbehandlung_per_VBA_hinzufuegen\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlerbehandlung_per_VBA_hinzufuegen\\\/\",\"name\":\"Fehlerbehandlung per VBA hinzuf&uuml;gen - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlerbehandlung_per_VBA_hinzufuegen\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlerbehandlung_per_VBA_hinzufuegen\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg02.met.vgwort.de\\\/na\\\/92052a09a2054d54922a3ad4fdb7de70\",\"datePublished\":\"2024-08-27T09:24:58+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlerbehandlung_per_VBA_hinzufuegen\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlerbehandlung_per_VBA_hinzufuegen\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlerbehandlung_per_VBA_hinzufuegen\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg02.met.vgwort.de\\\/na\\\/92052a09a2054d54922a3ad4fdb7de70\",\"contentUrl\":\"http:\\\/\\\/vg02.met.vgwort.de\\\/na\\\/92052a09a2054d54922a3ad4fdb7de70\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Fehlerbehandlung_per_VBA_hinzufuegen\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Fehlerbehandlung per VBA hinzuf&uuml;gen\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Fehlerbehandlung per VBA hinzuf&uuml;gen - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/","og_locale":"de_DE","og_type":"article","og_title":"Fehlerbehandlung per VBA hinzuf&uuml;gen","og_description":"Eine Fehlerbehandlung ist Teil einer professionellen Datenbankanwendung auf Basis von Microsoft Access. Sobald wir eine Datenbank an einen Kunden oder Mitarbeiter weitergeben, also an einen anderen Benutzer als uns selbst, ist dies praktisch ein Pflichtprogramm. Die Fehlerbehandlung soll den Benutzer &uuml;ber einen Fehler informieren und diesem die M&ouml;glichkeit geben, dem Entwickler Informationen &uuml;ber den Fehler zukommem zu lassen. In diesem Beitrag wollen wir die Hauptarbeit bei der Implementierung einer Fehlerbehandlung erledigen. Dazu wollen wir eine Prozedur schreiben, die beliebige Routinen, also Sub-, Function- und Property-Prozeduren, mit einer einfachen Fehlerbehandlung ausstattet - und &uuml;berdies noch mit einer Zeilennummerierung. Diese ist wichtig, wenn wir schnell herausfinden wollen, an welcher Stelle ein Fehler aufgetreten ist. Zusammen mit dem Namen des Moduls, dem Namen der Prozedur, der Fehlernummer und der Fehlerbeschreibung erhalten wir so Informationen, die in der Regel zum Aufdecken des Fehlers f&uuml;hren.","og_url":"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/","og_site_name":"Access im Unternehmen","article_published_time":"2024-08-27T09:24:58+00:00","author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"17\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Fehlerbehandlung per VBA hinzuf&uuml;gen","datePublished":"2024-08-27T09:24:58+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/"},"wordCount":2733,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/#primaryimage"},"thumbnailUrl":"http:\/\/vg02.met.vgwort.de\/na\/92052a09a2054d54922a3ad4fdb7de70","articleSection":["2024","5\/2024","VBA und Programmiertechniken"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/","url":"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/","name":"Fehlerbehandlung per VBA hinzuf&uuml;gen - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/#primaryimage"},"thumbnailUrl":"http:\/\/vg02.met.vgwort.de\/na\/92052a09a2054d54922a3ad4fdb7de70","datePublished":"2024-08-27T09:24:58+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/#primaryimage","url":"http:\/\/vg02.met.vgwort.de\/na\/92052a09a2054d54922a3ad4fdb7de70","contentUrl":"http:\/\/vg02.met.vgwort.de\/na\/92052a09a2054d54922a3ad4fdb7de70"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Fehlerbehandlung_per_VBA_hinzufuegen\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Fehlerbehandlung per VBA hinzuf&uuml;gen"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001514","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55001514"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001514\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001514"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001514"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001514"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}