2023-02-06
Il y a plein de méthodes pour calculer une moyenne mobile. Dans le cas que j’ai eu à traiter la règle de gestion était la suivante :
Ce calcul permet de comparer des évolutions en effaçant les écarts de valeurs au départ.
Visuellement, on a une première valeur à 100% et les valeurs suivantes qui évoluent par catégorie.
Le résultat du calcul est affiché par période (habituellement mois ou année). Mais il faut également laisser la possibilité à l’utilisateur du rapport de sélectionner la période de départ (l’année où le mois qui sera à 100%).
On prend le cas d’une table de faits Revenus liée à une table de dimension temps Calendrier :
┏━━━━━━━━━┓ ┏━━━━━━━━━━━━┓
┃ Revenus ┣━━━🡺┃ Calendrier ┃
┗━━━━━━━━━┛ ┗━━━━━━━━━━━━┛
Si on filtre le calendrier pour sélectionner la période de référence, le graphique qui affiche la moyenne mobile sera également filtré. Pour éviter ça on peut supprimer le filtrage dans la mesure (ALL('Calendrier')
) et utiliser le champs date de la table de faits. Mais dans ce cas on a plusieurs problèmes :
Il vaudrait donc mieux avoir une table dédiée à la sélection de la période de référence. La dimension Calendrier reste ainsi disponible pour l’affichage des visuels et les calculs des mesures temporelles. Cette nouvelle table peut être une copie à l’identique de la dimension originale, ou une sélection de quelques colonnes.
┏━━━━━━━━━┓ ┏━━━━━━━━━━━━┓
┃ Revenus ┣━━━🡺┃ Calendrier ┃
┗━━━━━━━━━┛ ┗━━━━━━━━━━━━┛
┏━━━━━━━━━━━━━━━┓
┃ Choix période ┃
┗━━━━━━━━━━━━━━━┛
La table n’est pas liée à la table de faits ou aux autres dimensions ; cette table ne sert pas à filtrer les données mais uniquement à connaitre la période de référence. On récupèrera la valeur sélectionnée dans le calcul de la moyenne mobile.
Une fois ce problème de dimension géré, la mesure DAX est assez simple. Il s’agit de récupérer la valeur pour la période de référence, la valeur pour la période en cours, et d’en faire le rapport.
revenu_moyenne_mobile = IF(MAX('Calendrier'[annee]) >= MAX('Choix période'[annee]),
VAR _Vn = SUM(Revenus[revenu])
VAR _V0 = CALCULATE(SUM(Revenus[revenu]), FILTER(ALL('Calendrier'), 'Calendrier'[annee] = MAX('Choix période'[annee])))
RETURN IF(MIN(_Vn, _V0) > 0, DIVIDE(_Vn, _V0))
)
MAX('Calendrier'[annee])
et la période de référence avec MAX('Choix période'[annee])
.MIN(_Vn, _V0) > 0
.