Support Formation DAX

Filtres explicites et implicites en DAX

Transition_de_contexte_DAX

L'idée en une phrase

  • Une mesure est toujours évaluée dans un contexte de filtre qui combine deux origines : les filtres posés par le rapport (implicites) et les filtres écrits dans la formule (explicites).
  • Quand les deux portent sur la même colonne, c'est la formule qui gagne : explicites > implicites.
  • ALLSELECTED et ALLEXCEPT servent à choisir finement quels filtres du rapport on garde et lesquels on supprime.
  • Source (Microsoft Learn)

Filtres implicites

  • Ils viennent du rapport, sans être écrits dans la formule :
    • les segments ;
    • le volet Filtres (filtres sur ce visuel, sur cette page, sur toutes les pages) ;
    • les lignes, colonnes et axes de la vignette (chaque cellule d'un tableau est un filtre) ;
    • le filtrage croisé provenant des autres visuels, l'extraction (drillthrough), l'exploration.
  • Ils changent dès que l'utilisateur clique : la même mesure affiche donc un résultat différent selon l'endroit où elle est posée.
  • Source (Microsoft Learn)

Filtres explicites

  • Ils sont introduits par des arguments de fonctions DAX, principalement les arguments de filtre de CALCULATE et CALCULATETABLE :
    • un prédicat : Ventes[Région] = "Ouest" ;
    • une table : FILTER ( ... ), VALUES ( ... ) ;
    • un modificateur : ALL, REMOVEFILTERS, ALLSELECTED, ALLEXCEPT, KEEPFILTERS, USERELATIONSHIP.
  • Ils sont fixes : ils ne dépendent pas des clics de l'utilisateur.
  • Source (Microsoft Learn)

Le jeu de données d'exemple

Table Ventes

RégionClientMontant
OuestAlice100
OuestBruno200
EstChloé300
EstDavid400
  • Total général : 1 000.
  • Mesure de base :
Total Ventes = SUM ( Ventes[Montant] )

Ordre de résolution : explicites > implicites

Ventes Ouest = CALCULATE ( [Total Ventes], Ventes[Région] = "Ouest" )
Ventes Ouest (KEEPFILTERS) = CALCULATE ( [Total Ventes], KEEPFILTERS ( Ventes[Région] = "Ouest" ) )
Vignette par RégionTotal VentesVentes OuestVentes Ouest (KEEPFILTERS)
Ouest300300300
Est700300(vide)
Total1 000300300
Vignette par ClientTotal VentesVentes Ouest
Alice100100
Bruno200200
Chloé300(vide)
David400(vide)
  • Même colonne (Région dans la vignette, Région dans la formule) : le filtre explicite remplace le filtre implicite. La ligne Est affiche 300, les ventes de l'Ouest.
  • Colonnes différentes (Client dans la vignette, Région dans la formule) : les deux filtres s'additionnent (intersection). Chloé et David sont dans l'Est, donc vides.
  • KEEPFILTERS : le filtre explicite s'ajoute au filtre existant au lieu de le remplacer. La ligne Est devient vide.
  • Même effet avec un segment : si l'utilisateur choisit Région = Est, une carte [Ventes Ouest] affiche toujours 300.
  • Source (SQLBI)
  • Source (Microsoft Learn)

ALLSELECTED

ALLSELECTED ( [<tableName> | <columnName> [, <columnName> [, <columnName> [, … ] ] ] ] )
  • Supprime les filtres « internes » : ceux qui viennent de l'intérieur de la vignette (lignes, colonnes, axes).
  • Conserve les filtres « externes » : segments, volet Filtres, filtrage croisé par d'autres visuels.
  • Résultat : le total visible dans la vignette, celui que l'utilisateur voit en bas du tableau.
  • Utilisation typique : comme modificateur dans CALCULATE, pour un pourcentage du total affiché.
  • Sans argument, ALLSELECTED () agit sur tout le modèle.
  • Source (Microsoft Learn)

Exemple : segment Client sur Alice, Bruno et Chloé (David exclu)

% du total général = DIVIDE ( [Total Ventes], CALCULATE ( [Total Ventes], ALL ( Ventes ) ) )
% du total visible = DIVIDE ( [Total Ventes], CALCULATE ( [Total Ventes], ALLSELECTED ( Ventes ) ) )
ClientTotal Ventes% du total général (ALL)% du total visible (ALLSELECTED)
Alice10010,0 %16,7 %
Bruno20020,0 %33,3 %
Chloé30030,0 %50,0 %
Total60060,0 %100,0 %
  • ALL ignore aussi le segment : le dénominateur vaut 1 000.
  • ALLSELECTED respecte le segment : le dénominateur vaut 600, le total affiché.
  • Prudence : éviter ALLSELECTED à l'intérieur d'un itérateur (SUMX, FILTER...), son résultat y devient difficile à prévoir. Calculer d'abord le total dans une variable.
  • Source (SQLBI)

ALLEXCEPT

ALLEXCEPT ( <table>, <column> [, <column> [, … ] ] )
  • Supprime tous les filtres appliqués à la table, quelle que soit leur origine (vignette, segment, volet Filtres).
  • Conserve le filtre sur la ou les colonnes indiquées, s'il existe dans le contexte (dans la vignette ou dans un segment).
  • Si la colonne indiquée n'est pas filtrée, il n'y a rien à conserver : on obtient le total général.
  • Source (Microsoft Learn)

Exemple : part de chaque client dans sa région

Total Région = CALCULATE ( [Total Ventes], ALLEXCEPT ( Ventes, Ventes[Région] ) )
% dans la région = DIVIDE ( [Total Ventes], [Total Région] )
RégionClientTotal VentesTotal Région% dans la région
OuestAlice10030033,3 %
OuestBruno20030066,7 %
EstChloé30070042,9 %
EstDavid40070057,1 %
Total1 0001 000100,0 %
  • Le filtre Client de la vignette est supprimé, le filtre Région est conservé.
  • Piège : si la vignette n'affiche que le Client (sans la Région), Total Région vaut 1 000 sur chaque ligne, car aucun filtre Région n'est présent.
  • Variante robuste, qui retrouve la région même quand elle n'est pas dans la vignette :
Total Région (robuste) =
CALCULATE ( [Total Ventes], REMOVEFILTERS ( Ventes ), VALUES ( Ventes[Région] ) )

Comparatif ALL, ALLSELECTED, ALLEXCEPT

FonctionFiltres de la vignetteSegments et volet FiltresUsage type
ALL ( Table )SupprimésSupprimés% du total général
ALLSELECTED ( Table )SupprimésConservés% du total visible
ALLEXCEPT ( Table, Colonne )Supprimés, sauf la colonneSupprimés, sauf la colonne% dans un groupe (région, catégorie)

Formulation à retenir pour les stagiaires

  • « Le rapport filtre (implicite), la formule filtre aussi (explicite). Sur une même colonne, la formule a le dernier mot. »
  • « ALLSELECTED : j'oublie la vignette, je garde les segments. »
  • « ALLEXCEPT : j'oublie tout sur la table, sauf la colonne que je nomme. »
  • Réflexe de vérification : se demander « quels filtres arrivent du rapport, et lesquels ma formule remplace-t-elle ? ».

Pense bête!

ALLSELECTED([<tableName> | <columnName>[, <columnName>[, <columnName>[,…]]]] )

  • Supprime les filtres “internes” (donc à l’intérieur de la vignette)

et

  • Applique des filtres “externes” (segments...).

ALLEXCEPT(<table>,<column>[,<column>[,…]])

  • Supprime tous les filtres appliqués à la table.

ET

  • Conserve le filtre sur la colonne indiquée si présent dans la vignette.