Klouzavé roční součty v jazyku DAX

Klouzavé roční součty v jazyku DAX

V tomto příspěvku věnovanému časovým kalkulacím si ukážeme výpočet klouzavých ročních prodejů (MAT) a všech souvisejících výpočtů. Jako související výpočty můžeme uvažovat například klouzavé roční prodeje v předchozím roce (MAT PY), rozdíl mezi klouzavými ročními prodeji v aktuálním a předchozím roce v absolutních hodnotách (MAT YOY) anebo rozdíl mezi aktuálním a předchozím rokem vyjádřený v relativních hodnotách (MAT YOY %).

Poznámka:
MAT - Moving Annual Total - klouzavý roční úhrn,
PY - Previous Year - předchozí rok,
YOY - Year Over Year - meziroční.

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

Výpočet klouzavých ročních prodejů spočívá v zobrazení součtu prodejů za posledních dvanáct měsíců v aktuálním období. Pokud bychom jako aktuální období brali například měsíc únor 2024, tak v tomto měsíci budou klouzavé roční prodeje představovat prodeje za období od začátku března 2023 do konce února 2024. Pro měsíc březen 2024 pak použijeme období od dubna 2023 do března 2024 atd. Slovo klouzavé proto vyjadřuje kontinuální posun dvanáctiměsíčních období pro každý atribut zobrazený v řádcích nebo na osách vizuálů.

Roční klouzavé součty se obvykle používají pro vykreslení trendů v grafech, a to buď na úrovni měsíců nebo na nižších úrovních. Klouzavé roční prodeje můžeme také porovnávat s klouzavými ročními prodeji za stejné období v předchozím roce, a to ať už absolutních hodnotách, nebo v relativních hodnotách.

Všechny tyto výpočty si vytvoříme ve cvičném Power BI souboru Adventure Works DW 2020.pbix. V tomto souboru je navíc měřítko [Prodeje], které má následující definici.

Měřítko:

Prodeje = SUM(Sales[Sales Amount])

Pokud měřítko [Prodeje] vložíme do vizuálu matice spolu s měsíci a roky z kalendářní tabulky v řádcích, výchozí vizuál se kterým budeme pracovat může vypadat například následovně.

Klouzavé roční součty v jazyku DAX 2

Měřítko [Prodeje] vrací sumu za prodeje produktů v aktuální měsíci nebo roce. V následující kapitolách si postupně vytvoříme výpočet klouzavých ročních prodejů, výpočet klouzavých ročních prodejů za předchozí rok a výpočet meziročních rozdílů v absolutních a relativních hodnotách.

Výpočet klouzavých ročních prodejů (MAT)

Pro vytvoření klouzavých ročních prodejů budeme potřebovat dostat do filtru funkce CALCULATE() období, které bude zahrnovat v každé buňce vizuálu dvanáct měsíců. Toto období bude začínat dnem, který získáme odečtením dvanácti měsíců od posledního dne dostupného v aktuálním kontextu vyhodnocení a končit bude právě posledním dnem dostupným v aktuálním kontextu vyhodnocení. K tomuto účelu můžeme použít Time intelligence funkci DATESINPERIOD()

Ve funkci DATESINPERIOD() definujeme poslední den v aktuálním kontextu vyhodnocení jednoduše pomocí funkce MAX(). Následně v dalších argumentech zadáme o kolik intervalů se chceme od tohoto dne posunout a jaký chceme použít typ intervalu. V našem příkladu můžeme zadat buď mínus dvanáct měsíců nebo mínus jeden rok. Před vypsáním výsledku si ještě ověříme pomocí funkce IF() zda jsou v aktuálním kontextu vyhodnocení dostupné záznamy v tabulce 'Sales' a zda je měřítko vyhodnoceno v kontextu pouze jednoho měsíce, abychom výsledky nezobrazovaly na vyšších úrovních než je úroveň měsíců, protože například na úrovni let už mohou být výsledky tohoto výpočtu za určitých okolností obtížně interpretovatelné. Celý takto popsaný výpočet může vypadat například následovně.

