EN

Mijn notitiesPraktische Power BI tips

CALCULATE vervangt de filter op die kolom: dag 1 van de DAX filter-burst

Kaart bij de notitie: CALCULATE vervangt de filter op die kolom: dag 1 van de DAX filter-burst

Je zet in het dashboard een year-slicer op 2024, en de kaart met Omzet 2025 blijft koppig 2025 tonen. Geen bug, geen verouderde cache, geen relatie die uit staat. Dit is dag 1 van de DAX filter-burst: we kijken naar wat CALCULATE werkelijk doet met je filtercontext, en waarom dat gedrag zo veel “vreemde” uitkomsten verklaart.

De enige DAX-functie die filtering in de measure zelf zet

De meeste measures ontvangen gewoon wat er in de filtercontext zit: de slicer die de gebruiker heeft gezet, de pagina-filter, de visual-filter. Ze kijken om zich heen en rekenen op basis van wat er op dat moment actief is. CALCULATE werkt anders.

CALCULATE([Omzet], 'Datum'[Jaar] = 2025) zegt letterlijk: reken [Omzet] uit, maar gebruik als filter op Datum[Jaar] dit: 2025. Die instructie zit in de measure zelf, niet in het rapport. Dat is de kern van wat CALCULATE doet: het is de enige DAX-functie waarmee jij een aangepaste filtercontext meegeeft aan de expressie die je evalueert, in plaats van te leunen op wat de visual of de slicer meegeeft.

Omzet 2025 = CALCULATE([Omzet], 'Datum'[Jaar] = 2025) ziet er onschuldig uit als je hem op een kaart zet zonder andere filters. Je krijgt precies het bedrag voor 2025. De aanname die je dan makkelijk meenam, is dat CALCULATE een filter heeft toegevoegd aan wat er al stond. Die aanname houdt één schermafdruk stand.

Waar de slicer het verliest

Dezelfde kaart, maar nu op een rapportpagina met een year-slicer. De gebruiker zet de slicer op 2024. Op dat moment komen er twee filters op Datum[Jaar] toe bij de kaart: de slicer zet Jaar = 2024, en de measure heeft Jaar = 2025 al staan. Eén kolom, twee uitspraken. DAX lost dat op met een duidelijke regel: het CALCULATE-filter wint. De kaart blijft 2025 tonen.

Dit is geen fout in het model, geen ontbrekende relatie, geen onjuiste instelling. De measure werkt precies zoals hij is geschreven. De verwarring komt doordat de slicer erbij voelt alsof hij iets zou moeten doen, terwijl hij op deze specifieke kolom al is overschreven.

De regel: per kolom, niet het hele rapport

De overschrijving geldt per kolom. Alleen de kolom die je in CALCULATE noemt, verliest zijn externe filter. Alle andere filters in de rapportcontext blijven gewoon actief.

Een land-slicer op Klant[Land] werkt dus nog steeds op dezelfde kaart, ook als de year-slicer op het dashboard geen effect meer heeft. Een segment-slicer, een product-filter, een pagina-filter: die raken er niet door. Alleen Datum[Jaar] is overschreven, omdat dat de kolom is die je in de measure hebt benoemd.

Dat kolom-voor-kolom-denken is de sleutel. Bijna elke keer dat een measure iets “vreemds” doet in een dashboard, is er een CALCULATE-filter op dezelfde kolom als een actieve slicer. De regel is consistent, de uitkomst is voorspelbaar, zodra je weet hoe te kijken.

Wat je in je eigen model kunt nakijken

Open een measure die een hardgecodeerde filter draagt: zoiets als een tijdintelligentie-measure (Omzet vorig jaar) of een segment-specifieke measure (Omzet Retail). Kijk welke kolom die measure expliciet filtert. Controleer dan of een slicer op diezelfde kolom in het rapport nog effect heeft op de visual.

Als de slicer geen effect heeft, is dat de override-regel in werking: de measure heeft die kolom al in beslag genomen. Dat is precies het bedoelde gedrag als je een tijdgefilterde measure bouwt. Het is een verrassing als je dat niet wist, en het wordt dubbel verwarrend zodra je het rapport aan een collega uitlegt die verwacht dat de slicer alles stuurt.

Elke measure die een hardgecodeerde filter draagt, maakt die ene kolom immuun voor slicers die hetzelfde veld filteren. Weten welke kolommen dat zijn in jouw model, is het begin van DAX-beheersing: je kijkt niet meer naar een “vreemd” getal, je kijkt naar welke filters er op dat moment actief zijn en welke de measure al heeft overschreven.

Morgen: FILTER

Dit is dag 1 van een vijfdelige serie over DAX-filterlogica. Vandaag ging het over de basisregel van CALCULATE: op de kolom die je noemt, vervangt je eigen filter de externe filter. Morgen gaan we door met FILTER, de eerste functie die je binnen CALCULATE zet om je filterlogica uit te breiden, en het begin van de patronen waarmee een slicer juist wél meepraat in plaats van te worden overschreven. Wordt vervolgd.

De hele serie samengevat vind je in de spiekbrief van de DAX filter-burst.

Meer op trainerbjorn.nl.

Alle notities in ‘Praktische Power BI tips’ →