Använda variabler för att förbättra DINA DAX-formler

Som datamodellerare kan det vara svårt att skriva och felsöka vissa DAX-beräkningar. I komplexa beräkningar måste du ofta använda sammansatta eller komplexa uttryck. Sammansatta uttryck kan bestå av många kapslade funktioner och eventuellt även uttryckslogik.

Om du använder variabler i DINA DAX-formler kan du skriva mer komplexa och effektiva beräkningar. Variabler kan förbättra prestanda och tillförlitlighet, läsbarhet och minska komplexiteten.

I den här artikeln går vi igenom de tre första fördelarna genom att använda ett exempelmått för försäljningstillväxten från år till år. (Formeln för försäljningstillväxt år för år är periodens försäljning mindre under samma period föregående år dividerat med försäljningen för samma period föregående år.)

Vi börjar med följande måttdefinition.

Sales YoY Growth % =
DIVIDE(
    ([Sales] - CALCULATE([Sales], PARALLELPERIOD('Date'[Date], -12, MONTH))),
    CALCULATE([Sales], PARALLELPERIOD('Date'[Date], -12, MONTH))
)

Måttet ger rätt resultat, men nu ska vi se om vi kan förbättra det.

Bättre prestanda

Observera att uttrycket som beräknar ”samma period förra året” upprepas i formeln. Den här formeln är ineffektiv eftersom Power BI måste utvärdera samma uttryck två gånger. Måttdefinitionen kan göras effektivare med hjälp av variabeln VAR.

Det här är en bättre måttdefinition. Där används ett uttryck för att tilldela resultatet för ”samma period förra året” till en variabel med namnet SalesPriorYear. Variabeln används sedan två gånger i RETURN-uttrycket.

Sales YoY Growth % =
VAR SalesPriorYear =
    CALCULATE([Sales], PARALLELPERIOD('Date'[Date], -12, MONTH))
RETURN
    DIVIDE(([Sales] - SalesPriorYear), SalesPriorYear)

Måttet ger fortfarande rätt resultat men på ungefär halva tiden.

Bättre läsbarhet

Lägg märke till hur valet av variabelnamn gör RETURN-uttrycket enklare att förstå i föregående måttdefinition. Uttrycket är kort och beskrivande.

Enklare felsökning

Variabler kan också göra en formel enklare att felsöka. Du kan testa ett uttryck som tilldelats till en variabel genom att tillfälligt skriva om RETURN-uttrycket så att variabeln matas ut.

I följande måttdefinition returneras endast variabeln SalesPriorYear. Observera hur det ursprungliga RETURN-uttrycket är utkommenterat. På så sätt kan du enkelt återställa koden när felsökningen är färdig.

Sales YoY Growth % =
VAR SalesPriorYear =
    CALCULATE([Sales], PARALLELPERIOD('Date'[Date], -12, MONTH))
RETURN
    --DIVIDE(([Sales] - SalesPriorYear), SalesPriorYear)
    SalesPriorYear

Mindre komplexitet

I tidigare versioner av DAX saknades stöd för variabler. Du behövde använda DAX-funktionerna EARLIER eller EARLIEST som referenser till yttre filtreringskontexter i komplexa uttryck med nya filterkontexter. De här funktionerna kunde tyvärr vara svåra att använda och förstå.

Variabler utvärderas alltid utanför de filter som används i RETURN-uttrycket. När du använder en variabel i en modifierad filterkontext får du därför samma resultat som med funktionen EARLIEST. Det gör att du inte behöver använda funktionerna EARLIER eller EARLIEST. På så sätt kan du skriva formler som är mindre komplexa och enklare att förstå.

Titta på den här beräknade kolumnen som lagts till i tabellen Subcategory. Där utvärderas en rangordning för varje produktkategori baserat på värdena i kolumnen Subcategory.

Subcategory Sales Rank =
COUNTROWS(
    FILTER(
        Subcategory,
        EARLIER(Subcategory[Subcategory Sales]) < Subcategory[Subcategory Sales]
    )
) + 1

Funktionen EARLIER används till att referera till kolumnvärdet Subcategory Salesi den aktuella radkontexten.

Du kan förbättra definitionen av den beräknade kolumnen genom att använda en variabel i stället för funktionen EARLIER. Variabeln CurrentSubcategorySales lagrar värdet i kolumnen Subcategory Salesi den aktuella radkontexten, och i RETURN-uttrycket används det i en modifierad radkontext.

Subcategory Sales Rank =
VAR CurrentSubcategorySales = Subcategory[Subcategory Sales]
RETURN
    COUNTROWS(
        FILTER(
            Subcategory,
            CurrentSubcategorySales < Subcategory[Subcategory Sales]
        )
    ) + 1

Se även