Live-Forum - Die aktuellen Beiträge
Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender

Forumthread: Zwei Fehler nacheinander

Zwei Fehler nacheinander
07.04.2016 18:01:22
Klexy
Moin zusammen.
Ich habe einen On Error GoTo Hierhin und danach einen On Error GoTo Dahin.
Wenn nur einer von den beiden anschlägt, ist alles gut. Wenn aber beide anschlagen, geht es nicht weiter.
Die Beispieldatei ist auf das Kernproblem reduziert. Dort, wo jetzt die Meldungen kommen, ist im Original "normaler" Code.
Ich hab nirgends eine Lösung dafür gefunden. Auch online-excel.de hat mir nicht weitergeholfen. Wo liegt der Hase im Pfeffer?
https://www.herber.de/bbs/user/104830.xls

Anzeige

22
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Zwei Fehler nacheinander
07.04.2016 18:11:40
Hajo_Zi
vielleicht solltest Du nach dem ersten Fehler On Error Goto 0 machen?

AW: Zwei Fehler nacheinander
07.04.2016 18:19:42
Klexy
Wo genau?
Hab ich alles ausprobiert. Auch Resume. Aber es hat nix geholfen.

AW: Zwei Fehler nacheinander
07.04.2016 18:23:40
Hajo_Zi
bevor Du die zweite Fehlerroutinestartest.

Anzeige
AW: Zwei Fehler nacheinander
08.04.2016 14:54:28
Klexy
wie gesagt: wo genau? Vor welche Code-Zeile (genauer Wortlaut).
Ich habe alle Möglichkeiten probiert, aber es hat nix geholfen.

AW: Zwei Fehler nacheinander
07.04.2016 18:23:17
Daniel
Hi
wenn nach einem "On Error Goto" ein Fehler auftritt, dann befindest du dich im "Fehlerbehandlungsmodus"
ist der Fehlerbehandlungsmodus aktiv, kann kein weiterer Fehlersprung mehr ausgeführt werden.
um den Fehlerbehandlungsmodus zu deaktivieren, gibt es die Anweisung Resume und ihre Varianten (gugst du Hilfe)
du könntest das ganze vielleicht auch so lösen (wobei exessive Goto-Programmierung ungefähr genauso aktuell und modern ist wie Breitcord-Schlaghosen):
Sub Zwei_Fehler_nacheinander()
Dim Wort As Variant
Wort = 123
Columns("A:A").Select
On Error Resume Next
Selection.Find(What:=Wort & "a", After:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False,  _
SearchFormat:=False).Offset(0, 0).Select
If Err = 0 Then
On Error GoTo 0
GoTo Alles_gut_A
End If
Err = 0
Selection.Find(What:=Wort & "b", After:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False,  _
SearchFormat:=False).Offset(0, 0).Select
If Err = 0 Then
On Error GoTo 0
GoTo Alles_gut_B
End If
On Error GoTo 0
MsgBox "Weder a noch b vorhanden"
GoTo Ende
Alles_gut_A:
MsgBox "a vorhanden"
Exit Sub
Alles_gut_B:
MsgBox "b vorhanden"
Exit Sub
Ende:
MsgBox "Trotzdem geht's weiter!"
End Sub

Anzeige
AW: Besser ohne Fehler und ohne Goto
07.04.2016 18:31:45
Daniel
und so dann ohne Fehler und ohne Gotos:
Sub Zwei_Fehler_nacheinander()
Dim Wort As Variant
Dim rngX As Range
Wort = 123
Columns("A:A").Select
Set rngX = Columns(1).Find(what:=Wort & "a")
If Not rngX Is Nothing Then
rngX.Select
MsgBox "a vorhanden"
Else
Set rngX = Columns(1).Find(what:=Wort & "b")
If Not rngX Is Nothing Then
rngX.Select
MsgBox "b vorhanden"
Else
MsgBox "weder a noch b vorhanden"
MsgBox "Trotzdem gehts weiter"
End If
End If
End Sub
wenn man das .Find-Ergebnis einer Range-Variable zuweist, so gibt es beim Nichtvorhandensein des Suchbegriffs keinen Fehler, sondern die Range-Variable wird auf NOTHING gesetzt, was man problemlos abfragen kann.
Gruß Daniel

