Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1820to1824
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

Daten enpivotieren - VBA

Daten enpivotieren - VBA
18.03.2021 17:29:25
Lutz
Hallo Excel Spezialisten,
ich möchte/muss Daten entpivotieren.
Das geht mit Power Query ganz gut aber ich muß ein Template basteln und viele unserer Kollegen haben keine Ahnung von PowerPivot.
Ich habe im Netz eionen guten Ansatz gefunden:
Sub KreuzEntpivotieren()
On Error GoTo Error
Dim IntLC As Integer, j As Integer 'IntLR ist die letzte Spalte
Dim LngLR As Integer, i As Long 'LngLR ist die letzte Zeile
Dim Kreuz As Worksheet, Liste As Worksheet
Set Kreuz = ThisWorkbook.Sheets("Daten")
Set Liste = ThisWorkbook.Sheets("Liste")
Kreuz.Activate
IntLC = Kreuz.Range("IV1").End(xlToLeft).Column
LngLR = Kreuz.Cells(Rows.Count, 1).End(xlUp).Row
Application.ScreenUpdating = False
k = 2
Liste.Activate
For i = 2 To IntLC
For j = 2 To LngLR
Liste.Cells(k, 1).Value = Kreuz.Cells(j, 1).Value
Liste.Cells(k, 2).Value = Kreuz.Cells(1, i).Value
Liste.Cells(k, 3).Value = Kreuz.Cells(j, i).Value
k = k + 1
Next j
Next i
Application.ScreenUpdating = True
Exit Sub
Error:
MsgBox "Ein Fehler ist aufgetreten"
End Sub

Der Code klappt super mit einer festen Spalte und mehreren Ergebnisspalten.
Wir haben aber manchmal 1,2 oder bis zu 6 feste Spalten und dann kommen die Spalten mit den Daten (bis zu 500 Spalten).
Gibt es einen Weg das variable zu gestalten? Am besten im ersten Schritt Auswahl der fixen Spalten und letzter Zeile und im 2ten Schritt die Auswahl der untereinander zu kopierenden Spalten.
Vielleicht hat jemand von Euch so etwas noch aus der Zeit von vor PowerPivot?
Vielen Dank und viele Grüße Lutz

6
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Daten enpivotieren - VBA
18.03.2021 22:41:27
Yal
Hallo Lutz,
Anbei einen Vorschlag. Ich habe mich erlaubt, die Variabeln soweit wie möglich zu reduzieren. Einige habe ich zu meinem Standard umbenannt. Es ist nur, dass ich so besser vorankomme...
Spaltenüberschrift sind die Element über die Spalten. Diese haben ein festen Anzahl an Zeilen.
Zeilenüberschrift stehen am Anfang der Zeilen. Diese haben ein fasten Anzahl an Spalten.
Diese beiden Werte werden als Parameter übergeben. Ich gehe dabei davon aus, dass keine leere Zwischenzeile (SpaltenÜb.) oder leere Zwischenspalte (ZeilenÜb.) vorhanden sind.
Bsp: Eine Zeile Spaltenüberschrift und 3 Zeilenüberschrift. Die erste Werte ist dann in D2.
KreuzEntpivotieren 3, 1

Sub KreuzEntpivotieren(AnzZeilenÜberschrift, AnzSpaltenÜberschrift)
Dim z As Long 'IntLR ist die letzte Spalte
Dim s As Long 'LngLR ist die letzte Zeile
Dim i, j, k
Dim Kreuz As Worksheet, Liste As Worksheet
On Error GoTo Error
Set Kreuz = ThisWorkbook.Sheets("Daten") 'Quelle
Set Liste = ThisWorkbook.Sheets("Liste") 'Ziel
Application.ScreenUpdating = False
For z = AnzSpaltenÜberschrift + 1 To Kreuz.Cells(9999, AnzZeilenÜberschrift).End(xlUp).Row
For s = AnzZeilenÜberschrift + 1 To Kreuz.Cells(AnzSpaltenÜberschrift, 9999).End( _
xlToLeft).Column
If Kreuz.Cells(z, s).Value  0 Then
'Ziel-Zeile ermitteln
k = Liste.Cells(99999, 1).End(xlUp).Row + 1
'ZeilenÜberschrift_übertragen (Zeile_i, Spalte1, AnzSpalten)
For i = 1 To AnzZeilenÜberschrift 'Zeilenüberschrift in n Spalten
Liste.Cells(k, i) = Kreuz.Cells(z, i).Value
Next
i = i - 1 'nach For i = 1 To n ist i = n+1
'SpaltenÜberschirft_übertragen (Spalte_j, Zeile1, AnzZeilen)
For j = 1 To AnzSpaltenÜberschirft 'Spaltenüberschrift in n Zeilen
Liste.Cells(k, j + i) = Kreuz.Cells(j, s).Value
Next
'Wert_übertragen (Zeile_i, Spalte_j)
Liste.Cells(k, j + i) = Kreuz.Cells(z, s).Value
End If
Next s
Next z
Application.ScreenUpdating = True
Exit Sub
Error:
MsgBox "Ein Fehler ist aufgetreten"
End Sub
Falls die Elemente in Zeilen- oder Spaltenüberschrift nicht überall vorhanden sind (z.B. Jahr kommt nur einmal über alle Monate vor), einfach die vorige Wert vom Zieltabelle übernehmen:
For i = 1 To AnzZeilenÜberschrift 'Zeilenüberschrift in n Spalten
If Kreuz.Cells(z, i).Value = "" Then
Liste.Cells(k, i) = Liste.Cells(k - 1, i)
Else
Liste.Cells(k, i) = Kreuz.Cells(z, i).Value
End If
Next

