Power BI zaawansowany – DAX w praktyce: miary, kalkulacje i analiza danych
Poznaj DAX od strony praktycznej: dobieraj miary i kolumny obliczeniowe, kontroluj kontekst filtrów i analizuj zmiany w czasie. Zobacz, jak używać CALCULATE, iteratorów i zmiennych VAR oraz diagnozować błędy i poprawiać wydajność obliczeń w Power BI.
Wprowadzenie: gdzie DAX „robi różnicę” w modelu Power BI
Wykres sprzedaży może poprawnie prezentować dane, a mimo to nie odpowiadać na najważniejsze pytanie: czy wynik rzeczywiście się poprawił? Wzrost przychodu nie musi oznaczać wyższej rentowności, a większa liczba zamówień — lepszej realizacji celu. W takich sytuacjach potrzebna jest logika obliczeń, która wykracza poza zsumowanie wartości z jednej kolumny. DAX pozwala zapisać tę logikę w modelu Power BI i wykorzystać ją do analizy danych z perspektywy konkretnych pytań biznesowych.
DAX, czyli Data Analysis Expressions, to język formuł używany między innymi do tworzenia miar i kolumn obliczeniowych. W analizie interaktywnej szczególne znaczenie mają miary: ich wyniki są wyznaczane zgodnie z kontekstem danego obliczenia, uwzględniającym na przykład filtry raportu oraz podział danych na wizualizacji. Ta sama definicja wskaźnika może więc służyć do oceny całej organizacji, pojedynczego regionu lub wybranej kategorii produktów — bez tworzenia osobnej formuły dla każdego widoku.
Warto przy tym rozdzielić zadania poszczególnych warstw rozwiązania. Power Query służy przede wszystkim do pobierania i przygotowywania danych. Model określa ich strukturę oraz relacje, a wizualizacje pomagają prezentować i eksplorować wyniki. DAX uzupełnia ten układ o reguły analityczne: sposób liczenia rentowności, udziałów w sprzedaży, odchyleń od planu czy zmian między okresami. Nie zastępuje jednak uporządkowanych danych ani prawidłowo zaprojektowanego modelu.
Różnicę dobrze widać na przykładzie marży procentowej. Średnia z procentów zapisanych przy poszczególnych transakcjach może dać inny wynik niż relacja łącznej marży kwotowej do łącznego przychodu. Wybór sposobu obliczenia nie jest wyłącznie kwestią techniczną — decyduje o interpretacji wskaźnika. Podobnie udział produktu w sprzedaży wymaga ustalenia, co stanowi punkt odniesienia: cała sprzedaż, wybrany segment czy zakres wskazany przez użytkownika.
Zaawansowana praca z DAX zaczyna się zatem nie od długości formuły, lecz od precyzyjnej definicji wyniku. Trzeba ustalić, co mierzymy, dla jakiego zakresu danych i jak wskaźnik powinien zachowywać się po zmianie filtrów. Dobrze zaprojektowane miary pozwalają następnie korzystać z jednej, spójnej definicji w wielu miejscach raportu. To właśnie tutaj DAX wnosi największą wartość: pomaga przełożyć wymagania biznesowe na obliczenia, których znaczenie pozostaje jasne podczas analizy.
Kolumny obliczeniowe vs miary: kiedy używać, konsekwencje dla modelu i wydajności
Kolumna obliczeniowa i miara mogą opisywać to samo zjawisko biznesowe, ale pełnią w modelu różne funkcje. Kolumna zapisuje wynik dla każdego wiersza, a miara oblicza wynik na potrzeby konkretnego zapytania — na przykład wyświetlenia wartości na karcie lub w macierzy. Wybór między nimi wpływa więc nie tylko na sposób budowania raportu, lecz także na rozmiar modelu, czas odświeżania i szybkość działania wizualizacji. W Cognity często słyszymy pytania, jak w praktyce dobrać właściwe rozwiązanie — odpowiadamy na nie także na blogu.
Kiedy potrzebna jest kolumna obliczeniowa?
Kolumna obliczeniowa sprawdza się wtedy, gdy potrzebujesz trwałej cechy rekordu: kategorii produktu, oznaczenia transakcji albo wartości służącej do sortowania. Możesz wykorzystać ją na osi wykresu, w wierszach macierzy czy we fragmentatorze. Przykładem jest przypisanie produktu do przedziału cenowego na podstawie jego ceny katalogowej. Taka etykieta pozwala później grupować produkty i filtrować raport.
W modelu działającym w trybie Import wartości kolumny obliczeniowej są wyliczane podczas przetwarzania modelu, zwykle przy odświeżaniu danych, a następnie przechowywane w modelu. Wybór użytkownika we fragmentatorze nie przelicza tych wartości — zmienia jedynie to, które dane uczestniczą w prezentowanym wyniku. Kolumna nie jest więc właściwym rozwiązaniem dla wskaźnika, który ma reagować na wybór okresu, regionu czy klienta.
Kiedy wybrać miarę?
Miara służy do obliczania wyników analitycznych: przychodu, liczby zamówień, średniej wartości transakcji czy rentowności. Jej rezultat zależy od danych objętych aktualnym widokiem raportu. Ta sama miara może pokazać sprzedaż całej organizacji na karcie, sprzedaż poszczególnych kategorii na wykresie oraz wynik wybranego regionu po użyciu fragmentatora.
Dobrze widać tę różnicę na przykładzie marży procentowej. Kolumna może opisywać marżę pojedynczej pozycji sprzedaży, ale średnia z takich procentów nie musi odpowiadać rentowności całej sprzedaży. Do raportowania wskaźnika zbiorczego zwykle potrzebna jest miara wyznaczająca relację łącznej marży kwotowej do łącznego przychodu. O wyborze rozwiązania decyduje znaczenie biznesowe wyniku, nie tylko możliwość zapisania obliczenia.
Wpływ na rozmiar modelu i szybkość raportu
W trybie Import każda dodatkowa kolumna obliczeniowa zwiększa ilość przechowywanych danych i dokłada pracę podczas przetwarzania modelu. Koszt zależy między innymi od liczby wierszy, typu danych oraz liczby unikalnych wartości. Szczególnej uwagi wymagają rozbudowane kolumny tekstowe i kolumny o dużej liczbie różnych wartości, które zwykle kompresują się gorzej.
Miara nie przechowuje osobnego wyniku dla każdego wiersza, dlatego zazwyczaj pozwala utrzymać mniejszy model. Nie oznacza to jednak, że jest zawsze szybsza: koszt jej obliczenia pojawia się podczas obsługi zapytań. Złożona miara analizująca duży zbiór danych może opóźniać wyświetlanie wizualizacji.
Praktyczna zasada jest prosta: do grupowania, filtrowania i opisywania rekordów wybieraj kolumny, a do dynamicznych wskaźników — miary. Jeśli cecha rekordu może zostać przygotowana w źródle danych lub w Power Query, rozważ tę możliwość przed dodaniem kolumny DAX. Nie usunie to kosztu przechowywania zaimportowanej kolumny, ale może uporządkować proces przygotowania danych i ograniczyć zakres obliczeń wykonywanych w modelu.
Kontekst wiersza i kontekst filtrów: przejścia kontekstu i relacje w modelu
Ta sama miara DAX może zwrócić inną wartość na karcie, w wierszu macierzy i w jej podsumowaniu — mimo że jej definicja pozostaje identyczna. O wyniku decyduje nie tylko formuła, lecz także kontekst jej obliczania. Zrozumienie tego mechanizmu pozwala wyjaśnić większość sytuacji, w których wynik wygląda poprawnie dla pojedynczego produktu, ale zaskakuje po zmianie filtrów lub poziomu szczegółowości raportu.
Kontekst wiersza: który rekord jest aktualnie przetwarzany?
Kontekst wiersza daje wyrażeniu dostęp do wartości z aktualnie przetwarzanego rekordu. Powstaje między innymi podczas obliczania kolumny obliczeniowej oraz wewnątrz funkcji iterujących po tabeli. Dzięki niemu DAX wie, z którego wiersza pobrać ilość i cenę, gdy wyrażenie wyznacza wartość pozycji sprzedaży.
Kontekst wiersza nie jest jednak filtrem tabeli. Samo przetwarzanie konkretnego rekordu nie sprawia, że zwykła agregacja zostaje ograniczona do tego rekordu. To istotne rozróżnienie: dostęp do wartości bieżącego wiersza i wybór zbioru danych do agregacji to dwa odrębne mechanizmy.
Kontekst filtrów: które dane uczestniczą w obliczeniu?
Kontekst filtrów określa zbiór danych dostępnych dla wyrażenia. Tworzą go między innymi fragmentatory, filtry raportu, strony i wizualizacji oraz kategorie umieszczone na osiach i w macierzach. Może być także modyfikowany przez formułę DAX.
Jeśli użytkownik wybierze rok 2025, a macierz pokazuje sprzedaż według kategorii produktów, komórka dla kategorii „Akcesoria” zostanie obliczona z uwzględnieniem obu ograniczeń. Wiersz macierzy tworzy kontekst filtrów dla miary, a nie kontekst wiersza w rozumieniu DAX. Podobieństwo nazw bywa tu źródłem błędnych interpretacji.
Także suma końcowa ma własny kontekst obliczania. Nie musi być sumą widocznych wyników: Power BI ponownie oblicza miarę dla kontekstu podsumowania. W przypadku średniej ceny czy udziału procentowego wynik może więc różnić się od prostego zsumowania wartości z poszczególnych wierszy — i być całkowicie poprawny.
Przejście kontekstu: kiedy bieżący wiersz staje się filtrem?
Przejście kontekstu polega na przekształceniu istniejącego kontekstu wiersza w kontekst filtrów. Kluczową rolę odgrywa tu funkcja CALCULATE. Przejście następuje również automatycznie, gdy w istniejącym kontekście wiersza wywoływana jest miara modelu.
Przykładowo podczas iteracji po klientach samo wskazanie bieżącego klienta nie ogranicza zwykłej agregacji sprzedaży do jego transakcji. Po przejściu kontekstu wartości bieżącego wiersza stają się filtrami, które — przy odpowiedniej relacji — mogą ograniczyć tabelę sprzedaży. Nie oznacza to jednak filtrowania według niewidocznego numeru rekordu: znaczenie mają wartości kolumn. Dlatego unikalność kluczy jest ważna także dla przewidywalności obliczeń.
Relacje określają, dokąd dociera filtr
W typowym modelu gwiazdy aktywna relacja jeden-do-wielu pozwala filtrowi z tabeli wymiaru, na przykład produktów, ograniczyć powiązane wiersze tabeli sprzedaży. Wybór kategorii wpływa więc na wynik miary sprzedażowej, choć kategoria i kwota znajdują się w różnych tabelach.
Filtry propagują się zgodnie z aktywnymi relacjami i ustalonym kierunkiem filtrowania, a nie automatycznie między wszystkimi tabelami. Relacja nieaktywna nie przenosi filtra domyślnie. Z kolei filtrowanie dwukierunkowe może rozszerzyć jego zasięg i utrudnić przewidywanie wyników, dlatego nie powinno być uniwersalnym sposobem naprawiania miar.
Gdy wynik budzi wątpliwości, warto sprawdzić kolejno: jakie filtry obowiązują w danej komórce, czy występuje kontekst wiersza i jego przejście oraz jaką drogą filtr dociera do tabeli faktów. Taka diagnoza pozwala oddzielić błąd formuły od problemu z konstrukcją modelu.
CALCULATE i modyfikacja filtrów: podstawy, najczęstsze pułapki i dobre praktyki
CALCULATE pozwala obliczyć wyrażenie w zmodyfikowanym kontekście filtrów. To podstawa miar, które mają odpowiadać na pytania bardziej precyzyjne niż „ile wynosi sprzedaż dla bieżącego wyboru?”. Możesz wskazać konkretną kategorię produktów, pominąć wybrany filtr w mianowniku albo ograniczyć wynik do części danych bez zmieniania ustawień wizualizacji.
Sama funkcja nie wykonuje agregacji — określa warunki, w których zostanie obliczone podane wyrażenie, na przykład istniejąca miara [Sprzedaż]. Najważniejsza decyzja dotyczy tego, czy filtr zapisany w formule ma zastąpić wybór użytkownika, zawęzić go, czy usunąć. W Cognity omawiamy modyfikację kontekstu filtrów zarówno od strony technicznej, jak i praktycznej — odnosząc ją do rzeczywistych zadań analitycznych uczestników szkoleń.
Jak CALCULATE zmienia filtry
Podstawowa składnia to CALCULATE(wyrażenie, filtr1, filtr2, …). Jeżeli wskazana kolumna nie jest jeszcze filtrowana, warunek zostaje dodany. Jeżeli filtr na tej kolumnie już istnieje, standardowo zostaje zastąpiony. Filtry na pozostałych kolumnach pozostają aktywne.
Załóżmy, że model zawiera tabelę 'Produkt', kolumnę [Kategoria] oraz miarę [Sprzedaż]. Poniższa kalkulacja wymusza kategorię „Akcesoria”:
Sprzedaż akcesoriów =
CALCULATE(
[Sprzedaż],
'Produkt'[Kategoria] = "Akcesoria"
)
Jeśli fragmentator korzysta z tej samej kolumny i użytkownik wybierze inną kategorię, miara nadal policzy sprzedaż akcesoriów. Jednocześnie zachowa między innymi filtry daty i regionu. Zachowa również filtr konkretnego produktu, jeżeli pochodzi on z innej kolumny — dlatego sprzeczne warunki mogą dać pusty wynik. Zastąpienie filtra kategorii nie oznacza usunięcia wszystkich ograniczeń dotyczących produktów.
Zastępowanie, zawężanie i usuwanie filtrów
| Mechanizm | Efekt | Typowe zastosowanie |
|---|---|---|
| Warunek w CALCULATE | Dodaje filtr lub zastępuje istniejący filtr na wskazanej kolumnie. | Wskaźnik zawsze liczony dla określonej kategorii lub statusu. |
| KEEPFILTERS | Stosuje przecięcie nowego warunku z istniejącym filtrem zamiast jego zastąpienia. | Wskaźnik ograniczony do określonej grupy, ale respektujący wybór użytkownika. |
| REMOVEFILTERS | Usuwa filtry ze wskazanych kolumn lub tabel. | Mianownik udziału procentowego albo punkt odniesienia niezależny od wybranego wymiaru. |
| FILTER | Zwraca tabelę wierszy spełniających warunek, którą można wykorzystać jako filtr. | Bardziej złożone kryteria, których nie da się zapisać jako prostego warunku kolumnowego. |
W pierwszym przykładzie zapis KEEPFILTERS('Produkt'[Kategoria] = "Akcesoria") zmieniłby zachowanie miary: wybór kategorii innej niż „Akcesoria” nie zostałby nadpisany. Przecięcie obu warunków byłoby puste.
Z kolei przy obliczaniu udziałów kluczowe jest precyzyjne wskazanie, jakie ograniczenie ma zniknąć z mianownika:
Udział sprzedaży kategorii =
DIVIDE(
[Sprzedaż],
CALCULATE(
[Sprzedaż],
REMOVEFILTERS('Produkt'[Kategoria])
)
)
W wizualizacji z kategoriami ta miara porównuje sprzedaż bieżącej kategorii ze sprzedażą obliczoną bez filtra kategorii. Pozostałe ograniczenia nadal obowiązują. Nie jest to więc automatycznie udział w całej sprzedaży zapisanej w modelu ani udział wyłącznie w kategoriach zaznaczonych na fragmentatorze.
Najczęstsze pułapki i dobre praktyki
- Zbyt szerokie usuwanie filtrów. Użycie całej tabeli w
REMOVEFILTERSmoże usunąć więcej ograniczeń, niż wymaga kalkulacja. Jeśli chcesz pominąć kategorię, zacznij od kolumny kategorii, a nie całej tabeli produktów. - Mylenie warunków „i” oraz „lub”. Oddzielne argumenty filtrujące w
CALCULATEmuszą być spełnione łącznie. Alternatywę dla wartości tej samej kolumny zapisuj na przykład za pomocąIN. - Używanie FILTER do każdego warunku. Dla prostych porównań preferuj bezpośredni warunek kolumnowy. Zwykle jest czytelniejszy i łatwiejszy do efektywnego wykonania przez silnik niż filtrowanie całej tabeli faktów.
- Traktowanie ALL i REMOVEFILTERS jako zamienników w każdej sytuacji. Obie funkcje mogą usuwać filtry wewnątrz
CALCULATE, aleALLmoże również zwracać tabelę. Gdy celem jest wyłącznie usunięcie filtrów,REMOVEFILTERSwyraźniej komunikuje intencję.
Przed wdrożeniem miary sprawdź ją na karcie, w tabeli z kategoriami oraz przy pojedynczym i wielokrotnym wyborze na fragmentatorze. Dla wskaźników procentowych warto pokazać osobno licznik i mianownik. Taki test szybko ujawnia, czy formuła usuwa właściwy filtr i czy wynik odpowiada definicji biznesowej, a nie tylko wygląda wiarygodnie.
Time intelligence w praktyce: YTD/MTD/QTD, porównania okresów i wymagania kalendarza
W analizie sprzedaży sam wynik za marzec nie odpowiada jeszcze na pytanie, czy firma realizuje plan i rozwija się w oczekiwanym tempie. Potrzebne są dwie perspektywy: wartość narastająca od początku okresu oraz porównanie z odpowiednim okresem odniesienia. Funkcje time intelligence w DAX pozwalają zbudować takie obliczenia bez tworzenia osobnej formuły dla każdego miesiąca czy roku. Ich poprawność zależy jednak od kalendarza, relacji w modelu i przyjętych zasad porównywania dat.
Kalendarz: warunek poprawnych obliczeń
Poniższe przykłady wykorzystują klasyczne funkcje time intelligence, którym przekazuje się kolumnę dat. W tym podejściu należy przygotować osobną tabelę kalendarza, zamiast opierać obliczenia wyłącznie na datach z tabeli transakcji. Dzień bez sprzedaży nadal musi istnieć na osi czasu.
- Jeden wiersz na dzień: kolumna dat powinna zawierać unikalne wartości, bez pustych pozycji i bez przerw między kolejnymi dniami.
- Pełne lata: kalendarz powinien obejmować pełne lata kalendarzowe lub fiskalne, wszystkie analizowane daty oraz okresy potrzebne do porównań historycznych.
- Oznaczenie tabeli dat: w Power BI należy oznaczyć kalendarz jako tabelę dat i wskazać właściwą kolumnę.
- Poprawna relacja: standardowo kalendarz łączy się relacją jeden-do-wielu z tabelą faktów. Klucz po stronie transakcji powinien reprezentować samą datę — godzina w znaczniku czasu może uniemożliwić dopasowanie.
- Pola kalendarza w raporcie: lata, kwartały, miesiące i daty na osiach oraz fragmentatorach powinny pochodzić z tej samej tabeli kalendarza.
Trzeba też ustalić, którą datę opisuje wskaźnik. Sprzedaż według daty zamówienia i sprzedaż według daty wysyłki to dwie różne analizy. Domyślnie filtr czasu działa przez aktywną relację, dlatego jej wybór ma znaczenie biznesowe, a nie tylko techniczne.
YTD, MTD i QTD — różne horyzonty narastania
| Wariant | Zakres obliczenia | Typowe zastosowanie |
|---|---|---|
| YTD — Year to Date | Od początku roku do daty granicznej | Ocena realizacji rocznego planu i wyniku narastającego |
| MTD — Month to Date | Od początku miesiąca do daty granicznej | Bieżąca kontrola wyniku miesięcznego |
| QTD — Quarter to Date | Od początku kwartału do daty granicznej | Monitorowanie celów kwartalnych |
„To date” nie oznacza automatycznie „do dzisiaj”. Datę graniczną wyznacza kontekst dat w danej komórce raportu. Przy wyborze 15 marca miara YTD obejmuje okres od początku roku do 15 marca. W wierszu reprezentującym cały marzec granicą będzie natomiast koniec miesiąca. Jeśli raport ma kończyć analizę na ostatnim dniu z kompletnymi danymi, trzeba tę regułę określić osobno.
Zakładając, że w modelu istnieje miara [Sprzedaż] oraz tabela 'Kalendarz', podstawowe obliczenia mogą wyglądać następująco:
Sprzedaż YTD =
CALCULATE([Sprzedaż], DATESYTD('Kalendarz'[Data]))
Sprzedaż MTD =
CALCULATE([Sprzedaż], DATESMTD('Kalendarz'[Data]))
Sprzedaż QTD =
CALCULATE([Sprzedaż], DATESQTD('Kalendarz'[Data]))
YTD domyślnie odnosi się do roku kalendarzowego. Dla roku fiskalnego należy odpowiednio ustalić jego koniec. Samo dodanie kolumny „Kwartał fiskalny” nie zmienia działania standardowego QTD; kalendarze niestandardowe, takie jak 4–4–5, wymagają osobnego podejścia.
Porównania okresów: najpierw ustal punkt odniesienia
Porównanie rok do roku ogranicza wpływ sezonowości, natomiast miesiąc do miesiąca pomaga ocenić krótkoterminowy kierunek zmian. Nie są to jednak zamienne wskaźniki. Grudniowy wzrost względem listopada może wynikać z sezonowego popytu, nawet jeśli wynik pozostaje niższy niż w grudniu poprzedniego roku.
Wartość sprzedaży dla okresu przesuniętego o rok można obliczyć następująco:
Sprzedaż rok wcześniej =
CALCULATE(
[Sprzedaż],
SAMEPERIODLASTYEAR('Kalendarz'[Data])
)
Ta miara nie zwraca zawsze sprzedaży za cały poprzedni rok — zakres odniesienia zależy od dat analizowanych w raporcie. Do przesuwania okresów o miesiące, kwartały lub lata służy również DATEADD. Dynamikę procentową wyznacza się następnie jako różnicę między wynikiem bieżącym a porównawczym, podzieloną przez wynik porównawczy; przy zerowej podstawie warto świadomie ustalić sposób prezentacji wyniku.
Niepełny okres może zniekształcić wniosek
Jeżeli dane są kompletne tylko do 12 marca, zestawienie bieżącego marca z całym marcem poprzedniego roku będzie mylące. Sam wybór miesiąca w kalendarzu nie skróci automatycznie okresu porównawczego do ostatniej daty transakcji. Oba wyniki powinny obejmować porównywalny zakres czasu, na przykład pierwsze 12 dni miesiąca albo tę samą liczbę dni roboczych — zależnie od celu analizy.
Datę odcięcia najlepiej powiązać z kompletnością zasilenia danych, a nie bezrefleksyjnie z datą dzisiejszą. Warto również sprawdzić zachowanie miar na przełomie roku, w lutym roku przestępnego oraz przy braku danych historycznych. To właśnie takie przypadki pokazują, czy wskaźnik mierzy rzeczywistą zmianę biznesową, czy jedynie różnicę w dostępności danych.
6. Iteratory (X) i praca na tabelach: SUMX/AVERAGEX, filtrowanie, agregacje warunkowe
Wartość sprzedaży nie zawsze znajduje się w jednej kolumnie gotowej do zsumowania. Często trzeba ją wyliczyć z ilości, ceny jednostkowej i rabatu dla każdej pozycji transakcji, a dopiero później zagregować. Właśnie do takich zadań służą iteratory DAX: funkcje, które obliczają wyrażenie dla kolejnych wierszy wskazanej tabeli i łączą otrzymane wyniki.
SUMX i AVERAGEX — co obliczają i kiedy ich używać?
SUM sumuje wartości istniejącej kolumny. SUMX przyjmuje tabelę oraz wyrażenie, które należy obliczyć dla każdego jej wiersza, a następnie sumuje rezultaty. Analogicznie AVERAGE wyznacza średnią z kolumny, natomiast AVERAGEX oblicza średnią z wyników wyrażenia ocenianego w kolejnych wierszach tabeli.
Jeśli tabela Sprzedaz zawiera pozycje transakcji, a rabat zapisano jako ułamek dziesiętny, wartość po rabacie można obliczyć następująco:
Wartosc po rabacie =
SUMX(
Sprzedaz,
Sprzedaz[Ilosc] * Sprzedaz[CenaJednostkowa] * (1 - Sprzedaz[Rabat])
)Najpierw powstaje wartość każdej pozycji, a następnie suma tych wartości. To istotne, ponieważ suma iloczynów nie jest tym samym co iloczyn sum. Pomnożenie łącznej liczby sztuk przez sumę cen jednostkowych dałoby inny, zwykle pozbawiony sensu biznesowego wynik.
Jeżeli potrzebna jest wyłącznie suma gotowej kolumny, zwykłe SUM będzie czytelniejszym wyborem. Iterator warto stosować wtedy, gdy rzeczywiście potrzebne jest obliczenie na poziomie wiersza albo praca na określonym zbiorze elementów.
Średnia zależy od tego, po czym iterujesz
W przypadku AVERAGEX kluczowe pytanie brzmi: co stanowi pojedynczą obserwację? Poniższe wyrażenie wyznacza średnią wartość pozycji sprzedaży przed rabatem, a nie średnią wartość całego zamówienia:
Srednia wartosc pozycji =
AVERAGEX(
Sprzedaz,
Sprzedaz[Ilosc] * Sprzedaz[CenaJednostkowa]
)Jeśli jedno zamówienie obejmuje pięć pozycji, uczestniczy w tej kalkulacji pięcioma wynikami. Aby analizować średnią wartość zamówienia, trzeba najpierw uzyskać zbiór zamówień z ich wartościami, a dopiero potem obliczyć średnią. Podobnie średnia po klientach, produktach i dniach odpowiada na różne pytania, nawet jeśli korzysta z tych samych danych źródłowych.
AVERAGEX pomija wyniki puste, ale uwzględnia zera. Nie wyznacza też automatycznie średniej ważonej: średnia cena zapłacona za sztukę wymaga podzielenia łącznej wartości przez łączną liczbę sztuk, zamiast uśredniania cen z pozycji transakcji.
Filtrowanie tabeli przed agregacją
Pierwszym argumentem iteratora może być zarówno tabela z modelu, jak i wyrażenie zwracające tabelę. Pozwala to najpierw wybrać wiersze spełniające warunek, a następnie wykonać obliczenie tylko dla nich. Funkcja FILTER zwraca taki podzbiór — sama niczego nie sumuje.
Wartosc pozycji powyzej progu =
SUMX(
FILTER(
Sprzedaz,
Sprzedaz[Ilosc] * Sprzedaz[CenaJednostkowa] > 1000
),
Sprzedaz[Ilosc] * Sprzedaz[CenaJednostkowa]
)Ta kalkulacja uwzględnia wyłącznie pozycje o wartości przed rabatem większej niż 1000. Nie wybiera zamówień, których łączna wartość przekroczyła ten próg — warunek dotyczy pojedynczego wiersza. Poziom sprawdzania warunku musi odpowiadać definicji biznesowej wskaźnika.
Filtrowanie tabeli przed iteracją jest szczególnie przydatne przy warunkach opartych na obliczeniach z kilku kolumn. Przy prostym ograniczeniu do jednej kategorii nie warto automatycznie budować konstrukcji FILTER i SUMX; często wystarcza standardowa agregacja z odpowiednim filtrem.
Zakres iteracji a wydajność
Praca na tabelach nie wymaga tworzenia nowej, trwałej tabeli w modelu. Iterator może korzystać z tabeli wirtualnej wyznaczanej podczas obliczania miary, na przykład listy unikalnych produktów. Dzięki temu zakres kalkulacji można dopasować do analizowanego zagadnienia.
Koszt obliczenia zależy jednak od liczby iterowanych wierszy i złożoności wyrażenia. Szczególnej uwagi wymagają zagnieżdżone iteratory oraz rozbudowane warunki wykonywane na dużych tabelach faktów. Wybieraj najmniejszy zbiór, który zachowuje poprawną logikę wyniku, ale nie agreguj danych wcześniej, jeśli utraciłoby to szczegóły potrzebne do obliczeń. Sam przyrostek „X” nie oznacza wolnej miary — wydajność warto oceniać pomiarem w konkretnym modelu.
Zmienne (VAR) i wzorce miar: czytelność, ponowne użycie i przykłady zastosowań
Rozbudowana miara DAX powinna dać się przeczytać jak opis obliczenia: najpierw ustalamy potrzebne wartości, następnie wykonujemy działania, a na końcu zwracamy wynik. Zmienne deklarowane przez VAR pomagają nadać formule taką strukturę. Zamiast wielokrotnie powtarzać długie wyrażenie, można zapisać jego wynik pod nazwą wskazującą znaczenie biznesowe, na przykład jako przychód netto, koszt sprzedaży lub wartość celu.
Największa korzyść pojawia się podczas utrzymania raportu. Łatwiej sprawdzić poszczególne etapy obliczenia, znaleźć źródło błędu i zmienić regułę biznesową bez przebudowy całej miary. Czytelność ma tu bezpośrednie znaczenie praktyczne: formułę powinien rozumieć nie tylko jej autor, lecz także osoba, która przejmie model.
VAR porządkuje obliczenie, ale nie zastępuje miar bazowych
Zmienna jest lokalna dla wyrażenia, w którym została zdefiniowana. Może przechowywać wartość skalarną lub tabelę, ale nie staje się samodzielnym elementem modelu dostępnym dla innych miar. Do współdzielenia logiki między wieloma wskaźnikami służą miary bazowe. Zmienne pomagają natomiast uporządkować konkretne obliczenie, które z tych miar korzysta.
Warto pamiętać, że zmienna przechowuje wynik oceniony w kontekście jej definicji, a nie instrukcję do ponownego wykonania przy każdym odwołaniu. Późniejsze użycie jej w zmienionym kontekście filtrów nie powoduje automatycznego przeliczenia zapisanej wartości. To istotne zwłaszcza wtedy, gdy miara zestawia wynik bieżącego wyboru z wynikiem odniesienia.
Zmienne mogą ograniczać powtarzanie tych samych obliczeń, lecz samo dodanie VAR nie gwarantuje poprawy wydajności. Ich pierwszym zadaniem jest uporządkowanie logiki. Ewentualne przyspieszenie należy potwierdzić pomiarem, a nie oceniać na podstawie krótszego zapisu.
10 przykładowych miar i ich zastosowania
Poniższe przykłady tworzą spójny zestaw wskaźników sprzedażowych. Pokazują, jak budować kolejne miary na wspólnych definicjach, zamiast za każdym razem odtwarzać całą logikę od podstaw.
- Przychód netto. Miara bazowa określająca wartość sprzedaży bez VAT, z uwzględnieniem uzgodnionego sposobu rozliczania rabatów, zwrotów i korekt. Stanowi wspólny punkt wyjścia dla analizy rentowności, realizacji celu i wartości zamówień.
- Koszt sprzedanych produktów. Druga miara bazowa, obejmująca koszty przypisane do analizowanej sprzedaży. Służy do oceny rentowności; nie należy utożsamiać jej z wartością zakupów dokonanych w tym samym okresie.
- Marża kwotowa. Różnica między przychodem netto a kosztem sprzedanych produktów. Korzysta z dwóch miar bazowych, dzięki czemu zmiana definicji przychodu lub kosztu pozostaje spójna także w tym wskaźniku. Pomaga wskazać produkty i klientów generujących największą marżę w wartości pieniężnej.
- Marża procentowa. Relacja marży kwotowej do przychodu netto. Przydaje się do porównywania rentowności segmentów o różnej skali sprzedaży. Wynik łączny powinien wynikać z relacji łącznej marży do łącznego przychodu, a nie ze zwykłej średniej procentów widocznych w wierszach raportu.
- Średnia wartość zamówienia. Przychód netto podzielony przez liczbę unikalnych zamówień uwzględnionych w analizie. Pozwala ocenić wartość koszyka zakupowego. Definicja powinna jasno określać sposób traktowania zamówień anulowanych i zwrotów, aby licznik oraz mianownik opisywały ten sam zbiór transakcji.
- Realizacja celu sprzedażowego. Relacja przychodu do przypisanego celu. Wykorzystywana na kartach KPI i w raportach menedżerskich. Cel musi być dostępny na poziomie zgodnym z analizą: planu miesięcznego dla regionu nie można bez dodatkowych reguł interpretować jako planu pojedynczego produktu.
- Odchylenie od celu. Różnica między wykonaniem a celem, pokazująca skalę przekroczenia planu lub niedoboru sprzedaży. Uzupełnia procent realizacji o konkretną kwotę. Warto przyjąć jednolitą konwencję: wynik dodatni oznacza przekroczenie celu, a ujemny — brakującą wartość.
- Efektywny poziom rabatu. Relacja wartości udzielonych rabatów do wartości sprzedaży przed rabatem. Pomaga kontrolować politykę cenową. Wymaga porównywalnych danych wejściowych i nie powinien być zastępowany nieważoną średnią rabatów z pozycji zamówień.
- Udział sprzedaży w wybranym zestawie. Przychód danej kategorii odniesiony do przychodu całego zestawu objętego wyborem użytkownika. Pokazuje strukturę sprzedaży. W tym wzorcu zmienne pomagają wyraźnie oddzielić wartość analizowanej kategorii od wartości odniesienia.
- Przychód na aktywnego klienta. Przychód netto podzielony przez liczbę klientów spełniających przyjętą definicję aktywności, na przykład posiadających kwalifikującą się transakcję w analizowanym okresie. Wspiera porównywanie segmentów i ocenę wartości bazy klientów. Liczenie wszystkich klientów z kartoteki odpowiadałoby na inne pytanie biznesowe.
Jak utrzymać spójność wzorców miar
Dobrym rozwiązaniem jest oddzielenie miar bazowych, wskaźników pochodnych i logiki prezentacji. Przychód oraz koszt definiuje się raz. Marża, realizacja celu i udziały odwołują się do tych definicji, a zmienne porządkują wartości pośrednie wewnątrz bardziej rozbudowanych obliczeń. Nazwy powinny opisywać znaczenie wartości, nie kolejność działań: „Przychód odniesienia” mówi więcej niż „Wynik 2”.
Dla każdego wskaźnika ilorazowego trzeba świadomie ustalić zachowanie przy braku lub zerowej wartości mianownika. Brak celu nie oznacza zerowej realizacji planu, podobnie jak brak sprzedaży nie musi oznaczać zerowej marży procentowej. Testy warto przeprowadzić dla pojedynczego elementu, wielu zaznaczeń, sumy całkowitej oraz pustego zakresu danych. To właśnie w tych sytuacjach najłatwiej sprawdzić, czy miara zachowuje sens biznesowy.
Debugowanie i wydajność DAX: narzędzia, podejście diagnostyczne, optymalizacja i antywzorce
Miara może zwracać poprawny wynik i jednocześnie spowalniać raport. Może też działać błyskawicznie, ale odpowiadać na inne pytanie biznesowe, niż zakładał autor. Dlatego debugowanie poprawności i optymalizację wydajności warto prowadzić oddzielnie: najpierw potwierdzić znaczenie wyniku, następnie zmierzyć koszt jego obliczenia. Skracanie formuły bez takiej diagnozy rzadko rozwiązuje właściwy problem.
Najpierw ustal, co dokładnie nie działa
Zamiast zaczynać od przepisywania DAX, zapisz warunki wystąpienia problemu: wybrane filtry, poziom szczegółowości wizualizacji, oczekiwany wynik oraz wynik rzeczywisty. Do weryfikacji wybierz niewielki fragment danych, który można sprawdzić niezależnie — na przykład jeden produkt w jednym miesiącu. Złożoną kalkulację rozbij diagnostycznie na tymczasowe miary pokazujące wyniki pośrednie.
Osobno sprawdź wiersze szczegółowe, sumy częściowe i sumę końcową. Suma w wizualizacji nie musi być sumą widocznych wartości, dlatego jej odmienny wynik nie jest automatycznie błędem. Zweryfikuj również zachowanie przy braku danych, zerowych wartościach oraz wyborze wielu elementów na fragmentatorze. Takie przypadki często ujawniają rozbieżności między definicją wskaźnika a implementacją. Podczas szkoleń Cognity pogłębiamy te zagadnienia na konkretnych przykładach z pracy uczestników.
Narzędzia: od wizualizacji do zapytania
Podstawowe narzędzia diagnostyczne odpowiadają na różne pytania. Warto używać ich kolejno, zamiast od razu analizować szczegółowy plan wykonania.
- Analizator wydajności w Power BI Desktop pomaga wskazać wolne wizualizacje i rozdzielić czas zapytania DAX od czasu renderowania oraz pozostałych operacji. Umożliwia także skopiowanie zapytania generowanego przez wizualizację. To dobry punkt wyjścia do ustalenia, czy opóźnienie rzeczywiście wynika z obliczeń.
- Widok zapytań DAX pozwala uruchamiać zapytania względem modelu i sprawdzać wyniki poza układem strony raportu. Przydaje się do odtwarzania problemów oraz porównywania wariantów kalkulacji.
- DAX Studio, w szczególności funkcje Server Timings i Query Plan, umożliwia dokładniejsze badanie wykonania zapytań. Pomaga ocenić udział silnika formuł i silnika magazynowania oraz znaleźć kosztowne operacje wymagające dalszej analizy.
Silnik formuł odpowiada między innymi za bardziej złożoną logikę obliczeń, a silnik magazynowania za pobieranie i agregowanie danych. Duży udział czasu jednego z nich jest wskazówką diagnostyczną, nie gotową receptą. Nie istnieje uniwersalna proporcja, do której powinno dążyć każde zapytanie.
Optymalizuj na podstawie porównywalnych pomiarów
Najpierw zapisz wynik i czas wykonania zapytania bazowego. Następnie zmieniaj jeden element naraz i ponawiaj test w tych samych warunkach. Uwzględnij wpływ pamięci podręcznej: pojedyncze szybkie wykonanie po wcześniejszym uruchomieniu nie dowodzi, że nowa wersja miary jest lepsza. Porównuj kilka przebiegów, rozróżniając testy z wyczyszczoną i rozgrzaną pamięcią podręczną.
Testuj zapytanie odpowiadające rzeczywistej wizualizacji. Miara sprawdzona na pojedynczej karcie może zachowywać się inaczej w macierzy obejmującej tysiące kombinacji kategorii. Po każdej zmianie sprawdzaj zarówno czas wykonania, jak i zgodność wyników — także dla przypadków brzegowych. Optymalizacja, która zmienia znaczenie wskaźnika, nie jest poprawą.
Antywzorce, które warto eliminować
Niepotrzebne przetwarzanie dużych tabel wiersz po wierszu, wielokrotne wykonywanie tych samych kosztownych obliczeń oraz budowanie obszernych tabel pośrednich to częste źródła problemów. Nie oznacza to jednak, że konkretna funkcja jest z definicji wolna. O koszcie decydują również liczba przetwarzanych wierszy, złożoność wyrażenia i sposób użycia miary w raporcie.
Antywzorcem jest także próba naprawiania formułą problemów modelu lub źródła danych. Wysoka kardynalność zbędnych kolumn, nieodpowiednie relacje czy opóźnienia zapytań DirectQuery mogą wymagać zmian poza DAX. Podobnie przeciążona strona z wieloma wizualizacjami nie zawsze przyspieszy po modyfikacji jednej miary. Najskuteczniejsze podejście polega na usunięciu zmierzonego wąskiego gardła, a nie na zastępowaniu czytelnych obliczeń bardziej skomplikowanymi tylko dlatego, że wyglądają na zaawansowane.
Najczęściej zadawane pytania i odpowiedzi odnośnie Power BI zaawansowany – DAX w praktyce: miary, kalkulacje i analiza danych
Miary DAX używaj do wskaźników, które mają reagować na filtry raportu, a kolumny obliczeniowej — do opisywania i grupowania rekordów. Przychód, rentowność czy realizacja celu wymagają zwykle miary. Kategoria produktu lub etykieta do fragmentatora wymaga kolumny. W trybie Import kolumna przechowuje wyniki dla poszczególnych wierszy, natomiast miara jest obliczana podczas obsługi zapytania i nie zapisuje osobnej wartości dla każdego rekordu.
Power BI oblicza miarę ponownie w kontekście sumy końcowej, zamiast automatycznie dodawać wyniki widocznych wierszy. Dla marży procentowej poprawne podsumowanie oznacza relację łącznej marży kwotowej do łącznego przychodu, a nie sumę procentów. Podobnie zachowują się średnie i udziały. Zanim zmienisz formułę, ustal, czy oczekujesz wskaźnika dla całego zbioru, czy rzeczywiście sumy wyników cząstkowych.
Zastosuj KEEPFILTERS, aby warunek w CALCULATE zawężał wybór użytkownika zamiast zastępować filtr na tej samej kolumnie. Standardowy warunek kategorii może nadpisać kategorię wskazaną we fragmentatorze. KEEPFILTERS wyznacza przecięcie obu ograniczeń. Jeśli użytkownik wybierze kategorię inną niż dopuszczona w formule, zbiór danych spełniających oba warunki będzie pusty. Filtry pozostałych kolumn nadal wpływają na obliczenie.
Przy nieoczekiwanym wyniku YTD sprawdź kalendarz, relację z danymi oraz datę graniczną obliczenia. Dla klasycznych funkcji time intelligence zweryfikuj:
- unikalne daty bez luk i pustych wartości oraz zakres obejmujący pełne lata;
- oznaczenie kalendarza jako tabeli dat;
- aktywną relację z właściwą datą transakcji;
- użycie pól kalendarza na osiach i fragmentatorach.
YTD narasta do daty wynikającej z kontekstu raportu, nie automatycznie do dzisiaj ani ostatniego dnia z kompletnymi danymi.
SUMX stosuj wtedy, gdy przed zsumowaniem trzeba obliczyć wyrażenie dla każdego wiersza, a SUM — gdy sumujesz gotową kolumnę. Przykładem zastosowania SUMX jest wartość sprzedaży liczona z ilości, ceny jednostkowej i rabatu dla każdej pozycji. Pomnożenie sum tych kolumn nie da równoważnego wyniku. Zakres iteracji powinien odpowiadać poziomowi analizy: pozycji transakcji, zamówieniu lub innemu zdefiniowanemu elementowi.
Zmienna VAR przechowuje wynik oceniony w kontekście swojej definicji, a nie formułę uruchamianą ponownie po zmianie filtrów. Jeśli zapiszesz wynik miary w zmiennej, późniejsze przekazanie tej zmiennej do CALCULATE nie przeliczy miary w nowym kontekście. Aby uzyskać wynik dla zmienionych filtrów, przekaż do CALCULATE bezpośrednie odwołanie do miary. Zmienną możesz następnie wykorzystać do przechowania rezultatu tego obliczenia.
Porównuj okresy o odpowiadającym sobie zakresie, zamiast zestawiać niepełny bieżący miesiąc z całym miesiącem poprzedniego roku. Datę odcięcia powiąż z kompletnością danych. Następnie ustal, czy porównanie ma obejmować tę samą liczbę dni kalendarzowych, czy roboczych. SAMEPERIODLASTYEAR przesuwa analizowany zakres dat, ale samo nie ustala kompletności danych i nie skraca okresu odniesienia do ostatniej dostępnej transakcji.
Zacznij od Analizatora wydajności w Power BI Desktop, aby sprawdzić, czy opóźnienie wynika z zapytania DAX, czy z renderowania wizualizacji. Dalszą diagnozę prowadź etapami:
- skopiuj zapytanie wolnej wizualizacji;
- zbadaj jego wykonanie w DAX Studio, korzystając z Server Timings i Query Plan;
- zmieniaj jeden element obliczenia naraz;
- porównuj czas i poprawność wyników przy tych samych filtrach oraz porównywalnym stanie pamięci podręcznej.
Sprawdź też relacje i konstrukcję modelu.