Introduction

Áttekintés

A Microsoft Power Query hatékony "adatok lekérése" felületet biztosít, amely számos funkciót magában foglal. A Power Query alapvető képessége az adatok szűrése és egyesítése, vagyis egy vagy több támogatott adatforrás gazdag gyűjteményéből származó adatok "összefésítése". Az ilyen adatösszesítések a Power Query képletnyelvével (nem hivatalos nevén "M") vannak kifejezve. A Power Query számos Microsoft-termékbe beágyazza az M-dokumentumokat, köztük az Excelt, a Power BI-t, az Analysis Servicest és a Dataverse-t, hogy lehetővé tegye az adatok megismételhető összeadását.

Ez a dokumentum az M specifikációját tartalmazza. A rövid bevezetés után, amelynek célja az első intuíció és a nyelv ismerete, a dokumentum pontosan több progresszív lépésben ismerteti a nyelvet:

  1. A lexikális struktúra határozza meg a lexikálisan érvényes szövegek készletét.

  2. Az értékek, kifejezések, környezetek és változók, azonosítók és a kiértékelési modell alkotják a nyelv alapfogalmait.

  3. A primitív és strukturált értékek részletes specifikációja határozza meg a nyelv céltartományát.

  4. Az értékek olyan típusokkal rendelkeznek, amelyek maguk is egy speciális értéktípust képviselnek, amelyek mind az alapvető értéktípusokat jellemzik, és további metaadatokat tartalmaznak, amelyek a strukturált értékek alakzataira vonatkoznak.

  5. Az M operátorkészlete határozza meg, hogy milyen típusú kifejezések alakíthatók ki.

  6. A függvények, másfajta különleges értékek biztosítják az M gazdag standard kódtárának alapjait, és lehetővé teszik az új absztrakciók hozzáadását.

  7. A kifejezések kiértékelése során operátorok vagy függvények alkalmazásakor hibák léphetnek fel. Bár a hibák nem értékek, vannak módszerek a hibák kezelésére, amelyek a hibákat visszaképezik az értékekre.

  8. A kifejezések lehetővé teszik az összetett kifejezések kisebb lépésekben történő összeállításához használt segéddefiníciók bevezetését.

  9. Ha a kifejezések támogatják a feltételes értékelést.

  10. A szakaszok egyszerű modularitási mechanizmust biztosítanak. (A power query még nem használja a szakaszokat.)

  11. Végül egy konszolidált nyelvtan egyetlen teljes definícióba gyűjti a dokumentum összes többi szakaszából származó nyelvtani töredékeket.

Számítógépes nyelvelmunkák esetén: az ebben a dokumentumban megadott képletnyelv többnyire tiszta, magasabb rendű, dinamikusan gépelt, részben lusta funkcionális nyelv.

Kifejezések és értékek

Az M központi konstrukciója a kifejezés. Egy kifejezés kiértékelhető (kiszámítva), egyetlen értéket eredményezve.

Bár számos érték szó szerint is írható kifejezésként, az érték nem kifejezés. A kifejezés 1 például az 1 értéket értékeli ki, a kifejezés pedig 1+1 a 2 értéket. Ez a különbség finom, de fontos. A kifejezések kiértékelési receptek; értékek a kiértékelés eredményei.

Az alábbi példák az M-ben elérhető különböző típusú értékeket szemléltetik. Konvencióként az érték írása a konstans formában történik, amelyben azok egy olyan kifejezésben jelennek meg, amely csak erre az értékre értékel. (Vegye figyelembe, hogy a // megjegyzés a sor végéig tartó megjegyzés kezdetét jelzi.)

  • A primitív érték egyrészes érték, például szám, logikai, szöveg vagy null. Az adatok hiányának jelzésére null érték használható.

    123                  // A number
    true                 // A logical
    "abc"                // A text
    null                 // null value
    
  • A listaérték az értékek rendezett sorozata. Az M támogatja a végtelen listákat, de ha konstansként van megírva, a listák rögzített hosszúságúak. A kapcsos kapcsos zárójelek { a } lista elejét és végét jelölik.

    {123, true, "A"}     // list containing a number, a logical, and 
                          //     a text 
    {1, 2, 3}            // list of three numbers 
    
  • A rekord mezők halmaza. A mező egy név/érték pár, ahol a név egy olyan szöveges érték, amely egyedi a mező rekordjában. A rekordértékek literális szintaxisa lehetővé teszi a nevek idézőjelek nélküli írását, egy más néven azonosítóként is ismert űrlapot. Az alábbiakban egy "", "A" és "C" nevű három mezőt tartalmazó rekord látható, amelyek értékei 1és 23.B

    [ 
          A = 1,  
          B = 2,  
          C = 3 
    ]
    
  • A táblák oszlopokba (név alapján azonosított) és sorokba rendezett értékek. A táblák létrehozásához nincs konstans szintaxis, de számos szabványos függvény használható listákból vagy rekordokból származó táblák létrehozásához.

    Például:

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

    Ez létrehoz egy táblázatot a következő alakzatból:

    Image of an example table in the M formula language.

  • A függvény olyan érték, amely argumentumokkal meghívva új értéket hoz létre. A függvények úgy írnak, hogy zárójelben felsorolják a függvény paramétereit , majd a továbbhaladó szimbólumot =>, majd a függvényt meghatározó kifejezést. Ez a kifejezés általában a paraméterekre (név alapján) hivatkozik.

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

Értékelés

Az M nyelv kiértékelési modelljét a számolótáblákban gyakran használt kiértékelési modell után modellezi a rendszer, ahol a számítás sorrendje a cellák képletei közötti függőségek alapján határozható meg.

Ha képleteket írt egy számolótáblában, például az Excelben, akkor a bal oldalon lévő képletek felismerhetők a jobb oldali értékekben, amikor kiszámolták:

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

Az M-ben a kifejezések részei név alapján hivatkozhatnak a kifejezés más részeire, és a kiértékelési folyamat automatikusan meghatározza a hivatkozott kifejezések kiszámításának sorrendjét.

Egy rekord használatával olyan kifejezést hozhat létre, amely megfelel az előző számolótábla-példának. Egy mező értékének inicializálásakor a mező nevével hivatkozhat a rekord más mezőire is, az alábbiak szerint:

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

A fenti kifejezés egyenértékű a következő kifejezéssel (ha mindkettő egyenlő értékre van kiértékelve):

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

A rekordok más rekordokon belül is tárolhatók vagy beágyazhatók. A keresési operátor ([]) használatával név szerint érheti el a rekord mezőit. A következő rekord például egy rekordot tartalmazó mezővel Sales rendelkezik, valamint egy olyan mezővelTotal, amely hozzáfér a rekord és SecondHalf a FirstHalfSales mezőihez:

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

A fenti kifejezés egyenértékű a következő kifejezéssel a kiértékelésekor:

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

A rekordok a listákban is megtalálhatók. A pozícióindex-operátor ({}) segítségével a lista elemeit numerikus index alapján érheti el. A lista értékeire a lista elejétől nulla alapú indexet használunk. Az indexek 01 például az alábbi lista első és második elemére hivatkoznak:

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

A tagkifejezések listázása és rögzítése (valamint a kifejezések engedélyezése) lusta kiértékeléssel történik, ami azt jelenti, hogy azokat csak szükség szerint értékeli ki a rendszer. Minden más kifejezés kiértékelése lelkes kiértékelés használatával történik, ami azt jelenti, hogy a kiértékelés azonnal történik, amikor a kiértékelési folyamat során találkoznak. Erre úgy érdemes gondolni, hogy a lista- vagy rekordkifejezések kiértékelése olyan lista- vagy rekordértéket ad vissza, amely maga is megjegyzi, hogyan kell kiszámítani a listaelemeket vagy rekordmezőket, ha szükséges (keresési vagy indexelési operátorok segítségével).

Funkciók

Az M függvény a bemeneti értékek halmazából egyetlen kimeneti értékre való leképezés. A függvények írásához először el kell nevezni a szükséges bemeneti értékeket (a függvény paramétereit), majd meg kell adni egy kifejezést, amely kiszámítja a függvény eredményét ezen bemeneti értékek (a függvény törzse) használatával az ugrás (=>) szimbólumot követve. Például:

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

A függvények olyan értékek, mint egy szám vagy egy szöveges érték. Az alábbi példa egy olyan függvényt mutat be, amely egy Add mező értéke, amelyet aztán meghív vagy végrehajt több más mezőből. Függvény meghívásakor a rendszer olyan értékkészletet határoz meg, amely logikailag helyettesíti a függvény törzskifejezésében a szükséges bemeneti értékek készletét.

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

Könyvtár

Az M egy általános definíciókészletet tartalmaz, amely egy standard kódtárnak nevezett kifejezésből, vagy csak egy rövid kódtárból használható. Ezek a definíciók nevesített értékekből állnak. A kódtár által megadott értékek nevei a kifejezés explicit definiálása nélkül használhatók egy kifejezésen belül. Például:

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

Operators

Az M a kifejezésekben használható operátorok készletét tartalmazza. Az operátorokat a rendszer az operandusokra alkalmazza szimbolikus kifejezések formájára. A kifejezésben 1 + 2 például a számok 1 és 2 operandusok, az operátor pedig az összeadás operátor (+).

Az operátorok jelentése attól függően változhat, hogy milyen típusúak az operandusai. A plusz operátor például a számokon kívül más típusú értékekkel is használható:

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

Egy operandustól függő operátorra egy másik példa a kombinációs operátor (&):

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

Vegye figyelembe, hogy egyes operátorok nem támogatják az értékek összes kombinációját. Például:

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

Azok a kifejezések, amelyek kiértékelésekor nem definiált operátori feltételekkel találkoznak, hibáknak lesznek kiértékelve.

Metaadatok

A metaadatok egy értékhez társított értékre vonatkozó információk. A metaadatok rekordértékként, úgynevezett metaadatrekordként jelenik meg. A metaadatrekord mezői egy érték metaadatainak tárolására használhatók.

Minden érték rendelkezik metaadatrekorddal. Ha a metaadat-rekord értéke nincs megadva, akkor a metaadatrekord üres (nincsenek mezői).

A metaadat-rekordok lehetővé teszik, hogy további információkat társítsunk bármilyen értékhez diszkrét módon. A metaadat-rekord értékhez való társítása nem változtatja meg az értéket vagy annak viselkedését.

A metaadatrekord értéke y egy meglévő értékhez x van társítva a szintaxis x meta yhasználatával. Az alábbi kód például egy metaadatrekordot társít a szöveges értékhez Rating"Mozart"és Tags a mezőkhöz:

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

A nem üres metaadatrekordot tartalmazó értékek esetében a metaadatok alkalmazásának eredménye a meglévő és az új metaadatrekord rekordegyesítésének kiszámítása. A következő két kifejezés például egyenértékű egymással és az előző kifejezéssel:

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

Egy metaadatrekord egy adott értékhez a Value.Metadata függvény használatával érhető el. Az alábbi példában a ComposerRating mező kifejezése hozzáfér a mező értékének Composer metaadatrekordhoz, majd hozzáfér a Rating metaadatrekord mezőjéhez.

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

Kifejezés hagyása

Az eddig bemutatott példák közül sok belefoglalta a kifejezés összes literálértékét a kifejezés eredményébe. A let kifejezés lehetővé teszi értékkészlet kiszámítását, hozzárendelt neveket, majd egy későbbi, a inkövetkező kifejezést követő kifejezésben való használatát. Az értékesítési adatok példájában például a következőt teheti:

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

A fenti kifejezés eredménye egy számérték (4600), amely a nevekhez Sales2007Sales2008és a .

Ha kifejezés

A if kifejezés két kifejezés között választ egy logikai feltétel alapján. Például:

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

Az első kifejezés (2 + 2) ki van jelölve, ha a logikai kifejezés (2 > 1) igaz, és a második kifejezés (1 + 1) ki van jelölve, ha hamis. A kiválasztott kifejezés (ebben az esetben 2 + 2) kiértékelése és eredménye lesz a if kifejezés (4).

Errors

A hiba azt jelzi, hogy a kifejezés kiértékelésének folyamata nem tudott értéket létrehozni.

A hibákat olyan operátorok és függvények okoznak, amelyek hibafeltételeket tapasztalnak, vagy a hibakifejezés használatával. A hibák kezelése a try kifejezés használatával történik. Hiba felmerülésekor meg van adva egy érték, amely a hiba okának jelzésére használható.

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

A fenti példa hozzáfér a Sales[UnitPrice] mezőhöz, és formázja az eredményt létrehozó értéket:

"Unit Price: 2"

Ha a Units mező nulla lett volna, akkor a UnitPrice mező hibát eredményezett volna, amelyet a tryprogram kezelt volna. Az eredményként kapott érték a következő lett volna:

"No Units"

A try kifejezés a megfelelő értékeket és hibákat rekordértékké alakítja, amely azt jelzi, hogy a try kifejezés hibát kezelt-e, vagy sem, és a hiba kezelésekor kinyert helyes értéket vagy hibarekordot. Vegyük például a következő kifejezést, amely hibát jelez, majd azonnal kezeli azt:

try error "negative unit count"

Ez a kifejezés a következő beágyazott rekordértékre kiértékeli az [HasError]előző egységár-példában szereplő , [Error]és [Message] mezőkereséseket.

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

Gyakori eset, hogy a hibákat alapértelmezett értékre cseréli. A try kifejezés egy opcionális otherwise záradékkal is használható, hogy kompakt formában is elérhető legyen:

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