Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1884to1888
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Schleifen mit GoTo verlassen

Schleifen mit GoTo verlassen
05.06.2022 23:43:33
Dieter
Moin aus Hamburg,
ich habe ein Projekt mit 20 Blöcken, in denen sich jeweils For ... Next Schleifen befinden und in den Schleifen steht jeweils ein If ... End If Block. Der End ... If Block wird mit einer GoTo Anweisung verlassen, wenn eine bestimmte Bedingung erfüllt ist. Das GoTo führt mit aktualisierten Variablen an den Anfang des Makros zurück, um die 20 Blöcke wiederholt zu durchlaufen. So der Plan ...
Bevor es die im Zusammenhang mit GoTo die grundsätzlich gerechtfertigte Aufregung gibt, hier eine Erklärung. Dieses Konstrukt ist nicht "schön", erspart aber die Verschachtelung von 20 Schleifen mit einer unzumutbaren Laufzeit.
Das Makro läuft ohne Fehlermeldungen durch, aber das Resultat unterscheidet sich erheblich von dem einer manuellen Simulation, und in das Arbeitsblatt werden auch nicht die erwarteten Werte eingetragen.
Meine Frage: Können Variable ihren Wert verlieren oder ändern, wenn For ... Next Schleifen oder If ... End If Blöcke so unkonventionell mit GoTo verlassen werden? Stichworte für eigene Lösungsversuche reichen erst einmal aus.
Zusatzinfos: Alle Variablen sind einzeln typgerecht mit Dim deklariert. Das Makro beginnt mit der Abschaltung "zeitfressender" Funktionen wie ScreenUpdating, Cursor, DisplayAlerts, EnableEvents, DisplayStatusBar, und die Berechnung wir auf xlCalculationManual gesetzt. An den Stellen, wo aktuelle Tabellenwerte gebraucht werden, erfolgt eine zwangsweise Neuberechnung mit ApplicationCalculate. Versuche mit Do ... While o.ä. waren bisher nicht erfolgreich.
Bin gespannt, schon mal vielen Dank

11
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Schleifen mit GoTo verlassen
05.06.2022 23:53:41
GerdL
Moin Dieter!
Meine Frage: Können Variable ihren Wert verlieren oder ändern, wenn For ... Next Schleifen oder If ... End If Blöcke so unkonventionell mit GoTo verlassen werden?
Ja, je nach Code.
Gruß Gerd
AW: Schleifen mit GoTo verlassen
06.06.2022 06:05:40
Oberschlumpf
Hi Dieter,
solange mit GoTo - nicht - das Makro selbst verlassen wird, behalten die Variablen auch ihre Werte.
Wenn aber z Bsp...