Und dasselbe für die Sapltenüberschrift-Element.
Wobei -fällt mir gerade ein- wenn die Wert 2021|Jan null ist, wird vom vorige Zeile im Ziel-Tabelle 2019 gelesen!
VG
Yal

Anzeige
AW: Daten enpivotieren - VBA
19.03.2021 10:15:23
Lutz
Hallo Yal,
vielen Dank für Deine Hilfe.
Ich habe die variablen mal definiert und das umgeschrieben aber es fehlen die Überschriften und er macht bei mir nur 1 Spalte der Daten statt vorhandenen 6 Spalten.
Siehe Datei Hier:
https://www.herber.de/bbs/user/144956.xlsm
Vielen Dank und viele Grüße Lutz

AW: Daten enpivotieren - VBA
19.03.2021 12:46:30
Lutz
Hallo zusammen,
bin fast fertig:
Sub KreuzTabellieren3()
On Error GoTo Error
Dim IntLC As Integer, j As Integer 'IntLR ist die letzte Spalte
Dim LngLR As Integer, i As Long 'LngLR ist die letzte Zeile
Dim LngLCF As Integer 'LngLCF ist die Anzahl der festen Spalten
Dim Kreuz As Worksheet, Liste As Worksheet
Set Kreuz = ThisWorkbook.Sheets("Daten")
Set Liste = ThisWorkbook.Sheets("Liste3")
Dim Range1 As Range, Range2 As Range, Rng As Range
Set Range1 = Application.Selection
Set Range1 = Application.InputBox("Source Ranges:", xTitleId, Range1.Address, Type:=8)
Set Range2 = Application.InputBox("Fixed Colums", xTitleId, Type:=8)
Kreuz.Activate
IntLC = Range1.Columns.Count
LngLR = Range1.Rows.Count
LngLCF = Range2.Columns.Count + 1
Liste.Cells.Clear
Application.ScreenUpdating = False
k = 2
Liste.Activate
For i = LngLCF To IntLC
For j = 2 To LngLR
Liste.Cells(k, 1).Value = Kreuz.Cells(j, 1).Value
Liste.Cells(k, 2).Value = Kreuz.Cells(j, 2).Value
Liste.Cells(k, 3).Value = Kreuz.Cells(j, 3).Value
Liste.Cells(k, 4).Value = Kreuz.Cells(1, i).Value
Liste.Cells(k, 5).Value = Kreuz.Cells(j, i).Value
k = k + 1
Next j
Next i
Application.ScreenUpdating = True
Exit Sub
Error:
MsgBox "Ein Fehler ist aufgetreten"
End Sub
Er fragt 2 Ranges:
1. Gesamtbereich der Daten
2. Anzahl fixe Spalten (im Moment 3)
Was mir noch fehlt:
im Bereich unten habe ich die 3 Fixen Spalten fest drin - das müsste eigentlich variabel sein (wenn es 2 sind nur 2x der Code...
Und die Überschriften fehlen mir noch. Zeile 1 der fixen Spalten liefert die Überschrift und Bei den Werten kann man ja einfach "Value" eintragen.
Hat jemand eine Idee wie man das anpassen könnte?
Viele Grüße Lutz

Anzeige
AW: Daten enpivotieren - VBA
19.03.2021 14:39:14
Yal
Hallo Lutz,
Unter Extras, Optionen..., setze "Variable-Deklaration erforderlich"
Es führt dazu, dass keine Variabel verwendet wird, ohne dass sie vorher als Dim oder als Parameter deklariert wird.
Es hätte dazu geführt, dass eine Meldung auf
SpaltenÜberbeschirft
kommt. Somit hätten wir entdeckt, dass es ein Vertipper gibt.
Du hast versucht, eine 6 Zeilige Spaltenüberschriftsberich zu behandeln, die ich in deine Test-Daten nicht finden könnte. Das Makro ist blind. Alle Zahlen der erste 6 Zeilen werden als Spaltenüberschrift-Element behandelt.
Sonst funktioniert es wie gewünscht.
Auf dem Blatt Daten habe ich den Excel bis Access Block nach links kopiert, eine Zeile darüber eingefügt und über die beide Excel 2021 und 2022 eingetragen, aber nicht über jede Element: Verhalten, wie gedacht: im zweite Datenzeile "Bea-Nord-Jan", fehlt für Excel ein Wert und 2021 und 2022 wird nicht übernommen.
Dagegen die neue Version: es wird immer ins in einem Array kopiert. Wenn die Wert nicht null oder wenn man die nullen haben will, wird den Array ins Zielblatt kopiert.
Sub Test erlaubt, schnell mehrere Szenarien zu testen.
Sub Test()
KreuzEntpivotieren "Daten", "Liste3", 3, 2
KreuzEntpivotieren "Daten", "Liste4", 3, 2, True
End Sub
Sub KreuzEntpivotieren(QuellTab, ZielTab, AnzZeilenÜberschrift, AnzSpaltenÜberschrift, Optional  _
NullÜbernehmen = False)
Dim z As Long 'IntLR ist die letzte Spalte
Dim s As Long 'LngLR ist die letzte Zeile
Dim i, j, k, l
Dim Kreuz As Worksheet, Liste As Worksheet
Dim Erg()
On Error GoTo Error
Set Kreuz = ThisWorkbook.Sheets(QuellTab) 'Quelle
Set Liste = ThisWorkbook.Sheets(ZielTab) 'Ziel
'    Application.ScreenUpdating = False
ReDim Erg(1 To AnzSpaltenÜberschrift + AnzZeilenÜberschrift + 1)
For z = AnzSpaltenÜberschrift + 1 To Kreuz.Cells(9999, AnzZeilenÜberschrift).End(xlUp).Row
For s = AnzZeilenÜberschrift + 1 To Kreuz.Cells(AnzSpaltenÜberschrift, 9999).End( _
xlToLeft).Column
'Ziel-Zeile ermitteln
k = Liste.Cells(99999, 1).End(xlUp).Row + 1
'ZeilenÜberschrift_übertragen (Zeile_i, Spalte1, AnzSpalten)
For i = 1 To AnzZeilenÜberschrift 'Zeilenüberschrift in n Spalten
If Kreuz.Cells(z, i).Value  0 Then Erg(i) = Kreuz.Cells(z, i).Value
Next
i = i - 1 'nach For i = 1 To n ist i = n+1
'SpaltenÜberschirft_übertragen (Spalte_j, Zeile1, AnzZeilen)
For j = 1 To AnzSpaltenÜberschrift 'Spaltenüberschrift in n Zeilen
If Kreuz.Cells(j, s).Value  0 Then Erg(j + i) = Kreuz.Cells(j, s).Value
Next
'Wert_übertragen (Zeile_i, Spalte_j)
Erg(j + i) = Kreuz.Cells(z, s).Value
If NullÜbernehmen Or Erg(i + j)  0 Then
Liste.Cells(k, 1).Resize(1, i + j) = Erg
End If
Next s
Next z
Application.ScreenUpdating = True
Exit Sub
Error:
MsgBox "Ein Fehler ist aufgetreten"
End Sub
Eigentlich eine Musterlösung. Mal sehen wie oft jemand diese nutzen wird.
VG
Yal

Anzeige
AW: Daten enpivotieren - VBA
19.03.2021 16:38:24
Lutz
Hallo Yal,
vielen Dank, passt leider mit meiner Datei gar nicht:(
Ich bekomme doppelte Daten und nicht die richtigen Ergebnisse.
Hier mal meine Datei:
https://www.herber.de/bbs/user/144965.xlsm
Das Makro von oben befüllt Tabellen 4 und 5
Viele Grüße Lutz

AW: Daten enpivotieren - VBA
22.03.2021 11:00:26
Yal
Hallo Lutz,
"VBA Bescheiden" ist ein Zustand, aber keine Entschuldigung.
Bitte setzt dich mit diesen Zeilen ausseinander:
Sub Test()
KreuzEntpivotieren "Daten", "Liste3", 3, 2
KreuzEntpivotieren "Daten", "Liste4", 3, 2, True
End Sub
Was haben sie mit den Parameter zu tun?

Sub KreuzEntpivotieren(QuellTab, ZielTab, AnzZeilenÜberschrift, AnzSpaltenÜberschrift, Optional  _
_
NullÜbernehmen = False)
und welche Zusammenhang hat das mit meiner bisherigen Meldung:
"Du hast versucht, eine 6 Zeilige Spaltenüberschriftsberich zu behandeln, die ich in deine Test-Daten nicht finden könnte. Das Makro ist blind. Alle Zahlen der erste 6 Zeilen werden als Spaltenüberschrift-Element behandelt."
Ich kann Dir bei "Problem" helfen, aber das genau Lesen und sich darüber gedenken zu machen, was es bedeutet, muss Du selber leisten.
VG
Yal
Anzeige

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige