DAX – Contexte d’évaluation (Partie 1)


Toute mesure est évaluée dans un contexte.

 

Le contexte, c’est-à-dire l’ensemble des filtres du rapport (lignes et colonnes d’un TCD, slicers..) pour le contexte de filtres, ou la ligne de la table, pour un contexte de ligne , détermine l’environnement dans lequel s’applique la formule de calcul.

 

Un élément clé à retenir : « Il y a toujours deux contextes qui coexistent : Le contexte de filtres et le contexte de ligne. »

 

Contexte de filtre.

Prenons une mesure simple comme :

Sum(Ventes[Total Ventes HT])

Elle retourne la somme des quantités de toute la table Ventes, en l’absence de filtres:

 

Elle retourne une valeur différente si l’on ajoute un filtre sur l’année dans le rapport :

 

 

Comment cela se produit-il ?

 

Il faut considérer chaque cellule :

Pour déterminer sa valeur, la table Ventes est filtrée comme dans un tableur Excel, pour ne retenir que les lignes concernant l’année 2017 (première ligne du rapport.)

Ensuite, l’expression s’applique sur les valeurs contenues dans la colonne Total Ventes HT (filtrées.)

 

Nous pouvons rajouter autant de filtres que nécessaire, la logique sera toujours la même : la table est filtrée en fonction du contexte d’évaluation de chaque cellule, avant d’appliquer l’expression.

Filtre Année=2018,Mois=Janvier,Site=228

Somme des Ventes HT,dans ce contexte = 7108 €

 

Les totaux de lignes sont calculés de la même manière , seul le filtre de ligne est ôté pour le calcul du total par colonne.

 

Contexte de ligne

 

Le second contexte est le contexte de ligne, c’est celui que l’on retrouve lorsqu’on crée une colonne calculée :

Marge = Ventes[Montant PV]-Ventes[Montant PRMP]

Colonne calculée dans la table de Ventes :

 

Si ce résultat semble logique pour un utilisateur d’Excel, il faut bien comprendre la mécanique utilisée pour retourner le résultat ligne par ligne :

DAX crée un contexte de ligne sur la table Ventes, c’est-à-dire un filtre sur chaque colonne de cette table.

Sur chaque colonne la valeur du filtre est égal à la valeur de la colonne, pour la ligne en cours.

 

La table filtrée ne comprend donc qu’une seule ligne, ce qui permet à la mesure d’utiliser les valeurs des colonnes sans les agréger(car il n’y a qu’une valeur par colonne).

 

Les fonctions d’aggrégation comme SUM,MIN,MAX.. utilisées dans un contexte de ligne ignorent ce contexte, c’est-à-dire par exemple, que la mesure SUM(Total Ventes HT), utilisée dans une colonne calculée, retournera la même valeur dans toutes les lignes : celle de la somme de toutes les lignes de la colonne Total Ventes HT.

 

Le contexte de ligne n’existe pas que dans une colonne calculée, il peut être créé par l’emploi d’une fonction d’ittération dans une mesure (fonctions X.)

 

Par exemple la mesure suivante :

 

Ventes +15% = SUMX(Ventes;Ventes[Total Ventes HT]*1.15)

 

Permet de calculer ligne par ligne, le montant de chaque vente +15 % : DAX va travailler par itération, en créant un contexte de ligne pour chaque ligne de la table, avant d’appliquer le calcul.

 

Comme nous l’avons écrit au début de l’article « Il y a  toujours deux contextes qui coexistent : Le contexte de filtres et le contexte de ligne », cela se vérifie dans cette mesure :

 

SUMX(

Ventes;                                                ->Contexte de filtre

Ventes[Total Ventes HT]*1.15      ->Contexte de filtre + Contexte de ligne

)

N’en déplaise aux puristes, on peut se représenter le déroulement du calcul ainsi :

Filtre de la table (par exemple par un filtre Année dans le rapport)  –>Année = 2017;

Création d’un contexte de ligne sur cette table filtrée sur 2017, et application de la formule ligne par ligne (comme dans une colonne calculée d’une table qui serait préalablement filtrée sur 2017.)

Aggrégation  -> 401 696 €

Le contexte d’origine cohabite avec le nouveau contexte de ligne créé (toujours deux contextes en présence !)

 

Attention cependant : si le contexte d’origine contenait déjà un contexte de ligne, ce dernier sera masqué par la création du nouveau contexte de ligne.

 

C’est le cas par exemple, lorsque dans une colonne calculée nous utiliserons la fonction FILTER.

En effet, FILTER crée systématiquement un contexte de ligne (qu’il soit utilisé dans une mesure ou dans une colonne calculée), or il existe déjà un contexte de ligne dans une colonne calculée !

 

Imaginons créer une colonne calculée dans la table des Ventes, elle-même en relation avec la tables des Articles :

 

 

Cette colonne calculée (dans la table Ventes) doit retourner le nombre d’articles (de la table Articles) dont le prix de vente unitaire serait inférieur à celui indiqué dans la ligne de Vente en cours.

 

Colonne calculée =

COUNTROWS(

FILTER(

Articles;Articles[Prix unit de Vente]<Ventes[Montant PV]

)

)

 

Cette mesure ne retournera pas les bonnes valeurs, car le contexte de ligne d’origine (celui de la colonne calculée permettant de récupérer le code article de la ligne en cours) n’existe plus.

 

Il faudra utiliser la fonction EARLIER qui permet de récupérer le contexte antérieur :

 

Colonne calculée =

COUNTROWS(

FILTER(

Articles;Articles[Prix unit de Vente]<EARLIER(Ventes[Montant PV])

)

)

 

Il est aussi possible de définir une variable permettant de conserver en mémoire la valeur de [Montant PV] pour la ligne en cours.

 

Var Montant = Ventes[Montant PV]

Return

COUNTROWS(

FILTER(

Articles;Articles[Prix unit de Vente]<Montant)

)

)

Voici pour la partie la plus simple…

 

Comprendre le fonctionnement des deux contextes d’évaluation est indispensable pour réaliser des mesures complexes avec DAX.

 

 

Laissez un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *