The Two DAX Contexts: The Foundation of Everything
Before covering CALCULATE, you need to understand the two evaluation contexts in DAX — this is the concept that confuses developers coming from SQL the most.
The Row Context
The row context exists when DAX iterates over the rows of a table. It is created automatically in calculated columns, or when using iterative functions (SUMX, AVERAGEX, FILTER, etc.).
The Filter Context
The filter context is the set of active filters when a measure is evaluated. It is created by your report visuals (filters, slicers, chart axes) and propagated via model relationships.
Anatomy of CALCULATE
CALCULATE's syntax is simple on the surface:
CALCULATE ( expression, -- Ce qu'on veut calculer [filtre1], -- Modificateurs de filtre (optionnels) [filtre2], ... )
But behind this simplicity lie subtle behaviors. CALCULATE does two things:
- Modifier le contexte de filtre en ajoutant, remplaçant ou supprimant des filtres
- Évaluer l'expression dans ce nouveau contexte de filtre
The ALL, ALLEXCEPT and ALLSELECTED Functions
These three functions are the most commonly used filter modifiers with CALCULATE.
-- Market share: divides by the total across all regions Part Marché % = DIVIDE ( [CA Total], CALCULATE ( [CA Total], ALL ( DIM_REGION ) ) ) -- % of category total only (other filters remain active) % Catégorie = DIVIDE ( [CA Total], CALCULATE ( [CA Total], ALLEXCEPT ( DIM_PRODUIT, DIM_PRODUIT[Catégorie] ) ) ) -- % respecting the user's filters in the report % Sélection = DIVIDE ( [CA Total], CALCULATE ( [CA Total], ALLSELECTED () ) )
Time Intelligence: Temporal Calculations
The DAX Time Intelligence functions are among the most requested in BI. They require a calendar dimension marked as "Date Table" in Power BI.
-- Year-to-date cumulative (YTD) CA YTD = CALCULATE ( [CA Total], DATESYTD ( 'Calendrier'[Date] ) ) -- Same period last year CA Année-1 = CALCULATE ( [CA Total], SAMEPERIODLASTYEAR ( 'Calendrier'[Date] ) ) -- Percentage change vs année précédente Var % YoY = DIVIDE ( [CA Total] - [CA Année-1], [CA Année-1] ) -- Running Total (cumul progressif) CA Running Total = CALCULATE ( [CA Total], FILTER ( ALL ( 'Calendrier'[Date] ), 'Calendrier'[Date] <= MAX ( 'Calendrier'[Date] ) ) )
Variables DAX : rendre le code lisible
Les variables (VAR/RETURN) améliorent considérablement la lisibilité et les performances des mesures complexes. La variable est évaluée une seule fois dans le contexte de filtre où elle est définie.
-- Sans variables (difficile à débuguer) Marge Nette % = DIVIDE ( [CA Total] - [Coût Total] - CALCULATE ( [Frais Fixes], ALL ( DIM_PRODUIT ) ), [CA Total] ) -- Avec variables (clair et maintenable) Marge Nette % = VAR vCA = [CA Total] VAR vCout = [Coût Total] VAR vFrais = CALCULATE ( [Frais Fixes], ALL ( DIM_PRODUIT ) ) VAR vMarge = vCA - vCout - vFrais RETURN DIVIDE ( vMarge, vCA )
Pièges courants à éviter
- Oublier qu'ALL() s'applique à la table entière : si vous voulez supprimer le filtre sur une colonne seulement, utilisez ALL(Table[Colonne]) et non ALL(Table).
- Confondre CALCULATE dans une colonne calculée vs une mesure : dans une colonne calculée, le contexte de ligne influence CALCULATE différemment.
- Les filtres implicites des relations : quand vous filtrez sur DIM_REGION, les filtres se propagent automatiquement Ă FAIT_VENTES via la relation. CALCULATE peut court-circuiter cette propagation.
- KEEPFILTERS vs remplacement : par défaut, les filtres dans CALCULATE remplacent les filtres existants. KEEPFILTERS() change ce comportement pour ajouter au lieu de remplacer.
Optimisation des performances DAX
Utilisez DAX Studio (gratuit) pour analyser les performances de vos mesures. Deux métriques clés :
- Storage Engine (SE) queries : requêtes rapides exécutées par le moteur VertiPaq en mémoire
- Formula Engine (FE) : calculs plus lents effectués en DAX pur — minimisez leur part
Besoin d'un accompagnement BI ?
ANAILYNIS vous accompagne dans la conception, le déploiement et la formation sur vos projets BI — Power BI, Oracle OAS, Data Warehouse.
Contact ANAILYNIS →