Kontext filtru v jazyku DAX

Úvodní obrázek

Jazyk DAX přinesl zcela revoluční koncept, který umožňuje opakovaně používat stejný výpočet v jiném prostředí. Tento výpočet pak vrací jiné hodnoty právě podle toho, v jakém kontextu je vyhodnocen. Díky tomu můžeme tvořit reporty efektivněji a nevytvářet pro každý vizuál obdobný výpočet znovu a znovu. To vše se děje díky takzvanému kontextu filtru, který na měřítka působí, což je pojem který si vysvětíme v tomto příspěvku.

K tomuto tématu je k dispozici také video:

Pokud v Tabulárním modelu vytvoříme měřítko, stane se toto měřítko součástí modelu, a můžeme ho používat opakovaně v různých vizuálech s různými atributy v řádcích nebo na osách, s různě nastavenými filtry v průřezech a v dalších vizuálech. Všechny tyto objekty tvoří celkové prostředí, ve kterém je měřítko vyhodnoceno. Prostředí, ve kterém je měřítko vyhodnoceno se při práci s jazykem DAX nazývá kontext vyhodnocení. Kontext vyhodnocení se následně dělí na kontextu filtru, kterému se věnujeme v tomto příspěvku, a na kontext řádku, který je aktivní uvnitř iteračních funkcí a v počítaných sloupcích. Kontextu řádku je věnovaný samostatný příspěvek dostupný pod tímto odkazem. 

Kombinace těchto dvou kontextů umožňuje pracovat s jazykem DAX jak začátečníkům, pro které je tento jazyk ze začátku obvykle velmi intuitivní a relativně jednoduchý, ale také pokročilým DAX vývojářům, kteří využívají detailní znalost kontextu řádku a kontextu filtru, díky čemuž jsou schopni tvořit velmi působivé výpočty.

Kontext filtru

Pochopení kontextu filtru nevyžaduje žádnou velkou představivost a v případě jednoduchých měřítek je práce s kontextem filtru velmi intuitivní. Kontext filtru je soubor filtrů aplikovaných na model. Tento soubor filtrů aplikovaný na jednotlivé sloupce v tabulkách změní počet řádků v modelu, které budou dostupné při vyhodnocení výpočtu. Mezi více filtry, které jsou aktivní v jednu chvíli existuje logický AND vztah. Kontext filtru je také propagován pomocí relací mezi jednotlivými tabulkami, pokud to směr filtrace nastavený na konkrétní relaci umožňuje.

Vyhodnocení měřítka v kontextu filtru

Pro znázornění fungování kontextu filtru si ve cvičném Power BI souboru můžeme vytvořit jednoduché měřítko, které bude vracet sumu za prodané produkty v aktuálním kontextu vyhodnocení.

Měřítko:

Prodeje = SUM(Sales[Sales Amount])

Funkce SUM() použitá v měřítku  [Prodeje] je sumarizační funkce, a stejně jako kterákoliv jiná sumarizační funkce tak i funkce SUM() respektuje kontext filtru. To si můžeme znázornit tak že použijeme měřítko [Prodeje] v různých kontextech filtru, a porovnáme si jeho výsledky. Pro začátek si vložíme měřítko [Prodeje] do vizuálu Tabulka, kde na výpočet nebudou působit žádné filtry.

Kontext filtru v jazyku DAX

Na obrázku výše je vidět suma všech hodnot ze sloupce 'Sales'[Sales Amount], protože před vyhodnocením výrazu není na model aplikován žádný filtr. Přesněji řečeno kontext filtru je prázdný. Pokud přidáme do Power BI reportu Průřez, například s roky z tabulky 'Date', a vybereme pouze rok 2020, výraz v měřítku [Prodeje] bude vyhodnocen v kontextu filtru roku 2020.

Kontext filtru v jazyku DAX 2

Nyní je hodnota měřítka [Prodeje] nižší než hodnota stejného měřítka vyhodnoceného bez jakéhokoliv filtru. Filtr aplikovaný na sloupec 'Date'[Rok] prochází přes relaci definovanou v modelu mezi tabulkou 'Sales' a tabulkou 'Date', a v době vyhodnocení měřítka je proto tabulka 'Sales' zafiltrována pouze na prodeje za vybraný rok. Protože sloupec 'Sales'[Sales Amount] použitý v měřítku [Prodeje] pochází právě z tabulky 'Sales', při aktivním filtru nastaveném na rok 2020 vidíme prodeje pouze za vybraný rok.

Kontext filtru v jazyku DAX 3

