Je le date avec les fonctions DAX INFO et leur colonne ModifiedTime. C’est simple, mais il faut savoir quoi interroger, où exécuter la requête, et surtout comment lire les résultats sans se faire piéger par les changements de métadonnées.
Où trouver la date de modification ?
La date de modification se trouve dans la colonne ModifiedTime, exposée par certaines fonctions DAX INFO, par exemple INFO.MEASURES(). Je m’en sers surtout dans un cas très terrain : une petite modification du modèle sémantique Power BI déclenche une régression de performance, et il faut retrouver vite ce qui a bougé.
La requête peut être lancée depuis plusieurs endroits, selon votre façon de travailler :
- Depuis la vue de requête DAX dans Power BI Desktop.
- Depuis le Service Power BI, si vous avez accès aux requêtes DAX sur le modèle.
- Depuis DAX Studio, qui reste souvent mon réflexe quand je veux auditer proprement un modèle.
Le point important, c’est d’utiliser INFO.MEASURES(), pas INFO.VIEW.MEASURES(). La version INFO.VIEW est plus orientée affichage lisible, mais ici je veux accéder aux métadonnées brutes, notamment ModifiedTime. C’est cette colonne qui m’intéresse.
-- Retourne le résultat de la requête
EVALUATE
-- Garde uniquement les colonnes utiles pour l’audit
SELECTCOLUMNS(
-- Lit les métadonnées des mesures du modèle
INFO.MEASURES(),
-- Ajoute une colonne fixe pour savoir que l’objet est une mesure
"ObjectType", "Measure",
-- Récupère le nom de la mesure
"ObjectName", [Name],
-- Récupère la date de dernière modification
"ModifiedTime", [ModifiedTime]
)
-- Trie les mesures modifiées le plus récemment en premier
ORDER BY [ModifiedTime] DESCLe tri descendant sur ModifiedTime permet de voir en haut les mesures modifiées le plus récemment. C’est souvent suffisant pour faire le lien entre “ça marchait hier” et “quelqu’un a touché à cette mesure ce matin”.
Je ne vends pas ça comme un historique Git complet. Ça ne remplace pas une vraie stratégie de versioning avec PBIP, Git ou un process de déploiement propre. C’est plutôt un audit rapide, très utile quand on doit comprendre vite, sans fouiller tout le modèle à la main.
Comment auditer tout le modèle ?
Je ne regarde pas seulement les mesures. C’est souvent là qu’on commence, mais dans un vrai modèle Power BI, les changements importants peuvent aussi venir des colonnes calculées, des groupes de calcul, ou des éléments de calcul. Donc j’agrège les objets importants du modèle pour obtenir une vue chronologique des changements.
L’idée est simple : je construis une requête DAX qui appelle plusieurs fonctions INFO, puis je standardise la sortie avec les mêmes colonnes partout : ObjectType, ObjectName, ModifiedTime. Comme ça, je peux tout empiler proprement et trier par date de modification.
DEFINE
-- Chaque bloc récupère une famille d'objets du modèle
VAR Measures =
SELECTCOLUMNS(
INFO.MEASURES(),
"ObjectType", "Measure",
"ObjectName", [Name],
"ModifiedTime", [ModifiedTime]
)
VAR CalculatedColumns =
SELECTCOLUMNS(
FILTER(
INFO.COLUMNS(),
NOT ISBLANK([Expression])
),
"ObjectType", "Calculated column",
"ObjectName", [ExplicitName],
"ModifiedTime", [ModifiedTime]
)
VAR CalculationGroups =
SELECTCOLUMNS(
INFO.CALCULATIONGROUPS(),
"ObjectType", "Calculation group",
"ObjectName", [Name],
"ModifiedTime", [ModifiedTime]
)
VAR CalculationItems =
SELECTCOLUMNS(
INFO.CALCULATIONITEMS(),
"ObjectType", "Calculation item",
"ObjectName", [Name],
"ModifiedTime", [ModifiedTime]
)
EVALUATE
UNION(
Measures,
CalculatedColumns,
CalculationGroups,
CalculationItems
)
ORDER BY
[ModifiedTime] DESCChaque bloc récupère une famille d’objets. SELECTCOLUMNS sert à renommer les colonnes pour obtenir une structure identique partout. UNION consolide tout dans une seule table. ORDER BY met les modifications les plus récentes en haut, ce qui est exactement ce que je veux quand je cherche à comprendre ce qui a bougé.

Petit point important, et je l’ai vu chez plusieurs clients : selon l’ancienneté du modèle, le niveau de compatibilité, ou la version de Power BI Desktop, certaines fonctions INFO ou certaines colonnes comme ModifiedTime peuvent ne pas être disponibles. Dans ce cas, je ne jette pas toute la méthode. Je commente juste le bloc qui plante, je relance la requête, puis j’avance objet par objet.
| Objet | Ce que je regarde |
| Mesures | Les changements de logique métier DAX |
| Colonnes calculées | Les calculs stockés dans le modèle |
| Groupes de calcul | Les structures qui modifient plusieurs mesures |
| Éléments de calcul | Les variantes appliquées dans les groupes de calcul |
| ModifiedTime | La date qui permet de reconstituer la chronologie |
Pourquoi les dates peuvent surprendre ?
ModifiedTime donne une information utile, oui. Mais ce n’est pas toujours une vérité métier évidente. Je le prends comme un signal, pas comme une preuve absolue. Sinon on peut vite raconter une mauvaise histoire à partir d’une bonne donnée.
Premier piège que je vois souvent : la requête d’audit elle-même peut tomber en erreur sur certains modèles. Surtout les modèles anciens, ou ceux avec un niveau de compatibilité plus bas. Le niveau de compatibilité, c’est la “version technique” du modèle tabulaire, celle qui détermine quelles fonctionnalités sont disponibles. Si la requête touche des objets récents, par exemple des fonctions DAX modernes comme les UDF, pour User Defined Functions, donc des fonctions personnalisées réutilisables en DAX, ça peut casser. Dans ce cas, je ne force pas. Je commente les sections concernées, je relance, et je récupère déjà ce qui est exploitable.


Deuxième point, certaines actions indirectes modifient des métadonnées auxquelles on ne pense pas. Exemple simple : vous ajoutez un groupe de calcul. Un groupe de calcul sert à centraliser une logique, par exemple “YTD”, “MTD”, “Variation N-1”, sans réécrire 40 mesures. Cette action peut déclencher une modification de propriété comme discourage implicit measures. En gros, Power BI décourage alors les mesures implicites, celles créées automatiquement quand on glisse une colonne numérique dans un visuel. Résultat : une date de modification apparaît, mais ça ne veut pas dire qu’une mesure métier a été réécrite à la main.
Troisième limite : ModifiedTime ne dit pas qui a changé quoi, ni pourquoi, ni la différence exacte entre deux versions. Il ne remplace pas un historique Git, un diff de modèle, ou un vrai journal d’audit. Chez un client, je commence souvent par trier les objets modifiés récemment avant de regarder les plans de requête. Franchement, ça évite de chercher au mauvais endroit pendant deux heures.
- Ne Pas conclure trop vite : une date récente peut venir d’un changement indirect.
- Vérifier le niveau de compatibilité : certains objets récents peuvent faire échouer la requête.
- Commenter les blocs qui cassent : mieux vaut une analyse partielle fiable qu’une requête inutilisable.
- Croiser avec d’autres sources : historique de déploiement, Git, pipeline, logs Power BI.
- Utiliser ModifiedTime comme un signal : c’est un point de départ pour diagnostiquer, pas une conclusion.
Comment relier ça aux performances ?
Le vrai intérêt, ce n’est pas juste de savoir qu’un objet a changé. C’est de croiser les objets récemment modifiés avec les objets réellement utilisés par une requête lente. Là, on commence à avoir quelque chose d’exploitable.

Si une mesure, une colonne calculée ou un groupe de calcul apparaît dans une requête DAX qui performait bien avant, et que son ModifiedTime est récent, je tiens une piste sérieuse. DAX, c’est le langage de calcul de Power BI. ModifiedTime, c’est la date de dernière modification exposée dans les métadonnées du modèle. Ce n’est pas une preuve, mais franchement, c’est rarement un hasard à ignorer.
La méthode reste simple. Je récupère les objets modifiés récemment avec les fonctions INFO, qui permettent d’interroger les métadonnées du modèle sémantique. Je récupère ensuite la liste des objets utilisés par la requête DAX que je veux analyser. Puis je compare les deux listes. Les objets communs passent en haut de la pile.
- Je regarde les mesures récemment modifiées.
- Je vérifie les colonnes calculées touchées récemment.
- Je surveille les groupes de calcul, parce qu’ils peuvent modifier le comportement de plusieurs mesures d’un coup.
- Je priorise ce qui est à la fois récent et présent dans la requête lente.
Un exemple très concret. Une mesure a été modifiée hier. Elle est utilisée dans un visuel qui était fluide la semaine dernière et qui devient lent ce matin. Je vais auditer cette mesure avant de revoir tout le modèle, les relations, les agrégations ou la capacité Power BI. J’ai vu ce cas chez un client, une petite modification dans une mesure de marge avait ajouté un filtre coûteux dans un CALCULATE. Rien de spectaculaire dans le code, mais assez pour plomber une page entière.
Je ne m’arrête pas à la date. Je vérifie ensuite l’expression DAX, les dépendances, les groupes de calcul éventuels et les effets de bord. Une mesure peut sembler innocente, mais appeler trois autres mesures plus lourdes derrière.
| Signal observé | Interprétation possible | Action utile |
| Objet modifié récemment et présent dans la requête lente | Piste prioritaire pour expliquer la régression | Auditer l’expression DAX et ses dépendances |
| Groupe de calcul modifié récemment | Impact possible sur plusieurs mesures à la fois | Tester les mesures affectées avec et sans le groupe |
| Aucun objet récent dans la requête | La cause est peut-être ailleurs | Passer au diagnostic classique : modèle, cardinalité, requête, capacité |
Cette approche ne remplace pas un diagnostic performance complet. Elle donne surtout un point de départ propre et rapide, au lieu de chercher partout dès les premières minutes.
On surveille quoi maintenant ?
Je retiens surtout un truc : ModifiedTime donne enfin un moyen simple de dater les changements dans un modèle sémantique Power BI. Avec les fonctions DAX INFO, je peux lister les mesures, colonnes calculées, groupes de calcul et autres objets utiles, puis trier tout ça par modification récente. Il faut juste garder la tête froide : certaines fonctions peuvent planter sur d’anciens modèles, et certaines dates viennent de changements indirects de métadonnées. Le vrai gain arrive quand je croise ces dates avec les objets utilisés par une requête lente. Vous gagnez du temps, vous ciblez mieux l’analyse, et vous évitez de démonter tout le modèle pour rien.
FAQ
- Comment savoir quand une mesure Power BI a été modifiée ?
J’utilise la fonction DAX INFO.MEASURES() et je récupère la colonne ModifiedTime. En triant les résultats par date décroissante, je vois rapidement les mesures modifiées en dernier. - Où exécuter une requête DAX INFO ?
Je peux l’exécuter dans la vue de requête DAX de Power BI Desktop, dans le Service Power BI, ou dans DAX Studio. Le plus important est d’interroger les bonnes fonctions INFO pour accéder aux métadonnées du modèle. - Pourquoi ne pas utiliser INFO.VIEW.MEASURES() ?
Pour cet audit précis, je veux accéder à ModifiedTime. La fonction à utiliser est donc INFO.MEASURES(). C’est elle qui expose les métadonnées utiles pour dater les changements des mesures. - ModifiedTime suffit-il pour expliquer une baisse de performance ?
Pas seul. C’est un signal de départ. Je le croise avec les objets utilisés par la requête lente, puis je vérifie le DAX, les dépendances et les effets possibles des groupes de calcul. - Que faire si la requête INFO renvoie une erreur ?
Je vérifie d’abord si le modèle est ancien ou si son niveau de compatibilité ne supporte pas certaines fonctions récentes. Ensuite, je commente les blocs qui posent problème, par exemple ceux liés à des fonctionnalités DAX plus récentes, et je relance l’audit.
A propos de l’auteur
Je suis Franck Scandolera, expert et formateur en tracking avancé server-side, Analytics Engineering, automatisation No/Low Code avec n8n, IA en entreprise et SEO/GEO. Je dirige l’agence webAnalyste et l’organisme Formations Analytics. J’accompagne des équipes qui ont besoin de fiabiliser leurs données, leurs modèles et leurs automatisations, avec des références comme Logis Hôtel, Yelloh Village, BazarChic, la Fédération Française de Football ou Texdecor. Si vous voulez remettre à plat vos usages Power BI, vos flux data ou vos automatisations, contactez-moi.
⭐ Analytics engineer, Data Analyst et Automatisation IA indépendant ⭐
Ref clients : Logis Hôtel, Yelloh Village, BazarChic, Fédération Football Français, Texdecor…
Mon terrain de jeu :
Data Analyst & Analytics engineering : tracking avancé (GA4, Matomo, Piano, GTM server, Tealium, Commander Act, e-commerce, CAPI, RGPD), entrepôt de données (BigQuery, Snowflake, PostgreSQL, ClickHouse), modèles (Airflow, dbt, Dataform), dashboards décisionnels (Looker, Power BI, Metabase, SQL, Python).
Automatisation IA des taches Data, Marketing, RH, compta etc : conception de workflows intelligents robustes (n8n, App Script, scraping) connectés aux API de vos outils et LLM (OpenAI, Mistral, Claude…).
Engineering IA pour créer des applications et agent IA sur mesure : intégration de LLM (OpenAI, Mistral…), RAG, assistants métier, génération de documents complexes, APIs, backends Node.js/Python.





