Januar 19, 2021, 06:12:51

Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!


Zwei verschachtelte Schleifen in VBA wobei erste Schleife nur einmal durchlaufen

Begonnen von brudertugg, Dezember 14, 2020, 09:47:22

⏪ vorheriges - nächstes ⏩

brudertugg

Hallo Forum,
hier ist er wieder der VBA Neuling.
Ich habe versucht meine Tabelle mit berechneten Werten zu füllen.
Dazu habe ich zwei Schleifen, das Ziel ist mit der inneren Schleife meine Datensätze (ca. 1300 Stück) in der ersten Spalte "HDM_Ebene1" zu berechnen.
Dies funktioniert auch.
Nun soll aber in der äußeren Schleife die Tabellenspalte gewechselt werden und die innere Schleife erneut durchlaufen werden. Nun soll die Spalte "HDM_Ebene2" berechnet werden. Die Rechnung dazu bleibt gleich.
Dies möchte so lange durchführen bis die ermitteltet Anzahl an Spalten erreicht ist, in meinem Fall hier 8x.
Problem ist nun, das der Code mir die erste Spalte "HDM_Ebene1" problemlos pflegt, dann aber aussteigt und beendet ist. Die äußere Schleife wird also nicht wiederholt.

Seht mir meine VBA Struktur bitte nach, dies ist mein erstes VBA unterstütztes Projekt.

Hoffe es findet sich jemand der den Fehler finden kann.

Danke
schon jetzt
brudertugg


[Sub Ebene1bisEnde()

Dim AnzDatensaetze   As Double
Dim db              As DAO.Database
Dim rs              As DAO.Recordset
Dim strSQL          As String
Dim Ebenevar        As Variant
Dim i               As Long
Dim a               As Long
Dim Anzahlakt       As Variant  'Aktuelle Anzahl Datensatz
Dim Anzahlvorher    As Variant  'Anzahl von Datensatz zuvor
Dim ebenevorher     As Variant
Dim Ebenenzaehler   As Variant
Dim SpalteEbenen    As String
Dim EbenenAnzahlmax As Variant

     
   If SpalteEbenen = Empty Then
   SpalteEbenen = "HDM_Ebene1"
   Else
   SpalteEbenen = SpalteEbenen
   End If

   If a = Empty Then
   a = 1
   Else
   a = a
   End If
   
   If ebenevorher = Empty Then
   ebenevorher = 1
   Else
   ebenevorher = ebenevorher
   End If
   
   If Ebenenzaehler = Empty Then
   Ebenenzaehler = 1
   Else
   Ebenenzaehler = Ebenenzaehler
   End If

 
   'Auslesen max von Ebene
        EbenenAnzahlmax = DMax("HDM_Ebene", "stbl_Hierachieebenen")
            If IsNull(EbenenAnzahlmax) Then
                MsgBox "Keine Werte in der Tabelle"
                    Exit Sub
                Else
                'Hier passiert nichts
            End If
           
 



   Set db = CurrentDb                                   ' Datenbank definieren
   strSQL = "SELECT * FROM stbl_Hierachieebenen"        ' SQL-String definieren
   Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)     ' Recordset öffnen (schreibender Zugriff)
   

      'Schleife für Anzahl Ebenen
      Do Until a = EbenenAnzahlmax
          If a = EbenenAnzahlmax Then
            Exit Do

            Else
                   
                   
                   'Anzahl der vorhandenen Datensätze ermitteln
                   rs.MoveLast
                   AnzDatensaetze = rs.RecordCount
                   'Ende Anzahl der vorhandenen Datensätze ermitteln
                   'zu erstem Datensatz springen
                   rs.MoveFirst
                   
                   'innere Schleife durchlaufen der Einträge in der Tabelle
                   Do Until i = AnzDatensaetze
                      If i = 10 Then                        'Schleife beendet nach x Anzahl Datensätzen
                        Exit Do
                   
                      Else
                   
                   
                        Ebenevar = rs!HDM_Ebene                           ' Wert auslesen
                        Anzahlakt = rs!Anzahl                             ' Wert auslesen
               
                         'MsgBox SpalteEbenen
                           
                        'Berechnen Ebenen 1 bis n
                        rs.Edit

                        If Ebenevar = a Then
                        Ebenenzaehler = Anzahlakt
                       
                        ElseIf Ebenevar > a Then
                        Ebenenzaehler = ebenevorher
                        Else
                        Ebenenzaehler = 1
                       
                        End If
                   
                        rs.Fields(SpalteEbenen).Value = Ebenenzaehler
                        rs.Update
                       
                 
                        ' Wichtig!!! Sonst wird die innere Schleife nie verlassen
                        i = i + 1
                       
                        Anzahlvorher = Anzahlakt
                        ebenevorher = Ebenenzaehler
                        rs.MoveNext                                       ' den nächsten Datensatz ansteuern.
                                                                 
                      'MsgBox "innere Schleife " & i
                      End If
   
                   Loop
   
           
                'MsgBox "Schleife2 fertig durchlaufen"
         
                'rs.Close                                             ' Recordset schließen

        ' Wichtig!!! Sonst wird die äussere Schleife1 nie verlassen
        a = a + 1
        Ebenenzaehler = a
         
        SpalteEbenen = "HDM_Ebene" & Ebenenzaehler


        End If
       
    Loop
   
MsgBox "Ebenen 1 bis " & EbenenAnzahlmax & " wurden berechnet"
 
rs.Close



End Sub]

 

DF6GL

Hallo,

dann debugge halt mal..


Haltepunkt an den Anfang des Codes setzen und mit Einzelschritt (F8) durchlaufen, dabei die Variableninhalte prüfen.

Zudem gibt es das "Lokal Fenster" und das "Überwachungsfenster"


Schreibe "Option Explicit" in JEDEN Modulkopf unter "Option Compare Database" und stelle die Eigenschaften des VBA-Editor entspr. ein.


Die Spaltenebenen sollten zudem besser so berechnet werden (Anpassungen im Rest des Codes nicht vegessen!):
Zitat.
.
.
   'Schleife für Anzahl Ebenen
      Do Until a = EbenenAnzahlmax
          If a = EbenenAnzahlmax Then
            Exit Do

            Else
                   

a=a+1
 SpalteEbenen = "HDM_Ebene" & a
.
.

brudertugg

Hallo Franz,
ich schreibe mal besser nicht was nun mein zweites ich zu mir spricht....
Es hat was mit "Mein Gott bist du do..." zu tun.
Ich danke dir, beim debuggen ist mir aufgefallen, dass die Variable i in der inneren Schleife seinen max Wert mit in die nächste Runde genommen hat. Ein i = 1 vor dem Do until ... hat hier geholfen.

Jetzt muss ich noch schauen dass der letzte Datensatz mit berechnet wird und dass die äußere Schleife einen Durchgang mehr macht.
Vermutlich ja ein Thema meiner Ausstiegsbedingung
If i = AnzDatensaetze Then                       
  Exit Do 
...

Gruß
brudertugg

DF6GL

Hallo,

auch in der inneren Schleife ist

 Do Until i = AnzDatensaetze
                      If i = 10 Then                        'Schleife beendet nach x Anzahl Datensätzen
                        Exit Do
                   
                      Else

Unsinn.


Do Until i = AnzDatensaetze
.
.
Loop

Durchläuft den Code solange, wie i < AnzDatensätze ist.

Vielleicht ist es besser zu schreiben:


Do

.
.

Loop Until i = AnzDatensaetze

brudertugg

Hallo Franz,
ich versuche das mal und setze das until zum loop.
Momentan habe ich das so geregelt und es scheint bisher zu laufen:
                   Do Until i = AnzDatensaetze + 1
                      If i = AnzDatensaetze + 1 Then                     
                        Exit Do
                   
                        Else

Auf die Schnelle hab ich deinen ersten Vorschlag a=a+1 ohne die If Bedingung nicht hinbekommen.
Das werde ich auch nochmal versuchen.

Danke Dir für die schnellen Antworten.
Gruß
brudertugg

DF6GL

Hallo,

Deine Code-Struktur ist unvorteilhaft...

Reduziere die Bedingungszeilen auf ein Minimum, es sind so gut wie keine If-Statements erforderlich.


Do Until i = AnzDatensaetze + 1

sicher läuft das, aber schwer zu lesen(soll heißen, +1 ist auf den ersten Blick nicht transparent) und es kommt auf den sonstigen Kontext an...