2009-04-10 9 views
8

Ich habe einige Code mit verschiedenen "On Error Goto" -Fehlerhandler an einigen Stellen, um einige defekte Hardware von Drittanbietern zu behandeln. Ich bekam einen Überlauffehler (gelesen von der Err-Variable) in einer Routine, die keine Fehlerfalle hat, aber von einer Routine aufgerufen wird, die tut. Ich dachte immer, dass Fehler-Traps nur in der Routine gültig waren, für die sie deklariert wurden, aber es sieht so aus, als ob ein Fehler in einer Subroutine dazu führen kann, dass sie zur Fehler-Trap der aufrufenden Funktion geht.Wie die Standardfehlerbehandlung in VB6 wieder aktiviert wird

Also habe ich die Fehlermeldung der aufrufenden Funktion ausgeschaltet und meinen Überlauf gefunden und alles ist gut. Aber bevor ich das tat, habe ich einige Zeit damit verbracht, einen programmatischen Weg zu finden, um VB dazu zu bringen, zu seiner Standardfehlerbehandlung innerhalb dieser Routine zurückzukehren (also würde ich keinen externen Code zum Debuggen ändern müssen), aber ich konnte nicht. Die einzigen Fehler Befehle, die ich finden konnte:

 On Error GoTo [label] 
    On Error Resume Next 
    On Error Goto 0 
    On Error GoTo -1

alle schalten Sie die manuelle Fehlerbehandlung - ist es eine Möglichkeit, um es auszuschalten (zurück zum VB6 Standard)?

Antwort

10

Dies wird ausführlich im VB6-Handbuch unter Error Handling Hierarchy erläutert. On Error Goto 0 deaktiviert den Fehlerhandler in der aktuellen Prozedur, nicht in den Prozeduren, die ihn aufgerufen haben.

Wenn ein Fehler in einer Prozedur auftritt und dieses Verfahren nicht über eine aktivierten Fehlerbehandlung, durchsucht Visual Basic rückwärts durch die anhängigen Verfahren in der Liste Anrufe - und führt die erste aktiviert Fehlerbehandlung es findet. Wenn kein Fehler Handler überall in der Anrufliste auftritt, zeigt einen Standard unerwarteten Fehler Nachricht und beendet die Ausführung.

Wie schon andere gesagt haben, können Sie auf gehen Extras-Einstellungen-Allgemein Registerkarte und wählen bei allen Fehlern. Dadurch werden alle Ihre On Error-Anweisungen wirksam deaktiviert - die IDE bricht sofort bei jedem Fehler ab.

Das kann irritierend sein, wenn Ihr VB6-Code Fehler als Teil des normalen Betriebs auslöst. Zum Beispiel, wenn Sie prüfen, ob eine Datei existiert oder wenn der Benutzer in einem allgemeinen Dialog auf Abbrechen klickt. Sie möchten nicht, dass die IDE jedes Mal in diesen Zeilen bricht. Sie können jedoch in allen Prozeduren für die Ereignisbehandlung Fehlercodes enthalten, um das Programm wegen unerwarteter Fehler abzustürzen. Aber sie sind ein Ärgernis, wenn Sie Probleme debuggen, da die IDE mit dem Fehler nicht in der Zeile bricht. Ein Trick besteht darin, diese Fehlerbehandlungsroutinen beim Ausführen in der IDE auszuschalten, sie jedoch in der ausführbaren Datei zu speichern. Du machst es so.

Diese Funktionen in ein Modul einfügen.

Public Function InIDE() As Boolean 
    Debug.Assert Not TestIDE(InIDE) 
End Function 

Private Function TestIDE(Test As Boolean) As Boolean 
    Test = True 
End Function 

Dann können Sie Ihre Fehlerhandler wie folgt schreiben.

Private Sub Form_Load() 
    If Not InIDE() Then On Error Goto PreventCrashes 
    <lots of code> 
    Exit Sub 

PreventCrashes: 
    <report the error> 
End Sub 

eingeklemmt von here. Noch ein Tipp: Verwenden Sie das kostenlose Add-In MZTools, um diese Fehlerhandler automatisch hinzuzufügen.Für Code in Produktionsqualität könnten Sie weiter gehen und einen Fehlerhandler in jede Routine einfügen, um eine ghetto stack trace zu erstellen. Sie können die Fehler auch sofort in jedem Fehlerhandler protokollieren.

EDIT: Ant hat richtig darauf hingewiesen, dass On Error Goto -1 ist ein VB.Net statement und ist nicht gültig in VB6.

BEARBEITEN: Arvo und OneNerd haben Antworten mit einigen interessanten Diskussion über das Emulieren von Teardown Blocks in VB6 Fehlerbehandlung geschrieben. Die Diskussion in this question ist ebenfalls einen Blick wert.

0

/Tools/Optionen/Allgemein/Error

0
on error goto 0 

Die Handhabung sollte das sein, was Sie wollen ... Es sollte den Fehler der geworfen verursachen, und wiederum wahrscheinlich auf die RTL unwind ...

Es ist eine lange Zeit, aber ich bin mir ziemlich sicher, dass Sie das wollen.

on error resume next 

wird nur an die nächste Anweisung weiter, so dass Sie genügend

if err.Number <> 0 then 

Anweisungen in Ihrem Code haben müssen, wo Fehler auftreten können ...

+0

Nicht korrekt LarryF. On Error Goto 0 deaktiviert den Fehlerhandler in der Routine selbst, aber dann schaut die Laufzeit den Aufruf-Stack für jeden aktiven Fehlerbehandler zurück. Wenn es einen gibt, wird es den Fehler behandeln. – MarkJ

