Úvod

Prehľad

Microsoft Power Query poskytuje výkonné prostredie na "získanie údajov", ktoré obsahuje množstvo funkcií. Základnou funkciou doplnku Power Query je filtrovanie, spájanie a kombinovanie údajov zo bohatej kolekcie podporovaných zdrojov údajov. Každá takáto kombinácia údajov sa vyjadruje pomocou jazyka vzorcov Power Query M (neformálne známym pod názvom "M"). Power Query vkladá dokumenty jazyka M do širokej škály produktov spoločnosti Microsoft vrátane Excelu, Power BI, služieb Analysis Services a Dataverse, čo umožní opakovateľnú mashup údajov.

Tento dokument obsahuje špecifikáciu pre jazyk M. Po krátkom úvode, ktorý sa zameriava na vytvorenie prvého dojmu a oboznámenie sa s jazykom, dokument popisuje jazyk presnejšie v niekoľkých postupných krokoch:

  1. Lexikálna štruktúra definuje množinu textov, ktoré sú lexikálne platné.

  2. Hodnoty, výrazy, prostredia a premenné, identifikátory a model hodnotenia tvoria základné koncepty jazyka.

  3. Podrobná špecifikácia hodnôt, primitívnych aj štruktúrovaných, definuje cieľovú doménu jazyka.

  4. Hodnoty majú typy, čo je sám o sebe špeciálny druh hodnoty, ktoré charakterizujú základné druhy hodnôt a nesú ďalšie metaúdaje špecifické pre tvary štruktúrovaných hodnôt.

  5. Množina operátorov v jazyku M definuje, aké druhy výrazov možno vytvárať.

  6. Funkcie, ďalší druh špeciálnych hodnôt, poskytujú základ pre bohatú štandardnú knižnicu jazyka M a umožňujú pridávať nové abstrakcie.

  7. Pri používaní operátorov alebo funkcií počas vyhodnocovania výrazu sa môžu vyskytnúť chyby . Hoci chyby nie sú hodnoty, existujú spôsoby, ako chyby spracovať tak, že chyby sa spätne namapujú na hodnoty.

  8. Výrazy "let" umožňujú zavedenie pomocných definícií používaných na vytváranie zložitých výrazov v menších krokoch.

  9. Výrazy "if" podporujú podmienené vyhodnocovanie.

  10. Sekcie poskytujú jednoduchý modulárny mechanizmus. (Power Query zatiaľ nepoužíva sekcie.)

  11. A nakoniec konsolidovaná gramatika zhromažďuje gramatické fragmenty zo všetkých ostatných sekcií tohto dokumentu do jednej komplexnej definície.

Pre teoretikov počítačových jazykov: jazyk vzorcov špecifikovaný v tomto dokumente je väčšinou čistý, vyššie uvedený, dynamicky zadaný, čiastočne lenivý funkčný jazyk.

Výrazy a hodnoty

Centrálnym konštruktom v jazyku M je výraz. Výraz je možné vyhodnotiť (vypočítať) a získať tak výsledok v rámci jednej hodnoty.

Hoci mnohé hodnoty možno zapísať presne ako výraz, hodnota nie je výrazom. Napríklad výraz 1 sa vyhodnotí na hodnotu 1. Výraz sa vyhodnotí 1+1 na hodnotu 2. Tento rozdiel je malý, ale dôležitý. Výrazy sú recepty na vyhodnotenie; hodnoty sú výsledky vyhodnotenia.

Nasledujúce príklady znázorňujú rôzne druhy hodnôt, ktoré sú k dispozícii v jazyku M. Ako konvencia sa hodnota zapíše pomocou literálového formulára, v ktorom by sa zobrazila vo výraze, ktorý sa vyhodnotí len na túto hodnotu. (Všimnite si, že // označuje začiatok komentára, ktorý pokračuje po koniec riadka.)

  • Primitívna hodnota je jednodielna hodnota, ako je napríklad číslo, logická hodnota, text alebo hodnota null. Hodnotu null možno použiť na označenie absencie akýchkoľvek údajov.

    123                  // A number
    true                 // A logical
    "abc"                // A text
    null                 // null value
    
  • Hodnota zoznamu je zoradená postupnosť hodnôt. Jazyk M podporuje nekonečné zoznamy, ale ak sú zoznamy napísané ako literál, majú pevnú dĺžku. Znaky zložených zátvoriek { a } označujú začiatok a koniec zoznamu.

    {123, true, "A"}     // list containing a number, a logical, and 
                          //     a text 
    {1, 2, 3}            // list of three numbers 
    
  • Záznam je množina polí. Pole je dvojica názov-hodnota, kde názov je textová hodnota, ktorá je v rámci záznamu danej poľa jedinečná. Literálová syntax pre hodnoty záznamov umožňuje zápis názvov bez úvodzoviek. Ide o formu, ktorá sa označuje aj ako identifikátory. V nasledujúcom príklade je zobrazený záznam obsahujúci tri polia s názvami "A", "B" a "C", ktoré majú hodnoty 1, 2a 3.

    [ 
          A = 1,  
          B = 2,  
          C = 3 
    ]
    
  • Tabuľka je množina hodnôt usporiadaných do stĺpcov (ktoré sú identifikované podľa názvu) a riadkov. Neexistuje žiadna literálová syntax na vytvorenie tabuľky, ale existuje niekoľko štandardných funkcií, ktoré možno použiť na vytváranie tabuliek zo zoznamov alebo záznamov.

    Napríklad:

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

    Týmto sa vytvorí tabuľka nasledujúceho tvaru:

    Image of an example table in the M formula language.

  • Funkcia je hodnota, ktorá pri vyvolaní s argumentmi vytvorí novú hodnotu. Funkcia sa zapisuje uvedením parametrov funkcie v zátvorkách , potom symbolu =>ide-to, za ktorým nasleduje výraz definujúci funkciu. Tento výraz zvyčajne odkazuje na parametre (podľa názvu).

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

Hodnotenie

Model vyhodnotenia jazyka M je modelovaný podľa modelu vyhodnotenia, ktorý sa bežne nachádza v tabuľkových hárkoch, kde možno určiť poradie výpočtov na základe závislostí medzi vzorcami v bunkách.

Ak ste písali vzorce do tabuľkového hárka, ako je napríklad Excel, môžete po vypočítaní rozpoznať vzorce na ľavej strane s hodnotami vpravo:

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

V jazyku M môžu časti výrazu odkazovať na iné časti výrazu podľa názvu a proces vyhodnotenia automaticky určí poradie, v ktorom sa vypočítavajú výrazy, na ktoré sa odkazuje.

Záznam môžete použiť na vytvorenie výrazu, ktorý je ekvivalentom predchádzajúceho príkladu tabuľkového hárka. Pri inicializácii hodnoty poľa môžete odkazovať na iné polia v rámci záznamu pomocou názvu poľa takto:

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

Vyššie uvedený výraz je ekvivalent nasledujúceho (v tomto sa oba vyhodnotia na rovnaké hodnoty):

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

Záznamy sa môžu nachádzať alebo byť vnorené v iných záznamoch. K poliam záznamu môžete získať prístup podľa názvu pomocou operátora vyhľadávania ([]). Nasledujúci záznam má napríklad pole s názvom Sales obsahujúce záznam, a pole s názvom , ktoré pristupuje FirstHalfTotal k poliam záznamu a SecondHalf záznamu Sales :

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

Vyššie uvedený výraz je pri vyhodnotení ekvivalentom nasledujúceho:

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

Záznamy sa môžu nachádzať aj v zoznamoch. Na prístup k položke v zozname môžete použiť číselný index pomocou operátora poziálneho indexu ({}). Na hodnoty v zozname sa odkazuje pomocou indexu založeného na nule od začiatku zoznamu. Indexy 0 a 1 sa napríklad používajú na odkazovanie na prvú a druhú položku v zozname nižšie:

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

Výrazy členov zoznamu a záznamu (ako aj výrazy let) sa vyhodnocujú pomocou lenivého hodnotenia, čo znamená, že sa vyhodnocujú len podľa potreby. Všetky ostatné výrazy sa vyhodnocujú pomocou nedočkavého vyhodnotenia, čo znamená, že sa vyhodnocujú okamžite, keď sa vyskytnú počas procesu hodnotenia. Dobrým spôsobom je zapamätať si, že vyhodnotením výrazu zoznamu alebo záznamu sa vráti hodnota zoznamu alebo záznamu, ktorá si sama pamätá, ako sa jej položky zoznamu alebo polia záznamov musia vypočítať, keď sa to vyžaduje (vyhľadávaním alebo operátormi indexu).

Funkcie

V jazyku M je funkcia mapovaním z množiny vstupných hodnôt na jednu výstupnú hodnotu. Funkcia sa zapisuje najskôr pomenovaním požadovanej množiny vstupných hodnôt (parametre funkcie) a potom zadaním výrazu, ktorý vypočíta výsledok funkcie pomocou týchto vstupných hodnôt (telo funkcie) podľa symbolu použitia (=>). Napríklad:

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

Funkcia je hodnota rovnako ako číselná alebo textová hodnota. Nasledujúci príklad znázorňuje funkciu, ktorá je hodnotou funkcie Add field (Pridať pole), ktorá sa potom vyvolá alebo vykoná z niekoľkých ďalších polí. Pri vyvolaní funkcie sa zadá množina hodnôt, ktoré sú logicky nahradené za požadovanú množinu vstupných hodnôt vo výraze tela funkcie.

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

Knižnica

Jazyk M obsahuje spoločný súbor definícií, ktoré sú k dispozícii na použitie z výrazu s názvom štandardná knižnica alebo skrátene len knižnica . Tieto definície pozostávajú z množiny pomenovaných hodnôt. Názvy hodnôt, ktoré obsahuje knižnica, sú k dispozícii na použitie v rámci výrazu bez toho, aby boli explicitne definované výrazom. Napríklad:

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

Operátory

Jazyk M obsahuje množinu operátorov, ktoré možno použiť vo výrazoch. Použitím operátorov na operandy sa vytvárajú symbolické výrazy. Napríklad vo výraze 1 + 2 sú čísla 1 a 2 operandy a operátorom je operátor sčítania (+).

Význam operátora sa môže líšiť v závislosti od typu hodnôt operandov. Operátor plus je napríklad možné použiť s inými typmi hodnôt okrem čísel:

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

Ďalším príkladom operátora s významom závislým od operátora je operátor kombinácie (&):

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

Všimnite si, že niektoré operátory nepodporujú všetky kombinácie hodnôt. Napríklad:

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

Výrazy, ktoré pri vyhodnotení narazia na nedefinované podmienky operátora, sa vyhodnotia ako chyby.

Metaúdaje

Metaúdaje sú informácie o hodnote, ktorá je priradená k hodnote. Metaúdaje sú vyjadrené ako hodnota záznamu a nazýva sa záznam metaúdajov. Polia záznamu metaúdajov možno použiť na ukladanie metaúdajov pre určitú hodnotu.

Každá hodnota má záznam metaúdajov. Ak hodnota záznamu metaúdajov nebola zadaná, záznam metaúdajov je prázdny (nemá žiadne polia).

Záznamy metaúdajov poskytujú spôsob, ako nevtieravým spôsobom priradiť ďalšie informácie k ľubovoľnému druhu hodnoty. Priradenie záznamu metaúdajov k hodnote nezmení hodnotu ani jej správanie.

Hodnota y záznamu metaúdajov je priradená k existujúcej hodnote x pomocou syntaxe x meta y. Nasledujúci kód napríklad priradí záznamu metaúdajov polia a Tags s Rating textovú hodnotou "Mozart":

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

V prípade hodnôt, ktoré už nesú neprázdny záznam metaúdajov, je výsledkom použitia funkcie meta výpočet zlúčenia záznamu existujúceho a nového záznamu metaúdajov. Napríklad nasledujúce dva výrazy sú ekvivalentné navzájom a predchádzajúcemu výrazu:

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

K hodnote záznamu metaúdajov je možné získať prístup pomocou funkcie Value.Metadata . V nasledujúcom príklade výraz v ComposerRating poli pristupuje k záznamu metaúdajov hodnoty v Composer poli a potom pristupuje k poľu Rating záznamu metaúdajov.

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

Výraz Let

Mnohé z doteraz uvedených príkladov obsahovali vo výsledku výrazu všetky literálové hodnoty výrazu. Výraz let umožňuje množinu vypočítavaných hodnôt, ktorým sa priradia názvy a ktoré sa potom použijú v následnom výraze, ktorý nasleduje po výraze in. V príklade našich údajov o predaji by ste napríklad mohli urobiť:

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

Výsledkom vyššie uvedeného výrazu je číselná hodnota (4600), ktorá sa vypočíta z hodnôt naviazaných na názvy Sales2007 a Sales2008.

Výraz If

Výraz if vyberie medzi dvomi výrazmi na základe logickej podmienky. Napríklad:

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

Prvý výraz (2 + 2) sa vyberie, ak je logický výraz (2 > 1) pravdivý, a druhý výraz (1 + 1) sa vyberie, ak je nepravdivý. Vybratý výraz (v tomto prípade 2 + 2) sa vyhodnotí a bude výsledkom výrazu if (4).

Errors

Chyba označuje, že proces vyhodnocovania výrazu nebol schopný vyprodukovať hodnotu.

Chyby sú vyvolávané operátormi a funkciami, ktoré sa stretávajú s podmienkami chyby, alebo pomocou výrazu error. Chyby sa spracováva pomocou výrazu try . Pri chybe špecifikovaná hodnota sa dá použiť na označenie jej príčiny.

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

Uvedený príklad pristupuje k poľu Sales[UnitPrice] a formátuje hodnotu s výsledkom:

"Unit Price: 2"

Units Ak by pole bolo nulové, UnitPrice pole by vyvolalo chybu, ktorá by bola spracovaná výrazom try. Výsledná hodnota by potom bola:

"No Units"

Výraz try konvertuje správne hodnoty a chyby na hodnotu záznamu, ktorá označuje, či try sa vyhodnotila chyba alebo nie, a či sa pri spracovávaní chyby vyhodnotila správna hodnota alebo záznam chyby. Uvažujme napríklad o nasledujúcom výraze, ktorý vyvolá chybu, a potom ho okamžite spracuje:

try error "negative unit count"

Tento výraz poskytuje nasledujúcu hodnotu vnoreného záznamu, pričom vysvetlí [HasError]vyhľadávania polí , [Error]a [Message] v predchádzajúcom príklade jednotkovej ceny.

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

Bežným prípadom je nahradenie chýb predvolenými hodnotami. Na try dosiahnutie iba toho v kompaktnej formy možno použiť výraz s voliteľnou otherwise klauzulou :

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