Hallo,
Private Sub blah()
On Error GoTo Fehler
....
Fehler:
Fehlermeldung Err.Number, Err.Description
Resume Next
End Sub
Private Sub Fehlermeldung(FCode, FText As String)
MsgBox "Ein Fehler mit dem Code " & FCode & " wurde festgestellt" & vbCrLf _
& "Die Beschreibung dazu lautet: " & FText
End Sub
Wann verliert der Errorhandler die Zeile, welche einen Fehler auslöste? Sobald ich Err.Clear aufrufe?
Oder wenn ich durch mehrere Prozeduren springe?
Gruß
Doming
Hallo,
der Handler kann nur in der Prozedur, in der er ist, den Fehler behandeln.
Wenn es keinen gibt, ist die aufrufende Zeile in der übergeordneten Prozedur der Fehlerauslöser dort, auch wenn der Fehler innerhalb der aufrufenden Prozedur stattfand. Wenn es dort einen Fehlerhandler gibt, wird dieser angesprungen. Wenn nicht, den nächst höheren Aufrufer, und wenn es keinen mehr gibt, springt der Access-Debugger an.
Err.Clear hebt natürlich jeden Fehler auf.
Resume in allen Varianten auch.
Eine Fehlerzeile kann nur verwendet werden, wenn man auch Zeilennummern verwendet, das sollte man aber heutzutage nicht mehr machen, ist auch völlig unnötig.
Ich mache das so, daß ich Errorhandler immer mit MZTools einfüge, was den Vorgang stark vereinfacht.
Dazu hänge ich an den Errorhandler unten nach der letzten Zeile eine Zeile "Resume" an. Diese wird also nie ausgeführt.
Wenn ich den Fehler untersuchen will und im Fehlerhandler stoppe, kann ich dann den Programmzähler auf "Resume" springen lassen und diesen ausführen, dann springt er mir auf genau die Zeile, die den Fehler verursacht hat - ganz ohne Zeilennummern.
Gruß
Christian
Hallo,
im Prinzip stimmt das schon, was Christian da mit den Errorhandlern beschrieben hat, nur
Zitat von: Bitsqueezer am Juli 14, 2025, 13:52:35Err.Clear hebt natürlich jeden Fehler auf.
Err.Clear löscht
nur das Error-Objekt, setzt aber nicht den Errorhandler zurück! Err.Clear wird implizit auch bei
- Allen Arten von Resume-Anweisungen
- Exit Sub, Exit Function, Exit Property
- Einer On Error -Anweisung
aufgerufen.
Hier mal ein paar weiter führende Links:
https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-basic-6/aa716196(v=vs.60) (https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-basic-6/aa716196(v=vs.60))
http://www.cpearson.com/excel/errorhandling.htm (http://www.cpearson.com/excel/errorhandling.htm)
https://stackoverflow.com/questions/14158901/difference-between-on-error-goto-0-and-on-error-goto-1-vba (https://stackoverflow.com/questions/14158901/difference-between-on-error-goto-0-and-on-error-goto-1-vba)
Gruß Knobbi38
Danke für die Ausführungen.
Mein aktuelles Problem ist folgendes: Offenbar ist letzte Nacht kein Datenexport aus SAP erfolgt, eine von mir genutzte Nachschlagetabelle funktioniert also nicht. Ein gute Gelegenheit, eine Ausnahme im Errorhandler einzubauen.
Public Function TabelleOK(Tabelle As String) As Boolean
On Error GoTo Fehler
Dim Menge
Menge = DCount("*", Tabelle)
TabelleOK = True
Ende:
Err.Clear
Exit Function
Fehler:
Resume Ende
End Function
Mit dieser Funktion setze ich eine lokale Variable
On Error Goto Fehler
BooltblOK = TabelleOK("tblSAPDaten")
If BooltblOK then
Eingabe "Importiere Daten aus SAP"
SAPLesen
Else
Eingabe "Tabelle tblSAPDaten ist nicht lesbar"
End if
...
Exit Sub
Fehler:
Eingabe "Fehler (" & Err.Number & ") Prozedur Ablauf:" & Err.Description
Resume Next
End Sub
'Eingabe' gibt dem Nutzer die aktuelle Aktion aus
Public Sub Eingabe(Txt As String)
Debug.Print Err.Number
CurrentDb.Execute "INSERT INTO tbl_WartungsProtokoll(Zeit, Tat) VALUES (" _
& fncTimSQL(Now) & ", '" _
& Txt & "')"
Das hat jetzt folgenden Effekt:
tblSAPDaten ist nicht vorhanden, also booltblOK ist False und die Meldung "nicht lesbar" wird ausgegeben.
Dann wird erneute eine Eingabe generiert, mit dem Fehler 3075 Tabelle nicht vorhanden, obwohl mit Err.Number vorher mit 0 angezeigt wird. Eigentlich war der Fehler doch schon abgefrühstückt?
Hallo,
mehrere Errorhandler machen eine Sache nicht sicherer! Wenn du Errorhandler in TabelleOK() und SAPLesen() hast, was ja richtig ist, dann kannst du dir in der aufrufenden Sub den Errorhandler sparen, weil dort eigentlich der Rückgabewert ausgewertet werden sollte. Die Variable "BooltblOK" ist deshalb auch nicht notwendig.
Der Programmablauf sollte also nochmal etwas überarbeitet werden, SAPLesen() einen Rückgabewert liefern und den Errorhandler in der übergeordneten Sub entfernen. Du kannst dir den PAP ja mal als Nassi-Shneiderman Diagramm auf Papier kurz skizzieren, oft hilft das.
Gruß Knobbi38
PS:
Was genau möchtest du eigentlich mit TabelleOK() überprüfen?
Zitat von: Doming am Juli 14, 2025, 15:05:24tblSAPDaten ist nicht vorhanden, also booltblOK ist False und die Meldung "nicht lesbar" wird ausgegeben.
Dann wird erneute eine Eingabe generiert, mit dem Fehler 3075 Tabelle nicht vorhanden, obwohl mit Err.Number vorher mit 0 angezeigt wird.
Dann schau dir mal genau an was in deinem hier nicht gezeigtem Code-Segment "..." passiert. M.M. muss dort erneut auf die nicht vorhandene SAP-Tabelle zugegriffen werden und dabei wird der neue Fehler ausgelöst.
Die lokale, boolsche Variable setze ich, weil ich im Nachgang noch mehrere Datensätze aus der Tabelle nutzen möchte, dazu muss nicht jedes Mal erneut das DCount losgeschickt werden.
Das ganze Resume Next ist mir eigentlich zuwider, aber der ganze Rotz soll im Hintergrund ablaufen. Wenn Fehler auftreten sollen sie ins Protokoll, ansonsten möchte ich da keine Unterbrechungen bei den Anwendern.
Morgen kann ich wieder weiter rumprobieren...
Zitat von: Doming am Juli 14, 2025, 21:06:18Das ganze Resume Next ist mir eigentlich zuwider, aber der ganze Rotz soll im Hintergrund ablaufen. Wenn Fehler auftreten sollen sie ins Protokoll, ansonsten möchte ich da keine Unterbrechungen bei den Anwendern.
Ich zweifle ob auch dafür dein Ansatz mit Resume Next so geeignet ist.
Wenn in einem mehrstufigen Ablauf Fehler auftreten, erscheint es fragwürdig, ob es Sinn macht den Prozess fortzusetzen, wenn bereits Fehler aufgetreten sind.
Zitat von: Doming am Juli 14, 2025, 21:06:18Die lokale, boolsche Variable setze ich, weil ich im Nachgang noch mehrere Datensätze aus der Tabelle nutzen möchte, dazu muss nicht jedes Mal erneut das DCount losgeschickt werden.
Wieso sollte man mehrmals DCount() aufrufen müssen? Alles gehört in einen IF THEN ELSE Zweig:
IF TabelleOK() then
' Todo:
ELSE
' Error:
END IF
Vielleicht kannst du mal deinen ganzen Code hier zeigen, sonst wird eine Hilfe schwierig.
Knobbi38
Hallo,
um die Geschichte mal etwas aufzuklären:
Ich habe hier ein paar alte Datenbanken, deren Daten aufeinander aufbauen. Der damalige Autor hat sich nicht unbedingt an die Normalisierung gehalten, d.h. er hat je nach Nutzung diverse Tabellen, die parallele Daten enthalten.
Wenn der Nutzer "sein" Formular startet, werden Abfragen gestartet die dann die gewünschten Daten aufbereitet und in eine neue Tabelle schreibt.
Ich versuche, bei einer nachgeschalteten Datenbank die Abläufe umzubauen. Leider kann ich das nur, wenn die vorherigen DB die richtigen Daten liefern. Also habe ich das, was die diversen Nutzer beim Starten ihrer Formulare bewirken, in eine SchattenDb ausgelagert. Diese DB wiederum wird immer von demjenigen gestartet, der am Tag als Erster mit den Daten zu tun hat. So kommen am Ende die Tabellen raus, die ich bei meinem eigentlichen Projekt brauche.
Deswegen auch die Tabelle mit den aktuellen Nutzern im Parallelthread (https://www.access-o-mania.de/forum/index.php?topic=28065.0) damit die SchattenDB nicht mehrmals gestartet wird und sich bei Nichtgebrauch wieder abschaltet.
Natürlich wäre es am besten, wenn man den ganzen DB-Wald mal komplett durchforstet und neu aufsetzt, um die gewachsenen Strukturen zu durchbrechen, aber solange die alten Dinge ,,irgendwie" laufen, nimmt keiner Geld in die Hand, um etwas neu zu bauen. Ich bin ja froh, dass man mich machen lässt, auch wenn ich keiner IT-Abteilung angehöre.
Achja, worum es mir bei der lokalen BoolVariable ging: Ich nehme immer mehr Zwischenaktionen in die SchattenDB auf, die dann auch auf die SAP-Daten zugreifen. Das kann dann auch mal im Ablauf etwas später sein. Wenn ich später dazu komme, kann ich den Ablauf auch nochmal durcharbeiten und optimieren. Erstmal soll es laufen, also die Pflicht vor der Kür ;-)
Gruß
Doming
Hallo Doming,
Zitat von: Doming am Juli 16, 2025, 08:50:25Achja, worum es mir bei der lokalen BoolVariable ging: Ich nehme immer mehr Zwischenaktionen in die SchattenDB auf, die dann auch auf die SAP-Daten zugreifen. Das kann dann auch mal im Ablauf etwas später sein. Wenn ich später dazu komme, kann ich den Ablauf auch nochmal durcharbeiten und optimieren.
ich weiß nicht, ob das die richtige Vorgehensweise ist, denn eine einfache Variable ist nicht persistent und um den Fortschritt der Verarbeitung zu speichern, sollte diese persistent festgehalten werden, damit ein "Restart" jederzeit möglich ist.
Gruß Knobbi38