Business Digital

Maîtriser DAX dans Power BI : CALCULATE et intelligence temporelle

11 min de lecture

DAX est le langage qui transforme un modèle de données en réponses business. Tant qu’on se contente de faire glisser des champs dans des graphiques, on n’utilise qu’une fraction de Power BI. Dès qu’on veut un taux de marge, une part de marché, une croissance d’une année sur l’autre ou un cumul annuel, il faut écrire des mesures. La difficulté de DAX ne vient pas de sa syntaxe, qui ressemble à celle d’Excel, mais d’un concept invisible : le contexte de filtre. Ce tutoriel le démystifie pas à pas.

Ce tutoriel prolonge une série sur Power BI et Microsoft Fabric — le guide de référence Power BI et Microsoft Fabric en donne la vue d’ensemble. Il suppose que vous avez déjà un modèle organisé en schéma en étoile avec une table de dates : c’est la condition pour que l’intelligence temporelle fonctionne.

Prérequis

  • Power BI Desktop avec un modèle comprenant une table de faits (ventes) et une table de dates marquée.
  • Des colonnes numériques à agréger (montant, coût, quantité).
  • Niveau : intermédiaire. Aucune expérience préalable de DAX requise, mais une aisance avec les formules de tableur aide.
  • Temps estimé : 60 à 80 minutes.

Étape 1 — Mesure ou colonne calculée ?

Avant d’écrire la moindre formule, il faut trancher une question qui déroute beaucoup de débutants : faut-il créer une colonne calculée ou une mesure ? La réponse oriente tout le reste. Une colonne calculée s’évalue ligne par ligne au moment de l’actualisation et occupe de la mémoire dans le modèle. Une mesure s’évalue à la volée, au moment de l’affichage, en fonction des filtres actifs, et n’occupe aucune mémoire de stockage.

La règle pratique : utilisez une mesure dès qu’il s’agit d’une agrégation (somme, moyenne, ratio) qui doit réagir aux filtres. Réservez la colonne calculée aux cas où vous avez besoin d’une valeur fixe par ligne pour filtrer, regrouper ou créer une relation. Dans le doute, créez une mesure : c’est presque toujours le bon choix en analyse, et cela garde le modèle léger.

Étape 2 — Écrire sa première mesure

Commençons par la brique de base sur laquelle reposeront toutes les autres. On crée une mesure qui additionne les montants de vente. Dans le volet Données, clic droit sur la table de faits, Nouvelle mesure, puis :

Total Ventes = SUM(Ventes[Montant])

La fonction SUM additionne toutes les valeurs de la colonne Montant qui se trouvent dans le contexte courant. Placez cette mesure dans une carte : vous obtenez le total général. Mais le vrai pouvoir apparaît quand vous la croisez avec une dimension — par produit, par mois — car la même formule renvoie alors un résultat différent dans chaque cellule. C’est là qu’intervient le concept central, le contexte de filtre.

Étape 3 — Comprendre le contexte de filtre

Le contexte de filtre est l’ensemble des filtres qui s’appliquent au moment où une mesure est calculée. Ces filtres viennent de partout : la ligne d’un tableau, la colonne d’une matrice, un segment cliqué, un filtre de page. Quand votre mesure Total Ventes apparaît sur la ligne « Mars » d’un tableau, Power BI restreint d’abord les données au mois de mars, puis exécute la somme. La même mesure, sur la ligne « Avril », somme uniquement avril.

Cette idée est libératrice une fois assimilée : vous n’écrivez pas une formule par mois ou par produit. Vous écrivez une seule mesure, et le contexte se charge de la décliner. La plupart des erreurs DAX des débutants viennent d’une mauvaise compréhension de ce mécanisme — par exemple s’attendre à ce qu’une mesure ignore le filtre de la ligne, alors qu’elle le respecte par défaut. Pour modifier ce comportement, on dispose d’une fonction maîtresse : CALCULATE.

Étape 4 — CALCULATE : modifier le contexte de filtre

CALCULATE est la fonction la plus importante de DAX. Elle évalue une expression dans un contexte de filtre que vous modifiez. Sa structure est simple : le premier argument est l’expression à calculer, les suivants sont des conditions de filtre à appliquer. Imaginons que l’on veuille le total des ventes d’une seule catégorie, indépendamment des filtres de ligne :

Ventes Électronique =
CALCULATE(
    [Total Ventes],
    Produit[Categorie] = "Électronique"
)

Ici, CALCULATE prend la mesure [Total Ventes] et lui ajoute le filtre « catégorie = Électronique ». Le résultat ignore les autres catégories même si la ligne du tableau en désigne une autre. C’est exactement ce mécanisme qui permet de construire des indicateurs comparatifs : ventes d’un segment, d’une zone, d’un statut. Retenez que CALCULATE ne fait pas que filtrer : il remplace ou ajoute des filtres au contexte existant, et c’est ce qui le rend si puissant.

Étape 5 — FILTER et ALL pour calculer des parts

Pour calculer une part — par exemple « quel pourcentage du total chaque produit représente-t-il ? » — il faut un dénominateur qui, lui, ignore le filtre de ligne. La fonction ALL sert précisément à retirer un filtre. Combinée à CALCULATE et à DIVIDE, elle donne un calcul de part robuste :

% du Total =
DIVIDE(
    [Total Ventes],
    CALCULATE([Total Ventes], ALL(Produit))
)

Le numérateur respecte le contexte (les ventes du produit de la ligne), tandis que le dénominateur, grâce à ALL(Produit), calcule le total de tous les produits sans tenir compte du filtre de ligne. Le rapport des deux donne la part de chaque produit. Quand vous avez besoin d’une condition plus fine qu’une simple égalité, FILTER prend le relais : il renvoie une table filtrée que CALCULATE utilise comme contexte, par exemple pour ne garder que les ventes supérieures à un seuil.

Étape 6 — Gagner en lisibilité avec les variables

Dès que les mesures se complexifient, elles deviennent illisibles si l’on imbrique tout sur une seule ligne. Les variables (VAR / RETURN) résolvent ce problème : elles nomment des résultats intermédiaires, ce qui rend la formule lisible et, souvent, plus rapide car chaque variable n’est évaluée qu’une fois.

Taux de Marge =
VAR ChiffreAffaires = [Total Ventes]
VAR Cout = SUM(Ventes[CoutAchat])
VAR Marge = ChiffreAffaires - Cout
RETURN
    DIVIDE(Marge, ChiffreAffaires)

On lit la formule comme un petit programme : on calcule le chiffre d’affaires, puis le coût, puis la marge, et on renvoie enfin le taux. Chaque étape porte un nom parlant. Adoptez cette habitude tôt : une mesure écrite avec des variables se relit six mois plus tard sans effort, là où une formule imbriquée devient un casse-tête. C’est une marque de maturité dans l’écriture DAX.

Étape 7 — Intelligence temporelle : le cumul annuel

L’intelligence temporelle regroupe les fonctions qui manipulent les périodes : cumuls, glissements, comparaisons. Elles exigent toutes une table de dates correctement marquée — c’est pourquoi cette étape de modélisation était un prérequis. Commençons par le cumul depuis le début de l’année, indicateur réclamé par toutes les directions :

CA Cumulé Annuel =
TOTALYTD([Total Ventes], Calendrier[Date])

La fonction TOTALYTD (Year-To-Date) additionne les ventes depuis le 1er janvier jusqu’à la date du contexte courant. Placée dans un graphique en courbe par mois, elle dessine une ligne croissante qui se réinitialise chaque début d’année. Le deuxième argument, Calendrier[Date], indique quelle colonne de dates utiliser : c’est pourquoi le marquage de la table de dates est indispensable. Si le résultat reste vide, c’est presque toujours que la table de dates n’a pas été marquée ou que la relation avec les faits est absente.

Étape 8 — Comparer une période à la précédente

La question « comment se compare ce mois à l’an dernier ? » revient sans cesse. DAX y répond avec des fonctions qui décalent le contexte temporel. On crée d’abord la valeur de la période de référence, puis la croissance.

CA Année Précédente =
CALCULATE(
    [Total Ventes],
    SAMEPERIODLASTYEAR(Calendrier[Date])
)

Croissance Annuelle =
VAR Actuel = [Total Ventes]
VAR Precedent = [CA Année Précédente]
RETURN
    DIVIDE(Actuel - Precedent, Precedent)

SAMEPERIODLASTYEAR décale le contexte d’un an en arrière : sur la ligne « mars 2026 », il renvoie les ventes de mars 2025. La mesure de croissance compare ensuite les deux et renvoie un pourcentage. On utilise à nouveau des variables pour la clarté, et DIVIDE pour gérer proprement le cas où la valeur précédente est nulle. Affichée en pourcentage, cette mesure permet de repérer immédiatement les tendances à la hausse ou à la baisse.

Étape 9 — Réflexes de robustesse

Quelques habitudes distinguent une mesure fragile d’une mesure professionnelle. La première : toujours utiliser DIVIDE plutôt que l’opérateur de division. DIVIDE(a, b) renvoie une valeur vide (ou une valeur de repli que vous précisez) quand le dénominateur est nul, là où une division classique provoque une erreur qui casse tout le visuel.

La deuxième : nommer ses mesures clairement et les regrouper dans une table dédiée, vide de données, qui sert de « table de mesures ». Cela évite que vos indicateurs se perdent au milieu des colonnes. La troisième : tester chaque mesure isolément dans un tableau avant de la combiner, exactement comme on a vérifié le modèle. Une mesure validée seule, puis croisée avec une dimension, révèle vite si le contexte se comporte comme prévu. Ces réflexes vous éviteront l’essentiel des heures de débogage DAX.

Aller plus loin : contexte de ligne et itérateurs

Il existe un second type de contexte, distinct du contexte de filtre : le contexte de ligne. Il apparaît quand une formule parcourt une table ligne par ligne, comme dans une colonne calculée ou dans une fonction dite « itérative ». Comprendre cette distinction évite une confusion classique : pourquoi SUM ne peut pas multiplier deux colonnes entre elles avant d’additionner.

Prenons le cas où le montant n’existe pas en colonne mais doit se calculer comme quantité multipliée par prix unitaire. SUM ne suffit pas, car il additionne une seule colonne. Il faut un itérateur, par exemple SUMX, qui parcourt la table, effectue un calcul sur chaque ligne, puis additionne les résultats :

Total Ventes Calculé =
SUMX(
    Ventes,
    Ventes[Quantite] * Ventes[PrixUnitaire]
)

Sur chaque ligne de la table Ventes, SUMX multiplie la quantité par le prix unitaire — c’est le contexte de ligne qui rend accessible la valeur de chaque colonne pour la ligne courante — puis additionne l’ensemble. Le résultat diffère totalement de SUM(Quantite) * SUM(PrixUnitaire), qui multiplierait les deux totaux et donnerait un chiffre absurde. Les fonctions itératives (SUMX, AVERAGEX, MAXX, etc.) sont la réponse chaque fois qu’un calcul doit se faire avant l’agrégation, ligne par ligne. Elles ouvrent la porte aux mesures les plus expressives de DAX.

Erreurs fréquentes

Erreur Cause Solution
L’intelligence temporelle renvoie du vide Table de dates non marquée Marquer la table de dates et vérifier la relation
Une part ne somme pas à 100 % Dénominateur qui respecte le filtre de ligne Retirer le filtre avec ALL dans le dénominateur
Visuel en erreur sur une division Division par zéro Remplacer l’opérateur par la fonction DIVIDE
Mesure qui ignore un segment attendu CALCULATE écrase le filtre voulu Vérifier l’ordre et la nature des filtres passés à CALCULATE
Modèle qui gonfle en mémoire Colonnes calculées là où des mesures suffiraient Convertir les agrégations en mesures
Formule illisible et lente Tout imbriqué sur une ligne Décomposer avec VAR / RETURN

Tutoriels liés

Références

  • Référence DAX (Microsoft Learn) : CALCULATE, FILTER, ALL, DIVIDE, SUM, SUMX.
  • Documentation « Fonctions d’intelligence temporelle » : TOTALYTD, SAMEPERIODLASTYEAR, DATEADD.
  • Guide « Contexte dans les formules DAX » (Microsoft Learn).

Questions fréquentes

DAX est-il le même langage que les formules Power Query ?
Non. Power Query utilise le langage M pour préparer les données en amont ; DAX calcule des agrégations dans le modèle, au moment de l’affichage. Les deux sont complémentaires et interviennent à des moments différents.

Pourquoi ma mesure change-t-elle selon l’endroit où je la place ?
Parce qu’elle respecte le contexte de filtre de la cellule. C’est le comportement attendu et voulu : une seule mesure se décline automatiquement par ligne, colonne et segment.

CALCULATE est-il vraiment indispensable ?
Oui, dès que vous sortez des agrégations simples. Tout calcul comparatif, toute part, tout indicateur conditionnel passe par CALCULATE. C’est la fonction à maîtriser en priorité.

Faut-il apprendre des dizaines de fonctions ?
Non. Une poignée — SUM, CALCULATE, FILTER, ALL, DIVIDE, TOTALYTD, SAMEPERIODLASTYEAR — couvre déjà l’essentiel des besoins. La maîtrise vient de la compréhension du contexte, pas du nombre de fonctions connues.

Service ITSkillsCenter

Application mobile Android et iOS

Création d'application mobile Android et iOS. À partir de 350 000 FCFA.

Démarrer mon projet
Publicité