Dela via


Introduktion

Översikt

Microsoft Power Query ger en kraftfull "hämta data"-upplevelse som omfattar många funktioner. En viktig funktion i Power Query är att filtrera och kombinera, dvs. att "kombinera" data från en eller flera av en omfattande samling datakällor som stöds. Alla sådana datasammanslagning uttrycks med formelspråket Power Query (kallas informellt "M"). Power Query bäddar in M-dokument i en mängd olika Microsoft-produkter, inklusive Excel, Power BI, Analysis Services och Dataverse, för att möjliggöra upprepningsbar kombination av data.

Det här dokumentet innehåller specifikationen för M. Efter en kort introduktion som syftar till att skapa lite första intuition och förtrogenhet med språket, täcker dokumentet språket exakt i flera progressiva steg:

  1. Den lexikala strukturen definierar den uppsättning texter som är lexikalt giltiga.

  2. Värden, uttryck, miljöer och variabler, identifierare och utvärderingsmodellen utgör språkets grundläggande begrepp.

  3. Den detaljerade specifikationen av värden, både primitiv och strukturerad, definierar språkets måldomän.

  4. Värden har typer, som själva är en särskild typ av värde, som båda kännetecknar de grundläggande typerna av värden och innehåller ytterligare metadata som är specifika för formerna för strukturerade värden.

  5. Uppsättningen operatorer i M definierar vilka typer av uttryck som kan skapas.

  6. Functions, en annan typ av specialvärden, utgör grunden för ett omfattande standardbibliotek för M och möjliggör tillägg av nya abstraktioner.

  7. Fel kan uppstå när operatorer eller funktioner används under uttrycksutvärderingen . Även om fel inte är värden finns det sätt att hantera fel som mappar fel tillbaka till värden.

  8. Låt uttryck tillåta införandet av hjälpdefinitioner som används för att bygga upp komplexa uttryck i mindre steg.

  9. Om uttryck stöder villkorsstyrd utvärdering.

  10. Avsnitt ger en enkel modularitetsmekanism. (Avsnitt används ännu inte av Power Query.)

  11. Slutligen samlar en konsoliderad grammatik in grammatikfragmenten från alla andra delar av det här dokumentet i en enda fullständig definition.

För datorspråksatoretiker: formelspråket som anges i det här dokumentet är ett mestadels rent, högre, dynamiskt skrivet, delvis lat funktionellt språk.

Uttryck och värden

Den centrala konstruktionen i M är uttrycket. Ett uttryck kan utvärderas (beräknas), vilket ger ett enda värde.

Även om många värden kan skrivas bokstavligen som ett uttryck är ett värde inte ett uttryck. Uttrycket 1 utvärderas till exempel till värdet 1. Uttrycken utvärderas 1+1 till värdet 2. Denna distinktion är subtil, men viktig. Uttryck är recept för utvärdering. värdena är resultatet av utvärderingen.

