PDA

Vollständige Version anzeigen : Goto mit Zeilennummer in Variable


Harry25
27.04.2011, 10:09
Hallo !

Ich möchte in einer Routine (Fehlerbehandlung) nach einem Fehler an eine bestimmte Stelle im Code zurückspringen. x-Einzelne Sprungmarken ist zu umfangreich. Die Stelle im Code steht in einer Variable. Daher würde ich gerne sagen "GoTo" und dann anschliessend die Zeilennummer per Variable angeben. Leider bringt er mir wenn ich nicht die Zeilennummer explicit hinschreibe den Fehler "Sprungmarke nicht definiert"
Was muß ich beachten um doch eine Variable zu benutzen ?

Atrus2711
27.04.2011, 10:20
Hi,
mit Zeilennummer läuft in VBA gar nichts. Jeder Kommentar oder jeder Leerzeile würde die Zählung verschieben -> :boah: :entsetzt:

Struktueriert geht anders:

Nach der Fehlerroutine mit Resume an die Stelle zurückkehren, wo der Fehler stand
Notfalls Aufräumcode in eine Marke "Cleanup:" o.ä. packen und da mit Goto hingehen.


Goto ist out und hat nur noch bei der (rudimentären) Fehlerbehandlung von VBA Existenzberechtigung. Sonst droht Spaghetticode (http://de.wikipedia.org/wiki/Spaghetticode).

avogt_at_home
27.04.2011, 10:34
Hallo,
Goto führt wie Martin sagte schnell zu Spaghetti-Code. Es gibt aber auch "erlaubte" Anwendungsfälle.
Definiere dir dazu Sprungmarken indem du hinter dem Namen ein Doppelpunkt setzt.

Gruß Andreas

Harry25
27.04.2011, 10:47
Hallo Atrus 2711

Dem "Jeder Kommentar oder jeder Leerzeile würde die Zählung verschieben" möchte ich entgegensetzen das es meinem Test nach nicht stimmt. Habe ich keine Zeilennummern vor meinen Codezeilen kennt mein Access keine Sprungmarken ebenso wenig als wenn ich welche habe und diese per Variable übergeben möchte. Sind im Code Zeilennummern und verweise ich darauf indem ich explicit die Nummer hinter Goto schreibe, dann springt er immer exakt dorthin, egal wieviele Kommentare oder Leerzeichen dazwischen sind.

Zu Resume. Resume ist ganz nützlich wenn ich die fehlerhafte Codezeile wiederholen und den darauffolgenden Code ganz normal weiter ausführen möchte. Das setzt aber voraus das Programm könnte den Fehler selbst beheben. Wenn ich aber weis ich kann z.B. die folgenden 5 Zeilen ohne Folgen überspringen dann müsste ich ihm sagen gehe in Zeile x und mach dort weiter.

Gut durchdacht gibt es keinen Spagetticode !!

Warum soll GOTO out sein ?

Atrus2711
27.04.2011, 11:02
Auch wenn Leer- und Kommentarzeilen funktionieren, ist es doch nicht gut. Denn die Verschiebung könnte z.B. durch einen Umbau völlig aus dem Ruder laufen. Eine MsgBox zu Debugzwecken dazwischen, schon ist das Konstrukt hinüber.

Du springst ja nicht aus Spaß zu Zeile 40, sondern weil du eine bestimmte Codefolge abarbeiten willst ("was immer in Zeile 40 steht"). Und diese Steuerung - Bedingungen, Schleifen, Fehlerverarbeitung - sollte durch benamste Programmteile erfolgen. Nicht durch Goto (Markenname).

Letztlich führt dein Ansatz zu selbstveränderndem Code. Und der ist geächtet...

Josef P.
27.04.2011, 11:05
Hallo!

Gut durchdacht gibt es keinen Spagetticode !!
Genau! ... weil gut durchdachter Code in überschaubare Prozeduren aufgeteilt wurde, in denen nicht gesprungen werden muss. :)

Warum soll GOTO out sein ?
Weil es meistens ein Zeichen für zu langen Code ist. ;)

mfg
Josef

Toast78
27.04.2011, 11:15
Warum soll GOTO out sein?Weils Mist ist! Das kann keiner mehr warten.

Ich habe vor 2 Jahren ein Fortran-Programm aus den 60ern für eine Generator-Berechnung nach VBA umgestellt. Bis auf wenige Unterschiede wurde die Berechnung 2mal für Erregerseite und Turbinenseite ausgeführt.
Der Code war dann so gestrickt, dass eine Zählvariable am Ende inkrementiert wurde, wenn sie nicht größer 1 war. Dann wurde zum Programmanfang zurückgesprungen. War die Zählvariable = 1 wurden die für die andere Seite relevanten Berechnungen und Ausgaben durchgeführt. Am Ende wurde das Programm abgebrochen, wenn die Zählvariable > 1 war.

Willst du das jetzt guten Programmierstil nennen?

Ich habe diesen Teil einfach so gelassen, weil es mir einfach zu heikel war, da irgendwie dran rumzufummeln.

Lass das mit dem GOTO!

