Prozedurdurchlauf

Moin auch,

In einem Makro rufe ich ein anderes Makro auf. Der Code sieht also so aus:
Sub Makro1()

If blabla then
GoSub test
else blabla

Anweisung
test:
blabla
End Sub
Wenn jetzt die If-Schleife nicht durchlaufen wird, wird dann am Ende, also nach Anweisung, begonnen, das Makro test zu durchlaufen, obwohl es nie aufgerufen wurde?

fragende Grüße,

Ralph

Hallo.

In einem Makro rufe ich ein anderes Makro auf. Der Code sieht
also so aus:
Sub Makro1()

If blabla then
GoSub test
else blabla

Anweisung
test:
blabla
End Sub
Wenn jetzt die If-Schleife nicht durchlaufen wird, wird dann
am Ende, also nach Anweisung, begonnen, das Makro test zu
durchlaufen, obwohl es nie aufgerufen wurde?

ja. Das ist der Nachteil, wenn man die veraltete Variante mit Gosub verwendet.

Besser ist es, Du wirfst den Teil:

test:
blabla

raus und schreibst dafür:

Private Sub Test()
blabla
End Sub

Statt …

Gosub Test

schreibst Du einfach nur …

Test

Das macht was Du möchtest, ist übersichtlicher und hat das Problem nicht.

Wenn Du aber unbedingt mit Gosub abrbeiten möchtest, schreibe in die Zeile vor …

test:

noch ein …

Exit Sub

… dann geht auch das.

Gruß Rainer

Hallo Rainer,

dat klappt nicht, was aber an der Struktur des Makros liegt. Ich muss noch ein bischen meditieren, hoffentlich komme ich auf eine Lösung. Danke erstmal.

Ralph

Hallo Ralph,

dat klappt nicht

was klappt nicht?
Das antike Gosub durch eine Prozedur ersetzen?

Doch, das klappt immer.
Ein Beispiel mit VB, einmal mit Gosub, einmal mit einer Prozedur:

Option Explicit

Private Sub Command1\_Click()
 test
End Sub

Private Sub test()
 Label1.Caption = "Versuch"
End Sub

Private Sub Command2\_Click()
 GoSub eintragen
 Exit Sub
eintragen:
 Label1.Caption = "Probe"
End Sub

Das klappt auch mit VBA so.

Gruß Rainer

Hallo Rainer,

irgendwie klappt der Rücksprung nicht. Das sieht jetzt so aus:
Sub Makro1()

If blabla then
Call test(Variablen)
Else blabla

Anweisung
End Sub
Private Sub test(Variablen)
Anweisung1
test2:
blabla
If Bedingung then GoSub test2
End Sub

test wird aus Makro1 aufgerufen (das klappt). test2 soll innerhalb von test mindestens einmal durchlaufen werden (das klappt auch). Wenn Bedingung wahr ist, soll test2 nochmals durchlaufen werden(auch das klappt). Wenn Bedingung nicht wahr ist, müsste doch eigentlich der Sprung zurück zum Aufruf von test in Marko1 erfolgen. Das Biest geht aber nach End Sub. Was mache ich denn falsch?

fragende Grüße,

Ralph

Hallo Ralph,

irgendwie klappt der Rücksprung nicht.

Deine Unterroutine hat kein Return, der kommt nicht zurück.
Du hast ein Gosub in der Unterroutine, die ruft sich selbst auf.
Wolltest Du wirklich eine rekursive prozedur schreiben?

Du verwendest immer noch Gosub. Warum?

Gosub gibt es in VB/VBA noch weil so alte Programme leichter zu portieren waren. Das braucht heute kein Mensch mehr! Gosub dürfte man ruhig aus dem Sprachumfang entfernen, es würde nicht fehlen.

Das sieht jetzt so aus:
Sub Makro1()

If blabla then
Call test(Variablen)
Else blabla

Anweisung
End Sub
Private Sub test(Variablen)
Anweisung1
test2:
blabla
If Bedingung then GoSub test2
End Sub