Sub Makro1()
Dim loZelle As Long
loZelle = 100
GoTo Ende
loZelle = 200
Ende:
Makro2
End Sub
Sub Makro1()
Makro1
End Sub
...in Makro1 die Variable loZelle einen Wert erhält, dann Makro2 startet, welches wieder zurück zu Makro1 startet, dann is loZelle = 0
Mach dich mal über Public Variablen schlauer, vielleicht wird dann dein VBA = (noch) Gut(er) ;-)
Wenn dir all das hier an Tipps nix hilft, zeig uns mal per Upload ne Bsp-Datei oder mehrere Bsp-Dateien, wenn erforderlich - natürlich auch mit allem anderen, was erforderlich ist, wie Bsp-Daten, VBA-Code usw.
Ciao
Thorsten
Anzeige
AW: Schleifen mit GoTo verlassen
06.06.2022 07:58:44
Anton
Hi Dieter, For-Schleifen kannst du mit dem Befehl Exit for vorzeitig verlassen. In der Praxis bedeutet das vorzeitige Verlassen von For oder For Each Schleifen in der Regel,, dass man mit Do While Schleifen womöglich besser dran ist, da man dort die Bedingungen direkt im Schleifenkopf definieren kann.
Viele Grüße
Anton
AW: Schleifen mit GoTo verlassen
06.06.2022 12:28:53
Dieter
Moin,
vielen Dank für die bisherigen Antworten. Ich glaube, dass eine Beschreibung in ein paar Zeilen nicht ausreicht. Deshalb im Anhang ein Auszug aus der Prozedur mit dem Fall K06 stellvertretend für alle (K01 ... K20): https://www.herber.de/bbs/user/153434.txt
Do ... While ohne Erfolg getestet. Die Bedingung, um diese Schleife zu verlassen, wird in der Zeile 'improvement detected' erfüllt. Es müssen danach aber noch weitere Programmzeilen bis zum GoTo ausgeführt werden, was bei Do ... While ausgelassen wird. Abgesehen davon stellt sich noch die Frage, wie der Rücksprung zu 'RestartLoop' mit Do ... While gehen soll.
Hintergrund zu dieser exotisch erscheinenden Prozedur: Es soll ein globales Maximum ermittelt werden, das von den Werten K01 ... K20 abhängt. Zielgrößen sind die optimierten Werte für Kxx. Die Emittlung der lokalen Optima für Kxx reicht nicht aus, weil die Kxx sich gegenseitig beeinflussen. Das macht so lange Rücksprünge zu 'RestartLoop' erforderlich, bis das globale Optimum erreicht ist und damit optimierte Kxx ermittelt sind.
Weitere Hinweise: Keine der Variablen im gesamten Projekt ist weder als 'global' noch als 'local' deklariert. Sprungmarken kommen im gesamten Projekt nur einmal vor. Kritisch sind die Wertzuweisungen an Zellen in Arbeisblättern, z.B. TgtRngSet(5, 103).Value = SrcRngSet(5, 101).Value, beide als Range gesetzt.
Danke schon mal
Dieter
Anzeige
AW: Schleifen mit GoTo verlassen
06.06.2022 12:43:57
Oberschlumpf
Hi Dieter,
wo bitte in deiner txt-Datei sind denn die Bsp-Daten aus z Bsp Excel-Zellen, oder anders gefragt:
Wieso zeigst du uns nicht per Upload bitte eine Excel-Bsp-Datei mit allem, was erforderlich ist, damit auch wir testen könn(t)en?
Und...jede Variable ist - immer - "nur" local gültig, so lange diese in einem allgemeinen Modul, außerhalb jeden Makros, nicht explizit als public deklariert wurde.
Ciao
Thorsten
AW: Schleifen mit GoTo verlassen
06.06.2022 13:58:12
Dieter
Moin Thorsten,
die in Frage stehende Prozedur greift auf mehrere worksheets und weitere Excel-Dateien zu. Hierin befinden sich sehr viele vertrauliche Informationen, die nicht unkenntlich gemacht werden können. Insgesamt ist die Rede von 10 MB (Masterdatei mit 15 worksheets), zusätzlich 22 MB weitere Dateien. Uploads sind auf 300 KB begrenzt. Also zwei Gründe, die ein upload unmöglich machen, was mir wirklich Leid tut.
Bis auf diese Prozedur läuft das Projekt schnell und reproduzierbar stabil. Damit kann die Fehlersuche zunächst auf diese Prozedur begrenzt werden.
Es würde mir schon helfen, vermutete Fehlerquellen zu erfahren, die ich dann selbst austesten kann. Vielen Dank hierzu.
Als nächstes werde ich probieren, welchen Einfluss das Beschleunigen durch Ausschalten der Hintergrundaktivitäten (Gnl_BckOff) hat.
Beste Grüße
Dieter
Anzeige
AW: Schleifen mit GoTo verlassen
06.06.2022 14:42:55
Zwenn
Hallo Dieter,
wie Du schon geschrieben hast, ist GoTo ein NoGo ;-) Deine Anforderung mit 20 Bedingungen, die je nach gesetzter Variable greifen sollen, klingt für mich nach einer einzigen Schleife mit einem Select Case für die 20 Fälle, plus der Möglichkeit komplett aus dem Ganzen Ding auszusteigen. Ist der Ausstieg nicht notwendig, ist es eine Endlosschleife, bei der in jedem Durchgang neu entschieden wird, welche Bedingung gerade greift.
Viele Grüße,
Zwenn
AW: Schleifen mit GoTo verlassen
06.06.2022 15:23:08
Dieter
Moin Zwenn,
ganz so einfach ist das nicht. Es MÜSSEN alle Blöcke K01 ... K20 durchlaufen sein, um jede Möglichkeit für ein besseres Resultat, das heißt, einen optimierten Wertesatz, zu testen. Ein vorzeitiges Verlassen der Schleife ist damit ausgeschlossen. Erst, wenn der letzte Test in Block K20 keine Vebesserung bringt, ist die GoTo Schleife beendet. Damit gibt es keine Endlosschleife (bereits getestet).
Ein Rücksprung per GoTo an den Beginn von K01 wird ausgelöst, wenn eine neue Parameterkombination aus K01 bis K20 ein besseres Ergebnis liefert. Dann beginnt mit dem neuen Parametersatz ein weiterer Optimierungsdurchlauf. Do ... While, Case und ähnliche helfen nicht weiter, weil nach der erfüllten Bedingung noch einige Berechnungen sein müssen, bevor es mit GoTo zum Anfang von K01 zurückgeht. Mit Do ... While etc. würde der Sprung unmittelbar ausgeführt.
Zur Zeit konzentriere ich mich auf das richtige Setzen von Zwischenergebnissen. Wenn das dann richtig funzt, werde ich mich melden.
Die Programmcodeästheten kann ich übrgens sehr gut verstehen, aber wenn es nur mit GoTo funktioniert, wird sogar ein Holzhammer zu einer Schönheit.
Danke für Deine Hilfe
Dieter
Anzeige
AW: Schleifen mit GoTo verlassen
06.06.2022 15:38:30
Zwenn
Hallo Dieter,
dann hatte ich es vorher nicht richtog verstanden. Mir war nicht klar, dass alle 20 Blöcke zusammen zum Ergebnis führen. Trotzdem bin ich sicher, es geht ohne GoTo. Aber das GoTo ist ja auch gar nicht die Frage. Du brauchst mehr Performance, wenn ich nicht wieder falsch liege ;-)
Du hattest bereits einen Code-Schnipsel geschickt. Den habe ich nach einem Rammstein-Konzert-Wochenende ehrlich gesagt nicht bis ins Detail angesehen. Aber am sinnvollsten erscheint mir dann Antons Antwort. Keine For-Schleifen. Do While, bzw. Do Until sollte auch zum Ziel führen. Womit aber nicht unbedingt an Performance gewonnen wird. Es wird "nur" lesbarer. Die Frage ist also, wann wird ein Zustand als "optimal" angenommen? Oder?
Kannst Du das ganze Makro mit den 20 Blockprüfungen posten? Daten dazu wären nice, wie Thorsten ja schon geschrieben hatte. Müssen ja keine 10 MB sein. Vielleicht geht ein Mini-Auszug. Aber auch der vollständige Code ansich kann schon hilfreich sein.
Viele Grüße,
Zwenn
Anzeige
AW: Schleifen ohne GoTo verlassen
06.06.2022 20:45:40
Mullit
Hallo,

