Support formation Rapports Power BI

Table de dates

En bref

  • Objectifs : créer une table de dates en Power Query, en DAX ou depuis Excel ; la marquer comme table de dates ; désactiver la date/heure automatique ; gérer plusieurs colonnes de dates avec un seul calendrier.
  • Prérequis : pages Schéma en étoile et Relations ; éditeur avancé de Power Query.
  • Niveau : intermédiaire.
Modélisation 3 - La table de dates

Pourquoi ?

Presque toutes les analyses ont un axe temporel : évolution mensuelle, cumul annuel, comparaison avec l'année précédente. Une table de dates dédiée, reliée aux tables de faits, est la dimension conforme par excellence. Elle est indispensable aux fonctions de time intelligence de DAX et vous donne la maîtrise des colonnes proposées (semaine ISO, trimestre, exercice fiscal).

Notions clés

Contenu d'une table de dates

  • Une colonne contenant tous les jours, sans trou ni doublon, du 1er janvier de la première année au 31 décembre de la dernière année.
  • Des colonnes qui déclinent cette date : année, trimestre, mois (numéro et nom), semaine, jour de la semaine, etc.
  • Les colonnes de noms (mois, jour) sont triées par leur numéro grâce à Trier par colonne (voir Propriétés des colonnes).

Date/heure automatique

Par défaut, Power BI Desktop crée une table de dates cachée pour chaque colonne de date du modèle. Ces tables alourdissent le modèle et ne se partagent pas entre tables de faits. Dès que vous créez votre propre table de dates, désactivez l'option : Fichier > Options et paramètres > Options > Fichier actif > Chargement des données > décochez Date/heure automatique (et dans Global pour les nouveaux fichiers).

Marquer comme table de dates

Marquer la table indique à Power BI quelle colonne porte les dates. C'est nécessaire pour la time intelligence classique, et lorsque les relations utilisent une clé entière au format AAAAMMJJ. Power BI vérifie que la colonne contient des valeurs uniques, sans valeur vide, et des dates contiguës. Source

Quelle méthode choisir ?

MéthodeAvantagesLimites
Power QueryTable chargée comme les autres, colonnes ajoutées par menusSemaine ISO à calculer par une formule
DAX (table calculée)Copier-coller d'une formule, semaine ISO nativeTable recalculée à chaque actualisation, non réutilisable dans Power Query
Fichier Excel partagéUn même calendrier pour plusieurs projets, colonnes métier (jours fériés, périodes)Fichier à maintenir et à rendre accessible à l'actualisation

Pas à pas

Créer la table en Power Query

1. Accueil > Nouvelle source > Requête vide, puis Accueil > Éditeur avancé.

2. Effacez le contenu et collez ce code, en adaptant les bornes :