test wird aus Makro1 aufgerufen (das klappt). test2 soll
innerhalb von test mindestens einmal durchlaufen werden (das
klappt auch). Wenn Bedingung wahr ist, soll test2 nochmals
durchlaufen werden(auch das klappt). Wenn Bedingung nicht wahr
ist, müsste doch eigentlich der Sprung zurück zum Aufruf von
test in Marko1 erfolgen.

Nein, dann kommt als nächstes End Sub der Prozedur Test und dann geht es zurück in die afrufende Prozedur. Dort zum Befehl der nach dem Aufruf steht. Bei Deinen Codefragmenten zu dem End If, das Du nicht mit gepostet hast.

Das Biest geht aber nach End Sub. Was
mache ich denn falsch?

Das kann ich den Codeschnipseln nicht ansehen.

Poste doch bitte lauffähigen Code und verwende dabei den pre Tag. Wenn Du nur Bruchstücke postest besteht immer die Gefahr, daß der Fehler in dem Teil steckt, den Du weg gelassen hast, weil Du den Fehler dort nicht vermutest.

Gruß Rainer

Hallo Rainer,

ja, ich wollte eine rekursive Prozedur. Das GoSub test2 nehme ich, weil Test2 innerhalb von test mindestens einmal durchlaufen werden muss. Evtl. aber eben auch 2-, 3-mal oder noch öfter.
Hier ist der Code, alle Variablen (auch die nicht deklarierten, die aus anderen Makros stammen) funktionieren.

Worksheets(FilStr$).Select
Do Until sscnt \> pubSSCnt Or emptycnt = 9999
 emptycnt = 0
 Do Until emptycnt \> 4
 rr = rr + 1
 cc = 1
 If Trim(Worksheets(FilStr$).Cells(rr, cc).VALUE) "" Then
 emptycnt = 0
 If Trim(Worksheets(FilStr$).Cells(rr, 1).VALUE) = "+BV" And \_
 Trim(Worksheets(FilStr$).Cells(rr, 2).VALUE) = "1012\_001" Then
 ActiveBVfor1012001$ = "Y"
 vaicnt = vaicnt + 1
 GoSub CntComp
 End If
 If Trim(Worksheets(FilStr$).Cells(rr, 1).VALUE) = "+ES" Then
 emptycnt = 9999
 End If
 End If
 Loop
 sscnt = sscnt + 1
 Mid$(FilStr$, Len(FilStr$), 1) = Trim(Str$(Int(sscnt)))
 rr = 0
Loop
Exit Sub

CntComp:

inside = rr

test:
inside = inside + 1
Do While Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) "+EV"
 inside = inside + 1
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "ORD" Then
 DGORD$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMPCAT" Then
 COMPCAT$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "PRECL" Then
 PRECL$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMPLOW" Then
 COMPLOW$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "PRECU" Then
 PRECU$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMPUPP" Then
 COMPUPP$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMPAVG" Then
 COMPAVG$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMPEXP" Then
 COMPEXP$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMPLOWDEC" Then
 COMPLOWDEC$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMUPPDEC" Then
 COMPUPPDEC$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMPAVGDEC" Then
 COMPAVGDEC$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "SUBIDREF" Then
 SUBIDREF$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "SUBCATREF" Then
 SUBCATREF$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
'neuer loop
 Loop
 If vaicnt \> 1 Then
 'nextrr = nextrr + 1
 End If

' Sheets(pubwsResults).Select
 Worksheets(pubwsResults).Cells(nextrr, pubRegHD1).VALUE = SUBIDREF$
 Worksheets(pubwsResults).Cells(nextrr, pubRegHD2).VALUE = SUBCATREF$
 'Worksheets(pubwsResults).Cells(nextrrpubRegHD3).VALUE = IDENTIFIER$
 Worksheets(pubwsResults).Cells(nextrr, pubRegHD4).VALUE = COMPCAT$
 Worksheets(pubwsResults).Cells(nextrr, pubRegHD5).VALUE = ORD$
 Worksheets(pubwsResults).Cells(nextrr, pubRegHD6).VALUE = COMPAVG$
 Worksheets(pubwsResults).Cells(nextrr, pubRegHD7).VALUE = COMPEXP$
 Worksheets(pubwsResults).Cells(nextrr, pubRegHD8).VALUE = PRECU$
 Worksheets(pubwsResults).Cells(nextrr, pubRegHD9).VALUE = COMPUPP$
 Worksheets(pubwsResults).Cells(nextrr, pubRegHD10).VALUE = PRECL$
 Worksheets(pubwsResults).Cells(nextrr, pubRegHD11).VALUE = COMPLOW$
 Worksheets(pubwsResults).Cells(nextrr, pubRegHD12).VALUE = COMPEXCVAL$
 nextrr = nextrr + 1

 COMPCAT$ = ""
 PRECL$ = ""
 DGORD$ = ""
 DGCOMPREL$ = ""
 DGAFlag = ""
 DGVaclid$ = ""
 DGRvlid$ = ""

