Filtercontext en rijcontext
Wat is filtercontext en rijcontext?
Filtercontext en rijcontext zijn de twee manieren waarop DAX beslist naar welke data een formule kijkt terwijl ze draait. Elke berekening in Power BI wordt uitgevoerd binnen de ene, de andere, of beide. Van zodra je ze kan lezen, verdwijnt het mysterie achter de meeste rare resultaten.
Rijcontext is 'de huidige rij'. Filtercontext is 'het geheel van filters dat nu op het model staat'. Dat zijn twee verschillende dingen die elk een ander werk doen, en net daar loopt het bij veel mensen mis.
Rijcontext
Rijcontext betekent dat DAX een tabel rij per rij overloopt en weet op welke rij ze staat. Een berekende kolom krijgt automatisch rijcontext: de formule draait een keer per rij en kan de waarde van elke kolom op die rij uitlezen.
Hier is een berekende kolom die per verkoopregel de hoeveelheid met de prijs vermenigvuldigt.
Regeltotaal = Sales[Aantal] * Sales[Eenheidsprijs]DAX wandelt door de tabel en leest op elke rij het aantal en de prijs van die rij. Iterator-functies zoals SUMX, AVERAGEX en FILTER maken dezelfde soort rijcontext aan: ze lopen over een tabel en geven je de huidige rij binnen de expressie die je meegeeft.
Wat rijcontext op zichzelf niet doet, is het model filteren. Ze kent de huidige rij, maar ze beperkt een SUM over de hele tabel niet vanzelf. Dat is de taak van filtercontext.
Filtercontext
Filtercontext is het geheel van filters dat actief is op het moment dat een berekening draait. In een rapport komen die filters overal vandaan waar de lezer aan kan komen: de rijen en kolommen van een visual, slicers, het filterpaneel en cross-filtering vanuit andere visuals. Ook een relatie geeft filtercontext door van de ene tabel aan de andere.
Neem een gewone measure.
Totale omzet = SUM(Sales[Bedrag])Zet die in een card en ze telt elke rij op. Zet ze in een staafdiagram per land en elke staaf toont een ander getal, want elke staaf draagt zijn eigen filtercontext: een land per keer. Klik maart aan in een slicer en de filtercontext versmalt opnieuw, nu tot maart. De formule verandert nooit, alleen de filtercontext eromheen.
Je kan filtercontext ook zelf zetten binnen een formule. CALCULATE is de functie die daarvoor bestaat, en functies als ALL, REMOVEFILTERS en KEEPFILTERS voegen filters toe, wissen ze of passen ze bewust aan.
Hoe de twee samenwerken
Filtercontext komt niet in de plaats van rijcontext. Ze komt erbovenop. Een berekende kolom draait in rijcontext, en als je daarin een aggregatie in CALCULATE wikkelt, maakt DAX van de huidige rij een filter. Die beweging heeft een eigen naam, context transition, en is een aparte term waard. Een measure begint in filtercontext, en een iterator daarbinnen voegt voor de duur van de lus een rijcontext toe.
Een korte denktest helpt. Vraag jezelf af: heeft deze formule de huidige rij nodig, of het huidige geheel aan filters? Een berekende kolom en de binnenkant van een iterator leunen op rijcontext. Een measure die in een visual zit, leeft in filtercontext. Een berekeningsgroep werkt vanuit de andere kant met hetzelfde idee: ze hervormt de filtercontext zodat een stuk logica, zoals een year-to-date- of vorig-jaar-variant, in een keer over veel measures kan gelden.
Waarom context de kern-DAX-vaardigheid is
Bijna elk 'mijn getal klopt niet'-moment in Power BI komt terug op context. De formule is in orde, maar de context eromheen is niet wat de auteur dacht. Een measure ziet er juist uit in een card en zakt dan in een tabel omdat een slicer een filter toevoegde dat niemand opmerkte. Een berekende kolom geeft op elke rij hetzelfde eindtotaal terug omdat ze wel rijcontext had, maar geen filtercontext, waardoor de aggregatie de hele tabel zag.
De twee contexten zitten ook dicht bij prestaties. De VertiPaq-engine die een geimporteerd model in het geheugen houdt, beantwoordt gefilterde aggregaties snel. Een measure die de filtercontext het werk laat doen, wint daarom meestal van een stapel berekende kolommen die dezelfde getallen rij per rij opslaan.
Waar moet je op letten bij het gebruik van filtercontext en rijcontext?
Verwachten dat rijcontext filtert. Een kale
SUMin een berekende kolom negeert welke rij hij op dat moment bekijkt, tenzij je metCALCULATEeen transition forceert. Zonder dat krijg je op elke rij het totaal van de hele kolom.Een filter vergeten dat er al staat. Slicers, het filterpaneel en de visual zelf voegen stil filtercontext toe. Als een getal je verrast, som dan eerst elk filter op dat op die cel werkt voor je aan de formule komt.
Tweerichtingsrelaties die filters verspreiden. Bidirectionele filtering kan filtercontext duwen in richtingen die je niet plande, wat resultaten verandert en het model kan vertragen. Houd relaties op een richting tenzij je een reden hebt.
Zware expressies binnen iterators. Een iterator zet voor elke rij die hij bezoekt een rijcontext op. Een dure berekening binnen een lus over miljoenen rijen loopt op. Haal logica uit de lus waar het kan.