

- Description
- Touches numérotées d'une calculatrice mécanique de bureau, sous son capot transparent.
- Source
- stiefkind · page d’origine
- Licence
- CC0 Domaine public
Mesures et calculs DAX
Ce thème mesure la qualité du code de calcul : mesures plutôt que colonnes, maîtrise du contexte de filtre et du contexte de ligne, transition de contexte (CALCULATE), variables, time…
En bref
Ce thème mesure la qualité du code de calcul : mesures plutôt que colonnes, maîtrise du contexte de filtre et du contexte de ligne, transition de contexte (CALCULATE), variables, time intelligence, mesures de base réutilisées, groupes de calcul, conventions de nommage et de formatage, stabilité des identifiants (lineage) pour ne pas casser les rapports clients. Les tests de ces mesures sont dans TST.
Niveau : 🟢→🔴 · Code thème : DAX
1. Pourquoi ce thème#
Les mesures sont la logique métier du rapport. Une règle (« visite réalisée », « client actif », « distribution numérique ») recopiée dans vingt mesures divergera. Le DAX a deux moteurs (formules et stockage) et deux contextes ; des erreurs classiques (itérer une table entière dans FILTER, oublier la transition de contexte) donnent des chiffres faux ou lents sans erreur visible. Coût de l'ignorer : des chiffres contradictoires entre pages, la peur de toucher aux mesures, des rapports clients cassés au renommage.
2. Ce que mesure le thème#
- Axe : de la colonne calculée improvisée à une bibliothèque de mesures lisible, testée, versionnée et stable.
- Indicateurs clés : part de mesures s'appuyant sur des mesures de base ; nombre de règles métier définies en plusieurs endroits ; part de mesures documentées ; nombre de mesures renommées/supprimées ayant cassé un rapport.
- Unités : %, nombre.
3. Les 5 niveaux#
| Niveau | Nom court | Promesse | Indicateur type (ordre de grandeur) |
|---|---|---|---|
| 1 | Colonnes et copier-coller | Le chiffre attendu sort pour la vue prévue, et seulement elle. | Colonnes calculées partout ; mesures implicites |
| 2 | Mesures nommées | Chaque chiffre affiché vient d'une mesure explicite, nommée et formatée. | 0 mesure implicite dans les rapports |
| 3 | Maîtrisé | Un chiffre garde le même sens quel que soit le visuel, le filtre ou la période. | Mesures de base + variables ; time intelligence correcte |
| 4 | Réutilisable | Une règle métier n'existe qu'une fois, et une nouvelle déclinaison s'ajoute en minutes. | 1 règle = 1 définition ; groupes de calcul |
| 5 | Bibliothèque | Le calcul est un produit : testé, versionné, documenté, et sa modification ne casse aucun consommateur. | 0 rapport cassé par modification de mesure en 12 mois |
4. Jalons par niveau#
| ID | Jalon | Preuve vérifiable |
|---|---|---|
| BI-DAX-1.1 | Les chiffres principaux sont calculés dans le modèle (pas à la main dans Excel) | Valeur recalculable |
| BI-DAX-1.2 | Les résultats sont comparés une fois à la source | Contrôle ponctuel consigné |
| BI-DAX-1.3 | Les colonnes calculées sont connues et inventoriées | Liste des colonnes calculées |
| BI-DAX-2.1 | Aucune « agrégation implicite » : les colonnes numériques sont en Ne pas résumer |
Résumé = aucun sur les colonnes |
| BI-DAX-2.2 | Mesures nommées par convention (Verbe/Nom + unité éventuelle) et formatées | Revue de nommage |
| BI-DAX-2.3 | Mesures rangées en dossiers d'affichage | Structure des dossiers |
| BI-DAX-2.4 | Pas de division sans protection (DIVIDE) |
Revue des / dans le code |
| BI-DAX-3.1 | Mesures de base (somme, comptage) distinctes des mesures dérivées | Arbre de dépendances des mesures |
| BI-DAX-3.2 | Usage de VAR/RETURN pour lisibilité et performance |
Revue de code |
| BI-DAX-3.3 | Time intelligence sur table de dates marquée (DATESYTD, SAMEPERIODLASTYEAR, DATEADD) |
Résultats vérifiés sur années bissextiles et années incomplètes |
| BI-DAX-3.4 | Filtres CALCULATE exprimés en prédicats de colonne, pas en FILTER(TABLE…) sans nécessité |
Revue de performance |
| BI-DAX-3.5 | La transition de contexte est comprise et documentée là où elle apparaît (mesure dans un itérateur) | Commentaires et cas de test |
| BI-DAX-4.1 | Chaque règle métier (« visite réalisée ») définie une fois, réutilisée par référence | Aucune duplication détectée |
| BI-DAX-4.2 | Groupes de calcul pour les déclinaisons transversales (période, devise, écart) | Table de calcul dans le modèle |
| BI-DAX-4.3 | Nomenclature de déclinaisons (base / cumul / N-1 / %) systématique | Table des suffixes |
| BI-DAX-4.4 | Mesures commentées : intention, hypothèses, exceptions | Description de la mesure renseignée |
| BI-DAX-4.5 | Mesures cachées (internes) séparées des mesures publiées | Visibilité gérée |
| BI-DAX-5.1 | Les mesures sont testées (requêtes de référence) et versionnées (TMDL) | Dépôt + tests (TST) |
| BI-DAX-5.2 | Une mesure publiée n'est jamais supprimée/recréée ; elle est modifiée en place (lineageTag conservé) | Historique du dépôt |
| BI-DAX-5.3 | Politique de dépréciation (marquage, délai, communication) pour les mesures retirées | Journal de dépréciations |
| BI-DAX-5.4 | Bibliothèque de mesures réutilisable entre modèles (ex. outil de script TMDL) | Dépôt partagé |
5. Lecture détaillée par niveau#
🟢 Niveau 1 — Colonnes et copier-coller#
- Signes : colonnes calculées pour tout (
=[Quantité]*[Prix]), mesures implicites créées par glisser-déposer, valeurs qui varient selon le visuel. - Ce qu'on comprend à ce stade : une colonne calculée est évaluée au chargement, stockée en mémoire, dans un contexte de ligne ; une mesure est évaluée à l'affichage, dans le contexte de filtre du visuel. Les colonnes consomment de la mémoire et ne réagissent pas aux filtres.
- Difficulté : 1/5 · Effort : 1/5.
🟢 Niveau 2 — Mesures nommées#
Nb Visites = COUNTROWS ( 'FACT_VISITE' )
Taux Réalisation =
DIVIDE ( [Nb Visites Réalisées], [Nb Visites Planifiées] )
- Signes : agrégation implicite désactivée, noms parlants, formats posés,
DIVIDEsystématique. - Gain : lisibilité, cohérence d'affichage.
- Limite : les règles sont encore dupliquées ; le time intelligence est souvent approximatif.
- Difficulté : 2/5 · Effort : 2/5.
🟡 Niveau 3 — Maîtrisé#
Compréhension du contexte :
-- Mesures de base
Nb Visites Réalisées =
CALCULATE ( [Nb Visites], 'FACT_VISITE'[Statut] = "Réalisée" )
-- Time intelligence : exige une table de dates continue et marquée
Nb Visites N-1 =
CALCULATE ( [Nb Visites Réalisées], SAMEPERIODLASTYEAR ( 'DIM_DATE'[Date] ) )
Évolution N-1 % =
VAR vCourant = [Nb Visites Réalisées]
VAR vPrec = [Nb Visites N-1]
RETURN DIVIDE ( vCourant - vPrec, vPrec )
- Transition de contexte : une mesure appelée dans un itérateur (
SUMX) embarque unCALCULATEimplicite qui convertit le contexte de ligne en contexte de filtre. Source d'erreurs et de coût :SUMX(Clients, [Mesure])évalue la mesure autant de fois que de clients. - Filtre en prédicat :
CALCULATE(..., 'T'[Col] = x)est replié en filtre sur colonne (efficace) ;FILTER('T', …)itère la table (coûteux). - Gain : mêmes chiffres quel que soit le visuel.
- Limite : chaque nouvelle déclinaison demande encore du code.
- Difficulté : 3/5 · Effort : 3/5.
Symptôme : « N-1 » vide ou faux en début de période. Cause : table de dates qui ne couvre pas l'année précédente, ou non marquée. Remède : calendrier continu sur toute la plage + horizon ; tester les bornes (1er janvier, 29 février).
Symptôme : une mesure « Total » plus petite que la somme des lignes. Cause : calcul non additif (moyennes, comptages distincts) ou filtre de total perdu. Remède : définir explicitement le comportement au total (HASONEVALUE, ISINSCOPE) et le tester.
🟡 Niveau 4 — Réutilisable#
- Signes : une règle métier = une mesure de base. Les déclinaisons (YTD, N-1, % de) passent par des groupes de calcul :
-- Élément de calcul « Période » : N-1
CALCULATE ( SELECTEDMEASURE (), SAMEPERIODLASTYEAR ( 'DIM_DATE'[Date] ) )
Un groupe de calcul remplace des dizaines de mesures dupliquées, mais il impose des précautions : précédence entre groupes, SELECTEDMEASURENAME() pour traiter les pourcentages différemment, formats dynamiques, et vérification que les mesures déjà publiées gardent leurs résultats.
- Gain : cohérence, ajout d'une déclinaison en minutes.
- Limite : difficile à déboguer sans méthode ; les rapports clients existants doivent rester compatibles.
- Difficulté : 4/5 · Effort : 4/5.
Fil rouge SFA : la règle « client actif = au moins une visite réalisée sur 90 jours glissants » est définie dans [Clients Actifs] ; toutes les mesures « par client actif » la référencent. Quand la règle passe à 120 jours, on modifie une mesure.
🔴 Niveau 5 — Bibliothèque#
- Signes : les mesures sont dans un dépôt (TMDL), testées par requêtes de référence, documentées, et jamais supprimées-recréées : renommer ou supprimer une mesure fait perdre son lineageTag et casse les rapports liés. Une mesure obsolète est marquée, déplacée, communiquée, retirée après un délai.
- Gain : le calcul est un produit stable ; le coût de changement est prévisible.
- Limite : discipline de revue indispensable.
- Difficulté : 5/5 · Effort : 5/5.
-- Test de mesure (DAX query, exécutable dans DAX Studio ou SSMS)
EVALUATE
ROW (
"Attendu", 12345,
"Calculé", [Nb Visites Réalisées],
"Écart", [Nb Visites Réalisées] - 12345
)
Écris le DAX pour être lu, pas seulement exécuté : VAR nommées vXxx, un CALCULATE par intention, des commentaires // sur les exceptions. Formate avec un outil dédié (DAX Formatter) et conserve le formatage dans le dépôt.
DEFINE MEASURE dans une requête DAX permet de prototyper une mesure sans toucher au modèle, comparer deux variantes et mesurer leurs timings (Server Timings) avant de les intégrer.
Les assistants écrivent bien des mesures courantes et expliquent un CALCULATE ; ils se trompent sur les contextes (sortie plausible, résultat faux), sur les relations inactives et sur les totaux. Toujours valider par requête de test avec un attendu connu.
6. Atteinte partielle et notation#
Règle commune. Chaque jalon DAX s'évalue par échantillon : tirer 10 mesures au hasard et compter celles qui respectent le jalon (≥ 8/10 → 1 ; 5 à 7 → 0,5 ; < 5 → 0). « Un 5 partiel » : les tests couvrent les 30 mesures les plus utilisées sur 220 (BI-DAX-5.1 = 0,5), la règle « jamais supprimer-recréer » est respectée depuis 6 mois (5.2 = 1), pas de politique de dépréciation (5.3 = 0).
7. Passer au niveau suivant#
Moyens possibles (facultatifs) :
| Passage | Leviers possibles |
|---|---|
| 1 → 2 | Désactiver l'agrégation implicite ; convention de nommage ; DIVIDE |
| 2 → 3 | Mesures de base ; variables ; calendrier marqué ; lecture de plans (DAX Studio) |
| 3 → 4 | Inventaire des règles ; groupes de calcul ; nomenclature de déclinaisons |
| 4 → 5 | Dépôt TMDL, tests de référence, politique de dépréciation, scripts de génération |
Pièges :
- Goodhart : « 100 % de mesures documentées » → descriptions vides de sens (« Mesure du nombre »).
- Réécrire toutes les mesures « pour faire propre » : on perd le lineageTag, on casse les rapports clients.
- Groupe de calcul activé trop tôt : effets de bord sur toutes les mesures du modèle, y compris celles qui ne le prévoient pas.
- Faux positif : une mesure rapide et fausse ; la vitesse n'est pas la justesse.
8. Voir aussi#
- Thèmes voisins : MOD · TST · PRF · IND · ACC (noms traduits)
- Autres matrices : DL — qualité du code · DL — tests
- Contenus : Bonnes pratiques Power BI transverses · SQL Server SaaS — IA · OneLake — IA · GDS et données SQL/BI
✻ Rédigé par Claude Sonnet 5.5