laufzahl = inside




Do While Trim(Worksheets(FilStr$).Cells(laufzahl, 1).VALUE) "+ES"
 BAI$ = Trim(Worksheets(FilStr$).Cells(laufzahl, 1).VALUE)
 estvp$ = Trim(Worksheets(FilStr$).Cells(laufzahl, 2).VALUE)
 If BAI$ = "+BAI" And estvp$ = "$ESTVP" Then
 inside = inside + 1
 GoSub test
 End If
 laufzahl = laufzahl + 1
 inside = laufzahl
Loop

'Einschubende
End Sub

Hallo,

ja, ich wollte eine rekursive Prozedur. Das GoSub test2 nehme
ich, weil Test2 innerhalb von test mindestens einmal
durchlaufen werden muss.

In Deinem Code steht nirgendwo ‚Return‘. Dann verhält sich Gosub nur wie Goto.

...
Gosub Test
...
Exit Sub
Test:
DoEvents
Return

Lässt Du das ExitSub weg und den Code auf ‚Test:‘ laufen, bekommst Du den Fehler: ‚Return ohne Gosub‘. Lässt Du ‚Return‘ weg, wird Dein Gosub zum Goto.

Mach es so:

...
Call Test(Parameter)
...

Private Sub Test(ByVal Parameter As ...)
...
If Bedingung = True Then
 Call Test(Parameter)
End If
...
Exit Sub

Ergänzung
Zur Erklärung …

Option Explicit

Private Sub Command1\_Click()
Dim a As Integer
 GoSub test
 Label1.Caption = "4"
 Label2.Caption = a
 Exit Sub
test:
 a = a + 1
 If a 

Command1\_Click ist richtig. 
In Command2\_Click lasse ich den Code in Test hineinlaufen, habe das Exit Sub weg gelassen. Das führt aber dann zum Fehler: 'Return ohne Gosub' und man ist versucht, das Return auch weg zu nehmen. Du hast das getan. 

Nun passiert folgendes:
Das erste Gosub ruft den Programmteil 'Test:' auf, das Programm kehrt aber nie mehr zurück, weil das Return fehlt. Der Programmteil: 'Label1 = "4"' wird nie durchlaufen. Label1 bleibt leer, nur in label2 steht die 4. Ersetze ich alle Gosub durch Goto passiert das Selbe! 

Gruß Rainer

Hallo Rainer,

ich glaube, ich habe es begriffen. Dummerweise bringt mich das zu einer neuen Verhaltensweise des Codes, die ich nicht verstehen kann. Das Ding sieht jetzt so aus:

Worksheets(FilStr$).Select
Do Until sscnt \> pubSSCnt Or emptycnt = 9999
 emptycnt = 0
 Do Until emptycnt \> 4
 rr = rr + 1
 cc = 1
 If Trim(Worksheets(FilStr$).Cells(rr, cc).VALUE) "" Then
 emptycnt = 0
 If Trim(Worksheets(FilStr$).Cells(rr, 1).VALUE) = "+BV" And \_
 Trim(Worksheets(FilStr$).Cells(rr, 2).VALUE) = "1012\_001" Then
 ActiveBVfor1012001$ = "Y"
 vaicnt = vaicnt + 1
 Call CntComp(FilStr$, nextrr, rr)
 End If
 If Trim(Worksheets(FilStr$).Cells(rr, 1).VALUE) = "+ES" Then
 emptycnt = 9999
 End If
 End If
 Loop
 sscnt = sscnt + 1
 Mid$(FilStr$, Len(FilStr$), 1) = Trim(Str$(Int(sscnt)))
 rr = 0