let
    DateDebut = #date(2020, 1, 1),
    DateFin = #date(2030, 12, 31),
    NbJours = Duration.Days(DateFin - DateDebut),
    Source = List.Dates(DateDebut, NbJours + 1, #duration(1, 0, 0, 0))
in
    Source

3. Cliquez sur Terminé, puis Transformer > Vers la table et validez par OK.

4. Renommez la colonne Column1 en Date, passez-la en type Date, puis renommez la requête Calendrier.

5. Sélectionnez la colonne Date, puis Ajouter une colonne > Date et choisissez une déclinaison (par exemple Année > Année). Resélectionnez la colonne Date avant chaque nouvelle déclinaison.

[Capture : Power Query, onglet Ajouter une colonne, menu Date ouvert sur Année > Année, colonne Date sélectionnée]

6. Accueil > Fermer et appliquer.

Pour borner le calendrier sur les dates d'une table de faits, remplacez les deux premières lignes par :

DateDebut = Date.StartOfYear(List.Min(Ventes[DateVente])),
DateFin = Date.EndOfYear(List.Max(Ventes[DateVente])),

Ajouter la semaine ISO en Power Query

Collez ce code dans une nouvelle requête vide : il crée la table et une colonne Semaine au format ISO (semaine commençant le lundi, semaine 1 contenant le premier jeudi de l'année).

let
    DateDebut = #date(2020, 1, 1),
    DateFin = #date(2030, 12, 31),
    NbJours = Duration.Days(DateFin - DateDebut),
    Source = List.Dates(DateDebut, NbJours + 1, #duration(1, 0, 0, 0)),
    #"Converti en table" = Table.FromList(Source, Splitter.SplitByNothing(), {"Date"}, null, ExtraValues.Error),
    #"Type modifié" = Table.TransformColumnTypes(#"Converti en table", {{"Date", type date}}),
    #"Semaine ISO" = Table.AddColumn(#"Type modifié", "Semaine", each
        if Number.RoundDown((Date.DayOfYear([Date]) - (Date.DayOfWeek([Date], Day.Monday) + 1) + 10) / 7) = 0 then
            Number.RoundDown((Date.DayOfYear(#date(Date.Year([Date]) - 1, 12, 31)) - (Date.DayOfWeek(#date(Date.Year([Date]) - 1, 12, 31), Day.Monday) + 1) + 10) / 7)
        else if (Number.RoundDown((Date.DayOfYear([Date]) - (Date.DayOfWeek([Date], Day.Monday) + 1) + 10) / 7) = 53
            and (Date.DayOfWeek(#date(Date.Year([Date]), 12, 31), Day.Monday) + 1 < 4)) then
            1
        else
            Number.RoundDown((Date.DayOfYear([Date]) - (Date.DayOfWeek([Date], Day.Monday) + 1) + 10) / 7),
        Int64.Type)
in
    #"Semaine ISO"

Créer la table en DAX

Dans la vue Rapport ou Table : Modélisation > Nouvelle table, puis collez :

Calendrier =
VAR BaseCalendar =
    CALENDAR ( DATE ( 2020, 1, 1 ), DATE ( 2030, 12, 31 ) )
RETURN
    GENERATE (
        BaseCalendar,
        VAR BaseDate = [Date]
        VAR YearDate = YEAR ( BaseDate )
        VAR MonthNumber = MONTH ( BaseDate )
        VAR TrimNumber = TRUNC ( ( MonthNumber - 1 ) / 3 ) + 1
        RETURN
            ROW (
                "Année", YearDate,
                "Mois", MonthNumber,
                "Nom du mois", FORMAT ( BaseDate, "mmmm" ),
                "Nom court du mois", FORMAT ( BaseDate, "mmm" ),
                "Mois Année", FORMAT ( BaseDate, "mmm yyyy" ),
                "Trimestre", TrimNumber,
                "Nom trimestre", "T" & TrimNumber,
                "Année trimestre", YearDate & " T" & TrimNumber,
                "Semaine", WEEKNUM ( BaseDate, 21 )
            )
    )
  • GENERATE combine chaque ligne de la première table avec la table renvoyée par la seconde expression.
  • ROW renvoie une table d'une seule ligne, faite de paires nom et expression.
  • WEEKNUM avec le paramètre 21 renvoie la semaine ISO.

Créer la table dans Excel

  1. Créez un classeur et insérez un tableau (Insertion > Tableau).
  2. Nommez la première colonne Date et listez tous les jours de la période voulue.
  3. Ajoutez les colonnes de déclinaison (formules ANNEE, MOIS, NO.SEMAINE.ISO...) et les colonnes métier utiles.
  4. Enregistrez le classeur dans un emplacement partagé (SharePoint, OneDrive professionnel) et importez-le dans chaque projet.

Marquer la table et la relier

1. Clic droit sur la table dans le volet Données > Marquer en tant que table de dates > Marquer en tant que table de dates, puis choisissez la colonne Date.

[Capture : boîte de dialogue Marquer en tant que table de dates, colonne Date sélectionnée et validation réussie]

2. Dans la vue Modèle, reliez Calendrier[Date] à la colonne de date de chaque table de faits (un-à-plusieurs, sens unique).

3. Masquez les colonnes de date des tables de faits : les utilisateurs filtrent par le calendrier.

Exemple

Un seul calendrier pour plusieurs dates

La table Ventes contient une colonne DateVente et une colonne DateExpédition. Deux approches sont possibles. Source

ApprochePrincipeÀ privilégier quand
Une table, plusieurs relationsUne relation active (DateVente) et une inactive (DateExpédition), activée par USERELATIONSHIP dans des mesures dédiéesPeu de mesures concernées par la seconde date
Une table par rôleCalendrier Vente et Calendrier Expédition, chacune avec une relation activeLes utilisateurs filtrent par les deux dates en même temps

Pour mettre en place la seconde approche :

1. Créez une table de dates « normale » nommée Calendrier, masquez-la et laissez-la sans relation.

2. Créez une table calculée :

image.png

3. Saisissez Calendrier Vente = Calendrier, puis recommencez avec Calendrier Expédition = Calendrier.

4. Reliez Calendrier Vente[Date] à Ventes[DateVente] et Calendrier Expédition[Date] à Ventes[DateExpédition].

5. Renommez les colonnes de chaque table pour lever toute ambiguïté : Année vente, Mois vente, Année expédition, etc. Marquez chaque table comme table de dates.

Vous pouvez aussi créer les deux tables par des requêtes de référence dans Power Query.

Les calendriers de la time intelligence

Power BI propose, en préversion à la date de rédaction, une time intelligence fondée sur des calendriers : vous définissez un ou plusieurs calendriers (fiscal, 4-4-5, semaines ISO) sur une table par clic droit > Options Calendrier, puis les fonctions comme TOTALYTD les utilisent. Activez-la dans Options > Fonctionnalités en préversion. Elle est présentée dans la page Time intelligence de la sous-partie DAX. Source

Pièges et bonnes pratiques

  • La table doit couvrir des années complètes et toutes les dates des tables de faits.
  • Une colonne de type Date/heure avec des heures différentes empêche le marquage : convertissez-la en Date.
  • Ne laissez pas la date/heure automatique activée avec votre propre table de dates.
  • Évitez une colonne Année générique quand plusieurs calendriers coexistent : nommez chaque colonne selon son rôle.

À retenir

  • Une table de dates contient tous les jours, sans trou, et se relie à chaque table de faits.
  • Marquez-la comme table de dates et désactivez la date/heure automatique.
  • Power Query, DAX ou Excel : choisissez selon le partage et la maintenance.
  • Pour plusieurs dates : relations inactives et USERELATIONSHIP, ou une table par rôle.

Pour aller plus loin

  • Créer des tables de dates dans Power BI Desktop (conseils). Source (Microsoft Learn)
  • Définir et utiliser des tables de dates dans Power BI Desktop. Source (Microsoft Learn)
  • Conseils sur la date/heure automatique. Source (Microsoft Learn)
  • Using GENERATE and ROW instead of ADDCOLUMNS in DAX (vidéo en anglais). Source (YouTube)