Del via


Introduksjon

Oversikt

Microsoft Power Query gir en kraftig «hent data»-opplevelse som omfatter mange funksjoner. En kjernefunksjonalitet i Power Query er å filtrere og kombinere, det vil eksempelvis være å «mash-up»-data fra én eller flere av en rik samling av støttede datakilder. En slik datafletting uttrykkes ved hjelp av Power Query-formelspråket (uformelt kjent som «M»). Power Query bygger inn M-dokumenter i et bredt spekter av Microsoft-produkter, inkludert Excel, Power BI, Analysis Services og Dataverse, for å aktivere gjentakende blanding av data.

Dette dokumentet inneholder spesifikasjonen for M. Etter en kort introduksjon som tar sikte på å bygge noen første intuisjon og kjennskap til språket, dekker dokumentet språket nøyaktig i flere progressive trinn:

  1. Den leksikalske strukturen definerer settet med tekster som er leksisk gyldige.

  2. Verdier, uttrykk, miljøer og variabler, identifikatorer og evalueringsmodellen danner språkets grunnleggende konsepter.

  3. Den detaljerte spesifikasjonen av verdier, både primitive og strukturerte, definerer måldomenet for språket.

  4. Verdier har typer, selv en spesiell type verdi, som både karakteriserer de grunnleggende verditypene og bærer flere metadata som er spesifikke for formene for strukturerte verdier.

  5. Operatorsettet i M definerer hvilke typer uttrykk som kan dannes.

  6. Funksjoner, en annen type spesialverdier, gir grunnlaget for et rikt standardbibliotek for M og gir mulighet for å legge til nye abstraksjoner.

  7. Feil kan oppstå når du bruker operatorer eller funksjoner under uttrykksevaluering. Selv om feil ikke er verdier, finnes det måter å håndtere feil som tilordner feil tilbake til verdier.

  8. La uttrykk tillate innføring av hjelpedefinisjoner som brukes til å bygge opp komplekse uttrykk i mindre trinn.

  9. Hvis uttrykk støtter betinget evaluering.

  10. Inndelinger gir en enkel modulær mekanisme. (Inndelinger er ennå ikke utnyttet av Power Query.)

  11. Til slutt samler en konsolidert grammatikk grammatikk inn grammatikkfragmentene fra alle andre deler av dette dokumentet i én enkelt fullstendig definisjon.

For dataspråkteoretikere: formelspråket som er angitt i dette dokumentet, er for det meste et rent, høyere rekkefølge, dynamisk skrevet, delvis lat funksjonelt språk.

Uttrykk og verdier

Den sentrale konstruksjonen i M er uttrykket. Et uttrykk kan evalueres (beregnet), noe som gir én enkelt verdi.

Selv om mange verdier kan skrives bokstavelig som et uttrykk, er ikke en verdi et uttrykk. Uttrykket 1 evalueres for eksempel til verdien 1. Uttrykkene evalueres 1+1 til verdien 2. Dette skillet er subtilt, men viktig. Uttrykk er oppskrifter for evaluering; verdiene er resultatene av evalueringen.

Eksemplene nedenfor illustrerer de ulike verditypene som er tilgjengelige i M. Som en konvensjon skrives en verdi ved hjelp av det litterale skjemaet der de vises i et uttrykk som evalueres til akkurat denne verdien. (Vær oppmerksom på // at indikerer starten på en kommentar som fortsetter til slutten av linjen.)

  • En primitiv verdi er en endelt verdi, for eksempel tall, logisk, tekst eller null. En nullverdi kan brukes til å angi fraværet av data.

    123                  // A number
    true                 // A logical
    "abc"                // A text
    null                 // null value
    
  • En listeverdi er en sortert rekkefølge med verdier. M støtter uendelige lister, men hvis de skrives som en litteral, har lister en fast lengde. Klammeparentestegnene { og } betegner begynnelsen og slutten av en liste.

    {123, true, "A"}     // list containing a number, a logical, and 
                          //     a text 
    {1, 2, 3}            // list of three numbers 
    
  • En post er et sett med felt. Et felt er et navn/verdipar der navnet er en tekstverdi som er unik i feltets post. Den litterale syntaksen for postverdier gjør at navnene kan skrives uten anførselstegn, et skjema som også kalles identifikatorer. Følgende viser en post som inneholder tre felt med navnet "A", "B" og "C", som har verdier 1, 2og 3.

    [ 
          A = 1,  
          B = 2,  
          C = 3 
    ]
    
  • En tabell er et sett med verdier organisert i kolonner (som identifiseres etter navn) og rader. Det finnes ingen litteral syntaks for å opprette en tabell, men det finnes flere standardfunksjoner som kan brukes til å opprette tabeller fra lister eller poster.

    Eksempel:

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

    Dette oppretter en tabell med følgende figur:

    Image of an example table in the M formula language.

  • En funksjon er en verdi som, når den aktiveres med argumenter, produserer en ny verdi. En funksjon skrives ved å vise funksjonens parametere i parenteser, etterfulgt av goes-to-symbolet =>, etterfulgt av uttrykket som definerer funksjonen. Dette uttrykket refererer vanligvis til parameterne (etter navn).

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

Evaluering

Evalueringsmodellen for M-språket er modellert etter evalueringsmodellen som vanligvis finnes i regneark, der beregningsrekkefølgen kan bestemmes basert på avhengigheter mellom formlene i cellene.

Hvis du har skrevet formler i et regneark, for eksempel Excel, kan det hende at du gjenkjenner formlene til venstre i verdiene til høyre når de beregnes:

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

I M kan deler av et uttrykk referere til andre deler av uttrykket etter navn, og evalueringsprosessen bestemmer automatisk rekkefølgen det refereres til uttrykk i.

Du kan bruke en post til å produsere et uttrykk som tilsvarer det forrige regnearkeksempelet. Når du initialiserer verdien for et felt, kan du referere til andre felt i posten ved hjelp av navnet på feltet, som følger:

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

Uttrykket ovenfor tilsvarer følgende (i at begge evalueres til like verdier):

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

Poster kan finnes i, eller nestes, i andre poster. Du kan bruke oppslagsoperatoren ([]) til å få tilgang til feltene i en post etter navn. Følgende post har for eksempel et felt med navnet Sales inneholder en post, og et felt med navnet Total som får FirstHalf tilgang til og SecondHalf feltene i Sales posten:

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

Uttrykket ovenfor tilsvarer følgende når det evalueres:

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

Poster kan også finnes i lister. Du kan bruke operatoren for posisjonsindeks ({}) til å få tilgang til et element i en liste etter den numeriske indeksen. Verdiene i en liste henvises til å bruke en nullbasert indeks fra begynnelsen av listen. Indeksene 0 og 1 brukes for eksempel til å referere til de første og andre elementene i listen nedenfor:

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

Liste- og postmedlemsuttrykk (i tillegg til la uttrykk) evalueres ved hjelp av lat evaluering, noe som betyr at de bare evalueres etter behov. Alle andre uttrykk evalueres ved hjelp av ivrig evaluering, noe som betyr at de evalueres umiddelbart når de oppstår under evalueringsprosessen. En god måte å tenke på dette på er å huske at evaluering av en liste eller et postuttrykk returnerer en liste eller postverdi som i seg selv husker hvordan listeelementene eller postfeltene må beregnes, når det blir bedt om (av oppslags- eller indeksoperatorer).

Funksjoner

I M er en funksjon en tilordning fra et sett med inndataverdier til én enkelt utdataverdi. En funksjon skrives ved først å navngi det nødvendige settet med inndataverdier (parameterne til funksjonen) og deretter gi et uttrykk som beregner resultatet av funksjonen ved hjelp av disse inndataverdiene (brødteksten i funksjonen) etter goes-to (=>)-symbolet. Eksempel:

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

En funksjon er en verdi akkurat som et tall eller en tekstverdi. Eksemplet nedenfor viser en funksjon som er verdien for et Legg til-felt som deretter aktiveres, eller kjøres, fra flere andre felt. Når en funksjon aktiveres, angis et sett med verdier som er logisk erstattet med det nødvendige settet med inndataverdier i brødtekstuttrykket for funksjonen.

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

Bibliotek

M inneholder et vanlig sett med definisjoner som er tilgjengelige for bruk fra et uttrykk kalt standardbiblioteket, eller bare bibliotek for kort. Disse definisjonene består av et sett med navngitte verdier. Navnene på verdier som leveres av et bibliotek, er tilgjengelige for bruk i et uttrykk uten å ha blitt definert eksplisitt av uttrykket. Eksempel:

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

Operatorer

M inneholder et sett med operatorer som kan brukes i uttrykk. Operatorer brukes på operander for å danne symbolske uttrykk. I uttrykket 1 + 2 er for eksempel tallene 1 og 2 operandene, og operatoren er addisjonsoperatoren (+).

Betydningen av en operator kan variere avhengig av hva slags verdier operandene er. Plussoperatoren kan for eksempel brukes med andre typer verdier i tillegg til tall:

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

Et annet eksempel på en operator med operand-avhengig betydning er kombinasjonsoperatoren (&):

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

Vær oppmerksom på at noen operatorer ikke støtter alle kombinasjoner av verdier. Eksempel:

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

Uttrykk som, når de evalueres, støter på udefinerte operatorbetingelser evalueres til feil.

Metadata

Metadata er informasjon om en verdi som er knyttet til en verdi. Metadata representeres som en postverdi, kalt en metadatapost. Feltene i en metadatapost kan brukes til å lagre metadataene for en verdi.

Hver verdi har en metadatapost. Hvis verdien for metadataposten ikke er angitt, er metadataposten tom (har ingen felt).

Metadataposter gir en måte å knytte tilleggsinformasjon til alle typer verdier på en diskret måte. Å knytte en metadatapost til en verdi endrer ikke verdien eller virkemåten.

En metadatapostverdi y er knyttet til en eksisterende verdi x ved hjelp av syntaksen x meta y. Følgende kode knytter for eksempel en metadatapost til Rating og Tags felter med tekstverdien "Mozart":

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

For verdier som allerede har en ikke-tom metadatapost, er resultatet av å bruke meta at du beregner postflettingen av den eksisterende og den nye metadataposten. Følgende to uttrykk tilsvarer for eksempel hverandre og det forrige uttrykket:

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

Du kan få tilgang til en metadatapost for en gitt verdi ved hjelp av value.metadata-funksjonen . I eksemplet nedenfor får uttrykket i ComposerRating feltet tilgang til metadataposten for verdien i Composer feltet, og deretter får Rating du tilgang til feltet for metadataposten.

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

La uttrykk

Mange av eksemplene som vises så langt, har inkludert alle de litterale verdiene i uttrykket i resultatet av uttrykket. Uttrykket let gjør at et sett med verdier kan beregnes, tilordnes navn og deretter brukes i et etterfølgende uttrykk som følger in. I eksempelet på salgsdata kan du for eksempel gjøre følgende:

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 uttrykket ovenfor er en tallverdi (4600) som beregnes fra verdiene som er bundet til navnene Sales2007 og Sales2008.

Hvis uttrykk

Uttrykket if velges mellom to uttrykk basert på en logisk betingelse. Eksempel:

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

Det første uttrykket (2 + 2) velges hvis det logiske uttrykket (2 > 1) er sant, og det andre uttrykket (1 + 1) velges hvis det er usant. Det valgte uttrykket (i dette tilfellet 2 + 2) evalueres og blir resultatet av if uttrykket (4).

Feil

En feil er en indikasjon på at prosessen med å evaluere et uttrykk ikke kunne produsere en verdi.

Feil oppstår av operatorer og funksjoner som støter på feilforhold eller ved hjelp av feiluttrykket. Feil håndteres ved hjelp av try uttrykket. Når det oppstår en feil, angis en verdi som kan brukes til å angi hvorfor feilen oppstod.

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

Eksemplet ovenfor får Sales[UnitPrice] tilgang til feltet og formaterer verdien som produserer resultatet:

"Unit Price: 2"

Hvis feltet Units hadde vært null, UnitPrice ville feltet ha utløst en feil, som ville ha blitt håndtert av try. Resultatverdien ville da ha vært:

"No Units"

Et try uttrykk konverterer riktige verdier og feil til en postverdi som angir om try uttrykket håndterte en feil, eller ikke, og enten den riktige verdien eller feilposten som ble trukket ut under håndtering av feilen. Vurder for eksempel følgende uttrykk som utløser en feil, og håndterer det umiddelbart:

try error "negative unit count"

Dette uttrykket evalueres til følgende nestede postverdi, og forklarer [HasError]oppslagene for , [Error]og [Message] feltet i forrige eksempel på enhetspris.

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

Et vanlig tilfelle er å erstatte feil med standardverdier. Uttrykket try kan brukes med en valgfri setningsdel otherwise for å oppnå nettopp dette i en kompakt form:

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