Měřítko:

Prodeje MAT =
VAR Vypocet =
    CALCULATE
    (
        [Prodeje],
        DATESINPERIOD
        (
            'Date'[Date],
            MAX('Date'[Date]),
            -1,
            YEAR
        )
    )
VAR Vysledek =
    IF
    (
        NOT ISEMPTY(Sales) && HASONEVALUE('Date'[Měsíc]),
        Vypocet
    )
RETURN
    Vysledek

Nové měřítko si můžeme vložit do vizuálu Matice a zobrazit si výsledky.

Klouzavé roční součty v jazyku DAX 3

Pokud se zaměříme například na měsíc březen 2020, tak v tomto měsíci vrací měřítko [Prodeje MAT] hodnotu 47 860 687,25. Tato částka odpovídá součtu hodnot, které vrací měřítko [Prodeje] za období od dubna 2019 do března 2020 včetně. Obdobně bychom mohli interpretovat hodnoty měřítka [Prodeje MAT] pro jakýkoliv jiný měsíc v řádcích vizuálu.

Než se přesuneme k dalším variacím výpočtů, podívejme se ještě na první řádky vizuálu Matice a na hodnoty měřítka [Prodeje MAT] v těchto řádcích.

Klouzavé roční součty v jazyku DAX 4

Měřítko [Prodeje MAT] vrací pro měsíc červenec 2017 hodnotu prodejů pouze za tento konkrétní měsíc. V měsíci srpen 2017 pak vrací měřítko [Prodeje MAT] prodeje za měsíce červenec a srpen 2017. Prodeje za dvanáct měsíců pak měřítko [Prodeje MAT] vrací až v měsíci červen 2018, což je první měsíc, ve kterém máme v použitém modelu k dispozici historii prodejů za dvanáct měsíců.

Pokud bychom nechtěli zobrazovat hodnoty měřítka [Prodeje MAT] v obdobích, ve kterých ještě není k dispozici dostatečná historie, můžeme použít následující variantu výpočtu.

Měřítko:

Prodeje MAT (2) =
VAR TabulkaDoFiltru =
    DATESINPERIOD
    (
        'Date'[Date],
        MAX('Date'[Date]),
        -1,
        YEAR
    )
VAR PocetMesicuSProdeji =
    CALCULATE
    (
        SUMX
        (
            SUMMARIZE
            (
                Sales,
                'Date'[Měsíc]
            ),
            1
        ),
        TabulkaDoFiltru
    )
VAR Vypocet =
    CALCULATE
    (
        [Prodeje],
        TabulkaDoFiltru
    )
VAR Vysledek =
    IF
    (
        NOT ISEMPTY(Sales) && HASONEVALUE('Date'[Měsíc]) && PocetMesicuSProdeji = 12,
        Vypocet
    )
RETURN
    Vysledek

V měřítku [Prodeje MAT (2)] je výsledek funkce DATESINPERIOD() uložen v samostatné proměnné nazvané TabulkaDoFiltru. Tato proměnná je pak dále ve výpočtu použita na dvou místech. V prvním případě pro zafiltrování měsíců s prodeji v proměnné PocetMesicuSProdeji, a v druhém případě v proměnné Vypocet před vyhodnocením měřítka [Prodeje]. Další změna oproti původnímu výpočtu je v proměnné Vysledek, kde je navíc v prvním argumentu funkce IF() podmínka, ve které ověřujeme zda proměnná PocetMesicuSProdeji vrací hodnotu 12. Jinak řečeno ve funkci IF() navíc ověřujeme, zda máme pro výpočet k dispozici dvanáct měsíců s prodeji. Pokud by tato podmínka nebyla splněna, výsledkem měřítka [Prodeje MAT(2)] bude prázdná hodnota BLANK. Měřítko [Prodeje MAT (2)] již tedy nebude vracet výsledky pro měsíce ve kterých nemáme k dispozici dostatečnou historii pro výpočet klouzavých ročních prodejů.

Klouzavé roční součty v jazyku DAX 5

Rozdíl mezi měřítkem [Prodeje MAT] a měřítkem [Prodeje MAT (2)] je tedy pouze v tom, že hodnoty měřítka [Prodeje MAT (2)] se zobrazují až v případě kdy máme k dispozici historii prodejů za dvanáct předchozích měsíců. Tento efekt může mít přínos zejména v grafech, ve kterých se obvykle klouzavé roční součty zobrazují z důvodů analýzy trendů, anebo při porovnávání klouzavých ročních prodejů v aktuálním roce s rokem předchozím, kde by mohli být meziroční rozdíly v prvních obdobích prodejů zkresleny z důvodu nedostatečné historie.

Výpočet klouzavých ročních prodejů za předchozí rok (MAT PY)

Jak už jsme si řekli v úvodu, výkonnost za posledních dvanáct měsíců se často porovnává s výkonností za stejné období v předchozím roce. Z pohledu jazyka DAX můžeme klouzavé roční prodeje za předchozí rok získat více různými způsoby. Jednou z možností je použít výpočet ročních klouzavých prodejů v aktuálním roce a před vyhodnocením tohoto výpočtu upravit kontext filtru tak, že všechny dny v aktuálním kontextu posuneme o jeden rok zpět pomocí funkce DATEADD().

Měřítko:

Prodeje MAT PY =
VAR Vypocet =
    CALCULATE
    (
        CALCULATE
        (
            [Prodeje],
            DATESINPERIOD
            (
                'Date'[Date],
                MAX('Date'[Date]),
                -1,
                YEAR
            )
        ),
        DATEADD('Date'[Date], -1, YEAR)
    )
VAR Vysledek =
    IF
    (
        NOT ISEMPTY(Sales) && HASONEVALUE('Date'[Měsíc]),
        Vypocet
    )
RETURN
    Vysledek

Nové měřítko si můžeme vložit do vizuálu a zobrazit si výsledky.

Klouzavé roční součty v jazyku DAX 6

Měřítko [Prodeje MAT PY] nyní vrací v každé buňce vizuálu stejné hodnoty jako měřítko [Prodeje MAT] v předchozím roce. Úplně stejně jako v případě měřítka [Prodeje MAT PY] i zde si můžeme vytvořit druhou variantu tohoto výpočtu, která bude vracet výsledky až v případě kdy je k dispozici historie prodejů za dvanáct měsíců.

Měřítko:

Prodeje MAT PY (2) =
VAR TabulkaDoFiltru =
    CALCULATETABLE
    (
        DATESINPERIOD
        (
            'Date'[Date],
            MAX('Date'[Date]),
            -1,
            YEAR
        ),
        DATEADD('Date'[Date], -1, YEAR)
    )
VAR PocetMesicuSProdeji =
    CALCULATE
    (
        SUMX
        (
            SUMMARIZE
            (
                Sales,
                'Date'[Měsíc]
            ),
            1
        ),
        TabulkaDoFiltru
    )
VAR Vypocet =
    CALCULATE
    (
        [Prodeje],
        TabulkaDoFiltru
    )
VAR Vysledek =
    IF
    (
        NOT ISEMPTY(Sales) && HASONEVALUE('Date'[Měsíc]) && PocetMesicuSProdeji = 12,
        Vypocet
    )
RETURN
    Vysledek

Pokud si novou verzi výpočtu vložíme do původního vizuálu tak výsledek bude vypadat následovně.

Klouzavé roční součty v jazyku DAX 7

Jak je nyní možné vidět na obrázku výše, nová verze měřítka vrací klouzavé roční prodeje v předchozím roce až v případě, kdy je máme k dispozici požadovaných dvanáct měsíců s prodeji. Na základě měřítek s klouzavými ročními prodeji v aktuálním a předchozím roce již můžeme jednoduchými výpočty vytvořit další měřítka, která budou porovnávat meziroční výkonnost ať už v absolutních nebo v relativních hodnotách.

Meziroční porovnání ročních klouzavých prodejů (MAT YOY a MAT YOY %)

Pro meziroční porovnání klouzavých ročních prodejů stačí od klouzavých ročních prodejů za předchozí rok odečíst klouzavé roční prodeje v aktuálním období. Výsledek tohoto výpočtu budeme zobrazovat pouze v případě že máme v aktuálním kontextu k dispozici obě hodnoty potřebné pro výpočet, což můžeme ověřit jednoduše v prvním argumentu funkce IF() například následujícím způsobem.

Měřítko:

Prodeje MAT YOY =
VAR ProdejeMAT = [Prodeje MAT]
VAR ProdejeMATPY = [Prodeje MAT PY]
VAR Vypocet =
    IF
    (
        NOT ISBLANK(ProdejeMAT) && NOT ISBLANK(ProdejeMATPY),
        ProdejeMAT - ProdejeMATPY
    )
RETURN
    Vypocet

Pokud bychom chtěli pro výpočet meziročních rozdílů použít druhé varianty výpočtů, které se zobrazují pouze v situacích kdy je k dispozici dostatečná historie pro výpočet ročních klouzavých prodejů, stačí změnit definici prvních dvou proměnných následujícím způsobem.

Měřítko:

Prodeje MAT YOY (2) =
VAR ProdejeMAT = [Prodeje MAT (2)]
VAR ProdejeMATPY = [Prodeje MAT PY (2)]
VAR Vypocet =
    IF
    (
        NOT ISBLANK(ProdejeMAT) && NOT ISBLANK(ProdejeMATPY),
        ProdejeMAT - ProdejeMATPY
    )
RETURN
    Vypocet

Pro výpočet rozdílu v relativních hodnotách pak můžeme opět definovat dvě varianty výpočtu.

Měřítka:

Prodeje MAT YOY % = DIVIDE([Prodeje MAT YOY], [Prodeje MAT PY])

Prodeje MAT YOY % (2) = DIVIDE([Prodeje MAT YOY (2)], [Prodeje MAT PY (2)])

Pokud si nyní do vizuálu vložíme všechna měřítka bez ošetření dostupnosti dostatečné historie pro výpočet dvanáctiměsíčních ročních prodejů, výsledky mohou být v prvních měsících překvapivé.

Klouzavé roční součty v jazyku DAX 8

Zaměříme-li se hned na první měsíc, pro který nám měřítko [Prodeje MAT YOY %] vrací hodnotu, tedy na měsíc červenec 2018, tak v tomto měsíci můžeme vidět u měřítka [Prodeje MAT YOY %] hodnotu 1682,91 %. Tato hodnota nemusí být špatně, pouze musíme vědět, že v tomto konkrétním měsíci porovnáváme souhrn prodejů za posledních dvanáct měsíců od měsíce červenec 2018 s prodeji pouze za jeden měsíc, konkrétně za měsíc červenec 2017. Důvodem je že v předchozím roce není k dispozici dostatečná historie pro výpočet prodejů za dvanáct předchozích měsíců od měsíce červenec 2017.

Na druhou stranu varianty výpočtů, ve kterých máme ošetřeno aby se zobrazovali pouze v obdobích, pro která máme dostatečnou historii, tento problém již nevidíme.

Klouzavé roční součty v jazyku DAX 9

Jak je možné vidět na obrázku výše, měřítka [Prodeje YOY (2)] a [Prodeje MAT YOY % (2)] vrací výsledky pouze pro měsíce, pro které máme k dispozici historii prodejů za dvanáct měsíců také v předchozím roce. Porovnání měsíců, pro které máme k dispozici kompletní historii potřebnou pro výpočet klouzavých ročních prodejů jak za aktuální, tak za předchozí rok, tak může dávat větší smysl než porovnávání měsíců, pro které tato historie ještě není k dispozici.

Další příklady, včetně jiných variant Time intelligence výpočtů, můžete najít na stránce DAX příklady. Všechna videa jsou pak k dispozici na mém Youtubovém kanále pod tímto odkazem.

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

Komentáře