Atrus2711
27.04.2011, 11:22
Warum soll GOTO out sein?
Hast du das Beispiel in meinem Link zu Spaghetticode mal angesehen? Nennst du das nachvollziehbar?

Goto (außer in den seltenen Fällen von Fehlerhandling) zeigt, dass man sich keine Gedanken um Strukturierung gemacht hat. Strukturierung heißt "Einschachteln von Problemlösungsmethoden" und ist die Grundlage von Wiederverwendbarkeit. Goto whereever ist nicht wiederverwendbar, eine Routine namens CleanupObjects schon.

Harry25
27.04.2011, 13:36
Hallo !

Das verlinkte Beispiel habe ich mir angesehen. Dies finde ich wie dargestellt per se unübersichtlich, was denke ich auch Ziel war.
GoTo sollte gezielt und so sparsam wie möglich eingesetzt werden. Andererseitz sollte Code auch nicht in zu kleine Bruckstücke aufgeteilt werden. Dann wird er auch unübersichtlich.
Mit der Aussage "selbstveränderndem Code" sollte man auch vorsichtig sein.

Da ich in den vergangenen Jahren mittlerweile mehrere hundertausende Codezeilen geschrieben habe, denke ich, kenne ich das richtige Maß.
Ich denke auch jeder sollte für sich beim Programmieren oder wenn er Code umschreibt Gedanken machen was er macht. Dann funktiert es auch.

Da keiner hier wirklich ein schlagendes Argument gegen einen sehr sparsamen gezielten Einsatz von GoTo bringt möchte ich gerne zu meiner Frage zurückkehren. Ich denke das Forum ist da um Anworten zu erhalten. Für Philosophiefragen wende ich mich an andere Foren.

Für alle die meine Frage nicht mehr wissen. Kann ich der GoTo-Anweisung eine Zeilennummer auch über eine Variable mitteilen ?

Sollte es keinem der Insider hier wissen wie oder ob es geht ?

FW
27.04.2011, 13:41
... nein! Alternativ könntest Du in einer SELECT-CASE-Anweisung, abhängig von dem Inhalt der "GOTO-Variablen" zu einer benamten Marke springen...

Atrus2711
27.04.2011, 13:42
Soweit ich weiß, geht das nicht.

jeder sollte für sich beim Programmieren oder wenn er Code umschreibt Gedanken machen was er macht
und darum, was andere machen, die künftig mal diesen Code warten sollen. Zu sich selbst ist fast jeder kompatibel.

GoTo sollte gezielt und so sparsam wie möglich eingesetzt werden
Da sind wir uns einig: so sparsam wie möglich. Heißt: wenn es ohne Goto geht, mach es ohne Goto. Und hier geht es ohne Goto. Wenn man will.

Harry25
27.04.2011, 14:21
@Atrus2711

Ich kann denke ich sagen das, nicht nur ich sondern jeder der einigermaßen gut VBA beherrscht jede Zeile meines Codes und sei er noch so alt versteht. Gedanken machen beim Programmieren heisst auch so zu programmieren, das es jedermann versteht, denn man entwickelt sich selbst auch weiter und man muß es dann nach vielen Jahren selbst aus dem FF noch verstehen. So sit es jedenfalls bei mir. Ich weiß das es einige gibt die Programmieren und meinten sie hätten es verständlich, übersichtlich, nachvollziehbar, ... programmiert und blicken es selbst am nächsten Tag bereits nicht mehr. Kleine Übertreibung :-). Realistisch nach ein paar Tagen oder Wochen. Soviel zum Kommentar zum ersten Zitat.

Danke für die anfängliche Zustimmung zum zweiten Zitat. Ohne jedoch meinen Code zu kennen, kannst du nicht beurteilen, ob es ohne geht. Ich komme jedoch nach reiflicher Überlegung zu dem Schluß, das der Code vernünftig geschrieben and der Stelle nicht ohne auskommt. Ich finde es daher überheblich zu sagen das es ohne geht.

Danke für das Statement in der ersten Zeile. Damit weiß ich wenigstens das du es nicht weißt was ich trotz allem positiv finde.

@FF
Danke für den Tipp. Leider lässt die Select-Case-Anweisung den Code auch nicht übersichtlicher werden, genauso wie eine Aufteilung in 20 (Anzahl aus dem hohlen Bauch heraus) Einzelprozeduren. Trotzdem Danke.


Schade das ich nicht richtig angemeldet bin, dann hätte ich mit dem ganzen philosofieren mächtig Beitragspunkte und Karma sammeln können ;-)

Atrus2711
27.04.2011, 14:30
Hallo Harry,

um nach einem Fehler an eine bestimmte Stelle im Code zurückspringen zu wollen, scheint ein Goto nötig zu sein, und die Behauptung, das sei unnötig, nennst du überheblich. Aber: mit einem anderen Aufbau wäre es gar nicht nötig, zu Zeile X zu springen. Springen zu Zeile X ist eben keine Struktur. Denn die Struktur liegt nicht in Zeile X, sondern in dem "Ansinnen", das in/ab diese Zeile gelöst werden soll. Das könnten z.B. "Aufräumarbeiten" an Objektvariablen sein oder alternative Verfahren, wenn irgendwelche Vorbedingungen nicht gegeben sind, oder was auch immer.

