Lambda Expressions in Power Query - Teil 1 - Einführung

Lambda Expressions in Power Query - Teil 1 - Einführung

Lambda Expressions in Power Query - Teil 1 - Einführung

In Teil 1 dieser Serie über Lambda Expression wird gezeigt, wie Lambda Expressions innerhalb von Power Query Iteratoren arbeiten. Grundsätzlich ist nahezu jede Power Query Funktion ein Iterator. Durch das Platzieren von Lambda Expressions innerhalb von Power Query Funktionen, werden daher die Lambda Funktionen wiederholt aufgerufen. Bei jedem Aufruf werden dabei andere Daten an die Lambda Expression übergeben.

Wie jede datenbezogene Sprache (SQL, Python, DAX etc.) bietet auch Power Query ein Set von Funktionen an, die irgendeine Art von Iteration verkapseln. Die Tatsache eines internen Iterations-Vorgangs kann offensichtlich sein, z.B. weil der Name der Funktion dies offenbart, oder die Iteration befindet sich sozusagen versteckt innerhalb der Power Query Funktion und ist nicht so einfach zu verstehen.

Offensichtliche Iteration.

Zum Beispiel zeigt der Name der Funktion "List.Accumulate" an, dass man einen Haufen von Elementen übergeben kann und dass der Rückgabe-Wert der Funktion ein Einzelnes Ding ist, das über den internen Vorgang aggregiert wurde. Wenn man dann darüber nachdenkt, wie wohl die Business Logik innerhalb der Funktion aussehen könnte, kommt man zum Schluss, dass es eine Schleife geben muss, die über die Liste der Eingabe-Elemente iteriert, den Wert jedes einzelnen Elements berücksichtigt und alles zusammen in ein Ergebnis aggregiert.

List: { 10, 50, 30 } Result: 90

Wenn man sich vorstellt, wie die Logik von "List.Accumulate" innerhalb einer OOP-Umgebung aussehen könnte, kommt man zu Pseudo-Code wie folgt:

Abbildung 1 - Iteration / OOP-Projektion
Abbildung 1 - Iteration / OOP-Projektion

Versteckte Iteration

Für andere Power Query Funktionen ist es nicht so offensichtlich, dass sie eine Iteration verkapseln. Beispielsweise ist die Power Query Funktion "Table.SplitColumn" in der Lage, eine einzelne Spalte in mehrere Spalten zu teilen. Ohne große Reflektion über die Interna dieser Funktion könnte man sich vorstellen, dass die Spalte zerteilt wird wie ein Stück Brot.

Aber worin besteht die Iteration?

Um Power Query besser zu verstehen und vor allem zu verstehen, was Lambda Expression sind, sollte man davon ausgehen, dass nahezu jede (!) Power Query Funktion eine Iteration verkapselt. Die Frage ist also immer "Welche Art von Iteration steckt in der Funktion und wie könnte diese (angenommene) Iteration dabei helfen, die Absicht der Funktion wie z.B. Teilen einer Spalte zu implementieren?

Hier ist die Tabelle, bei der eine Spalte geteilt werden soll:

Abbildung 2 - Tabelle mit der Spalte [Person] soll geteilt werden
Abbildung 2 - Tabelle mit der Spalte [Person] soll geteilt werden

Wenn man sich die Zeichenfolge "Judy, Munich" betrachtet, kann man sich vorstellen, dass sich nach erfolgreicher Teilung der Zeichenfolge Werte für zwei neue Spalten ergeben, nämlich "Judy" und "Munich".

Bevor aber die Werte irgendwo platziert werden können, muss es die beiden Spalten schon geben. Der erste Schritt vor einer Teilung der Zeichenfolge muss daher die Änderung des Tabellen-Schemas sein. Es müssen zwei neue Spalten hinzugefügt werden. Das letzte Argument der Funktion "Table.SplitColumn" instruiert die Engine, die Spalten "PersonName" und "CityName" zu erstellen.

Abbildung 3 - Power Query-Code und Table.SplitColumn
Abbildung 3 - Power Query-Code und Table.SplitColumn
Schritt 1: Modifizieren des Schemas. Hinzufügen zweier Spalten:
Abbildung 4 - Innerhalb von "Table.SplitColumn". Schritt 1: Schemaänderung. Spalte(n) hinzufügen
Abbildung 4 - Innerhalb von "Table.SplitColumn". Schritt 1: Schemaänderung. Spalte(n) hinzufügen
Schritt 2: Füllen der neuen Spalten