Anzeige
AW: Besser ohne Fehler und ohne Goto
08.04.2016 15:43:51
Klexy
Danke, Daniel.
Den Resume Next damit auszutrixen, dass der GoTo in eine If-Box gepackt wird, hätte mir auch einfallen können, aber da war die Fahrradkette nicht lang genug. Das ist ordentliche Hausmannskost mit Breitcord.
Allerdings sind in dieser Lösung alle drei On Error GoTo 0 und das Err = 0 überflüssig, oder?
Die zweite Möglichkeit, das Find-Ergebnis als Range zu definieren, kannte ich noch nicht. Again what learnt. Das gefällt mir ausnehmend gut und so werd ich es machen, weil es auch mit dem wenigsten Code auskommt.
Jetzt noch einmal zu meinem Grundproblem:
Zitat: "wenn nach einem "On Error Goto" ein Fehler auftritt, dann befindest du dich im "Fehlerbehandlungsmodus". Ist der Fehlerbehandlungsmodus aktiv, kann kein weiterer Fehlersprung mehr ausgeführt werden."
Soweit ist mir das klar.
Aber warum setzt mir das On Error GoTo 0 diesen Fehlerbehandlungsmodus nicht wieder auf "aus"? Dazu ist es doch da, wie ich das Internet zu verstehen glaubte (aber so richtig deutlich wird das nirgends erklärt). Und das Err = 0 bewirkt auch nicht, dass der Fehlerbehandlungsmodus ausgeschaltet wird. Was bringen die beiden denn? Wo wird das mal idiotensicher erklärt?

Anzeige
Das kannst du nur mit 'Resume' ausschalten! orT
08.04.2016 15:53:37
Luc:-?
Hatte das nicht Daniel schon gesagt…?!
Gruß, Luc :-?
Besser informiert mit …

AW: Das kannst du nur mit 'Resume' ausschalten! orT
08.04.2016 16:13:35
Klexy
Aber mit Resume schalte ich es ja nicht aus, nachdem ich meinen Fehler behandelt habe, sondern ich ignoriere den Fehler und mache einfach weiter. Den Fehler selber kann ich ja nur über den Umweg in den geschützten Bereich der If-Abfrage behandeln.
Ich hatte gedacht, es gibt eine Möglichkeit, dass ich an einer kritischen Stelle einen Fehler erkenne, abfange, bearbeite und beende. Und dann is wieder gut, bis 3 Meter weiter im Code der nächste Fehler kommt, der wieder erkannt, abgefangen, bearbeitet und beendet wird. Ansonsten ist es ja so, dass mir irgendein anderer Fehler, mit dem ich nicht gerechnet hatte, in eine Fehlerbehandlung springt, die gar nicht dafür vorgesehen ist und ohne Not noch offen im Hintergrund rumlungert. Das kann böse enden.
Wenn dieser unvorhergesehene Fehler kommt, will ich, dass er eine Fehlermeldung produziert. Und dann bau ich ihm ein Auffangbecken.
Bis der nächste User eine Lücke im Code findet und eine Schuhgröße statt ein Datum einträgt und mir den nächsten Bedarf an konkreter Fehlerbehandlung zeigt.
Oder?