Loop
Exit Sub
End Sub
Private Sub CntComp(ByVal FilStr$, nextrr, rr)

inside = rr
Call test(inside, nextrr, FilStr$, pubRegHD1, pubRegHD2, pubRegHD3, pubRegHD4, pubRegHD5, pubRegHD6, pubRegHD7, pubRegHD8, pubRegHD9, pubRegHD10, pubRegHD11, pubRegHD12, pubwsresults)
End Sub
Private Sub test(inside, nextrr, FilStr$, pubRegHD1, pubRegHD2, pubRegHD3, pubRegHD4, pubRegHD5, pubRegHD6, pubRegHD7, pubRegHD8, pubRegHD9, pubRegHD10, pubRegHD11, pubRegHD12, pubwsresults)

inside = inside + 1
Do While Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) "+EAI" And Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) "+ES"
 inside = inside + 1
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "ORD" Then
 DGORD$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMPCAT" Then
 COMPCAT$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "PRECL" Then
 PRECL$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMPLOW" Then
 COMPLOW$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "PRECU" Then
 PRECU$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMPUPP" Then
 COMPUPP$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMPAVG" Then
 COMPAVG$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMPEXP" Then
 COMPEXP$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMPLOWDEC" Then
 COMPLOWDEC$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMUPPDEC" Then
 COMPUPPDEC$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "COMPAVGDEC" Then
 COMPAVGDEC$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "SUBIDREF" Then
 SUBIDREF$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
 If Trim(Worksheets(FilStr$).Cells(inside, 1).VALUE) = "SUBCATREF" Then
 SUBCATREF$ = Trim(Worksheets(FilStr$).Cells(inside, 2).VALUE)
 End If
'neuer loop
 Loop
 If vaicnt \> 1 Then
 'nextrr = nextrr + 1
 End If

 'Sheets(pubwsresults).Select
 Worksheets(pubwsresults).Cells(nextrr, pubRegHD1).VALUE = SUBIDREF$
 Worksheets(pubwsresults).Cells(nextrr, pubRegHD2).VALUE = SUBCATREF$
 'Worksheets(pubwsResults).Cells(nextrrpubRegHD3).VALUE = IDENTIFIER$
 Worksheets(pubwsresults).Cells(nextrr, pubRegHD4).VALUE = COMPCAT$
 Worksheets(pubwsresults).Cells(nextrr, pubRegHD5).VALUE = ORD$
 Worksheets(pubwsresults).Cells(nextrr, pubRegHD6).VALUE = COMPAVG$
 Worksheets(pubwsresults).Cells(nextrr, pubRegHD7).VALUE = COMPEXP$
 Worksheets(pubwsresults).Cells(nextrr, pubRegHD8).VALUE = PRECU$
 Worksheets(pubwsresults).Cells(nextrr, pubRegHD9).VALUE = COMPUPP$
 Worksheets(pubwsresults).Cells(nextrr, pubRegHD10).VALUE = PRECL$
 Worksheets(pubwsresults).Cells(nextrr, pubRegHD11).VALUE = COMPLOW$
 Worksheets(pubwsresults).Cells(nextrr, pubRegHD12).VALUE = COMPEXCVAL$
 nextrr = nextrr + 1

 COMPCAT$ = ""
 PRECL$ = ""
 DGORD$ = ""
 DGCOMPREL$ = ""
 DGAFlag = ""
 DGVaclid$ = ""
 DGRvlid$ = ""

laufzahl = inside

Do While Trim(Worksheets(FilStr$).Cells(laufzahl, 1).VALUE) "+ES"
 BAI$ = Trim(Worksheets(FilStr$).Cells(laufzahl, 1).VALUE)
 estvp$ = Trim(Worksheets(FilStr$).Cells(laufzahl, 2).VALUE)
 If BAI$ = "+BAI" And estvp$ = "$ESTVP" Then
 inside = inside + 1
 Call test(inside, nextrr, FilStr$, pubRegHD1, pubRegHD2, pubRegHD3, pubRegHD4, pubRegHD5, pubRegHD6, pubRegHD7, pubRegHD8, pubRegHD9, pubRegHD10, pubRegHD11, pubRegHD12, pubwsresults)
 End If
 laufzahl = laufzahl + 1
 inside = laufzahl
Loop
Exit Sub
'Einschubende
End Sub

Im letzten Do…Loop komme ich irgendwann auf eine Zelle, deren Inhalt „+ES“ ist. Dann springt das Ding zu Exit Sub wie gewünscht, im nächsten Schritt aber auf das End If innerhalb des Do…Loop. Warum um Himmels Willen das denn? (nachgeprüft per schrittweiser Auaführung)

fragende Grüße,

Ralph

Hallo Ralph,

Im letzten Do…Loop komme ich irgendwann auf eine Zelle, deren
Inhalt „+ES“ ist. Dann springt das Ding zu Exit Sub wie
gewünscht, im nächsten Schritt aber auf das End If innerhalb
des Do…Loop. Warum um Himmels Willen das denn?

rekursive Programmierung. :smile:

Die Prozedur ruft sich selbst auf.

Nach dem End Sub wird der Code mit dem Befehl nach dem Aufruf fortgesetzt.

Probiere mal den folgenden Code aus, dann wird’s sicher klar:

Option Explicit

Private Sub Command1\_Click()
 cnt 0
End Sub

Private Sub cnt(ByVal n As Integer)
 n = n + 1
 List1.AddItem "vor dem Aufruf " & CStr(n)
 If n 


In List1 steht dann:


vor dem Aufruf 1
vor dem Aufruf 2
vor dem Aufruf 3
vor dem Aufruf 4
vor dem Aufruf 5
nach dem Aufruf 5
nach dem Aufruf 4
nach dem Aufruf 3
nach dem Aufruf 2
nach dem Aufruf 1


Gruß Rainer

Hallo Rainer,

Nach dem End Sub wird der Code mit dem Befehl nach dem Aufruf
fortgesetzt.

Jupp, in deinem Beispiel wäre dass das End Sub nach dem cnt 0, also ist Ende. Wo wird da nochmal was aufgerufen?

Probiere mal den folgenden Code aus, dann wird’s sicher klar:

nein, leider nicht. Dummerweise funktioniert es genau so, wie du das sagst, egal ob ich es verstehe oder nicht :frowning:(

Wenn ich jetzt in meinem Code das Makro test nicht als Makro definire, sondern als Sprungmarke innerhalb des Makros CntComp müsste es doch eigentlich gehen. CntComp wird aufgerufen, innerhalb dessen läuft test minestens einmal ab, wenn Bedingung wahr ist zurück auf test etc., wenn Bedingung nicht wahr ist, beende Makro CntComp. Das werde ich mal versuchen, mir gehen einfach die Ideen aus.

Vielen Dank,

Ralph

Hi Ralph,

Jupp, in deinem Beispiel wäre dass das End Sub nach dem cnt 0,
also ist Ende. Wo wird da nochmal was aufgerufen?

Option Explicit

Private Sub Command1\_Click()
 cnt 0
End Sub

Private Sub cnt(ByVal n As Integer)
 n = n + 1
 List1.AddItem "vor dem Aufruf " & CStr(n)
 If n 

Da steckt der recursive Aufruf.



> > Probiere mal den folgenden Code aus, dann wird's sicher klar:
> 
> nein, leider nicht. Dummerweise funktioniert es genau so, wie  
> du das sagst, egal ob ich es verstehe oder nicht :frowning:(


Die Prozedur wird aufgerufen und n wird um 1 erhöht.
Dann wird 'vor ..' ausgegeben.
Dann ruft sich die Prozedur selbst auf, bis zum 'nach ..' ist das Programm noch nicht gekommen. 
N wird wieder um 1 erhöht, zum 'nach ...' kommt das Programm immer noch nicht, die Prozedur steckt in einer Schleife, bis 'n = 5' ist.

Erst dann wird zu ersten mal 'nach ...' ausgegeben und die Prozedur beendet. Das Programm springt dann da hin, wo es her gekommen ist!
Das war der letzte Aufruf aus sich selbt, da war 'n' noch 4. Deshalb wird jetzt die 4 ausgegeben und die Prozedur beendet. 
Das Programm springt wieder da hin, wo es her gekommen ist, also wieder in die Prozedur, an die Stelle, an der 'n' noch drei war... 

Der Programmablauf ist recht kompliziert.

Du hast nun den rekursiven Aufruf auch noch in einer Schleife!
Das überfordert meine grauen Zellen, ich kann mir nicht mehr ausmalen, was da passiert. 



> Wenn ich jetzt in meinem Code das Makro test nicht als Makro  
> definire, sondern als Sprungmarke innerhalb des Makros CntComp  
> müsste es doch eigentlich gehen. CntComp wird aufgerufen,  
> innerhalb dessen läuft test minestens einmal ab, wenn  
> Bedingung wahr ist zurück auf test etc., wenn Bedingung nicht  
> wahr ist, beende Makro CntComp. Das werde ich mal versuchen,  
> mir gehen einfach die Ideen aus.


Ich habe noch nicht verstanden, was Du überhaupt mit dem Code vor hast. Mit Excel-VBA hab' ich's nicht so. :frowning: Nur mit VB.

Bist Du sicher, daß Du einen rekursiven Aufruf brauchst und den auch noch aus einer Schleife? Das kann doch kein Mensch mehr denken, was da passiert. 

Gruß Rainer
1 Like

Hallo Rainer,

Das bläst das Gehirn frei:smile:

Ich habe das mal mit der Sprungmarke versucht, scheint zu gehen, zumindest bei einem Beispiel (Ich habe verschiedene Dateien, die eingelesen werden und die scheinen nicht alle identisch zu sein, aber das ist ein anderes Problem). Meine Denke ist die: Ich habe ene Hauptprozedur, gefolgt von Ablauf 1 und Ablauf 2. A1 und A2 müssen beide durchlaufen werden. Unter Umständen muss nach dem ersten Durchlaufen von A1 und A2 A2 nochmal durchlaufen werden und vielleicht auch ein drittes, viertes…Mal. Wie kann man das machen, wenn nicht rekursiv?

Ralph

Hallo Ralph,

Das bläst das Gehirn frei:smile:

ne, das macht das Gehirn kaputt. *gg*

Ich habe das mal mit der Sprungmarke versucht, scheint zu
gehen, zumindest bei einem Beispiel (Ich habe verschiedene
Dateien, die eingelesen werden und die scheinen nicht alle
identisch zu sein, aber das ist ein anderes Problem). Meine
Denke ist die: Ich habe ene Hauptprozedur, gefolgt von Ablauf
1 und Ablauf 2. A1 und A2 müssen beide durchlaufen werden.
Unter Umständen muss nach dem ersten Durchlaufen von A1 und A2
A2 nochmal durchlaufen werden und vielleicht auch ein drittes,
viertes…Mal. Wie kann man das machen, wenn nicht rekursiv?

Mit mehreren Aufrufen aus einer Schleife, aber ohne Rekursion.

Beispiel:

Option Explicit

Private Sub Command1\_Click()
 Auswertung
End Sub

Private Sub Auswertung()
 Dim a As Integer
 While test = False
 a = a + 1
 List1.AddItem a
 Wend
End Sub

Private Function test() As Boolean
 Static n
 n = n + 1
 If n \> 4 Then
 test = True
 Else
 test = False
 End If
End Function

Das wird auf das hinauslaufen, was Du brauchst.

Die Rekursion brauchst Du, wenn es um eine Baumstruktur geht.

Ein Beispiel ist mit einem einfachen Programm alle Verzeichnisse und Unterverzeichnisse und alle deren Inhalte einer Festplatte anzuzeigen. Mit einem rekursiven Programm ist das wenig Code.

Oder ein Programm, das ein Sudoku schnell löst oder auch eine schnelle kleine Sortierroutine für Arrays (Quicksort).

Gruß Rainer

Hallo Ralph,

Ich habe das mal mit der Sprungmarke versucht, scheint zu
gehen, zumindest bei einem Beispiel

in mehreren Jahren Vbalen bist du der Erste der Gosub benutzt.
GOTOs (Sprungmarken) sah ich nahezu immer nur bei On ERROR GOTO .

(Ich habe verschiedene
Dateien, die eingelesen werden und die scheinen nicht alle
identisch zu sein, aber das ist ein anderes Problem).

Sehr schön :smile:

Meine
Denke ist die: Ich habe ene Hauptprozedur, gefolgt von Ablauf
1 und Ablauf 2. A1 und A2 müssen beide durchlaufen werden.
Unter Umständen muss nach dem ersten Durchlaufen von A1 und A2
A2 nochmal durchlaufen werden und vielleicht auch ein drittes,
viertes…Mal. Wie kann man das machen, wenn nicht rekursiv?

Sub tt()
Call Hauptroutine
Call subA1
Do
 Call SubA2
Loop While Umstand = True
End Sub

Gruß
Reinhard

1 Like

Hallo Rainer,

Du hast nun den rekursiven Aufruf auch noch in einer Schleife!
Das überfordert meine grauen Zellen, ich kann mir nicht mehr
ausmalen, was da passiert.

tja, wenn ich ja kapiert hätte was der obige Code von Ralph so macht und vor allem machen soll hätte ich dir ja gerne was gebastelt daß du dir das mit Malen nach Zahlen ausmalen kannst *lächel*

Ich habe noch nicht verstanden, was Du überhaupt mit dem Code
vor hast. Mit Excel-VBA hab’ ich’s nicht so. :frowning: Nur mit VB.

*Aargs* lese ich ungern, Rainer will sich da wohl rauswinden *hihi*

@Ralph, laß dich nicht beirren, das ist vom Programmablauf her erst einmal eindeutig ein VB-Problem.
Wenn Rainer da netterweise einen lauffähigen VB-Code bastelt aus dem was du da hast, natürlich mit korrektem Struktogramm, Programmablauf plan usw. dann übersetze ich das ggfs. :smile:

Bist Du sicher, daß Du einen rekursiven Aufruf brauchst und
den auch noch aus einer Schleife? Das kann doch kein Mensch
mehr denken, was da passiert.

Ja, wird mit F8 recht unübrsichtlich und langwierig…

Gibt es eigentlich für VB ein Programm was die Codezeilen/Prozeduren die ein Vb-Code beim Testen benutzt mitprotokolliert?
Quasi ein Programm was den Code via F8 testet und dabei jede angesprungene Zeile mitnotiert?

Gruß
Reinhard

Hallo Reinhard,

Gibt es eigentlich für VB ein Programm was die
Codezeilen/Prozeduren die ein Vb-Code beim Testen benutzt
mitprotokolliert?
Quasi ein Programm was den Code via F8 testet und dabei jede
angesprungene Zeile mitnotiert?

das wird auch recht unübersichtlich, schließlich gibt’s ja keine Zeilennummern. :smile:

Gruß Rainer

Gibt es eigentlich für VB ein Programm was die
Codezeilen/Prozeduren die ein Vb-Code beim Testen benutzt
mitprotokolliert?
Quasi ein Programm was den Code via F8 testet und dabei jede
angesprungene Zeile mitnotiert?

das wird auch recht unübersichtlich, schließlich gibt’s ja
keine Zeilennummern. :smile:

Hallo Rainer,

in VB5.0 gibts die noch, in VB6.0 nicht mehr?
Okay, auch Zeilennummern sah ich in vielen Jahren Vba nicht mehr in Codes, bis einmalig sehr kürzlich hier im VB-Brett.

Option Explicit
Public Umstand As Boolean
'
Private Sub Command1\_Click()
10 Call Hauptroutine
20 Call SubA1
30 Do
40 Call SubA2
50 Loop While Umstand = False
End Sub
'
Sub Hauptroutine()
MsgBox "H"
End Sub
'
Sub SubA2()
Static Z
Z = Z + 1
MsgBox "A2"
If Z = 3 Then Umstand = True
End Sub
'
Sub SubA1()
MsgBox "A1"
End Sub

Gruß
Reinhard

Tausend Dank
Hallo ihr beiden,

Danke für das Upgrade auf Brain.exe 2.0 :smile: Manchmal ist man einfach wie vernagelt. Ich habe den Code von Reinhard eingebaut und es funktioniert. Schade, dass ich euch nur je ein Sternchen geben kann, ihr habt mir wirklich sehr geholfen.

Ralph