V Power BI reportech je obvykle v době vyhodnocení měřítka aktivních více filtrů. Pokud změníme vizuál Tabulka na vizuál Matice, a přidáme do řádků hodnoty ze sloupce 'Reseller'[Country-Region] a do sloupců hodnoty ze sloupce 'Product'[Category], můžeme vidět, že výsledek měřítka [Prodeje] je v každé buňce jiný.

Kontext filtru v jazyku DAX 4

Pro určení kontextu filtru, ve kterém je výpočet vyhodnocen je vždy dobré zaměřit se na jednu konkrétní buňku nebo bod vizuálu. Uvažujme například hodnotu 32 356, 20 ve zvýrazněné buňce na předchozím obrázku. Tato hodnota představuje sumu za prodeje produktů v kategorii Accessories v roce 2020, které byly prodané ve státě Canada. V době vyhodnocení měřítka [Prodeje] ve zvýrazněné buňce působí na model všechny tyto tři filtry současně. 

Důležité je si uvědomit, že měřítko [Prodeje], stejně jako kterékoliv jiné měřítko, je vyhodnoceno v každé buňce v jiném kontextu filtru. Kontext filtru je v reportu zobrazeném na obrázku výše složen z filtrů působících z řádků vizuálu Matice, ze sloupců stejného vizuálu, a dále z filtrů nastavených ve vizuálu Průřez.

Filtry v Power BI reportu mohou přirozeně vznikat také v jiných vizuálech, jako jsou grafy, mapy, karty a tak dále. Filtry mohou být nastaveny také v panelu filtrů na celé stránky nebo na konkrétní vizuály. Jazyk DAX nerozlišuje v jakém vizuálu je měřítko použito, na pozadí je každý filtr přeměněn na konkrétní hodnoty, které následně filtrují celý model.

Doposud použité měřítko [Prodeje] obsahovalo jednoduchou agregační funkci SUM(). Všechny agregační funkce respektují kontext filtru, a proto je funkce SUM() ideální pro vysvětlení toho jak kontext filtru působí na měřítko. Komplexita kontextu filtru se ale může výrazně zvyšovat v případě složitějších výpočtů, protože v jednom měřítku mohou být aktivní různé filtry, v závislosti na použitých funkcích a na tom jakým způsobem s filtry ve výpočtu manipulujeme. Důležitou roli v celém kontextu vyhodnocení zastává také funkce CALCULATE(), pomocí které můžeme mimo jiné filtry odstraňovat, přepisovat nebo přidávat.

Různé kontexty filtru v jednom měřítku

Pro znázornění situace ve které působí na různé části výpočtu v měřítku jiné filtry použijeme funkci CALCULATE(), která je v jazyku DAX k dispozici přesně pro tyto účely. Uvažujme například následující jednoduchý vizuál, ve kterém jsou v řádcích roky z kalendářní tabulky a v hodnotách měřítko [Prodeje].

Kontext filtru v jazyku DAX 5

Měřítko [Prodeje] nyní vrací sumu za prodeje produktů za jednotlivé roky. V každém řádku vizuálu působí na měřítko filtr nastavený na konkrétní rok, a měřítko [Prodeje] je proto opět vyhodnoceno v každém řádku vizuálu v jiném kontextu filtru, v kontextu aktuálního roku.

V jednom z předchozích vizuálů jsme pro rozpad měřítka [Prodeje] použily mimo jiné kategorie produktů. V použitém modelu jsou čtyři kategorie produktů, kategorie Accessories, Bikes, Clothing a Components. Největší část tržeb tvoří v použitém modelu obvykle produkty z kategorie Bikes. Zboží v ostatních kategoriích tvoří z pohledu objemu tržeb pouze jakýsi doplňující sortiment. Představme si nyní situaci, kdy bychom chtěli vyčíslit přesný podíl, který tvoří tržby za jízdní kola na celkových prodejích. To můžeme zjistit pomocí následujícího měřítka.

Měřítko:

% Podíl kol =
DIVIDE
(
    CALCULATE
    (
        [Prodeje],
        'Product'[Category] = "Bikes"
    ),
    [Prodeje]
)

Měřítko [% Podíl kol] bude vracet procentuální podíl prodejů v kategorii Bikes vůči celkovým prodejům v aktuálním kontextu vyhodnocení.  Jakmile měřítko použijeme v reportu, budou na celé měřítko působit všechny filtry které jsou aktivní na aktuální stránce v reportu. V prvním argumentu funkce DIVIDE() je ale použita funkce CALCULATE(), která před vyhodnocením měřítka [Prodeje] v prvním argumentu této funkce přidá ke všem vnějším filtrům další filtr, nastavený na kategorii jízdních kol. Jinak řečeno, první měřítko [Prodeje] ve funkci CALCULATE() bude vyhodnoceno v kontextu všech filtrů aktivních v reportu a navíc v kontextu filtru kategorie Bikes. Druhé měřítko [Prodeje] na předposledním řádku výše zobrazeného kódu bude vyhodnoceno pouze v kontextu filtrů aktivních v reportu.

Pokud tedy vložíme nové měřítko do původního vizuálu s roky v řádcích, první měřítko [Prodeje] bude vyhodnoceno v kontextu filtru aktuálního roku a kategorie Bikes, a druhé měřítko [Prodeje] bude vyhodnoceno v kontextu aktuálního roku. Výsledkem je procentuální podíl prodejů v kategorii Bikes za aktuální rok vůči prodejům za všechny produkty ve všech kategoriích v aktuálním roce.

Kontext filtru v jazyku DAX 6

Měřítko [% Podíl kol] může být velmi užitečné pro analýzu prodejů jízdních kol. Pokud bychom ale chtěli zjistit podíl prodejů v jiných kategoriích vůči celku, potřebovali bychom při zachování stejné logiky výpočtu přidat do modelu další tři měřítka, jedno pro každou kategorii. Při práci s kontextem filtru ale můžeme dosáhnout stejného výsledku i jiným, více dynamickým způsobem.

V měřítku [% Podíl kol] jsme v prvním argumentu funkce DIVIDE() použili funkci CACULATE(), ve které jsme "natvrdo" přidali filtr na kategorii Bikes. Celou logiku ale můžeme úplně převrátit a to tak, že do reportu přidáme vizuál Průřez s kategoriemi produktů, který necháme působit na měřítko [Prodeje] v prvním argumentu funkce DIVIDE(), a naopak filtry nastavené na sloupec s kategoriemi produktů odstraníme před vyhodnocením měřítka [Prodeje] ve druhém argumentu funkce DIVIDE(). Uživatel si pak bude moct vybrat, jakou kategorii chce použít pro výpočet podílu. V měřítku tedy nebudeme přidávat filtry, ale naopak odstraňovat.

Měřítko:

% Podíl vybrané kategorie =
DIVIDE
(
    [Prodeje],
    CALCULATE
    (
        [Prodeje],
        REMOVEFILTERS('Product'[Category])
    )
)

První měřítko [Prodeje] bude v nové verzi výpočtu vyhodnoceno v kontextu všech filtrů které jsou aktivní v reportu, včetně vybrané kategorie produktů v průřezu. Druhé měřítko [Prodeje] bude respektovat všechny filtry, kromě filtrů nastavených na sloupec s kategoriemi produktů, a to díky funkce REMOVEFILTERS() použité ve druhém argumentu funkce CALCULATE(). Pokud nyní vložíme nové měřítko do stejného vizuálu, a v Průřezu vybereme pouze kategorii Bikes, výsledek měřítka [% Podíl ve vybrané kategorii] bude stejný jako u měřítka [% Podíl kol].

Kontext filtru v jazyku DAX 7

V nové verzi reportu ale můžeme vybrat v Průřezu jakoukoliv kategorii, a vždy uvidíme procentuální podíl prodejů vybrané kategorie vůči prodejům za všechny kategorie.

Kontext filtru v jazyku DAX 8

Jak je možné vidět na obrázku výše, produkty z kategorie Components tvoří výrazně menší podíl na celkových tržbách, než tomu bylo u kategorie Bikes.

Shrnutí

Kontext filtru je přirozenou součástí reportů vytvořených nad Tabulárním modelem. Díky tomu můžeme vytvořit jedno měřítko, které vrací různé hodnoty v různých řádcích tabulek nebo v jiných vizuálech, a to podle kontextu filtru, ve kterém je měřítko vyhodnoceno. Při tvorbě měřítek bychom tedy měli myslet na to, kde budeme měřítko používat a jaký bude jeho výsledek v závislosti na kontextu filtru. Pokud chceme kontext filtru upravit, doplnit nebo odstranit, můžeme použít funkci CALCULATE(), která umožňuje manipulovat s filtry. Příspěvky popisující chování funkce CALCULATE(), včetně příkladů použití různých modifikátorů filtrů ve funkci CALCULATE(), můžete najít na stránce jazyk DAX. Praktické příklady s použitím jazyka DAX můžete najít na stránce DAX - Příklady.

Stáhnout soubor s řešením.
č. 6

Komentáře

  1. Nejlepší česky psaný blog o DAXu (nejen)

    OdpovědětVymazat
    Odpovědi
    1. Děkuji za zpětnou vazbu. Jsem rád že se Vám obsah líbí.

      Vymazat

Okomentovat