Mehrfache Fehlerbehandlung mit "On Error GoTo"
hallo liebes forum,
ich habe einen vba code mit 2 schleifen und in jeder schleife habe ich die fehlerbehandlung On Error GoTo eingebaut, so dass bei einem fehler der algorithmus der schleife neu gestartet wird. also so ungefähr:
...
do while a<x
wiederholeschleife1:
On Error GoTo wiederholeschleife1
' Berechnungen
On Error GoTo 0
loop
...
for b = 0 to y
wiederholeschleife2:
On Error GoTo wiederholeschleife2
' Berechnungen
On Error GoTo 0
next b
funktioniert aber nicht, da bei einem Fehler immernoch abgebrochen wird...
ich hab halt gedacht, ich kann mit On Error GoTo 0 die vorherige On Error GoTo Anweisung deaktivieren, ist das richtig? oder was ist sonst falsch?
vielen dank schon mal für eure antworten!
gruß, simon
Antwort schreiben
Antwort 1 von Seradest vom 10.09.2019, 09:29 Options
Hi Simon,
du musst für die On Error GoTo Anweisung auch ein Label festlegen. Die fehlt offenbar in deinem Quelltext.
Bsp:
Marke1:
for b = 0 to y
wiederholeschleife2:
On Error GoTo wiederholeschleife2
' Berechnungen
On Error GoTo Marke1
Grüße
Carsten
Antwort 2 von Seradest vom 10.09.2019, 09:30 Options
Kleiner Nachtrag :)
Für eine differenzierte Fehlerbehandlung eignet sich das in der Form allerdings weniger.
Antwort 3 von Seradest vom 10.09.2019, 09:37 Options
Ich nochmal :)
Mir wird grade klar dass du ja gar keine Fehlerbehandlung betreiben willst, sondern die Fehlerbehandlung nur deaktivierst oder wie? Warum? Was genau willst du denn machen? Im Zweifelsfall würde ich On Error Resume Next empfehlen. Aber ich werd aus dem Code nicht so ganz schlau.
Antwort 4 von Seradest vom 10.09.2019, 09:42 Options
Hi Simon,
ich nochmal... Bin irgendwie total verplant heute. Ich seh aber in deinem Code nach wie vor nicht durch (in meinem übrigens auch nicht^^) Ist dir bewusst dass du im Fehlerfall eine Endlosschleife erzeugst? Oder liege ich da jetzt auch falsch, ich glaube ich sollte mich ausklinken, bevor ich nochmehr Unsinn erzähle^^
Grüße
Antwort 5 von simon* vom 10.09.2019, 09:51 Options
danke für deine antwort carsten,
also ich habe in beiden schleifen jeweils öfters überlauffehler, da ich kurz gesagt berechne: exp(zufallszahl)...
ich möchte bei einem überlauffehler nicht die komplette schleife neu starten, sondern nur die letzte berechnung (=ziehung der zufallszahl).
meine frage:
1. wird bei Initialisierung des zweiten On Error GoTo das erste On Error GoTo automatisch deaktiviert?
2. wie kann ich das zweite On Error GoTo nach verlassen der 2. schleife deaktivieren, so dass evtl fehler, die nach der 2 schleife auftauchen nicht abgefangen werden!?
On Error GoTo 0 ist offensichtlich falsch, da das die fehlerbehandlung der prozedur komplett deaktiviert.
On Error Resume Next will ich nicht verwenden, da ich ja dann eine variable mit einem sinnlosen wert mit mir herumschleppe!
ich hoffe, mein problem ist ein bisschen klarer geworden,
danke, simon
Antwort 6 von Seradest vom 10.09.2019, 10:09 Options
Ahja, jetzt verstehe ich. (denk ich)
Soweit ich weiß wird immer die zuletzt ausgeführte On Error Anweisung benutzt, es dürfte also nicht notwendig sein diese zu deaktivieren.
Was On Error Goto 0 angeht hab ich mich nochmal schlau gemacht, normalerweise müsste diese die Fehlerbehandlungsroutinen (Resume, Goto) deaktivieren und wieder zu normalen Laufzeitfehlern, also zum Programmabbruch, führen.
Ich muss da mal selbst was ausprobieren...
Grüße
Carsten
Antwort 7 von simon* vom 10.09.2019, 10:20 Options
ja genau, aber das problem ist das "On Error GoTo 0" die fehlerbehandlung im gesamten code deaktiviert, also auch die On Error GoTo's die vorher initialisiert wurden..., oder?
ich bräuchte etwas, was fehler ab einer bestimmten stelle wieder zulässt...
aber danke für deine hilfe!
simon
Antwort 8 von Seradest vom 10.09.2019, 10:46 Options
Das On Error Goto 0 deaktiviert nur Fehlerbehandlungen die zuvor eingerichtet wurden.
Danach kannst du neue Fehlerbehandlungen einrichten, hab ich gerade ausprobiert. Also müsste das genau das sein was du brauchst. Hab mir deinen Code auch nochmal angesehen, an welcher Stelle hast du damit Probleme? Nach meinem Verständnis müsste der Code nach deinen Vorstellungen laufen...
Grüße
Carsten
Antwort 9 von simon* vom 10.09.2019, 11:10 Options
mmh, also ich habe komischerweise einen überlauffehler in der 2.schleife bekommen, trotz der fehlerbehandlung, deswegen dachte ich On Error Goto 0 funktioniert nicht so wie gedacht.
muss ich dann nochmal ausprobieren,
danke dir!
Antwort 10 von Seradest vom 10.09.2019, 11:31 Options
Dann müsste ja die Schleifenbedingung selbst zum Fehler führen, oder?
Evtl zeigste mal den Code der den Fehler verursacht und markierst die genaue Zeile.
Grüße
Carsten
Antwort 11 von son_quatsch vom 10.09.2019, 11:34 Options
Zitat:
mmh, also ich habe komischerweise einen überlauffehler in der 2.schleife bekommen
Das rührt wahrscheinlich daher, dass die Schleife jetz viel zu oft durchlaufen wurde. Überprüf das dochmal mit z.B. "debug.print i" und "i= i+ 1" pro Durchlauf.
Antwort 12 von Teerbaby vom 10.09.2019, 11:45 Options
wenn du eine differenzierte Fehlerbehandlung willst, benutze doch den Fehlercode
Sub irgendwas
On Error Goto Fehler
.... dein Code ....
Exit Sub
Fehler:
if Error.Code = 0815 then
goto Wiederholschleife1
elseif Error.Code = 4711 then
goto Wiederholschleife2
End IF
End Sub
Antwort 13 von Teerbaby vom 10.09.2019, 11:54 Options
mmh, nachdem ich das nochmal durchgelesen habe, ist mir immer noch nicht ganz klar, was das soll.
Wieso läufst du überhaupt auf Fehler? Du solltest die Bedingungen eigentlich so setzen, dass sowas nicht passiert.
Antwort 14 von son_quatsch vom 10.09.2019, 12:00 Options
Zitat:
Wieso läufst du überhaupt auf Fehler?
Naja ich denk mir, er probiert irgendetwas zeitkritisches (z.B. wo ein Timeout auftreten könnte - oder wenn eine zu öffnende Datei noch nicht existiert, aber bald da sein müsste)... die wahre Lösung verbirgt sich also in der Umgestaltung dort drin, statt einer Dauerndneuversuchschleife.
Und wenn er einen Pufferüberlauf hat, dann sind die Chancen sogar hoch, dass in der Schleife immer wieder neu ein Objekt erzeugt wird und nicht wieder gelöscht. Klassischer Speicherleck wäre das...
Antwort 15 von simon* vom 10.09.2019, 12:10 Options
ich mach eine aktienkurs-simulation. dabei werden zufallszahlen gezogen und dann wird der kurs - vereinfacht ausgedrückt - mit K=a*Exp(b+c*Zufallszahl) berechnet. damit berechne ich ca. 500 kurse. und diesen kursverlauf wiederum simuliere ich 50000 mal, um eine verteilung zu erhalten.
dabei ist es nicht unwahrscheinlich, dass die zufallszahl zu groß wird. exp() kann aber nur bis zum maximalwert 709,782712893 arbeiten.
andererseits kann es auch mal vorkommen, dass exp() den wert null annimmt, nämlich bei sehr großen negativen exponenten (wie beim taschenrechner auch).
diese beiden fehlerquellen wollte ich vermeiden, indem ich bei einer ungeeigneten zufallszahl, einfach nochmal eine ziehe (also einfach den algorithmus der schleife wiederhole)
;-) simon
Antwort 16 von son_quatsch vom 10.09.2019, 12:54 Options
Würde ich definitiv in eine eigene Funktion packen. Z.B.:
Function rechne() As Double
On Error GoTo ende
rechne = 1 + 4 + 90
Exit Function ' Erfolgreich berechnet? Funktion beendet
ende:
rechne = 0 ' Standardrückgabe im Fehlerfall
End Function
...und dann den Funktionsaufruf entsprechend in eine eigene Schleife packen, bis er z.B. >0 zurückliefert
Antwort 17 von simon* vom 10.09.2019, 21:20 Options
also: folgendes hab ich jetzt rausgefunden:
folgender code verursacht einen fehler, da irgendwie die fehlerbehandlung ab dem zweiten mal nicht mehr greift (leider keine ahnung warum):
Sub test1()
Dim ergebnis As Double
Dim a As Long
a = 712
Do While a > 707
schleife:
a = a - 1
On Error GoTo schleife
' Überlauffehler bei a > 709!!
ergebnis = Exp(a)
On Error GoTo 0
Loop
End Sub
dagegen verursacht folgendes keinen fehler, obwohl es (meiner meinung nach) die selbe sache darstellt (abweichungen zu obrigem code sind fett):
Sub test2()
Dim ergebnis As Double
Dim a As Long
a = 712
Do While a > 707
schleife[b]_wiederholen[/b]:
a = a - 1
On Error GoTo schleife
' Überlauffehler bei a > 709!!
ergebnis = Exp(a)
On Error GoTo 0
Loop
[b]Exit Sub
schleife:
Resume schleife_wiederholen[/b]
End Sub
ich habs jetzt einfach wie im 2.beispiel gelöst.
danke für eure antworten!!
simon