Anzeige
AW: Das kannst du nur mit 'Resume' ausschalten! orT
08.04.2016 16:24:16
Daniel
Hi Klexy:
aufpassen, du verwechselst schon wieder das "Resume" mit dem "On Error Resume Next".
das sind aber zwei verschiedene Sachen
"On Error Resume Next" bewirkt einfach, dass bei einem Fehler mit dem nächsten Programmschritt weiter gemacht wird.
"Resume" bewirkt die Beendigung des Fehlerbehandlungsmodus nach einem "On Error Goto Sprungmarke" und erzwingt gleichzeitig den Rücksprung.
beim Rücksprung hast du drei Möglichkeiten:
a) Resume ohne weitere Angaben: Rücksprung zur Fehlerverursachenden Zeile und Wiederholen dieser
b) Resume Next: Rücksprung zur Zeile nach der Zeile, die den Fehler verursacht hat
c) Resume Sprungmarke: Sprung zu einer Sprungmarke.
die Option: Resume und Weitermachen mit dem nächsten Befehl nach Resume gibt es nicht, das müsste dann durch entsprechende weitere Sprungmarken realisiert werden:
hier nochmal eine weitere Variante, wie das mit Resume zu realisieren wäre:
Sub Zwei_Fehler_nacheinander()
Dim Wort As Variant
Wort = 123
Columns("A:A").Select
On Error GoTo Nicht_Gefunden_A
Selection.Find(What:=Wort & "a").Select
GoTo Alles_gut_A
Nicht_Gefunden_A:
Resume Weiter_gehts_1
Weiter_gehts_1:
On Error GoTo Nicht_Gefunden_B
Selection.Find(What:=Wort & "b").Select
GoTo Alles_gut_B
Nicht_Gefunden_B:
Resume Weiter_gehts_2
Weiter_gehts_2:
MsgBox "Weder a noch b vorhanden"
GoTo Ende
Alles_gut_A:
MsgBox "a vorhanden"
Exit Sub
Alles_gut_B:
MsgBox "b vorhanden"
Exit Sub
Ende:
MsgBox "Trotzdem geht's weiter!"
Exit Sub
End Sub
Gruß Daniel
PS: ich hoffe, es wird klar, warum diese Form des Programmierens auch "Spaghetti-Code" genannt wird.

Anzeige
AW: Das kannst du nur mit 'Resume' ausschalten! orT
08.04.2016 16:46:21
Klexy
Nicht "schon wieder" sondern "noch immer".
Der Thread ist so verschachtelt, dass ich deine andere Erklärung erst nach dieser Frage gelesen habe. Spaghetti-Thread ist halt übersichtlicher.
Ich bin (wie du bei meiner anderen Antwort siehst) auch auf genau diese Lösung gekommen. In meinem Fall ist Spaghetti die sinnvollere Lösung, weil es übersichtlicher ist. Im Prinzip können in Zukunft noch mehrere problematische Find-Abfragen in dieser Spalte kommen, die der Reihe nach abgeklappert werden sollen.
Jetzt hab ich kapiert, wie das mit dem Resume ist. Das hab ich noch nirgends so kurz und sinnvoll erklärt gesehen. Danke nochmal.

Anzeige
AW: Das kannst du nur mit 'Resume' ausschalten! orT
08.04.2016 17:09:43
Daniel
HI
Ohne Fehlerroutine oder zusätzliche Variablen könntest du für deinen Fall auch ZählenWenn verwenden um zu prüfen ob ein Begriff vorhanden ist:
If Worksheetfunction.CountIf(Columns(1), Wort & "a") > 0 Then
Msgbox "a vorhanden"
ElseIF Worksheetfunction.CountIf(Columns(1), Wort & "b") > 0 Then
Msgbox "b vorhanden"
Else
Msgbox "Weder a noch b vorhanden"
End If

Anzeige
Ganz so einfach ist es nicht Luc...
08.04.2016 16:15:05
Daniel
... denn das Resume beendet nicht nur den Fehlerbehandlungsmodus, es will danach auch immer noch irgendwohin springen, nämlich entweder wieder zu der Zeile, die den Fehler verursacht hat ("nochmal versuchen"), oder zur Zeile nach dem Fehler oder zu einer Sprungmarke.
Die Option: Resume mit dem nächsten Befehl nach Resume gibt es leider nicht, was sie Sache hier etwas komplizierter macht.
Gruß Daniel