+0

Opps .. Mein schlechtes. Ich muss über vbScript nachgedacht haben, das sich wie beschrieben verhalten würde. Oder es zumindest gewohnt ist. (Ich weiß nicht, was die neueste Version ist, und wenn es kürzlich geändert wurde ..) – LarryF

1

Es ist ein handliches rechts- Klicken Sie auf das Menü, mit dem Sie die Fehlerbehandlung ein- und ausschalten können. Klicken Sie mit der rechten Maustaste auf ein Code-Fenster und wählen Sie Toggle, dann können Sie "Break on all errors" auswählen. Dies hat zur Folge, dass alle Ihre "On Error" -Anweisungen deaktiviert werden.

0

haben mit LarryF, On Error Goto 0 sollte deaktivieren explizite Fehlerbehandlung, die eingeschaltet wurde durch On Error Resume Next zustimmen. Funktionen und Subroutinen haben dafür jedoch ihren eigenen Geltungsbereich. Von Dr. Scripto at Microsoft: Resume Next am Anfang des Skripts

On Error Einlochen, wie wir oft tun, macht es auf den ganzen Körper anwenden des Skripts. Aber, wie wir später in sehen werden, enthält sein Bereich nicht Funktionen oder Subroutinen. Wenn Sie Fehler innerhalb einer Funktion oder Subroutine behandeln möchten, müssen Sie auch On Error Resume Next in jedem davon einschließen, bevor Sie das Err Objekt überprüfen.

können Sie drehen Fehlerbehandlung mit On Error off GoTo 0 So ist es möglich, wiederum Fehlerbehandlung auf mit On Error Resume Next, kurz bevor Sie das Err-Objekt zu überprüfen möchten, und deaktivieren danach mit On Error GoTo 0.Hier

+0

Ähm, aber Dr. Scripto spricht über VBScript, und die Frage ist über VB6 – MarkJ

1

ist, was ich tue:

Schalten Sie zunächst Fehler wie diese Handhabung bei Bedarf in Ihrem Sub Main() oder Sub Form_Load() Sub:

'-- turn on error handling 
' 
On Error GoTo 0 
' 
'------------------------- 

Jetzt Fehler werden aktiviert.

nächstes Verwenden Sie die On Error Resume Next und On Error GoTo {label} Befehle in Kombination mit dem Err Objekt. Hier ist ein Beispiel eines try/catch/finally emulieren:

Function MyFunction() as String 

'-- start of error block 
' 
On Error Goto Catch 
    ' do something here that might cause an error 
    MyFunction = "IT WORKED" 
    Goto Finally 

    Catch: 
    ' error occured - do something else 
    MyFunction = Err.Description 
    Err.Clear 

Finally: 
    ' put your finally code here 

' 
'-- end of error block 

End Function 
+0

+1 Sie benötigen möglicherweise auf Fehler Resume Next in der "Endlich" blockiert für den Fall, dass der Fehler das Setup von allem, was heruntergerissen wird, stört. Und ich verstehe nicht, warum Sie den On Error Goto 0 in Form_Load/Sub Main gesetzt haben? – MarkJ

0

Es gibt keinen "On Error GoTo -1" so habe ich keine Ahnung, wo man das bekam.

Die VB6-Ausnahmebehandlung wird im Handbuch sehr ausführlich behandelt.

+1

Ich denke, das ist eine VB.NET-Anweisung: http://msdn.microsoft.com/en-us/library/5hsw66as(VS.80).aspx – Ant

3

Es gibt eine klare und einfache Möglichkeit, den Fehlerstatus zurückzusetzen - verwenden Sie das Schlüsselwort Resume. Es gibt drei Möglichkeiten:

Resume 
Resume Next 
Resume <Label> 

Fortsetzen wird die Ausführung bei fehlerbehaftete Leitung, Resume Next bei der nächsten Zeile und am wenigsten gesprochen Resume-Etikett weiterhin mit Etikett. Sehr nützlich, um try-catch-finally-ähnliche Konstrukte in VB6 zu erstellen. Entlehnt und aus OneNerd Antwort geändert:

Function MyFunction() as String 

'-- start of error block 
' 
On Error Goto Catch 
    ' do something here that might cause an error 
    MyFunction = "IT WORKED" 
    Goto Finally 

    Catch: 
    ' error occured - do something else 
    MyFunction = Err.Description 
    Err.Clear 
    Resume Finally   ''added to clear error status 

Finally: 
    On Error Resume Next ''added to avoid repeated errors 
    ' put your finally code here 

' 
'-- end of error block 

End Function 

Einfache Err.Clear hilft nicht, wenn einige Fehler folge Schließlich blockieren tritt in; Resume Schließlich wird der interne Fehlerzustand zurückgesetzt.

+0

On Error Resume Next setzt auch internen Fehlerzustand, so Err.Clear und Resume Schließlich sind redundant. Persönlich denke Goto Endlich ist klarer. Am wichtigsten von allem, setzen Sie Err.Clear oder On Error Goto 0 kurz vor der End-Funktion, sonst geht ein Fehlerzustand von Finally-Block zurück zum Aufrufer !! – MarkJ

+0

On Error Resume Next selbst (nach einem Fehler) setzt den Fehlerstatus nicht zurück. Ich habe gerade getestet, um 100% sicher zu sein, wirklich. – Arvo

Verwandte Themen