
Quand les choses deviennent bizarres avec les calendriers personnalisés dans les modèles tabulaires
Introduction
Après l’euphorie initiale suscitée par la nouvelle intelligence temporelle basée sur le calendrier, j’ai commencé à approfondir la nouvelle fonctionnalité pour voir ce que ces nouvelles possibilités signifient dans le monde réel.
Vous trouverez plusieurs liens à ce sujet dans la section Références à la fin de cet article, y compris un article SQLBI, qui vous plonge en profondeur dans le sujet.
Je recommande fortement de lire ces articles pour bien comprendre.
Mais au fil du temps, j’ai réalisé qu’il y avait des côtés plus sombres à cette nouvelle fonctionnalité brillante.
Je vais maintenant vous montrer quatre exemples dans lesquels j’ai découvert des effets intéressants.
Je proposerai des solutions de contournement ou des solutions à chaque problème lorsque cela sera possible.
Configuration des calendriers
Pour cet article, j’ai utilisé deux rapports Power BI avec chacun deux tables de dates pour éviter les interférences. Toutes les tables de dates ont la même table source.
Une éventuelle interférence entre les calendriers est décrite ici.
Pour le calendrier grégorien, j’ai utilisé cette configuration :

Pour le calendrier hebdomadaire, j’ai utilisé cette configuration :

Le calendrier hebdomadaire inclut la colonne YearOfWeek pour la catégorie Année.
Cette colonne contient l’année alignée sur la semaine, nécessaire pour un tel calendrier. Cette colonne est basée sur la définition de la semaine ISO. Chaque année commence le lundi de la semaine 1.
Vous pouvez trouver une explication pour la semaine ISO ici.
Les deux modèles de données Power BI utilisaient la même configuration.
Mois précédents et différentes durées de mois
OK, regardons d’abord les mois de différentes durées.
Je décris ce cas pour vous faire prendre conscience des différences avec la logique classique de l’intelligence temporelle.
J’ai créé deux mesures :
Online Sales (PM) =
CALCULATE([Online Sales]
,DATEADD('Date'[Date], -1, MONTH)
)
Et celui-ci utilise le calendrier grégorien :
Online Sales (PY Gregorian) =
CALCULATE([Online Sales]
,DATEADD('Gregorian Calendar', -1, YEAR)
)
J’ai ajouté les deux à un visuel de tableau.
Regardez maintenant les différences entre ces deux mesures pour le mois de mars :

Bien que ce résultat soit très intéressant, regardez celui-ci :

Dans les deux cas, le résultat est très différent.
Alors que la mesure utilisant l’intelligence temporelle classique montre la même valeur pour les trois derniers jours de mars, les résultats de février omettent les derniers jours de janvier.
La mesure basée sur le calendrier fonctionne bien mieux.
Le point crucial ici est que les sommes des lignes sont égales à la somme indiquée dans la ligne Total.
De plus, le DATEAJOUT() La fonction comporte désormais deux paramètres supplémentaires qui affectent les résultats des mois de durée inégale.
Même si ce n’est pas bizarre, il s’agit certainement d’un comportement différent de la fonction, dont vous devez être conscient. Cela s’applique partout où les règles ne sont pas de la même durée. J’y reviendrai plus tard.
Que se passe-t-il avec l’année précédente ?
Vient maintenant la première situation étrange.
Observez le tableau suivant en utilisant une mesure avec un appel DATEADD() utilisant le calendrier grégorien pour PY :

Comme vous pouvez le constater, tout semble bien.
Regardez maintenant les résultats, en comparant 2024 à 2025 :

Comme vous pouvez le constater, les valeurs PY de mars 2025 sont décalées d’un jour.
Ce n’est pas correct.
Pire encore, lorsque l’on compare les valeurs totales des mois, elles sont égales entre 2024 et la mesure PY en 2025.
Cet effet est observable jusqu’en décembre, où les résultats sont les suivants :

