DAX-formules in Power BI worden vaak pas lastig wanneer een berekening er syntactisch goed uitziet maar per visual een onverwacht getal toont. Een measure kan op een kaart de totale omzet tonen, in een tabel per product een deelbedrag geven en onder een andere selectie opnieuw veranderen. Dat gedrag ontstaat door de filtercontext. Bij berekende kolommen en iteratorfuncties speelt daarnaast de rijcontext een hoofdrol. Zonder begrip van deze twee concepten zijn veel DAX-fouten moeilijk systematisch te verhelpen.
Dit artikel bouwt de begrippen op vanuit een klein stermodel met verkooptransacties. De voorbeelden laten zien waarom een berekende kolom anders werkt dan een measure, wat SUMX doet en hoe CALCULATE filters beïnvloedt. Ook wordt de zogenoemde context transition besproken: een essentieel mechanisme dat verklaart waarom ogenschijnlijk vergelijkbare formules onder sommige omstandigheden andere waarden retourneren.
Begin met een betrouwbaar stermodel
Stel dat Power BI de tabel FactSales bevat met OrderId, DateKey, ProductKey, Quantity, UnitPrice en LineAmount. Daarnaast zijn er de dimensietabellen DimProduct, DimDate en DimRegion. Elke dimensie heeft een unieke sleutel en relaties filteren de bijbehorende transacties volgens het afgesproken model. Een gebruiker kan dan omzet per productgroep, jaar of regio analyseren.
De maat Omzet = SUM(FactSales[LineAmount]) is eenvoudig. Toch heeft deze formule zonder filtercontext geen vast ‘eigen’ jaar of product. Het resultaat hangt af van de gegevens die in de actuele evaluatiecontext beschikbaar zijn. Op een kaart zonder filters wordt het totaal over de relevante factregels berekend. In een matrix met productgroepen wordt dezelfde measure per productgroep opnieuw geëvalueerd met de betreffende productfilter.
Dit is een fundamenteel verschil met een Excel-formule die meestal expliciete celverwijzingen gebruikt. In DAX bepaalt het model samen met de filtercontext welke rijen voor de berekening relevant zijn. Een verkeerd gelegde relatie kan daarom de uitkomst veranderen zonder dat de DAX-formule zelf is aangepast.
Wat is rijcontext?
Rijcontext verwijst naar de huidige rij tijdens een berekening. In een berekende kolom kan een uitdrukking direct waarden van andere kolommen op dezelfde rij gebruiken. Bijvoorbeeld:
FactSales[RegelOmzet] = FactSales[Quantity] * FactSales[UnitPrice]
Voor iedere rij worden Quantity en UnitPrice uit diezelfde rij vermenigvuldigd. Deze berekening produceert een opgeslagen kolomwaarde wanneer het model wordt verwerkt. Dat maakt de berekening bruikbaar als een rijgebonden kenmerk, maar vergroot ook het model en reageert niet vanzelf als dynamische maat op selecties in het rapport.
Een rijcontext ontstaat ook binnen iteratoren, zoals SUMX. Dat betekent niet dat alle formules binnen de iterator automatisch dezelfde filters krijgen. Rijcontext maakt waarden van een rij beschikbaar; filtercontext bepaalt welke rijen uit tabellen voor geaggregeerde berekeningen meetellen. Die twee concepten moeten daarom afzonderlijk worden begrepen.
Wat is filtercontext?
Filtercontext bestaat uit de filters die gelden wanneer een formule wordt geëvalueerd. Die kunnen ontstaan door slicers, visualfilters, paginafilters, relaties en DAX-expressies. Een matrix met het jaar 2026 en de productgroep Software laat dezelfde measure evalueren binnen de combinatie van die filters. Daarom kunnen verschillende cellen in dezelfde matrix verschillende waarden tonen.
Neem een measure:
Omzet = SUM(FactSales[LineAmount])
Stel dat de hele dataset € 900.000 omzet bevat. Een filter voor regio West kan dat terugbrengen naar € 270.000. Een extra selectie voor productgroep Diensten kan vervolgens € 85.000 tonen. De formuletekst is niet veranderd; de verzameling meetellende factregels wel.
Filters op dimensietabellen werken doorgaans via relaties door naar de feitentabel. Bij een onjuiste relatie of een niet-unieke sleutel kan een verwachte filtering uitblijven of zich anders gedragen. Daarom is een visuele controle van de modelrelaties een eerste stap bij onverwachte DAX-uitkomsten.
Waarom een measure geen berekende kolom is
Een measure wordt in de context van de actuele query of visual berekend. Een berekende kolom wordt bij gegevensverwerking op rijniveau geëvalueerd en in het model opgeslagen. Daardoor zijn measures passend voor totalen, marges en andere aggregaties die met filters moeten veranderen. Berekende kolommen passen beter bij bepaalde statische classificaties of afgeleide rijwaarden, hoewel een brontransformatie soms efficiënter is.
Een veelgemaakte fout is een berekende kolom maken met een totaalomzetformule in de verwachting dat elke rij automatisch het omzetbedrag van het bijbehorende product toont. Een aggregatie in een berekende kolom werkt niet altijd zoals een slicergevoelige measure. De evaluatiecontext en eventuele context transition bepalen het resultaat. Een model met duizenden rijen kan bovendien onnodig groeien als dezelfde geaggregeerde waarde steeds wordt opgeslagen.
Begin bij de zakelijke behoefte: moet de waarde per opgeslagen rij bestaan of moet zij tijdens rapportgebruik worden berekend? Als een KPI per geselecteerde maand moet reageren, ligt een measure voor de hand. Voor een vaste productcodeclassificatie is een kolom of een eigenschap in de dimensietabel vaak passender.
SUMX: rijcontext binnen een aggregatie
SUMX is een iterator. De functie doorloopt de rijen van een tabel en evalueert voor elke rij een uitdrukking; daarna worden de resultaten opgeteld. Bijvoorbeeld:
Omzet Berekend =
SUMX(
FactSales,
FactSales[Quantity] * FactSales[UnitPrice]
)
Binnen de uitdrukking bestaat rijcontext voor de huidige factregel. Tegelijk wordt de tabel FactSales eerst bepaald binnen de geldende filtercontext. Wanneer het rapport is gefilterd op een productgroep, doorloopt SUMX doorgaans alleen de relevante factregels van die selectie. Daardoor ontstaat een combinatie van beide contexten: een tabelselectie op basis van filters en een rijgewijze berekening binnen die selectie.
Dit voorbeeld is geschikt wanneer de orderregelomzet uit Quantity en UnitPrice moet worden berekend. Controleer wel of prijs, kortingen en belastingregels op deze manier zakelijk juist zijn. Een bronsysteem kan eerder afgeronde of gecorrigeerde bedragen bevatten. De eenvoudigste DAX-uitdrukking hoeft dan niet identiek te zijn aan de officiële omzetdefinitie.
CALCULATE beïnvloedt de filtercontext
CALCULATE evalueert een uitdrukking in een aangepaste filtercontext. Een measure kan bijvoorbeeld omzet voor één productkleur berekenen:
Omzet Blauw =
CALCULATE(
[Omzet],
DimProduct[Color] = "Blue"
)
De kleurfilter werkt binnen de beschikbare modelcontext. Zonder extra voorzorg kan een filterargument een bestaande filter op dezelfde kolom vervangen. Dat is van groot belang: in een visual waarin de gebruiker bewust een andere kleur heeft gekozen, kan deze measure alsnog de omzet voor blauw tonen. Wanneer het doel juist is om bestaande filters te behouden en verder te beperken, moet bijvoorbeeld KEEPFILTERS worden overwogen.
Een andere bekende functie is REMOVEFILTERS, die bepaalde filters kan verwijderen om bijvoorbeeld een aandeel van een totaal te berekenen. Dit kan handig zijn voor marktaandeel of procentuele verdeling, maar maakt foutieve KPI’s mogelijk als te veel context wordt weggehaald. Leg altijd vast of het percentage een aandeel van het totaal van alle regio’s, de gekozen regio of de zichtbare selectie moet zijn.
Context transition: van rij naar filter
Een subtiel mechanisme ontstaat wanneer CALCULATE zonder extra filters binnen een bestaande rijcontext wordt gebruikt. DAX kan die rijcontext omzetten naar filtercontext. Dit staat bekend als context transition. In vereenvoudigde termen worden de kenmerken van de huidige rij dan relevant als filters voor de te evalueren uitdrukking. Het exacte resultaat hangt nog steeds af van de overige context en het datamodel.
Het mechanisme komt bijvoorbeeld voor in berekende kolommen en iteratoren die een aggregatie moeten bepalen voor de huidige rij. Een veelvoorkomende verwarring is aannemen dat een gewone rijcontext vanzelf elke SUM-uitdrukking filtert. Een aggregatie kijkt in beginsel naar haar filtercontext. Pas bepaalde expressies, waaronder CALCULATE, beïnvloeden die overgang expliciet. Microsoft documenteert ook dat een verwijzing naar een bestaande modelmeasure in rijcontext automatisch de relevante context transition kan activeren.
Een praktisch denkexperiment: een tabel bevat klanten en voor iedere klant moet historische omzet worden bepaald. Zonder correcte overgang of relatie kan een som het totaal over alle klanten opleveren in plaats van omzet voor de huidige klant. Een expliciete measure met correcte relaties, eventueel in combinatie met CALCULATE binnen de juiste context, kan de bedoelde waarde geven. De beste oplossing is vaak om eerst het stermodel en de gewenste filterrichting te controleren.
Casus: afwijkende omzet per regio en maand
Een organisatie rapporteert omzet per maand en regio. De financiële afdeling signaleert dat het totaalcijfer op een kaart klopt, terwijl de som van de zichtbare regio’s in een matrix afwijkt. De analist vermoedt direct een DAX-fout, maar begint met het model. Er blijkt een reeks factregels zonder geldige regiokoppeling te bestaan. Die transacties zijn wel zichtbaar in het totaal, maar vallen niet onder de verwachte regiogroepen.
De oplossing bestaat niet uit het willekeurig toevoegen van ALL of het verwijderen van filters. Eerst worden ontbrekende sleutels onderzocht en de datakwaliteit gecorrigeerd. Daarna vergelijkt de analist de maat Omzet op totaalniveau, per maand, per regio en per productcategorie. De gebruikte filtercontext wordt voor enkele testgevallen gedocumenteerd. Zo blijkt of verschillen uit modelrelaties, brongegevens of DAX-logica komen.
Een tweede probleem ontstaat wanneer een measure voor vorig jaar REMOVEFILTERS(DimDate) op de volledige datumtabel gebruikt en daarmee meer datumcontext verwijdert dan bedoeld. Ook dan kan de formule een ogenschijnlijk realistisch getal geven. De analytische controle moet de bedoelde vergelijking expliciet maken: dezelfde maanden van het vorige jaar, een volledig vorig jaar of een doorlopend twaalfmaandsvenster zijn verschillende zakelijke vragen.
Fouten herkennen via kleine testtabellen
Maak bij twijfel een tijdelijke tabelvisual met sleutels, relevante dimensies en de betrokken measures. Begin met enkele records waarvan de uitkomst handmatig bekend is. Voeg vervolgens één filter tegelijk toe. Wanneer de waarde onverwacht wijzigt, kan worden nagegaan of de filter via de relatie correct doorwerkt en of CALCULATE bepaalde filters overschrijft.
Test drie categorieën: normale waarden, ontbrekende of afwijkende sleutels en meerdere selecties tegelijk. Controleer ook totalen onderaan een matrix. Een totaalrij is bij DAX niet noodzakelijk de optelsom van alle zichtbare deelresultaten; de measure wordt in de totale context opnieuw geëvalueerd. Bij niet-additieve berekeningen zoals gemiddelden of ratio’s kan dat volledig terecht zijn.
Bij iteratormeasures kan performance een rol spelen. Een correct uitgevoerde SUMX over zeer grote tabellen kan meer rekenwerk vragen dan een som over een al bestaande geschikte kolom. Gebruik performancehulpmiddelen en toets of onderdelen beter vooraf in Power Query of de bron kunnen worden berekend. Optimalisatie hoort na juistheidscontrole te komen, niet ervoor.
Filters en beveiliging uit elkaar houden
Rij- en filtercontext zijn onderdelen van de berekeningslogica; zij vervangen geen beveiliging. Row-level security kan zichtbare gegevens voor bepaalde gebruikers beperken en beïnvloedt daarmee ook de informatie die measures mogen gebruiken. Het toevoegen van een DAX-filter in een visual is geen beveiligingsmaatregel. Controleer RLS afzonderlijk met testaccounts en leg vast welke rol toegang heeft tot welke gegevens.
Houd rekening met de beperkingen van bepaalde DAX-functies in DirectQuery-scenario’s en RLS-regels. Niet iedere techniek uit een geïmporteerd model mag letterlijk worden gekopieerd naar een andere opslagmodus. De actuele Microsoft-documentatie en de concrete modelinstellingen bepalen wat ondersteund wordt.
AI, Copilot en passende opleiding
Copilot of andere AI-assistenten kunnen helpen bij het uitleggen van DAX-expressies en het voorstellen van measures. Toch moet een gegenereerde CALCULATE-formule worden getest op filterrichting, context transition en de zakelijke betekenis van KPI’s. De kernopleiding bij dit onderwerp is Power BI Gevorderd met DAX en datamodellering. AI is een aanvullend hulpmiddel voor het analyseren van foutscenario’s, niet een vervanging voor begrip van evaluatiecontext.
Bekijk de cursus Power BI Gevorderd →Conclusie
Rijcontext maakt de waarden van een huidige rij beschikbaar; filtercontext bepaalt welke gegevens tijdens een berekening meetellen. Iteratoren zoals SUMX combineren beide begrippen, terwijl CALCULATE de filtercontext kan wijzigen en onder bepaalde omstandigheden rijcontext kan omzetten naar filtercontext. Een robuust stermodel en gerichte testtabellen zijn essentieel om DAX-resultaten te verklaren. Bij onverwachte cijfers begint de analyse daarom niet met blind formuleonderhoud, maar met de gegevens, relaties en gewenste zakelijke definitie.