Power BI Designer
Workflow
1. Analyser les besoins métier
- Identifier les KPIs (ex. : CA, taux de conversion, délai moyen), le public cible (direction = agrégats, opérationnel = détail transactionnel) et la fréquence de refresh requise.
- Livrable minimum : liste de 5-10 questions métier auxquelles le dashboard doit répondre.
2. Concevoir le modèle de données (star schema)
- Tables de faits : mesures numériques + clés étrangères uniquement. Jamais de colonnes de description.
- Tables de dimensions : attributs descriptifs, hiérarchies (Année → Trimestre → Mois → Jour).
- Règle des relations : toujours unidirectionnelles par défaut ; bidirectionnel seulement si le filtre croisé est strictement nécessaire et documenté.
- Typage des colonnes dans Power Query avant de charger : Date, Integer, Decimal, Text — évite l'auto-détection qui crée des colonnes inutiles.
// Power Query — typage explicite en fin de requête
#"Types appliqués" = Table.TransformColumnTypes(Source, {
{"DateVente", type date},
{"Montant", type number},
{"IdClient", Int64.Type}
})
3. Connecter et transformer les sources (Power Query / M)
- Utiliser le Query Folding : filtrer et agréger côté source (SQL, SSAS) avant de ramener les données dans Power BI.
- Rafraîchissement incrémental : configurer
RangeStart / RangeEnd pour les tables de faits > 1 M de lignes.
// Paramètres requis pour le rafraîchissement incrémental
// Créer deux paramètres de type Date/Time : RangeStart et RangeEnd
#"Filtre incrémental" = Table.SelectRows(Source, each
[DateVente] >= RangeStart and [DateVente] < RangeEnd
)
- Désactiver le chargement des requêtes intermédiaires (staging) pour ne charger que les tables finales.
4. Écrire les mesures DAX
Règle fondamentale : mesures pour les calculs dynamiques, colonnes calculées uniquement pour les attributs statiques.
-- Mesure de base
CA Total = SUM(Ventes[Montant])
-- DIVIDE pour éviter les divisions par zéro
Taux Conversion =
DIVIDE(
COUNTROWS(FILTER(Leads, Leads[Statut] = "Converti")),
COUNTROWS(Leads),
0
)
-- YTD (Year-to-Date)
CA YTD =
CALCULATE(
[CA Total],
DATESYTD(Calendrier[Date])
)
-- Comparaison année précédente
CA N-1 =
CALCULATE(
[CA Total],
SAMEPERIODLASTYEAR(Calendrier[Date])
)
-- Variation %
Var% CA =
DIVIDE([CA Total] - [CA N-1], [CA N-1], BLANK())
-- Mesure avec contexte filtré
CA Région Active =
CALCULATE(
[CA Total],
KEEPFILTERS(Régions[Actif] = TRUE())
)
Critères de choix mesure vs colonne calculée :
| Besoin |
Mesure DAX |
Colonne calculée |
| Agrégation dynamique |
Oui |
Non |
| Filtre par slicer |
Oui |
Non |
| Attribut de dimension fixe |
Non |
Oui |
| Tri personnalisé |
Non |
Oui |
5. Construire les visualisations
- Bar/Column chart : comparaisons catégorielles (max 10-12 barres).
- Line chart : tendances temporelles, ne pas mixer > 3 séries.
- Card / KPI visual : indicateurs en haut de page, valeur + variation.
- Matrix : tableaux croisés avec drill-down, activer "Stepped layout" pour les hiérarchies.
- Slicers : filtres Date en mode "Between", listes en mode "Dropdown" si > 5 valeurs.
- Bookmarks : navigation entre vues (vue Résumé / vue Détail) sans pages supplémentaires.
Ordre d'une page bien conçue : KPIs haut → graphiques principaux centre → filtres/drill gauche ou haut.
6. Configurer la Row-Level Security (RLS)
-- Rôle "Vendeur" : ne voit que ses propres ventes
[Email Vendeur] = USERPRINCIPALNAME()
-- Rôle "Région" : filtre par région assignée
[Code Région] IN
VALUES(
FILTER(RegionUtilisateurs,
RegionUtilisateurs[Email] = USERPRINCIPALNAME()
)[Code Région]
)
- Tester avec Modeling → View as → [nom du rôle] avant de publier.
- En mode Dynamic RLS : une table de mapping Email↔Périmètre est plus maintenable que des rôles statiques par région.
- RLS s'applique uniquement aux rapports Power BI Service, pas aux exports Excel ou aux connexions directes SSAS avec identité propre.
7. Optimiser les performances
- DAX Studio : analyser les mesures lentes avec Server Timings + Query Plan.
- Performance Analyzer (dans Power BI Desktop) : identifier les visuels lents (> 500 ms = à optimiser).
- Réduire la cardinalité : encoder les colonnes de statuts comme entiers (0/1/2) pas comme texte.
- Supprimer les colonnes non utilisées dans les rapports (réduire la taille du fichier .pbix).
- Préférer
SUMX sur des tables petites ; éviter FILTER(ALL(Table), ...) sur de grandes tables.
-- Mauvais : FILTER sur toute la table de faits
Mauvaise Mesure =
CALCULATE([CA Total], FILTER(ALL(Ventes), Ventes[Montant] > 1000))
-- Bon : utiliser KEEPFILTERS ou une dimension
Bonne Mesure =
CALCULATE([CA Total], Ventes[Montant] > 1000)
8. Publier et distribuer
- Pipelines de déploiement : workspace Dev → Test → Prod avec règles de paramétrage par étape.
- Refresh planifié : maximum 8x/jour en Pro, 48x/jour en Premium. Toujours configurer une alerte d'échec de refresh.
- Abonnements email : rapport en PDF/PNG envoyé automatiquement, utile pour les destinataires sans licence Power BI.
- Intégration Teams : épingler les rapports dans des onglets Teams pour la distribution sans sortir de l'outil.
Anti-patterns et pièges
| Piège |
Impact |
Solution |
| Relations bidirectionnelles excessives |
Ambiguïté des filtres, résultats incorrects |
Unidirectionnel par défaut, bidirectionnel documenté |
| Colonnes calculées pour les agrégations |
Modèle lourd, recalcul à chaque refresh |
Mesures DAX |
| CALCULATE sans REMOVEFILTERS |
Contexte non contrôlé, valeurs surprenantes |
Ajouter ALL() ou ALLEXCEPT() explicitement |
| Pas de table Calendrier dédiée |
Time intelligence impossible |
Toujours créer une DimCalendrier marquée comme "Date Table" |
| Ignorer Query Folding |
Toutes les transformations en mémoire locale |
Vérifier l'icône "Native Query" dans Power Query |
| RLS testée seulement en local |
Erreurs de périmètre en production |
Tester avec "View as role" + vérification USERPRINCIPALNAME() en service |
| Trop de visuels par page |
Temps de rendu > 3s |
Max 8-10 visuels par page |
Bonnes pratiques 2026
- Fabric / Direct Lake : pour les entrepôts sur Microsoft Fabric, utiliser le mode Direct Lake (remplace Import + DirectQuery) — lecture directe depuis OneLake sans import ni requêtes SQL en temps réel.
- Copilot Power BI : générer des mesures DAX avec le Copilot intégré, mais toujours relire et valider la logique métier — le Copilot hallucine sur les contextes de filtre complexes.
- Semantic Model centralisé : un seul modèle sémantique partagé (anciennement "dataset") référencé par plusieurs rapports — évite la duplication de la logique DAX.
- Versioning .pbix : Power BI Desktop 2025+ supporte le format
.pbip (dossiers) compatible Git — utiliser ce format pour les projets en équipe.
- Accessibilité : activer Alt text sur tous les visuels, tester avec le lecteur d'écran intégré (Tab order dans View → Accessibility).
1---2name: power-bi-designer3description: Conception de dashboards Power BI — DAX, modèle de données, visualisations avancées et Row-Level Security. Se déclenche avec "Power BI", "DAX", "dashboard Power BI", "rapport Power BI", "modèle de données Power BI". Also triggers on "Power BI dashboard", "DAX measure".4---56# Power BI Designer78## Workflow910### 1. Analyser les besoins métier11- Identifier les KPIs (ex. : CA, taux de conversion, délai moyen), le public cible (direction = agrégats, opérationnel = détail transactionnel) et la fréquence de refresh requise.12- Livrable minimum : liste de 5-10 questions métier auxquelles le dashboard doit répondre.1314### 2. Concevoir le modèle de données (star schema)15- **Tables de faits** : mesures numériques + clés étrangères uniquement. Jamais de colonnes de description.16- **Tables de dimensions** : attributs descriptifs, hiérarchies (Année → Trimestre → Mois → Jour).17- Règle des relations : **toujours unidirectionnelles** par défaut ; bidirectionnel seulement si le filtre croisé est strictement nécessaire et documenté.18- Typage des colonnes dans Power Query **avant** de charger : Date, Integer, Decimal, Text — évite l'auto-détection qui crée des colonnes inutiles.1920```m21// Power Query — typage explicite en fin de requête22#"Types appliqués" = Table.TransformColumnTypes(Source, {23 {"DateVente", type date},24 {"Montant", type number},25 {"IdClient", Int64.Type}26})27```2829### 3. Connecter et transformer les sources (Power Query / M)30- Utiliser le **Query Folding** : filtrer et agréger côté source (SQL, SSAS) avant de ramener les données dans Power BI.31- Rafraîchissement incrémental : configurer `RangeStart` / `RangeEnd` pour les tables de faits > 1 M de lignes.3233```m34// Paramètres requis pour le rafraîchissement incrémental35// Créer deux paramètres de type Date/Time : RangeStart et RangeEnd36#"Filtre incrémental" = Table.SelectRows(Source, each37 [DateVente] >= RangeStart and [DateVente] < RangeEnd38)39```4041- Désactiver le chargement des requêtes intermédiaires (staging) pour ne charger que les tables finales.4243### 4. Écrire les mesures DAX44**Règle fondamentale** : mesures pour les calculs dynamiques, colonnes calculées uniquement pour les attributs statiques.4546```dax47-- Mesure de base48CA Total = SUM(Ventes[Montant])4950-- DIVIDE pour éviter les divisions par zéro51Taux Conversion =52DIVIDE(53 COUNTROWS(FILTER(Leads, Leads[Statut] = "Converti")),54 COUNTROWS(Leads),55 056)5758-- YTD (Year-to-Date)59CA YTD =60CALCULATE(61 [CA Total],62 DATESYTD(Calendrier[Date])63)6465-- Comparaison année précédente66CA N-1 =67CALCULATE(68 [CA Total],69 SAMEPERIODLASTYEAR(Calendrier[Date])70)7172-- Variation %73Var% CA =74DIVIDE([CA Total] - [CA N-1], [CA N-1], BLANK())7576-- Mesure avec contexte filtré77CA Région Active =78CALCULATE(79 [CA Total],80 KEEPFILTERS(Régions[Actif] = TRUE())81)82```8384**Critères de choix mesure vs colonne calculée :**8586| Besoin | Mesure DAX | Colonne calculée |87|---|---|---|88| Agrégation dynamique | Oui | Non |89| Filtre par slicer | Oui | Non |90| Attribut de dimension fixe | Non | Oui |91| Tri personnalisé | Non | Oui |9293### 5. Construire les visualisations94- **Bar/Column chart** : comparaisons catégorielles (max 10-12 barres).95- **Line chart** : tendances temporelles, ne pas mixer > 3 séries.96- **Card / KPI visual** : indicateurs en haut de page, valeur + variation.97- **Matrix** : tableaux croisés avec drill-down, activer "Stepped layout" pour les hiérarchies.98- **Slicers** : filtres Date en mode "Between", listes en mode "Dropdown" si > 5 valeurs.99- **Bookmarks** : navigation entre vues (vue Résumé / vue Détail) sans pages supplémentaires.100101Ordre d'une page bien conçue : KPIs haut → graphiques principaux centre → filtres/drill gauche ou haut.102103### 6. Configurer la Row-Level Security (RLS)104105```dax106-- Rôle "Vendeur" : ne voit que ses propres ventes107[Email Vendeur] = USERPRINCIPALNAME()108109-- Rôle "Région" : filtre par région assignée110[Code Région] IN111 VALUES(112 FILTER(RegionUtilisateurs,113 RegionUtilisateurs[Email] = USERPRINCIPALNAME()114 )[Code Région]115 )116```117118- Tester avec **Modeling → View as → [nom du rôle]** avant de publier.119- En mode **Dynamic RLS** : une table de mapping Email↔Périmètre est plus maintenable que des rôles statiques par région.120- RLS s'applique uniquement aux rapports Power BI Service, pas aux exports Excel ou aux connexions directes SSAS avec identité propre.121122### 7. Optimiser les performances123- **DAX Studio** : analyser les mesures lentes avec Server Timings + Query Plan.124- **Performance Analyzer** (dans Power BI Desktop) : identifier les visuels lents (> 500 ms = à optimiser).125- Réduire la cardinalité : encoder les colonnes de statuts comme entiers (0/1/2) pas comme texte.126- Supprimer les colonnes non utilisées dans les rapports (réduire la taille du fichier .pbix).127- Préférer `SUMX` sur des tables petites ; éviter `FILTER(ALL(Table), ...)` sur de grandes tables.128129```dax130-- Mauvais : FILTER sur toute la table de faits131Mauvaise Mesure =132CALCULATE([CA Total], FILTER(ALL(Ventes), Ventes[Montant] > 1000))133134-- Bon : utiliser KEEPFILTERS ou une dimension135Bonne Mesure =136CALCULATE([CA Total], Ventes[Montant] > 1000)137```138139### 8. Publier et distribuer140- **Pipelines de déploiement** : workspace Dev → Test → Prod avec règles de paramétrage par étape.141- Refresh planifié : maximum 8x/jour en Pro, 48x/jour en Premium. Toujours configurer une alerte d'échec de refresh.142- **Abonnements email** : rapport en PDF/PNG envoyé automatiquement, utile pour les destinataires sans licence Power BI.143- Intégration Teams : épingler les rapports dans des onglets Teams pour la distribution sans sortir de l'outil.144145---146147## Anti-patterns et pièges148149| Piège | Impact | Solution |150|---|---|---|151| Relations bidirectionnelles excessives | Ambiguïté des filtres, résultats incorrects | Unidirectionnel par défaut, bidirectionnel documenté |152| Colonnes calculées pour les agrégations | Modèle lourd, recalcul à chaque refresh | Mesures DAX |153| CALCULATE sans REMOVEFILTERS | Contexte non contrôlé, valeurs surprenantes | Ajouter ALL() ou ALLEXCEPT() explicitement |154| Pas de table Calendrier dédiée | Time intelligence impossible | Toujours créer une `DimCalendrier` marquée comme "Date Table" |155| Ignorer Query Folding | Toutes les transformations en mémoire locale | Vérifier l'icône "Native Query" dans Power Query |156| RLS testée seulement en local | Erreurs de périmètre en production | Tester avec "View as role" + vérification USERPRINCIPALNAME() en service |157| Trop de visuels par page | Temps de rendu > 3s | Max 8-10 visuels par page |158159## Bonnes pratiques 2026160161- **Fabric / Direct Lake** : pour les entrepôts sur Microsoft Fabric, utiliser le mode Direct Lake (remplace Import + DirectQuery) — lecture directe depuis OneLake sans import ni requêtes SQL en temps réel.162- **Copilot Power BI** : générer des mesures DAX avec le Copilot intégré, mais toujours relire et valider la logique métier — le Copilot hallucine sur les contextes de filtre complexes.163- **Semantic Model centralisé** : un seul modèle sémantique partagé (anciennement "dataset") référencé par plusieurs rapports — évite la duplication de la logique DAX.164- **Versioning .pbix** : Power BI Desktop 2025+ supporte le format `.pbip` (dossiers) compatible Git — utiliser ce format pour les projets en équipe.165- **Accessibilité** : activer Alt text sur tous les visuels, tester avec le lecteur d'écran intégré (Tab order dans View → Accessibility).