Dim blnFound As Boolean
For Mde = 1 To 2 'mode '1' for case 1, mode '2' for case2
For Day = DayMin To DayMax
blnFound = False
If Not ((Mde = 1 And IntFac(6, 1) = IntFac(6, 2)) And (Mde = 2 And IntFac(26, 1) = IntFac(26, 2))) Then
If Mde = 1 Then 'H:A
LoopMax = 0
TgtRngTdy(10, 109).Value = 1
For K06 = IntFac(6, 1) To IntFac(6, 2)
If K06 = 1 Then TgtRngTdy(5, 103).Value = 0 'reset
TgtRngSet(6, 1).Value = K06
Application.Calculate
If SrcRngTdy(5, 101).Value > TgtRngTdy(5, 103).Value Then 'improvement detected
TgtRngTdy(5, 103).Value = SrcRngTdy(5, 101).Value
LoopMax = SrcRngTdy(5, 101).Value
TgtRngTdy(10, 109).Value = K06
If LoopMax > GnlMax Then
GnlMax = LoopMax
blnFound = True
Exit For
End If
End If
Next K06
End If
If Not blnFound Then
If Mde = 2 Then '1-X-2
LoopMax = 0
For K06 = IntFac(26, 1) To IntFac(26, 2)
If K06 = 1 Then TgtRngTdy(5, 144).Value = 0 'reset
TgtRngSet(6, 1).Value = K06
Application.Calculate
If SrcRngTdy(5, 142).Value > TgtRngTdy(5, 144).Value Then 'improvement detected
TgtRngTdy(5, 144).Value = SrcRngTdy(5, 142).Value
LoopMax = SrcRngTdy(5, 142).Value
TgtRngTdy(10, 150).Value = K06
If LoopMax > GnlMax Then
GnlMax = LoopMax
blnFound = True
Exit For
End If
End If
Next K06
End If
End If
End If
Next Day
Next Mde
Gruß, Mullit
Anzeige
AW: Schleifen ohne GoTo verlassen
06.06.2022 21:58:05
Dieter
Moin Mullit,
in der Variable blnFound steckt die Lösung, danke dafür.
Die habe ich leicht verändert in meinen Code eingebaut und noch an den vielen Indizes gefeilt. Insgesamt ist das einschließlich GoTo (smile) jetzt eine runde Sache. Auf jeden Fall weiß ich jetzt, wie und unter welchen Randbedingungen loops und if ... then Blöcke mit einem GoTo verlassen muss, ohne den Wert von Variablen zu ändern.
Beste Grüße
Dieter

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige