Microsoft Excel

Herbers Excel/VBA-Archiv

Informationen und Beispiele zum Thema MsgBox
BildScreenshot zu MsgBox MsgBox-Seite mit Beispielarbeitsmappe aufrufen

doppelte for schleife - irgendwas ist kaputt


Betrifft: doppelte for schleife - irgendwas ist kaputt von: Marc
Geschrieben am: 29.04.2017 08:45:40

Hi,

keine Ahnung was ich zuletzt kaputt gemacht habe, aber meine zuvor funktionierende for schleife will nicht mehr das tun was ich von ihr will:


    Spalte = 2
    
    'Kategorien pro Monat
    ParentKeys = Parent.Keys
    For i = UBound(ParentKeys) To LBound(ParentKeys) Step -1
    
        'MsgBox ParentKeys(i)
        ChildKeys = Parent(ParentKeys(i)).Keys
        
        For j = LBound(ChildKeys) To UBound(ChildKeys) Step 1
            
            If ChildKeys(j) = "Kat A" Then
                sht.Cells(2, Spalte).Value = ParentKeys(i) & "/" & ChildKeys(j) & " - " & Child( _
ChildKeys(j))
                'sht.Cells(2, Spalte).Value = Child(ChildKeys(j))
            End If
            
            If ChildKeys(j) = "Kat B" Then
                sht.Cells(3, Spalte).Value = ParentKeys(i) & "/" & ChildKeys(j) & " - " & Child( _
ChildKeys(j))
                'sht.Cells(3, Spalte).Value = Child(ChildKeys(j))
            End If
        
        Next j
        
        Spalte = Spalte + 1
       
    Next i
Wie am obigen Beispiel zu sehen baue ich ein Dictionary auf welches als Key einen String (Monatsrepresentation) enthält und als Value ein weiteres Dictionary. Das zweite Dictionary hat als Key eine Kategorie und als Value einen anderen String.

Was ich jetzt versuche ist mit diesem Konstrukt eine Matrix zu befüllen, welche auf der X-Achse die Kategorien hat und auf der Y-Achse die Monate ausweist.

Grundsätzlich befülle ich die Matrix auch abhängig von den vorhandenen Kategorien. Soll heißen wenn im Monat 1 beide Kategorien vorhanden sind werden auch beide Zellen befüllt, gibts in Monat 2 nur Kat A wird auch nur eine Zelle befüllt usw...

Allerdings habe ich es wohl kürzlich geschafft nicht mehr die Values vom "richtigen" Child auszuweisen, sondern immer nur vom ersten Parent.

Die Idee ist ja, dass ich durch das erste Dictionary von hinten nach vorne durchlaufe und pro Eintrag wieder durch das zweite Dictionary laufe. Je nach Inhalt vom 2. Dictionary soll dann die Matrix mit den Values befüllt werden.
Aber aus irgendeinem Grund greife ich nicht den Value vom aktuellen Durchlauf des (2.) Dictionary, sondern immer den vom ersten Durchlauf. Dabei sehe ich aber, dass j immer korrekt hochgezählt wird und auch die Information aus ParentKeys(i) zeigt mir, dass ich beim Eltern-Element richtig durchlaufe.

Mein Eindruck: Aus irgendeinem Grund greife ich nicht auf die richtigen Kinder-Elemente sondern verbleibe irgendwie auf dem ersten Kinds-Element?!

Aktuell sieht eine beispielhafte Befüllung so aus:
          M3             M2              M1
Kat A     M3/Kat A - 1   M2/Kat A - 1    M1/Kat A - 1
Kat B                    M2/Kat B -     
Dabei ist der Value von M2/Kat A nicht 1, sondern z.B. 2, und für M1 z.B. 4.
Was noch auffällt: Das was im ersten Durchlauf befüllt wurde wird auch in allen Folgemonaten befüllt. Das was im ersten Durchlauf nicht enthalten war wird zwar noch richtig in den Folgemonaten ausgewiesen, aber eben ohne Value.

Stehe total auf dem Schlauch zumal das alles schon mal funktioniert hat :(

Danke für eure Hilfe vorab!!

P.S.: Meine Dictionaries heißen immer noch Parent & Child - sorry. "Aufräumen" werde ich am Ende...

  

Betrifft: AW: doppelte for schleife - irgendwas ist kaputt von: Zwenn
Geschrieben am: 29.04.2017 18:52:47

Hallo Marc,

keine Lösung, eher zwei Fragen:

1. Warum läuft die äußere Schleife entgegengesetzt der inneren Schleife?
2. Wenn Du von Dictionary schreibst, warum verwendest Du dann keins?

CreateObject("Scripting.Dictionary")
Vielleicht fehlt auch nur der Rest Deines Makros, um zu verstehen, was Dein Problem ist ;-)

Viele Grüße,

Zwenn


  

Betrifft: AW: doppelte for schleife - irgendwas ist kaputt von: Marc
Geschrieben am: 30.04.2017 10:04:45

Mit ein paar Code-Schnipseln ist es natürlich nicht gerade einfacher. Drum habe ich mal die komplette Prozedur kopiert:

Sub MatrixFuerKumulierteUmsaetzeSchreiben()

    Dim sht As Worksheet
       
    '____________________________________________________________________________________
    '__________Ermittlung Monatsblöcke und Kategorien____________________________________
    
    Dim LastRow As Long, Zeile As Long, AnzahlMonate As Long
    Dim currentMonth As String
    
    Set sht = Sheets("Umsaetze")
    
    'Anzahl Monatsblöcke bestimmen
    AnzahlMonate = 0
    LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
    For Zeile = LastRow To 7 Step -1
    
        If sht.Cells(Zeile, 1).Value = "Buchungstag" Then
            AnzahlMonate = AnzahlMonate + 1
        End If
        
    Next Zeile
    
    'Befüllung Array mit Monatswerten (für X-Achse)
    Dim Monate() As String
    Dim i As Integer
    i = AnzahlMonate
    
    ReDim Monate(AnzahlMonate)
    For Zeile = LastRow To 7 Step -1
    
        If sht.Cells(Zeile, 1).Value = "Buchungstag" Then
            Monate(i) = Mid(sht.Cells(Zeile + 1, 1).Value, 4)
            i = i - 1
        End If
        
    Next Zeile
    
    'Befüllung Array mit Kategorien (Y-Achse)
    Set sht = Sheets("Konfiguration")
    LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
    
    Dim Kategorien() As String
    ReDim Kategorien(LastRow - 2)
    i = 0
    
    For Zeile = 3 To LastRow Step 1
        Kategorien(i) = sht.Cells(Zeile, 1).Value
        i = i + 1
    Next Zeile
    
    
    '__________________________________________________________________________
    '__________ Erhebung Betragswerte pro Monat und Kategorie _________________
    
    Dim Parent As Object, Child As Object
    Dim SummeA As Double, SummeB As Double, SummeC As Double, SummeD As Double
    Dim Monat As String
    
    SummeA = 0
    SummeB = 0
    SummeC = 0
    SummeD = 0
    
    Set Parent = CreateObject("Scripting.Dictionary")
    Set sht = Sheets("Umsaetze")
    LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
    
    For Zeile = LastRow To 7 Step -1
    
        If IsDate(sht.Cells(Zeile, 1)) Then
        
            If sht.Cells(Zeile, 7).Value = "A" Then
                SummeA = SummeA + sht.Cells(Zeile, 8).Value
            ElseIf sht.Cells(Zeile, 7).Value = "B" Then
                SummeB = SummeB + sht.Cells(Zeile, 8).Value
            ElseIf sht.Cells(Zeile, 7).Value = "C" Then
                SummeC = SummeC + sht.Cells(Zeile, 8).Value
            ElseIf sht.Cells(Zeile, 7).Value = "D" Then
                SummeD= SummeD + sht.Cells(Zeile, 8).Value
            Else
                MsgBox ("Unbekannte Kategorie gefunden: " & sht.Cells(Zeile, 7).Value & ".  _
Skript-Abbruch")
                End
            End If
            
        'Falls es sich nicht um ein Datum handelt sind wir für den Monat fertig
        'und hinterlegen die Werte im Dictionary
        Else
        
            'Berechnung soll natürlich nur 1x durchgeführt werden und nicht bei jeder folgenden  _
Leerzeile
            If sht.Cells(Zeile, 1).Value = "Buchungstag" Then
                Monat = Mid(sht.Cells(Zeile + 1, 1).Value, 4)
                Set Child = CreateObject("Scripting.Dictionary")
                
                If SummeA <> 0 Then
                    Child.Add "A", SummeA
                    SummeA = 0
                End If
                If SummeB <> 0 Then
                    Child("B") = SummeB
                    SummeB = 0
                End If
                If SummeC <> 0 Then
                    Child("C") = SummeC
                    SummeC = 0
                End If
                If SummeD <> 0 Then
                    Child("D") = SummeD
                    SummeD = 0
                End If
                
                Parent.Add Monat, Child
                
            End If
        
        End If
        
    Next Zeile
    
    
    '_______________________________________________________________________
    '__________ Befüllung  _________________________________________________
    
    Set sht = Sheets("Umsaetze kumuliert")
    
    'Zeitraum (X-Achse)
    For i = 0 To AnzahlMonate Step 1
        
        sht.Cells(1, i + 1).NumberFormat = "@" 'Formatierung der Zelle zu Text
        sht.Cells(1, i + 1).Value = Monate(i)
    
    Next i
    
    'Kategorien (Y-Achse)
    Laenge = UBound(Kategorien) 'UBound liefert den höchsten Index des Arrays
    
    For i = 2 To Laenge + 1 Step 1 'Da Arrays mit 0 starten muss hier noch +1 gerechnet werden
        sht.Cells(i, 1).Value = Kategorien(i - 2)
    Next i
    
    Spalte = 2
    
    'Kategorien pro Monat
    ParentKeys = Parent.Keys
    For i = UBound(ParentKeys) To LBound(ParentKeys) Step -1
    
        'MsgBox ParentKeys(i)
        ChildKeys = Parent(ParentKeys(i)).Keys
        
        For j = LBound(ChildKeys) To UBound(ChildKeys) Step 1
            
            If ChildKeys(j) = "A" Then
                sht.Cells(2, Spalte).Value = ParentKeys(i) & "/" & ChildKeys(j) & " - " & Child( _
ChildKeys(j))
                'sht.Cells(2, Spalte).Value = Child(ChildKeys(j))
            End If
            
            If ChildKeys(j) = "B" Then
                sht.Cells(3, Spalte).Value = ParentKeys(i) & "/" & ChildKeys(j) & " - " & Child( _
ChildKeys(j))
                'sht.Cells(3, Spalte).Value = Child(ChildKeys(j))
            End If
            
            If ChildKeys(j) = "C" Then
                sht.Cells(4, Spalte).Value = ParentKeys(i) & "/" & ChildKeys(j) & " - " & Child( _
ChildKeys(j))
                'sht.Cells(4, Spalte).Value = Child(ChildKeys(j))
            End If
            
            If ChildKeys(j) = "D" Then
                sht.Cells(5, Spalte).Value = ParentKeys(i) & "/" & ChildKeys(j) & " - " & Child( _
ChildKeys(j))
                'sht.Cells(5, Spalte).Value = Child(ChildKeys(j))
            End If
        
        Next j
        
        Spalte = Spalte + 1
       
    Next i
    
End Sub

Beispiel-Ausgabe sieht aktuell so aus:
	04.2017	             03.2017	          02.2017	       01.2017
A       04.2017/A - 227,67   03.2017/A - 227,67	  02.2017/A - 227,67   01.2017/A - 227,67
B	                                          02.2017/B - 	       01.2017/B - 
C	                     03.2017/C - 	  02.2017/C - 	
D       04.2017/D - -1981,32 04.2017/D - -1981,32 04.2017/D - -1981,32 04.2017/D - -1981,32
Zu den Fragen:
1. Weil ich sie aufsteigend befüllt habe, für diesen Usecase aber absteigend ausweisen möchte. Stört mich allerdings nicht weiter...
2. Sollte mit dem Code geklärt sein?!

Danke im Voraus


Beiträge aus den Excel-Beispielen zum Thema "doppelte for schleife - irgendwas ist kaputt"