Följande exempel illustrerar de olika typer av värden som är tillgängliga i M. Som en konvention skrivs ett värde med hjälp av det bokstavliga formuläret där de visas i ett uttryck som utvärderas till just det värdet. (Observera att // indikerar början av en kommentar som fortsätter till slutet av raden.)

  • Ett primitivt värde är endelsvärde, till exempel ett tal, logiskt, text eller null. Ett null-värde kan användas för att indikera att det inte finns några data.

    123                  // A number
    true                 // A logical
    "abc"                // A text
    null                 // null value
    
  • Ett listvärde är en ordnad sekvens med värden. M stöder oändliga listor, men om de skrivs som en literal har listor en fast längd. Klammerparenteserna { och } anger början och slutet av en lista.

    {123, true, "A"}     // list containing a number, a logical, and 
                          //     a text 
    {1, 2, 3}            // list of three numbers 
    
  • En post är en uppsättning fält. Ett fält är ett namn/värde-par där namnet är ett textvärde som är unikt i fältets post. Med literalsyntaxen för postvärden kan namnen skrivas utan citattecken, ett formulär som även kallas identifierare. Följande visar en post som innehåller tre fält med namnet "A", "B" och "C", som har värdena 1, och .32

    [ 
          A = 1,  
          B = 2,  
          C = 3 
    ]
    
  • En tabell är en uppsättning värden ordnade i kolumner (som identifieras med namn) och rader. Det finns ingen literalsyntax för att skapa en tabell, men det finns flera standardfunktioner som kan användas för att skapa tabeller från listor eller poster.

    Till exempel:

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

    Detta skapar en tabell med följande form:

    Image of an example table in the M formula language.

  • En funktion är ett värde som, när den anropas med argument, genererar ett nytt värde. En funktion skrivs genom att ange funktionens parametrar inom parenteser, följt av symbolen =>goes-to , följt av uttrycket som definierar funktionen. Det uttrycket refererar vanligtvis till parametrarna (efter namn).

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

Utvärdering

Utvärderingsmodellen för M-språket modelleras efter den utvärderingsmodell som vanligtvis finns i kalkylblad, där beräkningsordningen kan fastställas baserat på beroenden mellan formler i cellerna.

Om du har skrivit formler i ett kalkylblad, till exempel Excel, kanske du känner igen formler till vänster resulterar i värdena till höger när de beräknas:

Image of the formulas on the right resulting in the values on the left.

I M kan delar av ett uttryck referera till andra delar av uttrycket efter namn, och utvärderingsprocessen avgör automatiskt i vilken ordning refererade uttryck beräknas.

Du kan använda en post för att skapa ett uttryck som motsvarar föregående kalkylbladsexempel. När du initierar värdet för ett fält kan du referera till andra fält i posten med hjälp av namnet på fältet enligt följande:

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

Uttrycket ovan motsvarar följande (eftersom båda utvärderas till lika värden):

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

Poster kan finnas i, eller kapsla, i andra poster. Du kan använda uppslagsoperatorn ([]) för att komma åt fälten i en post efter namn. Följande post har till exempel ett fält med namnet Sales som innehåller en post och ett fält med namnet Total som kommer åt postfälten FirstHalfSales ochSecondHalf:

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

Uttrycket ovan motsvarar följande när det utvärderas:

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

Poster kan också finnas i listor. Du kan använda positionsindexoperatorn ({}) för att komma åt ett objekt i en lista med dess numeriska index. Värdena i en lista refereras till med hjälp av ett nollbaserat index från början av listan. Till exempel används indexen 0 och 1 för att referera till de första och andra objekten i listan nedan:

[ 
    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 
]

List- och postmedlemsuttryck (samt let-uttryck) utvärderas med hjälp av lat utvärdering, vilket innebär att de endast utvärderas efter behov. Alla andra uttryck utvärderas med ivrig utvärdering, vilket innebär att de utvärderas omedelbart när de påträffas under utvärderingsprocessen. Ett bra sätt att tänka på detta är att komma ihåg att utvärdering av ett list- eller postuttryck returnerar ett list- eller postvärde som i sig kommer ihåg hur dess listobjekt eller postfält måste beräknas när det begärs (av uppslags- eller indexoperatorer).

Funktioner

I M är en funktion en mappning från en uppsättning indatavärden till ett enda utdatavärde. En funktion skrivs genom att först namnge den obligatoriska uppsättningen indatavärden (parametrarna till funktionen) och sedan tillhandahålla ett uttryck som beräknar resultatet av funktionen med hjälp av dessa indatavärden (funktionens brödtext) efter symbolen goes-to (=>). Till exempel:

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

En funktion är ett värde precis som ett tal eller ett textvärde. I följande exempel visas en funktion som är värdet för ett Lägg till fält som sedan anropas eller körs från flera andra fält. När en funktion anropas anges en uppsättning värden som logiskt ersätts med den obligatoriska uppsättningen indatavärden i funktionstextuttrycket.

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

Bibliotek

M innehåller en gemensam uppsättning definitioner som är tillgängliga för användning från ett uttryck som kallas standardbiblioteket, eller bara bibliotek för kort. Dessa definitioner består av en uppsättning namngivna värden. Namnen på värden som tillhandahålls av ett bibliotek är tillgängliga för användning i ett uttryck utan att uttryckligen ha definierats av uttrycket. Till exempel:

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

Operatorer

M innehåller en uppsättning operatorer som kan användas i uttryck. Operatorer tillämpas på operander för att bilda symboliska uttryck. I uttrycket 1 + 2 är till exempel talen 1 och 2 operanderna och operatorn additionsoperatorn (+).

Innebörden av en operator kan variera beroende på vilken typ av värden dess operander är. Till exempel kan plusoperatorn användas med andra typer av värden förutom tal:

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

Ett annat exempel på en operator med operandberoende betydelse är kombinationsoperatorn (&):

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

Observera att vissa operatorer inte stöder alla kombinationer av värden. Till exempel:

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

Uttryck som vid utvärdering påträffar odefinierade operatorvillkor utvärderas till fel.

Metadata

Metadata är information om ett värde som är associerat med ett värde. Metadata representeras som ett postvärde som kallas för en metadatapost. Fälten i en metadatapost kan användas för att lagra metadata för ett värde.

Varje värde har en metadatapost. Om värdet för metadataposten inte har angetts är metadataposten tom (har inga fält).

Metadataposter är ett sätt att associera ytterligare information med alla typer av värden på ett diskret sätt. Att associera en metadatapost med ett värde ändrar inte värdet eller dess beteende.

Ett värde y för metadataposter associeras med ett befintligt värde x med hjälp av syntaxen x meta y. Följande kod associerar till exempel en metadatapost med Rating och Tags fält med textvärdet "Mozart":

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

För värden som redan har en icke-tom metadatapost är resultatet av att tillämpa meta att databehandling av postsammanfogningen av den befintliga och den nya metadataposten. Följande två uttryck är till exempel likvärdiga med varandra och till föregående uttryck:

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

Du kan komma åt en metadatapost för ett visst värde med funktionen Value.Metadata . I följande exempel kommer uttrycket i ComposerRating fältet åt metadataposten för värdet i Composer fältet och kommer sedan åt fältet för Rating metadataposten.

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

Let-uttryck

Många av de exempel som hittills har visats har inkluderat alla literalvärden för uttrycket i resultatet av uttrycket. Uttrycket let gör att en uppsättning värden kan beräknas, tilldelas namn och sedan användas i ett efterföljande uttryck som följer in. I vårt exempel på försäljningsdata kan du till exempel göra följande:

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

Resultatet av uttrycket ovan är ett talvärde (4600) som beräknas från de värden som är bundna till namnen Sales2007 och Sales2008.

If-uttryck

Uttrycket if väljer mellan två uttryck baserat på ett logiskt villkor. Till exempel:

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

Det första uttrycket (2 + 2) väljs om det logiska uttrycket (2 > 1) är sant och det andra uttrycket (1 + 1) väljs om det är falskt. Det valda uttrycket (i det här fallet 2 + 2) utvärderas och blir resultatet av if uttrycket (4).

Fel

Ett fel är en indikation på att processen för att utvärdera ett uttryck inte kunde generera ett värde.

Fel utlöses av operatorer och funktioner som påträffar feltillstånd eller med hjälp av feluttrycket. Fel hanteras med uttrycket try . När ett fel utlöses anges ett värde som kan användas för att ange varför felet inträffade.

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

Exemplet ovan öppnar fältet Sales[UnitPrice] och formaterar värdet som ger resultatet:

"Unit Price: 2"

Om fältet Units hade varit noll skulle fältet UnitPrice ha genererat ett fel som skulle ha hanterats av try. Det resulterande värdet skulle då ha varit:

"No Units"

Ett try uttryck konverterar korrekta värden och fel till ett postvärde som anger om try uttrycket hanterade ett fel, eller inte, och antingen rätt värde eller felposten som extraherades vid hanteringen av felet. Tänk till exempel på följande uttryck som genererar ett fel och sedan hanterar det direkt:

try error "negative unit count"

Det här uttrycket utvärderas till följande kapslade postvärde och förklarar [HasError]fältsökningarna , [Error]och [Message] i föregående enhetsprisexempel.

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

Ett vanligt fall är att ersätta fel med standardvärden. Uttrycket try kan användas med en valfri otherwise sats för att uppnå just det i kompakt form:

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