C’est le même effet que nous pouvons observer dans la mesure Mois précédent présentée plus tôt, puisque ces deux années n’ont pas la même durée.
Cet effet étrange est dû à la façon dont DAX calcule les résultats en fonction de la hiérarchie du calendrier.
Le mécanisme est appelé « Distance du parent ».
Mais le Parent est défini par le troisième paramètre de DATEADD() : Année
Par conséquent, DATEADD() calcule la distance depuis le début de l’année et renvoie le résultat en utilisant la même distance pour l’année précédente.
Une solution à ce problème consiste à garantir que tous les mois soient de même durée.
Dans mon premier article sur cette nouvelle fonctionnalité, lié dans la section Références ci-dessous, j’ai créé un tableau de dates personnalisé et un calendrier de 31 jours pour tous les mois.
Lorsque vous effectuez la même opération avec ce calendrier, l’effet disparaît :

Bien que cette approche fonctionne parfaitement, elle nécessite un calendrier personnalisé, ce qui peut entraîner d’autres problèmes ou ne pas répondre à des exigences spécifiques. D’autant plus que les colonnes de date ne contiennent pas de dates réelles et que la colonne date_real présente des lacunes. Cela peut entraîner des problèmes lors de son utilisation dans des calculs personnalisés.
Une autre solution est de calculer le PY en reculant de 12 mois :
Online Sales (-12 M Gregorian) =
CALCULATE([Online Sales]
,DATEADD('Gregorian Calendar', -12, MONTH)
)
Et voici les résultats de la nouvelle mesure :

En rouge, vous voyez les mêmes résultats qu’avant, décalés d’un jour.
En vert, vous voyez les résultats de la mesure avec une granularité mensuelle.
Il est intéressant de noter que les sommes pour les trimestres et les années sont également correctes.
Pour le moment, je ne vois aucun problème à utiliser cette approche, et je l’utiliserai et la testerai à l’avenir.
Calculs hebdomadaires – Se gratter la tête
C’est une question très étrange.
Regardez l’image suivante avec le même tableau dans différents états côte à côte :

Sur la gauche, vous voyez que toutes les lignes de 2023 sont identiques lorsque 2022 est réduite.
Sur la droite, vous voyez les valeurs correctes pour 2023, mais elles ne sont affichées que lorsque j’étends au moins une semaine de 2022 jusqu’à la date.
Mais les valeurs en 2022 sont encore une fois les mêmes.
J’en ai déjà fait l’expérience et je l’ai montré dans mon premier article sur la fonctionnalité de calendrier (lien ci-dessous).
Dans ce cas, je l’ai résolu en créant un tableau séparé pour le calendrier hebdomadaire. Mais cette fois, ça n’a pas marché.
J’ai dû reconstruire le modèle de données à partir de zéro, et cela a fonctionné immédiatement :

Comme vous pouvez le constater, les résultats sont corrects.
Si vous regardez attentivement, les résultats PY sont corrects pour obtenir la valeur PY de la même semaine et du même jour de la semaine de l’année précédente.
Je n’ai aucune idée de la différence entre ces deux configurations.
La table Date provient de la même source dans les deux modèles de données et le calendrier est défini à l’aide des mêmes colonnes.
Mais je suis un peu inquiet à ce sujet car je n’en comprends pas la raison et je n’ai pas de solution. Même après avoir examiné le fichier TMDL de cette table, je n’ai rien trouvé qui indique la cause.
J’ai rencontré un tel effet uniquement avec des calculs hebdomadaires.
Mélange hebdomadaire avec logique mensuelle
Un de mes clients souhaite voir un rapport montrant les résultats quotidiens du mois en cours, comparés à la même semaine et au même jour de la semaine de l’année précédente.
Il s’agit d’un mélange du calendrier mensuel (grégorien) et de la logique hebdomadaire.
Comme je le montrerai plus en détail dans le cas suivant, la logique hebdomadaire mappe correctement les semaines et les jours de la semaine à l’année précédente. Cela devrait donc poser un problème.
Mais comme les semaines ne correspondent pas aux mois, je ne peux pas ajouter la catégorie Mois. J’obtiendrai une erreur lors de la validation en essayant d’ajouter la catégorie Mois.
Par conséquent, je ne peux pas utiliser un calcul MTD, car la fonction ne trouvera pas la catégorie recherchée :

