C'est le point qui bloque tous les débutants. Les deux s'écrivent en DAX, mais ils ne font pas la même chose :
| Colonne calculée | Mesure | |
|---|---|---|
| Quand | Au chargement / rafraîchissement | À l'affichage, dans chaque visuel |
| Comment | Ligne à ligne, dans la table | Agrégée selon le contexte du visuel |
| Stockage | Stockée, occupe de la mémoire | Non stockée, calculée à la volée |
| Pour quoi | Catégoriser, créer un axe (dimension) | Mesurer, agréger (CA, marge, CAC) |
Créer une tranche d'âge dans SRC_USERS pour pouvoir ensuite répartir le CA par tranche — ça, c'est un axe, donc une colonne :
// Colonne calculée dans SRC_USERS Tranche Age = SWITCH( TRUE(), SRC_USERS[age] < 25, "18-24", SRC_USERS[age] < 35, "25-34", SRC_USERS[age] < 50, "35-49", "50+" )
Bonne pratique dès le départ : dans l'onglet Modélisation, créez une « Nouvelle table » vide nommée _Mesures. Toutes vos mesures y seront rangées, séparées des tables de données. C'est plus propre et plus facile à retrouver.
On commence par les fondations. Ces mesures agrègent les colonnes de la table de faits SRC_ORDER_ITEMS :
CA Réel = SUM(SRC_ORDER_ITEMS[sale_price]) Coût = SUM(SRC_ORDER_ITEMS[cost]) Marge = SUM(SRC_ORDER_ITEMS[margin])
Une mesure peut en réutiliser une autre — c'est même vivement recommandé. Le taux de marge se construit à partir des deux précédentes :
Taux de Marge = DIVIDE([Marge], [CA Réel], 0)
Pourquoi DIVIDE et pas un simple / ? Parce qu'une division par zéro provoque une erreur qui casse le visuel. DIVIDE gère ce cas proprement :
DIVIDE( numérateur, dénominateur, [résultat_si_zéro] ) // Si le dénominateur vaut 0 (ou est vide) : // / → erreur, le visuel casse // DIVIDE → renvoie le 3e argument (ici 0), jamais d'erreur
DIVIDE. Le troisième argument (souvent 0 ou vide) décide quoi afficher quand il n'y a pas de dénominateur. C'est un réflexe de robustesse : un canal sans dépense ne doit pas faire planter tout le tableau.
On enrichit avec les dépenses média (table SRC_MARKETING) et le nombre de clients (table SRC_USERS) :
Spend Mkt = SUM(SRC_MARKETING[spend]) Marge après Mkt = [Marge] - [Spend Mkt] Clients = DISTINCTCOUNT(SRC_USERS[user_id]) CAC = DIVIDE([Spend Mkt], [Clients], 0)
Notez DISTINCTCOUNT pour les clients : on compte des user_id uniques, pas des lignes (rappel du module 4). Et le CAC — coût d'acquisition client — est un simple DIVIDE de la dépense par le nombre de clients. Une mesure de trois lignes qui répond à une vraie question de pilotage marketing.
CALCULATE est la fonction la plus puissante de DAX. Elle évalue une expression en modifiant le contexte de filtre. Autrement dit : « calcule ce KPI, mais comme si tel filtre était appliqué ».
CALCULATE( expression, filtre1, filtre2, ... ) // CA du canal Search uniquement, quel que soit le visuel CA Search = CALCULATE( [CA Réel], SRC_ORDER_ITEMS[traffic_source] = "Search" )
Cas concret et grounded sur TheLook : certaines commandes n'ont pas de canal (traffic_source vide, vu au module 3). Pour isoler ce CA non attribué, on force le contexte avec CALCULATE + ISBLANK :
CA Sans Canal = CALCULATE( [CA Réel], ISBLANK(SRC_ORDER_ITEMS[traffic_source]) )
CALCULATE permet de changer ce filtre à l'intérieur d'une mesure. C'est ce qui rend possibles les comparaisons, les « part du total », les « versus budget » — tout ce qui fait la vraie analyse.
Deux contextes cohabitent en DAX, et les distinguer évite la plupart des confusions :
sale_price - cost sur chaque ligne).CALCULATE vient modifier.Règle pratique : une colonne raisonne « à l'intérieur d'une ligne » ; une mesure raisonne « à l'intérieur d'un contexte de filtre ». C'est pour ça qu'une même logique s'écrit différemment selon qu'on en fait une colonne ou une mesure.
// Correction Taux de Marge = DIVIDE([Marge], [CA Réel], 0)
Lecture attendue : sur le périmètre « Performance par canal » du modèle, la marge totale (≈ 50 196 €) rapportée au CA (≈ 102 794 €) donne un taux de marge global de l'ordre de 48,8 %. Si votre carte affiche 4 880 % ou 0,49, c'est un problème de format (pourcentage vs décimal), pas de calcul — un sanity check à faire systématiquement.
DIVIDE(num, dénom, 0)CALCULATE([Mesure], filtre)DIVIDE([Marge], [CA Réel], 0)DIVIDE([Spend Mkt], [Clients], 0)DISTINCTCOUNT(SRC_USERS[user_id])CALCULATE([CA Réel], ISBLANK(SRC_ORDER_ITEMS[traffic_source]))