În lansarea din noiembrie a desktopului Power BI, am introdus o nouă expresie DAX, care este cu adevărat grozavă. Lucrul cu ierarhiile din DAX a fost întotdeauna un pic dureros, mai ales în scenariile în care trebuie să vă schimbați calculul în funcție de nivelul în care vă aflați.

Scenariul

Să luăm un scenariu în care compania are câteva reguli speciale pentru calcularea totalelor. Pentru fiecare total din ierarhie rezultatele sunt pre-calculate (o sumă simplă ar fi incorectă), nu spre deosebire de operatorii unari sau rolurile personalizate, așa cum le avem în AS Multi Dimensional.

Începem cu o ierarhie ca aceasta. După cum sa menționat anterior, totalurile sunt deja calculate, așa că vom avea nevoie de un rând în tabel pentru fiecare dintre ele. Pentru a putea face calculul corect, avem nevoie de o modalitate de a ști care rând este total sau nu, așa că am adăugat o coloană IsTotal.

obține

Pentru fiecare nivel din ierarhie avem o valoare în tabelul de date:

Apoi creez o relație și creez o ierarhie .

În cele din urmă, trag în coloana Valori și ierarhia într-o matrice (am activat și pictogramele +/-, astfel încât să putem extinde colapsul, care este o altă caracteristică din noiembrie). Primul lucru pe care îl vedem este că matricea arată ciudat cu goluri și tot.

Motivul pentru care vedem acest lucru este modul în care sunt configurate datele, am stocat totaluri și totaluri mari la cel mai scăzut nivel din ierarhie. În schimb, vrem să le arătăm la nivelul în care sunt corecți. De asemenea, nu vrem să afișăm agregarea creată de SUM.

DAX

Pentru a face acest lucru, trebuie să folosim DAX pentru a determina nivelul la care ne aflăm, pe baza căruia se determină calculul de făcut. Putem folosi funcția DAX ISFILTERED pentru a verifica dacă ne aflăm la un anumit nivel, dar această funcție are ca problemă și ascultă „filtre” setate în raport, precum slicere, astfel încât s-ar putea să vă dea fals pozitiv la niveluri greșite, deci nu este minunat fie.

Alternativ, putem verifica dacă vă aflați la un nivel, numărând numărul de valori pentru o anumită coloană. Dacă este 1, știi că ești la acel nivel. DAX ar arăta astfel:

Măsura 2 =
DACĂ (
CALCULATI (
COUNTROWS (VALORI (Vânzători [Vânzător])),

ALLEXCEPT (Vânzători, Vânzători [Vânzător])
)
= 1,
ADEVĂRAT ()
)

sau scris cu o scurtătură simplă (face la fel ca mai sus, dar încapsulat într-o singură funcție):

Măsura 2 =
IF (HASONEFILTER (Vânzători [Vânzător]), ADEVĂRAT ())

Această măsură are ca rezultat adevărat la cel mai scăzut nivel, utilizează ALLExcept pentru a șterge orice filtre setate pe vânzător din exterior (cum ar fi un feliator).

Cu actualizarea recentă a Power BI și funcția IsInScope, am făcut acest lucru și mai ușor. În loc de expresia complicată de mai sus puteți scrie acest lucru:

Măsura 2 =
IF (ISINSCOPE (Vânzători [Vânzător]), ADEVĂRAT ())

IsInScope poate detecta chiar și mai multe cazuri și nu poate fi exprimat folosind funcții DAX existente care depind de detectarea contextului filtrului și/sau a valorilor coloanei rămase după aplicarea filtrelor. IsInScope returnează true dacă o coloană se află în contextul filtrului și este o coloană de grupare în rândul curent al unui set de rezultate de interogare. Aceste informații nu pot fi derivate doar din contextul filtrului.

Se returnează calculul corect pe nivel

În cele din urmă, dacă doriți să testați orice alt nivel, atunci partea de jos va trebui să testați pentru ambele. Iată ce se întâmplă când testez pentru Channel:

După cum puteți vedea, ambele se întorc adevărate, ceea ce este de înțeles, deoarece ambele sunt în domeniul de aplicare. Pentru a rezolva acest lucru, trebuie să testați pentru ambele. Astfel (folosesc din nou trucul Switch True):

Măsura 2 =
INTRERUPATOR (
ADEVĂRAT,
ISINSCOPE (Vânzători [Vânzător]), „vânzător”,
ISINSCOPE (Vânzători [Canal]), „canal”,
"Alte"
)

Acest lucru ne permite acum să vedem la ce nivel mă aflu:

Punând totul împreună într-o expresie DAX care returnează un calcul diferit pentru fiecare nivel.

Măsurați =
VAR grandtotal =
CALCULAȚI ([Suma valorii], Vânzătorii [IsTotal] = 3)
VAR sellersum =
CALCULAȚI ([Suma valorii], Vânzătorii [IsTotal] = 0)
VAR selectat de vânzător =
ISINSCOPE (vânzători [Vânzător])
VAR canale selectate =
ISINSCOPE (vânzători [canal])
VAR Countrysum =
CALCULATI (
[Suma valorii],
Vânzători [IsTotal] = 1,
ALLEXCEPT (Vânzători, Vânzători [ȚARA])
)
VAR contraselectat =
ISINSCOPE (vânzători [Țara])
Regiuni VAR =
CALCULATI (
[Suma valorii],
Vânzători [IsTotal] = 2,
ALLEXCEPT (Vânzători, Vânzători [Regiune])
)
VAR Regionselected =
ISINSCOPE (vânzători [Regiune])
ÎNTOARCERE
INTRERUPATOR (
ADEVĂRAT (),
sellerselected, sellersum,
canale selectate, BLANK (),
contranselectat, Countrysum,
regionelected, Regionsum,
Total general
)

Prin utilizarea câmpului IsTotal, am adăugat înainte pentru a obține valorile pentru fiecare nivel din ierarhie și pentru a ignora orice alte valori, ceea ce ne asigură că nu cumulăm copii. ALLEXCEPT se asigură că ignorăm orice filtre, cu excepția celor setate la nivelul pe care îl căutăm, acest lucru ar putea fi sau nu necesar în scenariul dvs. În cele din urmă, acest lucru ne aduce acest rezultat:

Acum afișează valorile pentru fiecare nivel pe baza calculului nostru personalizat, fără a utiliza suma obișnuită. Destul de cool 🙂