Je ne peux pas ajouter un calendrier grégorien à la même table de dates, car le moteur attend la même colonne pour la même catégorie pour tous les calendriers de la même table.
Voir ici pour la déclaration de Microsoft à ce sujet.
Étant donné que j’utilise la colonne YearForWeek pour la catégorie Année, elle ne fonctionnera pas avec la catégorie Mois car elles ne s’alignent pas.
En conséquence, j’ai dû écrire une logique personnalisée pour répondre à toutes les exigences.
Calculs hebdomadaires – C’est intéressant !
Pour terminer sur une note positive, je peux vous montrer quelque chose qui fonctionne très bien.
Vous vous souvenez du problème des mois qui ne sont pas de la même durée et de la façon dont les valeurs PY ont été modifiées ?
Cet effet n’apparaît pas lors de l’exécution de calculs hebdomadaires.

Comme vous pouvez le constater, les résultats sont correctement calculés en fonction de la semaine et des bons jours de la semaine.
Comme prévu, les valeurs ne sont pas mappées aux dates de l’année précédente mais aux jours de la semaine.
C’est ce à quoi je m’attends en observant les résultats par semaine et en semaine.
La raison en est que chaque semaine a la même durée et que la table de dates est conçue pour prendre en charge un tel scénario.
Conclusion
Comme vous pouvez le constater, les résultats sont mitigés.
Lorsque l’on examine les résultats de périodes précédentes de différentes durées (mois ou années), les résultats changent.
Lorsque les périodes sont de même durée (semaines ou calendrier personnalisé), alors tout fonctionne comme prévu.
J’ai été extrêmement surpris et bouleversé lorsque j’ai vu les résultats des années bissextiles.
Mais heureusement, ce problème peut être résolu en comprenant le fonctionnement de la nouvelle logique.
L’autre problème avec lequel j’ai un mauvais pressentiment est le fonctionnement incohérent du calendrier hebdomadaire et du calcul PY.
C’est inquiétant, car il n’est pas toujours aussi simple de reconstruire un modèle de données.
Un autre problème que j’ai est que SQLBI signale des problèmes potentiels lors de l’utilisation de plusieurs calendriers dans la même table de dates dans son article. J’y ai ajouté un lien ci-dessous.
Cela introduira la nécessité de plusieurs tables de dates dans le même modèle de données.
Quelque chose que j’hésite à faire.
J’imagine que cela affecte plusieurs visuels dans un rapport, où ils utilisent la logique de différents calendriers mais avec des catégories différentes.
Cela peut être difficile à résoudre.
Mais nous verrons comment cette fonctionnalité évoluera, car nous sommes encore en Preview.
Références
L’article SQLBI expliquant en détail la fonctionnalité d’intelligence temporelle basée sur le calendrier :
https://www.sqlbi.com/articles/introducing-calendar-based-time-intelligence-in-dax
L’article SQLBI expliquant DATEADD() avec les nouveaux paramètres :
Documentation de Microsoft sur la nouvelle fonctionnalité (l’URL peut changer avec le temps) :
Mon article avec trois cas d’utilisation réels avec les nouveaux calendriers :
Mon deuxième article sur l’intelligence temporelle basée sur le calendrier et la moyenne mobile :
Un article de blog de Chris Webb sur les effets de l’intelligence temporelle basée sur le calendrier :
Définition de l’ISO-Semaine basée sur la norme ISO8601
https://www.calendarz.com/blog/iso-week-numbers-explained-week-1-week-53-and-year-boundaries
Comme dans mes articles précédents, j’utilise l’exemple de jeu de données Contoso. Vous pouvez télécharger gratuitement l’ensemble de données ContosoRetailDW depuis Microsoft. ici.
Les données Contoso peuvent être utilisées librement sous la licence MIT, comme décrit dans ce document. J’ai mis à jour l’ensemble de données pour déplacer les données vers des dates contemporaines et supprimé toutes les tables non nécessaires pour cet exemple.



