Introduktion
Överblick
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:
Den lexikala strukturen definierar den uppsättning texter som är lexikaliskt giltiga.
Värden, uttryck, miljöer och variabler, identifierare och utvärderingsmodellen utgör språkets grundläggande begrepp.
Den detaljerade specifikationen av värden, både primitiva och strukturerade, definierar språkets måldomän.
Värden har typer, själva en speciell typ av värde, som både 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.
Uppsättningen med operatorer i M definierar vilka typer av uttryck som kan skapas.
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.
Fel kan inträffa 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.
Låt uttryck tillåta införandet av hjälpdefinitioner som används för att bygga upp komplexa uttryck i mindre steg.
If-uttryck stödjer villkorsstyrd utvärdering.
avsnitt tillhandahåller en enkel modularitetsmekanism. (Avsnitt utnyttjas ännu inte av Power Query.)
Slutligen samlar en konsoliderad grammatik grammatikfragmenten från alla andra delar av det här dokumentet till en enda fullständig definition.
För datorspråksteoretiker: formelspråket som anges i det här dokumentet är ett mestadels rent, högre ordning, dynamiskt typat, 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 värdet 1; uttrycken 1+1
utvärderas 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 olika typer av värden som är tillgängliga i M. Som en konvention skrivs ett värde med hjälp av den bokstavliga formen där de visas i ett uttryck som utvärderas till precis det värdet. (Observera att //
anger början på en kommentar som fortsätter till slutet av raden.)
Ett primitivt värde är endelsvärde, till exempel ett tal, logiskt värde, 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
En lista värde är en ordnad sekvens med värden. M stöder oändliga listor, men om de skrivs bokstavligt, har listorna 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 inom postens fält. Med det bokstavliga syntaxen för postvärden kan namnen skrivas utan citattecken, ett format som också kallas identifierare. Följande visar en post som innehåller tre fält med namnet "
A
", "B
", och "C
", som har värden1
,2
och3
.[ 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:
En funktion är ett värde som, när den anropas med argument, genererar ett nytt värde. En funktion skrivs genom att lista funktionens parametrar inom parenteser, följt av gå till-symbolen
=>
, 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:
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 postering för att skapa ett uttryck som är ekvivalent med 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 inbäddasi, andra poster. Du kan använda uppslagsoperatorn ([]
) för att komma åt fälten i en post med 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 fälten FirstHalf
och SecondHalf
i posten Sales
.
[
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
]
Register kan också finnas i listor. Du kan använda positionsindexoperator ({}
) 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. Indexen 0
och 1
används till exempel 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 låta 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 hjälp av 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 kort och gott bibliotek. 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
Operatörer
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
till exempel talen 1
och 2
är operander och operatorn är 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 stöter på odefinierade villkor för operatorer, leder 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 metadatapostvärde y
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 resulterar tillämpningen av meta i beräkningen av sammanslagningen 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"} ])
En metadatapost kan nås för ett visst värde med hjälp av funktionen Value.Metadata. I följande exempel får uttrycket i fältet ComposerRating
åtkomst till metadataposten för värdet i fältet Composer
och kommer sedan åt fältet Rating
i 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. Med uttrycket let
kan en uppsättning värden 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 värdena 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 det 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 det Units
fältet 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 omvandlar korrekta värden och fel till en registervärde som anger om try
-uttrycket hanterade ett fel eller inte, och ger antingen det korrekta värdet eller felregistret som extraherades när felet hanterades. 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]
, [Error]
och [Message]
fältsökningar 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 detta i kompakt form:
try error "negative unit count" otherwise 42
// 42