Ohne jedoch meinen Code zu kennen, kannst du nicht beurteilen, ob es ohne geht
Du zeigst ihn ja nicht her. :) Wenn du mal ausführst, was an der anzuspringenden Stelle geschehen soll, kann man meine These des "Das-geht-auch-anders" vielleicht sogar im Praxisbeweis antreten.

Dass dein Code an dieser Stelle ein Goto erzwingt, glaube ich gern. Ich glaube aber nicht, dass dein Code der einzig denkbare Code ist. DAS nenn ich überheblich.

ebs17
27.04.2011, 14:33
Anmerkung zur GoTo-Anweisung (aus meiner VBA-Hilfe):
Durch zu viele GoTo-Anweisungen wird der Code schwer verständlich, und das Testen des Codes wird schwieriger. Verwenden Sie daher möglichst nur die Anweisungen zu strukturierten Ablaufsteuerung (Do...Loop, For...Next, If...Then...Else, Select Case).
Das heißt für mich auf deutsch: Jedes GoTo (außer dem obligatorischen zur Fehlerbehandlung) ist eines zu viel, da ich Testen für wichtig halte und ich im Zweifel zu einem strukturierten Ablauf neige.

Und: Wenn schon "philosofieren", dann richtig filosofieren.

FW
27.04.2011, 14:37
... naja, aber nachdem Harry mehrmals darauf hingewiesen hat, dass er sich der grundsätzlichen GOTO-Problematik bewusst ist, könnte man/frau sich ja nun mal seiner eigentlichen Frage widmen. Durch die Vielzahl der möglichen Verzweigungen (lt. Harry ca. 20) und der Unmöglichkeit über eine Variable zu einer nummerierten Zeile zu springen werden die Grenzen des Vorhabens ja ohnehin aufgezeigt...

avogt_at_home
27.04.2011, 14:43
Hallo,
Ich denke das ist ein Programmstruktur-Problem.
Ich empfehle den Algorithmus sauber zu entwickeln z.B. unter der Zuhilfenahme von Nassi-Schneiderman-Diagramm (http://de.wikipedia.org/wiki/Nassi-Shneiderman-Diagramm) (die älteren werden es noch kennen) oder eines Programmablaufplan (http://de.wikipedia.org/wiki/Programmablaufplan).

Gruß Andreas

Harry25
27.04.2011, 15:07
Hallo ein letztes mal in diesem Thema !

Sorry FW das ich "@FF" geschrieben habe.

Danke an den Kollegen der den Schreibfehler gefunden hat. Darauf habe ich nicht mehr geachtet. Wer noch weitere findet darf sie behalten ;-).

Ich möchte mich ernsthaft für die wenigen hilfreichen Beiträge wirklich bedanken.

Desweiteren Dank an die Philosophen, Theoretiker, ... auch wenn sie dadurch zur Fragebeantwortung nicht wirklich beigetragen haben, als ihre Beitragszahl zu erhöhen.

Ich werde mich aus dem Thema verabschieden und wieder selbst nach einer vernünftigen Lösung suchen. Hoffe vielleicht in einem nächsten Thema mehr zielführende Hilfe zu bekommen.

Den Admin bitte ich hiermit das Thema zu schließen, da es mir selbst scheinbar nicht möglich ist.

Gruß an alle.

Atrus2711
27.04.2011, 15:15
wieder selbst nach einer vernünftigen Lösung suchen
Vernunft := das, was man schon immer so gemacht hat :rolleyes:

Du hast Vorschläge bekommen und von Unmöglichkeiten erfahren. Was brauchst du noch, um zu erkennen, dass es so nicht geht?

Aber nur weiter so. Mit genügend Hydraulik dahinter gibts keine Sackgassen.

Im übrigen haben viele hier den "5-Sterne-Status" schon erreicht, und höher gehts eh nicht. Es geht nicht ums Karma. Es geht um guten Code.

Josef P.
27.04.2011, 18:01
Hallo!

Den VbWatchdog könnte man übrigens für das beschriebene Vorhaben missbrauchen.
Dim X As Long
X = 1

ErrEx.GoToBookmark X
Debug.Print 0

ErrEx.Bookmark = 2
Debug.Print 2
Exit Sub

ErrEx.Bookmark = 1
Debug.Print 1
X = 2
ErrEx.GoToBookmark X

mfg
Josef

Maxel
27.04.2011, 18:04
Hallo Harry,
Den Admin bitte ich hiermit das Thema zu schließen, da es mir selbst scheinbar nicht möglich ist.
So (http://www.ms-office-forum.net/forum/showthread.php?t=102899#erledigen) geht's.

Arne Dieckmann
27.04.2011, 19:03
@Maxel: Wenn der Threadersteller ein Gast ist, geht's so nicht.

Maxel
27.04.2011, 19:17
@Arne,

und da heißt es immer, der Gast ist der König. :grins: