Kontext řádku v jazyku DAX

Úvodní obrázek

Kontext řádku vzniká při vyhodnocení výrazu v počítaných sloupcích a při vyhodnocení výrazů v iteračních funkcích. Výsledkem kontextu řádku je vždy pouze jeden řádek tabulky. Kontext řádku, na rozdíl od kontextu filtru, neprochází přes relace do jiných tabulek v datovém modelu.

Počítaný sloupec a kontext řádku

Kontext řádku si můžeme znázornit na vytvoření nového počítaného sloupce v existující tabulce v modelu. Ve cvičném Power BI souboru Adventure Works DW 2020.pbix si vytvoříme nový počítaný sloupec v tabulce 'Sales', který bude obsahovat částku inkasovanou za prodané produkty. Částka za prodané produkty odpovídá násobku jednotkové ceny produktu a prodaného množství produktu.

Počítaný sloupec:

Prodeje = Sales[Unit Price] * Sales[Order Quantity]

V definici výpočtu se odkazujeme přímo na sloupce ze stejné tabulky, ve které je výpočet vyhodnocen. Výsledkem je nový počítaný sloupec v tabulce 'Sales'.

Kontext řádku v jazyku DAX

Výraz uvedený v řádku vzorců na obrázku výše je jednoduchý. Počítáme součin mezi hodnotami ve sloupci 'Sales'[Unit Price] a 'Sales'[Order Quantity]. Při výpočtu se odkazujeme pouze na názvy sloupců, a nikde není uvedeno, pro který řádek tabulky se má výraz vyhodnotit. 

To, že je například v prvním řádku nového počítaného sloupce hodnota, která odpovídá součinu mezi hodnotami 'Sales'[Unit Price] a 'Sales'[Order Quantity] ze stejného řádku, je dáno právě kontextem řádku, ve kterém je výraz vyhodnocen a který vzniká automaticky při vytvoření nového počítaného sloupce.

Iterační funkce a kontext řádku

Kontext řádku vzniká také při použití iteračních funkcí. Mezi iterační funkce řadíme například funkce ADDCOLUMNS(), FILTER(), SUMX(), MINX() a mnohé jiné. Pokud bychom chtěli získat získat sumu prodejů pomocí měřítka namísto počítaného sloupce, nemůžeme použít stejný výpočet uvedený v příkladu výše, protože v měřítku není dostupný žádný kontext řádku. Stejný výpočet, který jsme použili pro vytvoření počítaného sloupce, vrací v měřítku chybu.

Kontext řádku v jazyku DAX 2

V měřítku není k dispozici kontext řádku, protože měřítka nepatří do žádné tabulky a mohou být vyhodnocena v různých kontextech, podle toho, kde je v reportech použijeme.

Pozn. Měřítka sice vytváříme v modelu v konkrétních tabulkách, ale jedná se pouze o umístění měřítka, a ne o jeho vyhodnocení. Měřítko vytvořené v jedné tabulce můžeme klidně přesunout do jiné tabulky. K vyhodnocení měřítka dochází až na úrovni vizuálů v reportech.

Pokud se chceme odkazovat na hodnoty ze sloupce v měřítku, musíme mít jistotu, že výsledkem bude pouze jedna skalární hodnota. Mohli bychom tedy zkusit použít sumarizační funkci SUM().

Měřítko:

Prodeje 2 (Špatně) =
    SUM(Sales[Unit Price]) * SUM(Sales[Order Quantity])

Takto definované měřítko již sice půjde vytvořit, ale vrací nesmyslné výsledky. 

Kontext řádku v jazyku DAX 3

Na obrázku výše jsou v řádcích kategorie produktů. Měřítko [Prodeje 2 (Špatně)]  je vyhodnoceno v kontextu filtru každé kategorie. V prvním řádku tedy násobíme sumu všech jednotkových cen pro prodané produkty z kategorie Accessories sumou všech prodaných kusů ze stejné kategorie. Tento výpočet ale nedává smysl. Pro získání správného výsledku potřebujeme násobit jednotkovou cenu každého prodaného produktu množstvím toho stejného prodaného produktu v daném řádku v tabulce 'Sales'. Jinak řečeno, 2 * 2 + 2 * 2 není to samé, jako 4 * 4. Pokud chceme získat správný výsledek v měřítku, musíme vytvořit kontext řádku programově uvnitř výpočtu.

Funkce SUMX

Správný výsledek v měřítku získáme v tomto případě pomocí funkce SUMX(). Funkce SUMX() má dva povinné argumenty. Prvním argumentem je tabulka, pro kterou chceme spočítat výraz ve druhém argumentu. Výpočet ve druhém argumentu probíhá postupně v kontextu každého řádku tabulky v prvním argumentu. Správně definované měřítko počítající sumu prodejů by mohlo vypadat následovně.

Měřítko:

Prodeje (Správně) =
SUMX
(
    Sales,
    Sales[Unit Price] * Sales[Order Quantity]
)

Nově vytvořené měřítko si můžeme vložit do původního vizuálu a porovnat tak výsledky.

Kontext řádku v jazyku DAX 4

Měřítko [Prodeje (Správně)] již vrací správné výsledky. Pro úplnost si ještě musíme popsat, kde ve výpočtu vzniká kontext řádku. 

Ve čtvrtém řádku kódu na obrázku výše je odkaz na tabulku 'Sales'. Tato tabulka je vyhodnocena v kontextu filtru každé kategorie, které jsou uvedené ve v řádcích vizuálu. Výpočet prodejů pro kategorii Accessories v prvním řádku vizuálu si můžeme představit následovně.

Tabulka 'Sales' při výpočtu prodejů pro kategorii Accessories obsahuje pouze záznamy o prodejích produktů z kategorie Accessories, díky filtru který působí na model při vyhodnocení měřítka. Následně je pro každý řádek takto zafiltrované tabulky 'Sales' vyhodnocen v nově vytvořeném kontextu řádku druhý argument funkce SUMX(), který obsahuje výpočet součinu jednotkové ceny a prodaného množství. Výsledná hodnota měřítka v prvním řádku vizuálu je sumou jednotlivých výsledků výrazu v druhém argumentu funkce SUMX() pro všechny řádky v tabulce 'Sales', které jsou dostupné v kontextu filtru kategorie Accessories. Stejný princip je pak aplikovaný i na další kategorie v dalších řádcích vizuálu. V řádku souhrnů již na tabulku 'Sales' nepůsobí žádný filtr, a výsledek v řádku souhrnů odpovídá sumě za prodeje všech produktů, bez ohledu na kategorii.

Shrnutí

Kontext řádku vzniká automaticky při vytvoření nového počítaného sloupce v tabulce. Výpočet v měřítku je na druhou stranu vyhodnocen v kontextu filtru. Pokud potřebujeme vyhodnotit výpočet v měřítku v kontextu řádku tabulky, musíme kontext řádku vytvořit programově. K vytvoření kontextu řádku jsou v jazyku DAX k dispozici iterační funkce, které mají obvykle dva povinné argumenty. Prvním argumentem je tabulka, která je vyhodnocena v kontextu filtru. Druhým argumentem je pak výraz, který je vyhodnocen v nově vzniklém kontextu řádku tabulky uvedené v prvním argumentu iterační funkce. Dalším důležitou součástí kontextu vyhodnocení je kontext filtru. Více informací o kontextu filtru můžete najít v samostatném příspěvku.

č. 7

Komentáře