Anzeige
Sicher, deshalb muss man dann auch ...
08.04.2016 21:35:03
Luc:-?
…eine Art SprungmarkenStatistik bzw -Verwaltung betreiben, Daniel & Klexy;
kann mich erinnern, das mal voll durchgezogen zu haben — ziemlicher Aufwand bei einem längeren Pgm. Hier deshalb mal nur ein RudimentärBsp für Resume Next:
Sub TestFehler()
Dim isErrResume As Boolean
On Error GoTo fx
wh: isErrResume = CBool(1 / 0)
On 8 - MsgBox("PgmEnde?", vbQuestion + vbYesNo + _
IIf(isErrResume, vbDefaultButton1, vbDefaultButton2)) GoTo wh, ex
fx: If CBool(Err.Number) Then
MsgBox Err.Description, vbCritical, "Fehler " & Err.Number
isErrResume = True: Resume Next
End If
ex: MsgBox "PgmEnde", vbExclamation
End Sub
Und hier noch eine ganz simple Resume-Anwendung:
Sub TestFehler()
Dim isErrResume As Long
On Error GoTo fx
MsgBox "1/" & isErrResume & "=" & 1 / isErrResume
fx: If CBool(Err.Number) Then
MsgBox Err.Description, vbCritical, "Fehler " & Err.Number: isErrResume = 1: Resume
End If
End Sub
Gruß, Luc :-?

Anzeige
AW: Besser ohne Fehler und ohne Goto
08.04.2016 16:08:25
Daniel
Hi
du musst zwei Sachen unterscheiden, die du hier nicht durcheinander werfen darfst:
der Fehlersprung: On error Goto Sprungmarke startet den Fehlerbehandlungsmodus und dieser wird mit Resume Rücksprung wieder beendet.
davon zu unterscheiden ist das On Error Resume Next, welches bewirkt dass bei einem Fehler nichts passiert sondern einfach mit dem nächsten Programmschritt weiter gemacht wird.
Diesen Modus beendet man dann wieder On Error Goto 0, welches wieder das normale Fehlerverhalten (Abbruch) aktiviert.
die Variable err brauchst du bei On Error Resume Next um festzustellen, ob ein Fehler passiert ist oder nicht, nach einem Fehler bekommt diese Variable als Wert die Fehlernummer.
sie behält diesen Fehlerwert, bis man sie entweder manuell auf 0 setzt, oder On Error Goto 0 ausführt oder ein neuer Fehler passiert (dann bekommt sie die neue Fehlernummer als Wert)
wenn du jetzt also zwei Stellen hast, an denen ein Fehler passieren kann, dann musst du vor der zweiten Stelle err = 0 setzen, weil du sonst ja nicht erkennen kannst, ob das err0 vom zweiten Fehler stammt oder noch vom ersten.
Unter Verwendung von Resume könnte man dein Problem so lösen (wobei dann weitere Sprungmarken verwendet werden müssen:
Sub Zwei_Fehler_nacheinander()
Dim Wort As Variant
Wort = 123
Columns("A:A").Select
On Error GoTo Nicht_Gefunden_A
Selection.Find(What:=Wort & "a").Select
GoTo Alles_gut_A
Weiter_gehts_1:
On Error GoTo Nicht_Gefunden_B
Selection.Find(What:=Wort & "b").Select
GoTo Alles_gut_B
Weiter_gehts_2:
MsgBox "Weder a noch b vorhanden"
GoTo Ende
Alles_gut_A:
MsgBox "a vorhanden"
Exit Sub
Alles_gut_B:
MsgBox "b vorhanden"
Exit Sub
Ende:
MsgBox "Trotzdem geht's weiter!"
Exit Sub
'--- Ab hier die Fehlerbehandlung mit Abschluss der Fehlerbehandlungsroutine
Nicht_Gefunden_A:
Resume Weiter_gehts_1
Nicht_Gefunden_B:
Resume Weiter_gehts_2
End Sub
Gruß Daniel

Anzeige
AW: Besser ohne Fehler und ohne Goto
08.04.2016 16:37:18
Klexy
Jetzt ist der Groschen gefallen.
Mit Resume kann wie mit einem GoTo die Stelle der Wiederaufnahme festgelegt werden.
Im Prinzip kann ich meinen alten Code nehmen und an der Stelle
Weiter_gehts_1:

einfach dies schreiben:
Weiter_gehts_1:
Resume HierWeiter
HierWeiter:

Anzeige
AW: Besser ohne Fehler und ohne Goto
08.04.2016 16:45:59
Daniel
Richtig
und irgendwann hast du dann mehr Sprungmarken im Code als Anweisungen ;-)
Gruß Daniel

