PQ Self-Join Loop mit Exit-Bedingung
07.01.2022 16:46:51
ChrisL
Hier eine neue Datei:
https://www.herber.de/bbs/user/150236.xlsx
@ Marvin
Das Ergebnis ist identisch mit der vorherigen Datei, jedoch ist die verwendete Technik ausgefeilter und die Obergrenze an möglichen Ebenen lässt sich individuell einstellen.
Wenn du versuchst die Power-Query nachzuvollziehen, ist die erste Dateiversion besser geeignet. Die neue Variante erfordert M-Code Programmierung und ist darum für Einsteiger weniger geeignet. Anwenden kannst du die Datei natürlich trotzdem.
Also lass dich vom nachfolgenden Code nicht beirren, damit brauchst du dich nicht auseinandersetzen.
@ all
Als Einstieg ins PQ-Loopen hat mir folgendes Video geholfen:
https://www.youtube.com/watch?v=T1q3BF5_YJ8
Exit-Bedingung:
1. currentLoop >= 20
Entspricht der "Notbremse" im Falle einer irrtümlich definierten Endlosschleife (Apfel-Birne, Birne-Apfel Thema). Die Zahl lässt sich natürlich anpassen.
2. List.NonNullCount(Table.Column(#"Erweiterte NeueSpalte","Zutat."&Number.ToText(currentLoop)))=0
Wenn der Join nur noch Null-Werte zurückgibt, wird ebenfalls ausgestiegen. Der Loop läuft also nur noch solange wie notwendig. Ich denke diese Neuerung ist spürbar.
Länger geknobelt habe ich u.a. an der Multiplikation der Mengen. Eigentlich eigentlich einfach =[Feld1]*[Feld2]
Allerdings kann man so keine Variablen benutzen. Lösung:
Record.Field(_, "Menge."&Number.ToText(loops))*Record.Field(_, "Menge."&Number.ToText(loops+1))
So sieht die PQ-Funktion letztlich aus:
(loops as number, tb as table) =>
let
Quelle = Quelldaten,
tb = if loops=0 then Quelle else tb,
#"Zusammengeführte Abfragen" = Table.NestedJoin(tb, {"Zutat."&Number.ToText(loops)}, Quelle, {"Rezept"}, "NeueSpalte", JoinKind.LeftOuter),
#"Erweiterte NeueSpalte" = Table.ExpandTableColumn(#"Zusammengeführte Abfragen", "NeueSpalte", {"Menge.0", "Zutat.0"}, {"Menge."&Number.ToText(loops+1), "Zutat."&Number.ToText(loops+1)}),
#"Hinzugefügte benutzerdefinierte Spalte" = Table.AddColumn(#"Erweiterte NeueSpalte", "MengeMultipliziert", each Record.Field(_, "Menge."&Number.ToText(loops))*Record.Field(_, "Menge."&Number.ToText(loops+1))),
#"Entfernte Spalten" = Table.RemoveColumns(#"Hinzugefügte benutzerdefinierte Spalte", {"Menge."&Number.ToText(loops+1)}),
#"Umbenannte Spalten" = Table.RenameColumns(#"Entfernte Spalten", {"MengeMultipliziert", "Menge."&Number.ToText(loops+1)}),
message = #"Umbenannte Spalten",
currentLoop = loops + 1,
output =
if currentLoop >= 20 or List.NonNullCount(Table.Column(#"Erweiterte NeueSpalte","Zutat."&Number.ToText(currentLoop)))=0 then message
else @#"fxLoop" (currentLoop, #"Umbenannte Spalten")
in
output