Czysty kod to podstawa dobrego rozwiązania. W przypadku miar pisanych w języku DAX, czysty kod to nie tylko formatowanie, ale także ich dobra organizacja, enkapsulacja i reużywalność. Z założenia im mniej kodu, tym lepiej. Dlatego też, tworząc nowy model danych Power BI lub Analysis Services, warto zastanowić się nad wykorzystaniem Calculation Groups.
Czym są Calculation Groups?
Zacznę od razu od praktycznego przykładu. Dodając Calculation Groups do Tabulara, tworzysz tabelę z jedną kolumną, z kilkoma wartościami, a każda z nich odpowiada jednej kalkulacji. Załóżmy, że dodasz dwie wartości (Calculation Item) YTD i QTD. W definicji każdej z nich umieścisz kod, który „nadbudowuje” dynamicznie wybraną miarę. Czyli jeśli ktoś w tabeli przestawnej doda miarę, a do tego wybierze kolumnę YTD z Calculation Groups, to wartość, którą powinien zobaczyć, jest wartością miary policzoną za okres od początku roku do bieżącego dnia. Takie rozwiązanie nie tylko zmniejsza liczbę miar, jakie musimy dodać do modelu, ale taże upraszcza zarządzanie nimi. Jeśli zajdzie sytuacja, w której konieczna będzie zmiana logiki wyliczania YTD, to zrobimy to w jednym miejscu, bez konieczności modyfikacji wszystkich miar z dopiskiem YTD.
Time Intelligence vs Calculation Groups
Zastosowanie Calculation Groups do Time Intelligence jest sztandarowym przykładem wykorzystania tego mechanizmu. Można powiedzieć, że do niedawna aby obliczać miary w różnych przedziałach czasowych, należało po prostu dodać kolejne warianty YTD, QTD, MTD. Takie działanie skutkowało zwiększeniem liczby miar w modelu, a w konsekwencji trudniejszym jego utrzymaniem. Calculation Groups umożliwia utrzymanie całej logiki Time Intelligence w jednym miejscu.
Jak dodać Calculation Groups?
Zacznijmy od otworzenia modelu danych. Ja będę edytował model z przykładowego raportu (link). Podłączę się do niego za pośrednictwem Tabular Editora i dodam Calculation Groups, a także dwie kalkulacje: YTD i QTD. Każda z nich będzie wyliczała wartość miary w danym okresie. Zwróćmy uwagę na dwa elementy. Pierwszym jest właściwość Precedence, której używamy do określenia kolejności zastosowania grupy, jeśli mamy ich kilka. „0” jest tutaj najwyższą wartością.
Drugim elementem jest funkcja SELECTEDMEASURE(), która jest jakby miejscem, gdzie zostanie „wklejona” definicja wybranej miary. Po dodaniu Calculation Groups konieczne jest odświeżenie modelu w Power BI lub procesowanie tabeli (full + recalc) w Analysis Services.
Wyjątki w działaniu Calculation Groups
Są pewne sytuacje, w których nie chcemy, aby pewne miary korzystały z Calculation Groups. Na przykład istnieje potrzeba utworzenia miar YTD lub innych Time Intelligence, które zawsze powinny liczyć się w okresie YTD. Aby nie było nieporozumień – chcemy, aby takie miary zwracały pustą wartość, gdy któryś Calculation Item jest wybrany. W tym celu możemy posłużyć się funkcją SELECTEDMEASURENAME(), która zwraca nazwę wybranej miary. Na tej podstawie możemy dodać warunek, w którym określimy, że jeśli nazwa kończy się na YTD, to ma zostać zwrócona pusta wartość. Przykład takiego rozwiązania prezentuję poniżej.
Default Member - kolejne zastosowanie Calculation Groups
Jest jeszcze jedno ciekawe zastosowanie Calculation Groups. Chodzi o funkcjonalność Default Member. W sytuacji, gdy ktoś nie wybierze żadnej wartości atrybutu, to domyślnie miara ma być odfiltrowana do jakiejś wartości. Na przykład – chcemy, aby miara Net Sales domyślnie wyliczała się tylko dla klientów w wieku 15-20 lat, chyba, że ktoś wybierze inną wartość.
Oczywiście nie będzie problemu, jeśli dodamy po prostu warunek do miary, ale gorzej będzie jeśli takich Default Memberów będzie więcej i wtedy nasz kod stanie się nieczytelny, a co gorsza, gdy zajdzie potrzeba zmiany logiki, nawet przy wykorzystaniu skryptów, będzie to trudne do zrobienia. Aby miara wykorzystywała tę funkcjonalność, konieczne jest dodanie warunku, który sprawdza, czy wymiar/atrybut jest filtrowany, a także wartość, która ma zostać zwrócona.
Takie operacje możemy wykonać właśnie wykorzystując Calculation Groups, dzięki czemu przy bardziej skomplikowanych rozwiązaniach zarządzanie kodem będzie prostsze. Do miary wystarczy dodać konstrukcję opartą na funkcji Treatas.
Calculation Groups - wiele możliwości
Oczywiście przedstawiłem tutaj tylko kilka zastosowań Calculation Groups – jest to naprawdę elastyczny i użyteczny mechanizm. Natomiast do pełni szczęścia brakuje możliwości dynamicznego wybierania miary na podstawie nazwy, coś jak dynamiczny SQL. Być może w przyszłości taka funkcjonalność zostanie dodana.
Jak zwykle zachęcam do odwiedzenia mojego kanału na Youtube, gdzie rozwijam temat Calculation Groups.