Teilen über


Einleitung

Überblick

Microsoft Power Query bietet eine leistungsstarke Oberfläche zum Abrufen von Daten, die viele Features umfasst. Eine Kernfunktion von Power Query ist das Filtern und Kombinieren von Daten aus einer oder mehreren einer umfangreichen Sammlung unterstützter Datenquellen. Jede solche Datenmashup wird mithilfe der Power Query-Formelsprache ausgedrückt (informell als "M" bezeichnet). Power Query bettet M-Dokumente in eine breite Palette von Microsoft-Produkten ein, einschließlich Excel, Power BI, Analysis Services und Dataverse, um wiederholbares Mashup von Daten zu ermöglichen.

Dieses Dokument enthält die Spezifikation für M. Nach einer kurzen Einführung, die darauf abzielt, erste Intuition und Vertrautheit mit der Sprache zu entwickeln, deckt das Dokument die Sprache genau in mehreren progressiven Schritten ab:

  1. Die lexikalische Struktur definiert den Satz von Texten, die lexikalisch gültig sind.

  2. Werte, Ausdrücke, Umgebungen und Variablen, Bezeichner und das Auswertungsmodell bilden die grundlegenden Konzepte der Sprache.

  3. Die detaillierte Spezifikation von Werten, sowohl grundtyp als auch strukturiert, definiert die Zieldomäne der Sprache.

  4. Werte haben Typen, selbst eine besondere Art von Wert, die beide die grundlegenden Arten von Werten charakterisieren und zusätzliche Metadaten tragen, die für die Formen strukturierter Werte spezifisch sind.

  5. Die Gruppe von Operatoren in M definiert, welche Arten von Ausdrücken gebildet werden können.

  6. Funktionen, eine andere Art von speziellen Werten, stellen die Grundlage für eine umfangreiche Standardbibliothek für M bereit und ermöglichen das Hinzufügen neuer Abstraktionen.

  7. Fehler können beim Anwenden von Operatoren oder Funktionen während der Ausdrucksauswertung auftreten. Fehler sind zwar keine Werte, es gibt jedoch Möglichkeiten, Fehler zu behandeln , die Fehler zurück zu Werten zuordnen.

  8. Lassen Sie Ausdrücke die Einführung von Hilfsdefinitionen ermöglichen, die zum Erstellen komplexer Ausdrücke in kleineren Schritten verwendet werden.

  9. Wenn Ausdrücke die bedingte Auswertung unterstützen.

  10. Abschnitte bieten einen einfachen Modularitätsmechanismus. (Abschnitte werden noch nicht von Power Query genutzt.)

  11. Schließlich sammelt eine konsolidierte Grammatik die Grammatikfragmente aus allen anderen Abschnitten dieses Dokuments in einer einzigen vollständigen Definition.

Für Computersprachentheoretiker: Die in diesem Dokument angegebene Formelsprache ist eine meist reine, höhere Reihenfolge, dynamisch eingegebene, teilweise faule Funktionale Sprache.

Ausdrücke und Werte

Das zentrale Konstrukt in M ist der Ausdruck. Ein Ausdruck kann ausgewertet (berechnet) werden, ergibt einen einzelnen Wert.

Obwohl viele Werte buchstäblich als Ausdruck geschrieben werden können, ist ein Wert kein Ausdruck. Der Ausdruck 1 wertet z. B. den Wert 1 aus; die Ausdrücke 1+1 werden mit dem Wert 2 ausgewertet. Diese Unterscheidung ist subtil, aber wichtig. Ausdrücke sind Rezepte für die Auswertung; Werte sind die Ergebnisse der Auswertung.

Die folgenden Beispiele veranschaulichen die verschiedenen Arten von Werten, die in M verfügbar sind. Als Konvention wird ein Wert mithilfe der Literalform geschrieben, in der sie in einem Ausdruck angezeigt werden, der nur diesen Wert auswertet. (Beachten Sie, dass der // Anfang eines Kommentars angibt, der bis zum Ende der Zeile fortgesetzt wird.)

  • Ein Grundtypwert ist einteiliger Wert, z. B. eine Zahl, ein logischer Text oder null. Ein NULL-Wert kann verwendet werden, um das Fehlen von Daten anzugeben.

    123                  // A number
    true                 // A logical
    "abc"                // A text
    null                 // null value
    
  • Ein Listenwert ist eine sortierte Reihenfolge von Werten. M unterstützt unendliche Listen, aber wenn sie als Literal geschrieben werden, weisen Listen eine feste Länge auf. Die geschweiften Klammern und {} geben den Anfang und das Ende einer Liste an.

    {123, true, "A"}     // list containing a number, a logical, and 
                          //     a text 
    {1, 2, 3}            // list of three numbers 
    
  • Ein Datensatz ist eine Reihe von Feldern. Ein Feld ist ein Name/Wert-Paar, bei dem der Name ein Textwert ist, der innerhalb des Datensatzes des Felds eindeutig ist. Mit der Literalsyntax für Datensatzwerte können die Namen ohne Anführungszeichen geschrieben werden, ein Formular, das auch als Bezeichner bezeichnet wird. Im Folgenden sehen Sie einen Datensatz mit drei Feldern namens "A", "B" und "C", die Werte 1enthalten, 2und 3.

    [ 
          A = 1,  
          B = 2,  
          C = 3 
    ]
    
  • Eine Tabelle ist eine Gruppe von Werten, die in Spalten organisiert sind (die anhand des Namens identifiziert werden) und Zeilen. Es gibt keine Literalsyntax zum Erstellen einer Tabelle, aber es gibt mehrere Standardfunktionen, mit denen Tabellen aus Listen oder Datensätzen erstellt werden können.

    Beispiel:

    #table( {"A", "B"}, { {1, 2}, {3, 4} } ) 
    

    Dadurch wird eine Tabelle der folgenden Form erstellt:

    Abbildung einer Beispieltabelle in der M-Formelsprache.

  • Eine Funktion ist ein Wert, der beim Aufrufen mit Argumenten einen neuen Wert erzeugt. Eine Funktion wird geschrieben, indem die Parameter der Funktion in Klammern aufgelistet werden, gefolgt von dem Zu-Symbol =>, gefolgt vom Ausdruck, der die Funktion definiert. Dieser Ausdruck bezieht sich in der Regel auf die Parameter (nach Name).

    (x, y) => (x + y) / 2`
    

Evaluation

Das Auswertungsmodell der M-Sprache wird nach dem Auswertungsmodell modelliert, das häufig in Kalkulationstabellen zu finden ist, wobei die Berechnungsreihenfolge basierend auf Abhängigkeiten zwischen den Formeln in den Zellen bestimmt werden kann.

Wenn Sie Formeln in einer Kalkulationstabelle wie Excel geschrieben haben, erkennen Sie möglicherweise die Formeln auf der linken Seite in den Werten rechts, wenn sie berechnet werden:

Screenshots der Formeln auf der rechten Seite, die zu den Werten auf der linken Seite führen.

In M können Teile eines Ausdrucks auf andere Teile des Ausdrucks anhand des Namens verweisen, und der Auswertungsprozess bestimmt automatisch die Reihenfolge, in der referenzierte Ausdrücke berechnet werden.

Sie können einen Datensatz verwenden, um einen Ausdruck zu erzeugen, der dem vorherigen Kalkulationstabellenbeispiel entspricht. Beim Initialisieren des Werts eines Felds können Sie auf andere Felder innerhalb des Datensatzes verweisen, indem Sie den Namen des Felds verwenden, wie im folgenden Beispiel gezeigt:

[  
    A1 = A2 * 2,  
    A2 = A3 + 1,  
    A3 = 1  
]

Der vorherige Ausdruck entspricht dem folgenden Beispiel (in dem beide wertegleich ausgewertet werden):

[  
    A1 = 4,  
    A2 = 2,  
    A3 = 1  
]

Datensätze können in anderen Datensätzen enthalten oder geschachtelt werden. Sie können den Nachschlageoperator ([]) verwenden, um auf die Felder eines Datensatzes anhand des Namens zuzugreifen. Der folgende Datensatz hat beispielsweise ein Feld Sales mit einem Datensatz und ein Feld mit dem Namen Total , das auf die FirstHalf Felder SecondHalf des Sales Datensatzes zugreift:

[  
    Sales = [ FirstHalf = 1000, SecondHalf = 1100 ], 
    Total = Sales[FirstHalf] + Sales[SecondHalf] 
]

Der vorherige Ausdruck entspricht dem folgenden Beispiel, wenn er ausgewertet wird:

[  
    Sales = [ FirstHalf = 1000, SecondHalf = 1100 ], 
    Total = 2100 
]

Datensätze können auch in Listen enthalten sein. Sie können den Positionsindexoperator ({}) verwenden, um auf ein Element in einer Liste anhand seines numerischen Indexes zuzugreifen. Die Werte in einer Liste werden anhand eines nullbasierten Indexes vom Anfang der Liste referenziert. Beispielsweise werden die Indizes 0 und 1 verwendet, um auf die ersten und zweiten Elemente in der folgenden Liste zu verweisen:

[ 
    Sales =  
        {  
            [  
                Year = 2007,  
                FirstHalf = 1000,  
                SecondHalf = 1100, 
                Total = FirstHalf + SecondHalf // 2100 
            ], 
            [  
                Year = 2008,  
                FirstHalf = 1200,  
                SecondHalf = 1300, 
                Total = FirstHalf + SecondHalf // 2500 
            ]  
        }, 
    TotalSales = Sales{0}[Total] + Sales{1}[Total] // 4600 
]

Listen- und Datensatzmememmausdrücke (sowie Let-Ausdrücke) werden mithilfe der faulen Auswertung ausgewertet, was bedeutet, dass sie nur nach Bedarf ausgewertet werden. Alle anderen Ausdrücke werden mit eifriger Auswertung ausgewertet, was bedeutet, dass sie sofort ausgewertet werden, wenn sie während des Auswertungsprozesses aufgetreten sind. Dies ist eine gute Möglichkeit, sich daran zu erinnern, dass die Auswertung eines Listen- oder Datensatzausdrucks einen Listen- oder Datensatzwert zurückgibt, der sich daran erinnert, wie die Listenelemente oder Datensatzfelder bei Bedarf (durch Nachschlage- oder Indexoperatoren) berechnet werden müssen.

Funktionen

In M ist eine Funktion eine Zuordnung aus einer Reihe von Eingabewerten zu einem einzelnen Ausgabewert. Eine Funktion wird geschrieben, indem zuerst der erforderliche Satz von Eingabewerten (die Parameter für die Funktion) benannt und dann ein Ausdruck bereitgestellt wird, der das Ergebnis der Funktion mithilfe dieser Eingabewerte (den Textkörper der Funktion) nach dem Wechselsymbol (=>)berechnet. Beispiel:

(x) => x + 1                    // function that adds one to a value 
(x, y) =>  x + y                // function that adds two values

Eine Funktion ist ein Wert wie eine Zahl oder ein Textwert. Das folgende Beispiel zeigt eine Funktion, die den Wert eines Add-Felds darstellt, das dann aus mehreren anderen Feldern aufgerufen oder ausgeführt wird. Wenn eine Funktion aufgerufen wird, wird eine Gruppe von Werten angegeben, die logisch durch den erforderlichen Satz von Eingabewerten innerhalb des Funktionstextausdrucks ersetzt werden.

[ 
    Add = (x, y) => x + y,
    OnePlusOne = Add(1, 1),     // 2 
    OnePlusTwo = Add(1, 2)      // 3
]

Bibliothek

M enthält einen allgemeinen Satz von Definitionen, die für die Verwendung aus einem Ausdruck verfügbar sind, der als Standardbibliothek bezeichnet wird, oder nur bibliothek für kurze Zeit. Diese Definitionen bestehen aus einer Gruppe benannter Werte. Die Namen der von einer Bibliothek bereitgestellten Werte sind für die Verwendung innerhalb eines Ausdrucks verfügbar, ohne explizit durch den Ausdruck definiert zu werden. Beispiel:

Number.E                        // Euler's number e (2.7182...) 
Text.PositionOf("Hello", "ll")  // 2

Betriebspersonal

M enthält eine Reihe von Operatoren, die in Ausdrücken verwendet werden können. Operatoren werden auf Operanden angewendet, um symbolische Ausdrücke zu bilden. In dem Ausdruck 1 + 2 beispielsweise sind die Zahlen 1 und Operanden, 2 und der Operator ist der Additionsoperator (+).

Die Bedeutung eines Operators kann abhängig davon variieren, welche Art von Werten seine Operanden sind. Beispielsweise kann der Plusoperator mit anderen Arten von Werten neben Zahlen verwendet werden:

1 + 2                   // numeric addition: 3 
#time(12,23,0) + #duration(0,0,2,0) 
                        // time arithmetic: #time(12,25,0)

Ein weiteres Beispiel für einen Operator mit operand-abhängiger Bedeutung ist der Kombinationsoperator (&):

"A" & "BC"              // text concatenation: "ABC" 
{1} & {2, 3}            // list concatenation: {1, 2, 3} 
[ a = 1 ] & [ b = 2 ]   // record merge: [ a = 1, b = 2 ]

Beachten Sie, dass einige Operatoren nicht alle Kombinationen von Werten unterstützen. Beispiel:

1 + "2"  // error: adding number and text isn't supported

Ausdrücke, die bei der Auswertung auf nicht definierte Operatorbedingungen stoßen, werden auf Fehler ausgewertet.

Metadaten

Metadaten sind Informationen zu einem Wert, der einem Wert zugeordnet ist. Metadaten werden als Datensatzwert dargestellt, der als Metadatendatensatz bezeichnet wird. Die Felder eines Metadatendatensatzes können verwendet werden, um die Metadaten für einen Wert zu speichern.

Jeder Wert verfügt über einen Metadatendatensatz. Wenn der Wert des Metadatendatensatzes nicht angegeben wurde, ist der Metadatendatensatz leer (enthält keine Felder).

Metadatendatensätze bieten eine Möglichkeit, zusätzliche Informationen jeder Art von Wert auf unaufdringliche Weise zuzuordnen. Durch das Zuordnen eines Metadatendatensatzes zu einem Wert wird der Wert oder sein Verhalten nicht geändert.

Ein Metadatendatensatzwert y ist einem vorhandenen Wert x mithilfe der Syntax x meta yzugeordnet. Der folgende Code ordnet beispielsweise einem Metadatendatensatz Rating und Tags Feldern den Textwert "Mozart"zu:

"Mozart" meta [ Rating = 5, Tags = {"Classical"} ]

Bei Werten, die bereits einen nicht leeren Metadatendatensatz enthalten, besteht das Ergebnis der Anwendung von Meta darin, den Datensatzzusammenführungsvorgang des vorhandenen und des neuen Metadatendatensatzes zu berechnen. Die folgenden beiden Ausdrücke entsprechen beispielsweise einander und dem vorherigen Ausdruck:

("Mozart" meta [ Rating = 5 ]) meta [ Tags = {"Classical"} ] 
"Mozart" meta ([ Rating = 5 ] & [ Tags = {"Classical"} ])

Auf einen Metadatendatensatz kann mithilfe der Value.Metadata Funktion für einen bestimmten Wert zugegriffen werden. Im folgenden Beispiel greift der Ausdruck im ComposerRating Feld auf den Metadatendatensatz des Werts im Composer Feld zu und greift dann auf das Rating Feld des Metadatendatensatzes zu.

[ 
    Composer = "Mozart" meta [ Rating = 5, Tags = {"Classical"} ], 
    ComposerRating = Value.Metadata(Composer)[Rating] // 5
]

Ausdruck zulassen

Viele der bisher gezeigten Beispiele enthalten alle Literalwerte des Ausdrucks im Ergebnis des Ausdrucks. Der let Ausdruck ermöglicht es, einen Satz von Werten zu berechnen, zugewiesenen Namen zu berechnen und dann in einem nachfolgenden Ausdruck zu verwenden, der vor dem in. Beispielsweise können Sie in unseren Verkaufsdaten folgendes tun:

let 
    Sales2007 =  
        [  
            Year = 2007,  
            FirstHalf = 1000,  
            SecondHalf = 1100, 
            Total = FirstHalf + SecondHalf // 2100 
        ], 
    Sales2008 =  
        [  
            Year = 2008,  
            FirstHalf = 1200,  
            SecondHalf = 1300, 
            Total = FirstHalf + SecondHalf // 2500 
        ],
    TotalSales = Sales2007[Total] + Sales2008[Total]
in
    TotalSales  // 4600

Das Ergebnis des obigen Ausdrucks ist ein Zahlenwert (4600), der aus den Werten berechnet wird, die an die Namen Sales2007 gebunden sind, und Sales2008.

Wenn Ausdruck

Der if Ausdruck wählt basierend auf einer logischen Bedingung zwischen zwei Ausdrücken aus. Beispiel:

if 2 > 1 then
    2 + 2
else  
    1 + 1

Der erste Ausdruck (2 + 2) wird ausgewählt, wenn der logische Ausdruck (2 > 1) wahr ist und der zweite Ausdruck (1 + 1) ausgewählt wird, wenn er falsch ist. Der ausgewählte Ausdruck (in diesem Fall 2 + 2) wird ausgewertet und wird zum Ergebnis des if Ausdrucks (4).

Errors

Ein Fehler ist ein Hinweis darauf, dass der Prozess der Auswertung eines Ausdrucks keinen Wert erzeugen konnte.

Fehler werden von Operatoren und Funktionen ausgelöst, die auf Fehlerbedingungen oder mithilfe des Fehlerausdrucks stoßen. Fehler werden mithilfe des try Ausdrucks behandelt. Wenn ein Fehler ausgelöst wird, wird ein Wert angegeben, der verwendet werden kann, um anzugeben, warum der Fehler aufgetreten ist.

let Sales = 
    [ 
        Revenue = 2000, 
        Units = 1000, 
        UnitPrice = if Units = 0 then error "No Units"
                    else Revenue / Units 
    ], 
    UnitPrice = try Number.ToText(Sales[UnitPrice]),
    Result = "Unit Price: " & 
        (if UnitPrice[HasError] then UnitPrice[Error][Message]
        else UnitPrice[Value])
in
    Result

Im obigen Beispiel wird auf das Sales[UnitPrice] Feld zugegriffen und der Wert formatiert, der das Ergebnis erzeugt:

"Unit Price: 2"

Wenn das Units Feld null gewesen wäre, hätte das UnitPrice Feld einen Fehler ausgelöst, der von der try. Der resultierende Wert wäre dann:

"Unit Price: No Units"

Ein try Ausdruck konvertiert die richtigen Werte und Fehler in einen Datensatzwert, der angibt, ob der try Ausdruck einen Fehler behandelt hat oder nicht, und entweder den richtigen Wert oder den Fehlerdatensatz, den er beim Behandeln des Fehlers extrahiert hat. Betrachten Sie beispielsweise den folgenden Ausdruck, der einen Fehler auslöst, und behandelt ihn dann sofort:

try error "negative unit count"

Dieser Ausdruck wertet den folgenden geschachtelten Datensatzwert aus, in dem die [HasError][Error][Message] Feld-Nachschlagevorgänge im vorherigen Einzelpreisbeispiel erläutert werden.

[ 
    HasError = true, 
    Error = 
        [ 
            Reason = "Expression.Error", 
            Message = "negative unit count", 
            Detail = null 
        ] 
]

Ein gängiger Fall besteht darin, Fehler durch Standardwerte zu ersetzen. Der try Ausdruck kann mit einer optionalen otherwise Klausel verwendet werden, um nur dies in einer kompakten Form zu erreichen:

try error "negative unit count" otherwise 42 
// 42