Nachdem die beiden Spalten fertig für die Aufnahme der Werte "Judy" und "München" sind, kommt die Iteration ins Spiel und man kann sich vorstellen, wie die Werte in die Spalten gelangen. Aus der Sicht einer OOP-Umgebung würde der Pseudo-Code folgendermaßen aussehen:

Abbildung 5 - Innerhalb von "Table.SplitColumn". Schritt 2: Iteration und Aufteilung
Abbildung 5 - Innerhalb von "Table.SplitColumn". Schritt 2: Iteration und Aufteilung

Wie man sieht, wird die Split-Operation innerhalb der Iteration erledigt. Nachdem die Operation beendigt ist, sind die beiden Spalten gefüllt und die originale Quellspalte kann gelöscht werden:

Abbildung 6 - Innerhalb von "Table.SplitColumn". Schritt 3: Beendet
Abbildung 6 - Innerhalb von "Table.SplitColumn". Schritt 3: Beendet

Lambda Expressions

Die MSDN-Syntax-Hilfe für "Table.SplitColumns":

Table.SplitColumn(
   table as table,
   sourceColumn as text,
   splitter as function,
   optional columnNamesOrNumber as any,
   optional default as any,
   optional extraColumns as any) as table

Im Power Query Code-Beispiel von oben werden nur die ersten 4 Argumente von insgesamt 6 möglichen Argumenten verwendet:

  • Argument 'table' of type 'table': customer
  • Argument 'sourceColumn' of type 'text': Person
  • Argument 'splitter' of type 'function': Splitter.SplitTextByDelimiter
  • Argument 'columnNamesOrNumber' of type 'any': PersonName, CityName

Die Syntax-Hilfe informiert, dass der Typ für Argument 3 "function" ist. Immer dann, wenn man ein Argument vom Typ "function" sieht, bedeutet das, dass man an dieser Stelle eine Funktion wie z.B. "Splitter.SplitTextByDelimiter" einsetzen kann. Allerdings ist man nicht nur auf BuiltIn-Funktionen beschränkt, sondern syntaktisch sind hier auch benutzerdefinierte Ausdrücke vom Typ "function" erlaubt. Die allgemeine Syntax hierfür lautet:

Abbildung 7 - Lambda-Syntax
Abbildung 7 - Lambda-Syntax

Das "=>" steht für den Lambda-Operator. Sie werden wahrscheinlich nur wenige Artikel zu Power Query und Lambda Expressions finden. Die Zielgruppe für Power Query sind im Großen und Ganzen Anwender bzw. PowerUser und es könnte für diese Personengruppe schwieriger sein zu verstehen, was Lambda Expression sind, als ein paar allgemeine Anwendungsfälle und den Einsatz von Code-Schnipseln.

Dieser Artikel geht darüber hinaus und hat die Absicht, Anwendern, PowerUsern und Entwicklern die Verwendung von Lambda Expressions als wichtiges Konzept der Power Query Sprache näher zu bringen. Es versetzt die Leser des Artikels in die Lage, smarteren Code zu schreiben und auch die Fälle zu bewältigen, in denen Oberfläche und BuiltIn-Funktionen nicht mehr ausreichend sind.

Am Ende zeige ich auch die gebräuchlicheren Syntax-Alternativen. Aber jetzt - um das Konzept der Lambda Expressions zu verstehen - ist es besser, die native Syntax zu nehmen.

Allgemeine Idee einer Lambda Expression.

Eine Lambda Expression besteht aus zwei Teilen: auf der linken Seite befinden sich runde Klammern, die 0, 1 oder mehrere Variablen einschließen. Wie mit jeder Variablen sind Sie frei, sich einen passenden Namen zu überlegen. Die Variablen der linken Seite erhalten ihren Wert von der äußeren Funktion. In unserem Fall ist das "Table.SplitColumn".

Ablauf:

Schritt 1:

Die äußere Funktion startet eine Schleife. Die äußere Funkton verwendet interne Variablen, deren Wert an die Lambda Variablen weitergegeben werden. Im Falle des ersten Schleifen-Durchgangs aus dem Beispiel ist dies die Zeichenfolge "Judy, Munich". Die innere Funktion - die Lambda Expression - nimmt den Wert für ihre internen Zwecke entgegen.

Schritt 2:

Der Ausdruck auf der rechten Seite wird parametriert durch die Variable(n). In unserem Beispiel nutzt die Splitter-Funktion die Zeichenfolge "Judy, Munich" als Eingabe. An diesem Punkt spielen grundsätzlich die Daten-Typen als auch deren Werte eine Rolle: die übergebenen Werte müssen "in den Ausdruck der rechten Seite passen". Beispielsweise erwartet die Splitter-Funktion eine Zeichenfolge mit 0, 1 oder mehreren Kommata als Separatoren. Nach dem Splitting gibt die Lambda Expression eine Liste von Zeichenfolgen zurück {"Judy", "Munich"}. An diesem Punkt kommen wieder Daten-Typen und Werte zum Zuge. Die äußere Funktion muss in der Lage sein, mit dem Ergebnis "etwas anzufangen".

Schritt 3:

Die äußere Funktion empfängt den Rückgabewert der Lambda Expression und fährt mit internen Vorgängen fort. Beispielsweise werden die Rückgabe-Werte in die zwei neuen Spalten geschrieben.

Schritt 4:

Die äußere Funktion startet den nächsten Schleifen-Durchgang einschließlich der Lambda Expression.

Wir können der Power Query Code auch umschreiben, um zu einer deutlicheren bzw. detaillierten Syntax zu gelangen:

Abbildung 8 - Umschreiben einer Lambda-Funktion (detaillierte Syntax)
Abbildung 8 - Umschreiben einer Lambda-Funktion (detaillierte Syntax)

In diesem Fall habe ich eine etwas andere Syntax für die Splitter-Funktion verwendet: das letzte Argument "column" enthält die Lambda Variable von der linken Seite, die Referenz zu der Zeichenfolge, die gesplittet werden soll. Es gibt eine generelle Herausforderung bezüglich Lambda Expressions. Es ist zwar klar, dass eine äußere Funktion wie "Table.SplitColumn" Werte an die Lambda-Variablen übergibt und auch Rückgabe-Werte entgegennimmt.

Aber die MSDN-Syntax-Hilfe gibt keine Auskunft über die Details des unsichtbaren Verkehrs. Es ist nicht klar, welche Daten-Typen an die Lambda Variable übergeben werden. Es ist auch nicht klar, welche Daten-Typen die Lambda-Expression zurückgeben muss. Dies kann zu verschiedenen Fehlern führen:

  • Ein Entwickler könnte die falsche Anzahl an Variablen definieren
  • Ein Entwickler könnte eine Lambda Expression schreiben, die nicht auf den Daten-Typ oder Inhalt passt, der von der äußeren Funktion übergeben wird
  • Ein Entwickler könnte eine Lambda Expression schreiben, die einen falschen Typ oder unerwarteten Inhalt zurückgibt; anders, als die äußere Funktion es erwartet
Fehler und Missverständnisse.

Das nächste Beispiel zeigt, dass der Entwickler einen schlechten Namen für die Variable gewählt hat. Der Code funktioniert, aber der Variablen-Name zeigt eine Art von Missverständnis. Es ist nicht die Zeile, die an die Variable übergeben wird, sondern eine einzelne Spalte.

Abbildung 9 - Falscher Variablenname
Abbildung 9 - Falscher Variablenname

Empfehlung: Es könnte eine gute Vorgehensweise sein, einer Variablen grundsätzlich zunächst einen generischen Namen zu vergeben, wenn man mit dem Coding beginnt. Z.B. könnte man immer den Ausdruck "(item)" auf der linken Seite platzieren. Später, wenn dann klar ist, was die Variable enthält, könnte man der Variablen einen passenderen Namen vergeben wie z.B. "(column)".

Falsche Anzahl an Variablen:
Abbildung 10 - Falsche Anzahl von Variablen
Abbildung 10 - Falsche Anzahl von Variablen

Der einzige Weg, die versteckte Signatur der Lambda Expression zu verstehen, ist Trial-and-Error. Zum Glück sind die BuiltIn-Funktionen sauber benannt. Es ist daher intuitiv, die Signatur zu "erraten". Zum Beispiel: Eine BuiltIn-Funktion, die aus einer Zeichenfolge Werte für mehrere neue Spalten generiert, erwartet offensichtlich als Rückgabe-Wert eine Liste. Und sicherlich muss die Liste für jede Zeile der äußeren Funktion die gleiche Anzahl an Werten zurückgeben. Wenn zwei Spalten zu füllen sind, kann die Lambda Expression nicht drei Werte zurückgeben.

Alternative Each-Syntax

Anwender tendieren dazu, die "Each-Syntax" zu benutzen. Bei der "Each-Syntax" wird die Variablen-Deklaration der linken Seite mit dem konstanten Ausdruck "Each" ersetzt. Der Lambda-Operator “=>” kann nicht zusammen mit der "Each-Syntax" benutzt werden. Auf der rechten Seite kann die generische Variable "_" aufgerufen werden.

Einigen Anwendern kommt die Variable sicherlich bekannt vor: in PowerShell existiert ein ähnliches Konzept. Das "Each"-Schlüsselwort unterstreicht, dass die Lambda Expression innerhalb einer Schleife aufgerufen wird.

Abbildung 11 - Each-Syntax
Abbildung 11 - Each-Syntax

Benutzerdefinierte Funktion / Lambda Expression

Lambda Expression sind nützlich, wenn eine BuiltIn-Funktion die Aufgabe nicht lösen kann. Im folgenden Beispiel wird die BuiltIn-Funktion "Splitter.SplitTextByDelimiter" innerhalb einer Lambda Expression benutzt. Das Ziel ist, mögliche NULL-Werte zu ersetzen.

Einige Personen-Namen enthalten NULL und einige Städte enthalten ebenfalls NULL. Während der Split-Operation sollen diese NULL-Werte durch "n/a" ersetzt werden.

Abbildung 12 - Spalte teilen & NULL-Werte ersetzen
Abbildung 12 - Spalte teilen & NULL-Werte ersetzen

Die Splitter-Funktion wird benutzt. Aber anstatt direkt zur äußeren Funktion zurückzukehren, wird der Rückgabe-Wert der Splitter-Funktion erst in einer Variablen abgelegt. Die Variable "colValues" wird implizit als String Array dimensioniert. Jedes Element des String Arrays wird separat verarbeitet, um die Ersetzung des NULL-Wertes zu steuern.

Am Ende wird das Resultset an die äußere Funktion zurückgegeben. Neben dem eigentlichen Zweck dieses Beispiels wird auch wieder deutlich, dass die äußere Funktion tatsächlich eine Liste erwartet.

Abbildung 13 - Lambda-Ausdruck
Abbildung 13 - Lambda-Ausdruck

Und so sieht das finale Ergebnis aus:

Abbildung 14 - Fertigstellung
Abbildung 14 - Fertigstellung
Artikel und Copyright von Lukas Hillesheim (https://blog.n-dimensions.de)

Wenn Sie weitere Informationen wünschen, empfehlen wir:

Ihr Kommentar zum Artikel

"Lambda Expressions in Power Query - Teil 1 - Einführung"

Wir freuen uns über Ihren Kommentar und antworten so schnell es geht!

Das Angebot von "HECKER CONSULTING" richtet sich ausschließlich an Unternehmen und Behörden (iSv § 14 BGB). Verbraucher (§ 13 BGB) sind vom Vertragsschluss ausgeschlossen. Mit Absendung der Anfrage bestätigt der Anfragende, dass er nicht als Verbraucher, sondern in gewerblicher Tätigkeit handelt. § 312i Abs. 1 S. 1 Nr. 1-3 und S. 2 BGB (Pflichten im elektronischen Geschäftsverkehr) finden keine Anwendung.

Vielen Dank, Ihr Kommentar wurde empfangen!
Beim Absenden des Formulars ist etwas schief gelaufen.
Unsere Beratungs-Leistungen für Das Thema

Power Platform

Wir erweitern ständig unser Beratungsportfolio. Über 300 Beratungsleistungen haben wir für Sie im Programm. Selbstverständlich lassen sich die einzelnen Themen kombinieren. So erhalten Sie genau die Beratung, die Sie wünschen und brauchen

Mehr IT-, Online-, Digital-Beratungsleistungen anzeigen >>
Mehr IT-, Online-, Digital-Beratungsleistungen anzeigen >>

Kontaktanfrage

Das Angebot von "HECKER CONSULTING" richtet sich ausschließlich an Unternehmen und Behörden (iSv § 14 BGB). Verbraucher (§ 13 BGB) sind vom Vertragsschluss ausgeschlossen. Mit Absendung der Anfrage bestätigt der Anfragende, dass er nicht als Verbraucher, sondern in gewerblicher Tätigkeit handelt. § 312i Abs. 1 S. 1 Nr. 1-3 und S. 2 BGB (Pflichten im elektronischen Geschäftsverkehr) finden keine Anwendung.

Vielen Dank, Ihre Nachricht wurde empfangen!
Beim Absenden des Formulars ist etwas schief gelaufen.
WEITERE INFORMATIONEN AUS UNSEREM BLOG ZUM THEMA

Power Platform

Aktuelle und interessante Themen und Beiträge für Sie zusammengetragen und aufbereitet.

Mehr IT-, Online-, Digital-Neuigkeiten anzeigen >>
Nach oben