AW: Besser ohne Fehler und ohne Goto
08.04.2016 16:48:36
Klexy
Bei meinen Usern muss ich immer auf dem Sprung sein.
It's springtime ;-)

AW: Naja, dann läufst du weniger Gefahr,
08.04.2016 21:53:58
Gerd
in die Fallstricke einer wider besseres Wissen ohne die für die manuell verstellbaren Einstellungen definierten Argumente der Find-Methode zu geraten, Klexy. :-)
Gruß Gerd

Anzeige
GoTo Salat
07.04.2016 18:42:09
ChrisL
Hi
Kurz die Frage aufgeworfen, wie man so etwas ohne GoTo strukturieren könnte. Ich gehe davon aus, dass Search nur beispielhaft verwendet wurde.
Da ich Funktionen so toll finde :) Folgender Vorschlag:
Freihand, ungetestet...
Sub Mach()
Dim sWort As String
sWort = "xy"
If MyFunktion1(sWort) And MyFunktion2(sWort) Then
MsgBox "a + b"
Exit Sub
End If
If MyFunktion1(sWort) Then
Msgbox "a"
Exit Sub
End If
If MyFunktion2(sWort) Then
MsgBox "b"
Exit Sub
End If
End Sub
Private Function MyFunktion1(sWort As String) As Boolean
On Error Goto ErrorHandler
'Search: sWort
'Zufall ob Fehler oder nicht
Exit Function
ErrorHandler:
MyFunktion1 = True
End Function

Private Function MyFunktion2(sWort As String) As Boolean
On Error Goto ErrorHandler
'Search: sWort
'Zufall ob Fehler oder nicht
Exit Function
ErrorHandler:
MyFunktion2 = True
End Function

cu
Chris

Anzeige
AW: GoTo Salat
07.04.2016 18:49:55
ChrisL
stimmt, es soll ja weiter gehen. If-Then verschachteln wie von Daniel vorgeschlagen und Exit Sub entfernen. Die Funktionen finde ich trotzdem hübsch :)

AW: GoTo Salat
08.04.2016 15:27:02
Klexy
Danke, Chris.
Die Lösung mit einer externen Funktion hatte ich mir für den Notfall aufgespart.
Hat einen gewissen Charme, wollte ich aber vermeiden, um nicht so viel hin und her zu hüpfen, wenn ich wieder was ändere und das Makro in der Schritt-für-Schritt-Ansicht mit F8 durchlaufen lasse.
Ich wollte außerdem einfach diesen verdammten Error endlich verstehen und bezwingen.
Anzeige
;

Forumthreads zu verwandten Themen

Anzeige
Anzeige
Anzeige
Entdecke relevante Threads

Schau dir verwandte Threads basierend auf dem aktuellen Thema an

Alle relevanten Threads mit Inhaltsvorschau entdecken
Anzeige
Anzeige

Infobox / Tutorial

Fehlerbehandlung in Excel VBA: On Error Resume Next und Co.


Schritt-für-Schritt-Anleitung

  1. Fehlerbehandlungsmodus aktivieren: Beginne mit On Error GoTo ErrorHandler, um einen Fehlerbehandlungsmodus zu aktivieren.

    On Error GoTo ErrorHandler
  2. Fehlerbehandlung implementieren: Füge eine Fehlerbehandlungsroutine hinzu. Hier kannst du entscheiden, was bei einem Fehler geschehen soll.

    ErrorHandler:
    MsgBox "Ein Fehler ist aufgetreten: " & Err.Description
    Exit Sub
  3. On Error Resume Next verwenden: Wenn du bestimmte Fehler ignorieren möchtest, kannst du On Error Resume Next verwenden. Dies lässt das Programm bei einem Fehler einfach mit dem nächsten Schritt fortfahren.

    On Error Resume Next
  4. Fehlerstatus zurücksetzen: Um den Fehlerstatus zurückzusetzen, kannst du Err = 0 oder On Error GoTo 0 verwenden.

    On Error GoTo 0
  5. Fehlerbedingungen überprüfen: Verwende If Err.Number <> 0 Then, um zu prüfen, ob ein Fehler aufgetreten ist, und handle entsprechend.

    If Err.Number <> 0 Then
       ' Fehlerbehandlungscode
    End If

Häufige Fehler und Lösungen

  • Fehlerbehandlungsmodus nicht zurückgesetzt: Wenn du nach einem On Error GoTo nicht On Error GoTo 0 verwendest, bleibt der Fehlerbehandlungsmodus aktiv. Dies kann dazu führen, dass nachfolgende Fehler nicht korrekt behandelt werden.

    Lösung: Setze den Fehlerbehandlungsmodus nach der Behandlung eines Fehlers zurück.

  • Mehrere Fehler gleichzeitig: Wenn du mehrere On Error-Anweisungen hast, kann es sein, dass der zweite Fehler nicht erkannt wird.

    Lösung: Verwende On Error Resume Next, um den ersten Fehler zu ignorieren, und setze dann Err = 0 vor der nächsten Fehlerprüfung.


Alternative Methoden

  • Verwendung von CountIf: Anstatt Fehlerbehandlung zu verwenden, kannst du auch CountIf nutzen, um zu prüfen, ob ein Wert vorhanden ist. Dies kann eine einfachere Lösung sein.

    If WorksheetFunction.CountIf(Columns(1), Wort & "a") > 0 Then
       MsgBox "a vorhanden"
    ElseIf WorksheetFunction.CountIf(Columns(1), Wort & "b") > 0 Then
       MsgBox "b vorhanden"
    Else
       MsgBox "Weder a noch b vorhanden"
    End If
  • Funktionen verwenden: Du kannst auch externe Funktionen erstellen, um die Fehlerbehandlung zu kapseln und deinen Code übersichtlicher zu gestalten.


Praktische Beispiele

  1. Beispiel mit On Error Resume Next:

    Sub BeispielFehler()
       On Error Resume Next
       Dim rng As Range
       Set rng = Columns(1).Find("NichtVorhanden")
       If rng Is Nothing Then
           MsgBox "Wert nicht gefunden!"
       Else
           MsgBox "Wert gefunden!"
       End If
       On Error GoTo 0
    End Sub
  2. Beispiel mit On Error GoTo:

    Sub BeispielMitErrorHandler()
       On Error GoTo ErrorHandler
       ' Code, der einen Fehler verursachen könnte
       Exit Sub
    ErrorHandler:
       MsgBox "Fehler aufgetreten: " & Err.Description
    End Sub

Tipps für Profis

  • Vermeide übermäßige Nutzung von GoTo, da dies zu "Spaghetti-Code" führen kann. Strukturierte Fehlerbehandlung mit Funktionen macht deinen Code lesbarer.
  • Nutze On Error Resume Next nur sparsam, um unerwartete Fehler zu vermeiden. Es ist besser, spezifische Fehler zu behandeln.
  • Halte deine Fehlerbehandlungsroutinen so einfach wie möglich, um die Wartbarkeit zu erhöhen.

FAQ: Häufige Fragen

1. Was ist der Unterschied zwischen On Error Resume Next und On Error GoTo? On Error Resume Next ignoriert Fehler und fährt mit dem nächsten Befehl fort. On Error GoTo aktiviert den Fehlerbehandlungsmodus und springt zu einer definierten Stelle im Code.

2. Wie setze ich den Fehlerstatus zurück? Du kannst den Fehlerstatus zurücksetzen, indem du On Error GoTo 0 verwendest oder Err = 0 setzt.

3. Was passiert, wenn ich mehrere On Error-Anweisungen habe? Wenn mehrere On Error-Anweisungen ohne richtiges Management verwendet werden, kann das zu unerwartetem Verhalten führen. Stelle sicher, dass du den Fehlerbehandlungsmodus korrekt zurücksetzt.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Entdecke mehr
Finde genau, was du suchst

Die erweiterte Suchfunktion hilft dir, gezielt die besten Antworten zu finden

Suche nach den besten Antworten
Unsere beliebtesten Threads

Entdecke unsere meistgeklickten Beiträge in der Google Suche

Top 100 Threads jetzt ansehen
Anzeige