100% ont trouvé ce document utile (1 vote)
39 vues278 pages

Guide complet sur Power Query (M)

Le guide définitif de Power Query présente le langage de formule Power Query (M), conçu pour la manipulation et la transformation des données. Il explore les fonctionnalités et l'utilisation de M dans divers outils comme Excel et Power BI, tout en fournissant des bases solides pour les utilisateurs souhaitant maîtriser ce langage. Le document aborde également des concepts clés, des erreurs courantes et des stratégies de débogage.

Transféré par

jacquetmar
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
100% ont trouvé ce document utile (1 vote)
39 vues278 pages

Guide complet sur Power Query (M)

Le guide définitif de Power Query présente le langage de formule Power Query (M), conçu pour la manipulation et la transformation des données. Il explore les fonctionnalités et l'utilisation de M dans divers outils comme Excel et Power BI, tout en fournissant des bases solides pour les utilisateurs souhaitant maîtriser ce langage. Le document aborde également des concepts clés, des erreurs courantes et des stratégies de débogage.

Transféré par

jacquetmar
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Machine Translated by Google

Machine Translated by Google

Le guide définitif de Power Query


(M)
Copyright © 2023 Packt Publishing

Tous droits réservés. Aucune partie de ce livre ne peut être reproduite, stockée dans un
système de recherche documentaire ou transmise sous quelque forme ou par quelque moyen
que ce soit, sans l'autorisation écrite préalable de l'éditeur, sauf dans le cas de brèves
citations intégrées à des articles critiques ou à des comptes rendus.

Tout a été mis en œuvre lors de la préparation de ce livre pour garantir l'exactitude des
informations présentées. Cependant, les informations contenues dans ce livre sont vendues sans
garantie, expresse ou implicite. Ni l'auteur, ni Packt Publishing, ni ses revendeurs et distributeurs ne
sauraient être tenus responsables des dommages causés ou prétendument causés, directement
ou indirectement, par ce livre.

Packt Publishing s'est efforcé de fournir des informations sur les marques déposées de toutes les
entreprises et de tous les produits mentionnés dans ce livre en utilisant les majuscules
de manière appropriée. Cependant, Packt Publishing ne peut garantir l'exactitude de ces
informations.

Publication en accès anticipé : Le guide complet de Power Query (M)

Référence de production en accès anticipé : B21453

Publié par Packt Publishing Ltd.

Lieu de livraison

35, rue Livery

Birmingham

B3 2PB, Royaume­Uni

ISBN : 978­1­83508­972­9

[Link]
Machine Translated by Google

Table des matières


1. Le guide définitif de Power Query (M : Maîtriser les données complexes)
Transformation avec Power Query 2. 1 Présentation
de M I. Rejoignez notre
communauté de lecteurs sur Discord II. Qu'est­ce que le
langage de formules Power Query (M) i. Classification formelle ii.
Caractéristiques informelles de M

III. Histoire de M IV. Qui


devrait apprendre M ?
V. Pourquoi apprendre M ?
VI. Comment M est­il utilisé ?
VII. Où M est­il utilisé ? i.
Expériences ii.
Produits et services
VIII. Bases du langage M i. Soit IX.
Résumé
3. 2 Travailler avec
Power Query/M I. Rejoignez notre communauté de
livres sur Discord II. Découvrir l'expérience bureautique
de Power Query
i. Présentation rapide
ii. Votre première requête iii.
Options et paramètres de la source de données III.
Ajustement du code généré par l'expérience IV. Création de
colonnes personnalisées i. Ajout d'une
colonne d'index ii. Ajout de colonnes
par des exemples iii. Opérations mathématiques
iv. Ajout de colonnes de code
M personnalisées V. Utilisation de l'éditeur avancé
VI. Résumé 4. 3 Comprendre les valeurs et
les expressions

I. Rejoignez notre communauté de lecteurs sur Discord II.


Présentation des valeurs III.
Structure et utilisation de chaque type de valeur IV. Valeurs
binaires i. Structure ii.
Exemples iii.
Fonctions
associées iv. Considérations
particulières V. La famille de valeurs
Date/Heure i. Valeurs Date ii. Valeurs Heure iii.
Valeurs DateTime
iv. Valeurs
DateTimeZone v. Valeurs
Durée
Machine Translated by Google

VI. Valeurs logiques i.


Structure ii.
Exemples iii.
Fonctions apparentées iv.
Considérations particulières VII.
Valeurs nulles i.
Structure ii.
Exemples iii.
Fonctions apparentées iv.
Considérations particulières VIII.
Valeurs numériques i. Structure
et exemples ii. Fonctions apparentées
iii. Considérations particulières
IX. Valeurs textuelles i. Structure ii.
Exemples iii. Fonctions
apparentées iv.
Considérations
particulières

X. Valeurs de liste i.
Structure ii.
Exemples iii.
Fonctions associées iv.
Considérations particulières XI.
Valeurs d'enregistrement
i. Structure ii.
Exemples iii.
Fonctions associées iv.
Considérations particulières XII.
Valeurs de tableau i.
Structure ii.
Exemples iii.
Considérations particulières XIII.
Valeurs de fonction
i. Structure ii.
Exemples iii.
Fonctions associées iv.
Considérations particulières XIV.
Valeurs de type i.
Structure ii.
Exemples iii.
Fonctions associées iv.
Considérations particulières XV.
Expressions i. Bonnes
pratiques de codage pour les expressions XVI. Opérateurs
XVII. Structures de
contrôle XVIII. Énumérations XIX.
Résumé 5. 5 Gestion des
erreurs et débogage I.
Rejoignez notre communauté de livres sur Discord
Machine Translated by Google

II. Qu’est­ce qu’une erreur ?


III. Confinement des erreurs
IV. Détection des erreurs
V. Génération d'erreurs
VI. Gestion des erreurs
VII. Stratégies de débogage VIII. Erreurs
courantes
IX. Mise en place X. Résumé 6. 6
Travailler avec
des valeurs structurées I. Rejoignez notre
communauté de livres sur Discord II. Présentation
des valeurs structurées III. Importance des
valeurs structurées IV. Listes i. Introduction aux
listes ii.
Opérateurs de liste iii. Méthodes
pour créer une liste iv.
Accéder aux éléments d'une liste v.
Opérations courantes avec les listes
vi. Attribution de types de données à une
liste V. Enregistrements

i. Introduction aux enregistrements


ii. Méthodes de création d'un
enregistrement iii. Opérateurs
d'enregistrement iv. Accès aux champs
d'un enregistrement v. Opérations courantes
avec les enregistrements vi. Attribution d'un
type de
données aux enregistrements VI.
Tables i. Introduction aux
tables ii. Opérateurs de table iii.
Méthodes de création d'une table iv. Accès
aux éléments d'une table v. Opérations
courantes avec les tables vi. Attribution d'un
type de données
aux tables VII. Résumé 7. 9 Paramètres et fonctions personnalisées
I. Rejoignez notre communauté de lecteurs sur
Discord II.
Paramètres i. Comprendre les
paramètres ii. Créer des
paramètres iii. Utiliser des paramètres dans vos
requêtes iv. Assembler le tout III.
Fonctions personnalisées dans M i.
Que sont les fonctions personnalisées ?
ii. Anatomie des fonctions personnalisées
IV. Transformer une requête en fonction i. Qu'est­ce que
la fonctionnalité « Créer une fonction » ? ii. Comment créer
une fonction à partir d'une requête ? iii. Simplification du
dépannage et améliorations ; iv. Appel d'une fonction personnalisée ;
v. L'expression « Each » .
Machine Translated by Google

vi. Référencement des noms de colonnes et de


champs vii. Portée de la
fonction V.
Résumé 8. 11 Comparateurs, remplaçants, combinateurs et
séparateurs I. Rejoignez notre communauté de
livres sur Discord II.
Concepts clés i. Appel de
fonction ii.
Fermetures iii . Fonctions d'ordre
supérieur iv. Fonctions
anonymes v. Ordre
des valeurs III.
Comparateurs i.
[Link] ii.
[Link] iii.
[Link] iv .
[Link] IV.
Critères de
comparaison i. Valeur
numérique ii. Calcul d'une clé de
tri iii. Liste avec clé et ordre V. Critères d'équation
i. Comparateurs par défaut
ii. Comparateur
personnalisé iii.
Sélecteurs de clés iv. Combinaison de sélecteurs de
clés et de
comparateurs VI. Remplaçants
i. [Link] ii.
[Link] VII.
Remplaçants personnalisés VIII. Combineurs
i. [Link] ii.
[Link] iii.
[Link] iv.
[Link] v.
[Link] IX.
Séparateurs i.
Sé[Link] ii.
Sé[Link] iii.
Sé[Link] iv.
Sé[Link] v.
Sé[Link] vi.
Sé[Link] vii.
Sé[Link] viii.
Sé[Link] ix.
Sé[Link] x.
Sé[Link] X.
Exemples pratiques
i. Scénario 1. La tâche. ii.
Scénario 1. Une solution. iii.
Scénario 2. La tâche. iv.
Scénario 2. Une solution.
Machine Translated by Google

v. Scénario 3. La tâche. vi.


Scénario 3. Une solution. vii.
Scénario 4. La tâche. viii.
Scénario 4. Une solution. ix.
Scénario 5. La tâche. x.
Scénario 5. Une solution.
XI. Résumé 9. 16
Activation des extensions I.
Rejoignez notre communauté de livres sur Discord
II. Exigences techniques III. Que
sont les extensions Power Query ?
i. Que pouvez­vous faire avec des extensions ?
IV. Préparation de votre environnement i.
Obtenir Visual Studio ii.
Obtenir le SDK Power Query iii.
Configuration des services Internet (IIS) iv. Configuration
de Discord V. Création d'un
connecteur personnalisé i. Création d'un
projet d'extension ii. Configuration de
l'authentification iii. Configuration de la
navigation et du contenu VI. Installation et utilisation
d'un connecteur personnalisé VII. Résumé

1.
Couverture 2. Table des matières
Machine Translated by Google

Le guide définitif de Power Query


(M : Maîtriser les données complexes
Transformation avec Power Query
Bienvenue dans Packt Early Access. Nous vous offrons un aperçu exclusif de ce livre
avant sa mise en vente. Écrire un livre peut prendre des mois, mais nos auteurs ont des
informations de pointe à partager avec vous dès aujourd'hui.
L'accès anticipé vous permet de découvrir les dernières nouveautés en mettant à votre
disposition des ébauches de chapitres. Les chapitres sont peut­être encore un peu
inachevés pour le moment, mais nos auteurs les mettront à jour au fil du temps. Vous
pouvez consulter ce livre de façon continue ou le suivre du début à la fin ; l'accès
anticipé est conçu pour être flexible. Nous espérons que vous apprécierez d'en savoir
plus sur le processus d'écriture d'un livre Packt.

1. Chapitre 1 : Présentation de
M 2. Chapitre 2 : Travailler avec Power Query/M 3.
Chapitre 3 : Comprendre le type dans Power Query/M 4.
Chapitre 4 : Éléments constitutifs de M 5.
Chapitre 5 : Gestion des erreurs 6.
Chapitre 6 : Utilisation de la sélection, de la projection et des paramètres
7. Chapitre 7 : Accès et combinaison des données 8.
Chapitre 8 : Conceptualisation des combinateurs, des comparateurs, des remplaçants et

Séparateurs 9. Chapitre 9 : Explication de l'environnement


et de la portée 10. Chapitre 10 : Travailler avec des
structures imbriquées 11. Chapitre 11 :
Réaliser la récursivité 12. Chapitre 12 :
Activation des extensions 13. Chapitre 13 : Gestion des dates, des
heures et des durées 14. Chapitre 14 : Débogage et optimisation
des performances 15. Chapitre 15 : Documentation,
métadonnées et sections 16. Chapitre 16 : S'attaquer aux modèles de données problématiques
Machine Translated by Google

1 Présentation de M

Rejoignez notre communauté de livres sur Discord

[Link]

Le langage de formule Power Query, souvent appelé M, est un langage de formule puissant
et polyvalent, spécialement conçu pour la manipulation et la transformation des données. M
est le langage au cœur de Power Query, un outil de transformation et de préparation des
données largement utilisé dans diverses applications telles que Microsoft Excel, Power BI,
Power Automate, Azure Data Factory et Data Factory dans Microsoft Fabric. Il offre un
ensemble de fonctionnalités robustes et flexibles pour récupérer, transformer et manipuler des
données provenant de sources diverses, vous permettant ainsi de les adapter à vos
besoins spécifiques. Que vous soyez analyste commercial, data scientist ou passionné de
données, la maîtrise de Power Query/M vous permettra d'effectuer des
transformations de données complexes et de préparer vos données pour l'analyse et
le reporting avec une facilité déconcertante. Grâce à sa syntaxe intuitive, sa vaste
bibliothèque de fonctions et son intégration transparente avec les outils de données les plus
répandus, Power Query/M est devenu un outil indispensable dans la boîte à outils des
professionnels des données modernes. Dans ce chapitre, nous commencerons
notre exploration en acquérant une solide compréhension de M et de son intégration
dans l'écosystème Power Query. De plus, nous aborderons les aspects fondamentaux de
Power Query/M et poserons les bases de votre compréhension de ce puissant langage.
Les connaissances acquises dans ce chapitre constituent une base solide pour une
exploration plus approfondie de M tout au long de ce livre. Ce chapitre aborde les sujets
suivants :

• Qu'est­ce que le langage Power Query Formula (M) • Histoire


de M • Qui devrait
apprendre M ? • Pourquoi
apprendre M ? •
Comment M est­il
utilisé ? • Où M est­il
utilisé ? • Principes de base du langage M
Machine Translated by Google

Qu'est­ce que le langage de formule Power Query (M)


M constitue l'épine dorsale de Power Query et permet aux utilisateurs d'extraire, de nettoyer
et de remodeler des données provenant de diverses sources telles que des bases de données,
des feuilles de calcul, des pages web, etc. M propose un riche ensemble de fonctions,
d'opérateurs et d'expressions permettant d'effectuer des transformations, des calculs et
des agrégations de données complexes.

Classification formelle

Les langages de programmation sont classés selon plusieurs propriétés, telles que pur/impur,
ordre inférieur/ordre supérieur, typage statique/dynamique, typage fort/faible, évaluation
rapide/paresseuse, impératif/fonctionnel. Microsoft a décrit M comme
suit :

• Presque pur – Un langage de programmation est dit pur s'il offre une intégrité
référentielle. Autrement dit, toute expression peut être remplacée par sa valeur sans
modifier le comportement ni la signification du programme.

Un langage de programmation impur autorise des effets secondaires, c'est­à­dire des


actions provoquant des modifications hors du champ d'application de la valeur de retour d'une
fonction. M est couramment utilisé pour les tâches de transformation et de récupération de
données, qui impliquent souvent l'interaction avec des sources de données externes, l'exécution
d'opérations sur les données et la production de résultats. Ces actions constituent des effets
secondaires car elles affectent l'état de la source de données ou produisent des
résultats au­delà de la valeur de retour de la fonction. Bien que M fournisse des
constructions de programmation fonctionnelle et prenne en charge l'immuabilité, permettant
la création de fonctions pures, ce langage n'est pas purement fonctionnel en raison de sa
nature impure. Il intègre une combinaison de paradigmes de programmation
fonctionnelle et impérative pour faciliter une manipulation et une récupération de
données efficaces et pratiques.

• Ordre supérieur – Pour les langages d’ordre inférieur, tels que le code machine et le
langage assembleur, chaque instruction de programmation correspond à une seule
instruction pour l’ordinateur tandis que dans les langages d’ordre supérieur, chaque
instruction correspond à plusieurs instructions pour l’ordinateur.

Les langages d'ordre supérieur permettent généralement d'utiliser des fonctions, des objets et
des modules comme valeurs dans le programme. Ils traitent souvent les fonctions comme
des éléments de première classe. Concrètement, cela signifie que les fonctions peuvent
être affectées à des variables, transmises comme arguments à d'autres fonctions et
renvoyées comme valeurs par ces dernières. Power Query M prend en charge la programmation
d'ordre supérieur en permettant de définir et de manipuler des fonctions comme valeurs.
Vous pouvez affecter des fonctions à des variables, les transmettre comme arguments à
d'autres fonctions et renvoyer des fonctions comme résultats. Cela vous permet de créer du
code plus modulaire et flexible en abstrayant et en réutilisant la logique des fonctions. Grâce
à ses capacités de programmation d'ordre supérieur, M permet d'appliquer des transformations
et des calculs dynamiquement en fonction des entrées.
Machine Translated by Google

Paramètres, flux de contrôle et caractéristiques des données. Vous pouvez écrire des fonctions
qui interagissent avec d'autres fonctions, ce qui permet de puissants scénarios de manipulation
et de transformation des données. Par exemple, vous pouvez utiliser des fonctions d'ordre
supérieur dans M pour appliquer dynamiquement une série de transformations à un ensemble de
données selon des critères définis par l'utilisateur ou pour créer des pipelines de fonctions
réutilisables pour le traitement des données. En offrant des fonctionnalités de programmation
d'ordre supérieur, M permet aux développeurs d'écrire du code expressif et modulaire, facilitant
ainsi le traitement de transformations de données complexes et la personnalisation du comportement
des fonctions pour répondre à des besoins spécifiques.

• Typage dynamique – Les langages typés dynamiquement effectuent la vérification de


type à l'exécution plutôt qu'à la compilation, comme c'est le cas avec les langages
typés statiquement. La vérification de type consiste simplement à s'assurer que des
éléments tels que les paramètres passés à une fonction sont du type correct, comme du
texte, un nombre ou une date. • Faiblement typé – Bien
que étroitement lié à la propriété de
Les langages statiquement/dynamiquement typés, fortement typés et faiblement typés
sont très différents. Les langages fortement typés sont extrêmement sensibles à la
compatibilité des types et nécessitent des définitions de type explicites pour les variables
avant leur utilisation. À l'inverse, les langages faiblement typés comme M ne nécessitent
pas de définitions de type explicites et certains effectuent même une conversion de
type automatique.

M n'est pas aussi faiblement typé que des langages de programmation comme Python, car les
variables sont immuables une fois calculées. Ainsi, la définition de type faible de M fait généralement
référence à la possibilité d'utiliser des variables dont le type de données n'a pas été explicitement
spécifié. Prenons le code Python suivant :

a = 42
a = « Bonjour tout le monde »
print(a)

Ce code ne générerait pas d'erreur en Python, même si deux types de données différents étaient
attribués à la variable a. Cependant, un code similaire est impossible en M, car les variables,
une fois calculées, sont immuables (ne peuvent pas être modifiées). La flexibilité du typage
des données permet à Power Query M de gérer un large éventail de sources de données et
d'effectuer efficacement diverses transformations de données. Cela simplifie le travail avec
des ensembles de données hétérogènes pouvant contenir différents types et structures de données.
Il est important de noter que, même si Power Query M est faiblement typé, il effectue tout de même
une vérification de type lors de l'exécution (runtime) afin de garantir la cohérence des
opérations. Si une opération particulière n'est pas compatible avec le type inféré d'une
valeur, une erreur peut survenir à l'exécution. Globalement, le typage faible de Power Query M offre
un équilibre entre flexibilité et intégrité des données, offrant aux utilisateurs un langage polyvalent
pour les tâches de transformation de données.

• Partiellement paresseux – En général, M suit une stratégie d'évaluation rapide : lorsque


vous définissez des transformations ou des calculs, ces transformations et calculs
sont exécutés immédiatement après leur application aux données. Cette approche
d'évaluation rapide garantit que les transformations de données sont rapides et que les
résultats sont immédiatement disponibles pour un traitement ou une analyse ultérieurs.
Power Query M est
Machine Translated by Google

conçu pour gérer efficacement les tâches de manipulation et de récupération de données, en


se concentrant sur l'évaluation immédiate pour fournir un retour d'information en temps réel
sur les transformations.

Le terme « partiellement paresseux » fait référence à une fonctionnalité spécifique de M appelée


évaluation paresseuse, distincte de la stratégie d'évaluation globale du langage. Dans M,
l'évaluation paresseuse s'applique aux expressions de certaines constructions spécifiques,
notamment les expressions List, Record et Table , ainsi que l' expression let . Ces constructions
permettent de définir des expressions évaluées uniquement lorsque cela est nécessaire, offrant ainsi
une forme d'évaluation à la demande ou paresseuse dans ces contextes. M permet également de
définir des arguments optionnels pour les fonctions. Ces arguments optionnels sont évalués
paresseusement, ce qui signifie qu'ils ne sont calculés que s'ils sont explicitement utilisés dans le
corps de la fonction. L'évaluation paresseuse des arguments optionnels optimise les performances
en évitant les calculs inutiles pour les valeurs optionnelles non réellement utilisées dans la fonction. Elle
garantit que les calculs des arguments optionnels sont différés jusqu'à ce que leurs valeurs soient
requises par l'exécution de la fonction. M prend également en charge les constructions de
branchement conditionnel comme les instructions if­then­else. Seule la branche qui remplit la condition
est évaluée, tandis que l'autre branche n'est pas calculée, ce qui entraîne une évaluation paresseuse.
Ceci contraste avec une stratégie d'évaluation avide, où les deux branches sont évaluées quel que soit
le résultat de la condition. Cette forme d'évaluation paresseuse au sein de la construction if­then­
else permet un calcul efficace en évitant les évaluations inutiles des expressions dans la branche non
correspondante. Il est important de noter que, malgré ces fonctionnalités partiellement paresseuses,
la stratégie d'évaluation globale du langage reste principalement avide. La plupart des
expressions dans Power Query M sont évaluées avidement, ce qui garantit que les transformations
de données se produisent rapidement et que les résultats sont immédiatement disponibles pour un
traitement ultérieur. Ainsi, M est avant tout un langage de programmation avide, mais il intègre
une évaluation paresseuse partielle dans des constructions spécifiques, telles que les expressions
List, Record, Table et let, ainsi que les arguments de fonction facultatifs et le branchement conditionnel.
Ces évaluations partiellement paresseuses offrent flexibilité et optimisent les performances dans ces
contextes.

• Fonctionnel – M intègre de nombreuses programmations fonctionnelles


concepts et fonctionnalités, ce qui en fait un langage de programmation fonctionnel.
Ces concepts et caractéristiques fonctionnels incluent l’immuabilité, les fonctions d’ordre
supérieur, la composition de fonctions, les fonctions pures et la récursivité.

M favorise l'immuabilité, ce qui signifie que les valeurs des données ne sont pas modifiées sur place,
mais transformées en nouvelles valeurs. Cela favorise le principe de programmation
fonctionnelle qui évite les effets secondaires. M prend en charge les fonctions d'ordre supérieur,
permettant ainsi de les traiter comme des valeurs de premier ordre. Vous pouvez passer des fonctions
en arguments à d'autres fonctions, renvoyer des fonctions depuis des fonctions et stocker des fonctions
dans des variables. M facilite la composition de fonctions, vous permettant de combiner plusieurs
fonctions pour créer des transformations plus complexes.
Cette composabilité est une caractéristique de la programmation fonctionnelle. M favorise
l'utilisation de fonctions pures, sans effets secondaires, qui produisent le même résultat pour la même
entrée. Les fonctions pures rendent le code plus prévisible et plus facile à dépanner. M prend
en charge la récursivité, bien que celle­ci ne soit pas aussi largement prise en charge que
dans d'autres langages fonctionnels.
Machine Translated by Google

Dans les langages de programmation, M offre un support limité pour les fonctions récursives,
permettant aux développeurs de résoudre des problèmes grâce à des techniques
récursives. Comparé à d'autres langages, M est probablement le plus proche de F#,
un langage de programmation développé et implémenté par Don Syme de Microsoft
Research, à Cambridge, au Royaume­Uni. Maintenant que nous avons abordé la classification
formelle du langage M, examinons quelques caractéristiques plus informelles de M.

Caractéristiques informelles de M

De manière plus informelle, voici quelques caractéristiques et fonctionnalités clés de M :

1. Langage fonctionnel – M est un langage fonctionnel, ce qui signifie qu'il repose sur le
concept de fonctions comme éléments constitutifs principaux des transformations de
données. Les fonctions de M peuvent être combinées, imbriquées et composées pour
effectuer des manipulations de données complexes. M propose plus de 700 fonctions
intégrées pour les opérations courantes, ainsi que la possibilité de créer des fonctions
personnalisées adaptées à vos besoins spécifiques.

La vaste collection de fonctions intégrées de M offre aux utilisateurs des outils puissants
pour gérer divers scénarios de transformation de données. Ces fonctions sont conçues
pour simplifier les tâches courantes de manipulation de données et permettre aux utilisateurs
de transformer et de mettre en forme efficacement leurs données.

1. Syntaxe expressive et lisible – La syntaxe de M est conçue pour être intuitive et facile à
lire, la rendant accessible aux programmeurs débutants comme expérimentés. Les
expressions M sont écrites de manière claire et concise, facilitant la création de
transformations de données complexes sans compromettre la lisibilité. La
syntaxe suit une approche étape par étape, vous permettant de définir une série de
transformations séquentielles à appliquer à vos données.

2. Types de données et valeurs – M prend en charge divers types de données, notamment les
types de données primitifs tels que le texte, les nombres, les dates et la durée, ainsi que les
types de données structurés tels que les listes, les tableaux et les enregistrements. Il offre
de puissantes fonctionnalités pour manipuler et transformer les données à un niveau
granulaire. M permet également de définir et d'utiliser des variables, des constantes et
des paramètres pour stocker et réutiliser les résultats intermédiaires lors du processus de
transformation des données.

3. Intégration avec l'éditeur Power Query – M s'intègre parfaitement à l'éditeur Power


Query, offrant une interface conviviale pour interagir avec le code M et le développer.
L'éditeur Power Query vous permet de créer visuellement les étapes de
transformation des données, de prévisualiser les résultats et de générer
automatiquement du code M. Il offre un environnement de développement
robuste pour écrire, déboguer et affiner vos expressions M.

4. Extensibilité et personnalisation – L'une des principales caractéristiques de Microsoft


est son extensibilité. Outre une large gamme de transformations intégrées,
Microsoft vous permet également d'aller plus loin et de créer des transformations
personnalisées adaptées à vos besoins spécifiques.
Vous pouvez définir vos propres fonctions, des extraits de code réutilisables et créer
Machine Translated by Google

logique de manipulation de données avancée utilisant M. Ce niveau de personnalisation


vous permet de gérer des scénarios de données complexes qui ne sont pas couverts
par les transformations standard accessibles via l'interface utilisateur.
5. Optimisation des performances – M est optimisé pour les performances,
Permettant un traitement efficace des données, même avec des ensembles de données
volumineux. Le moteur Power Query évalue et optimise intelligemment les
expressions M afin de minimiser les charges et les transformations de données, pour
un traitement plus rapide et plus efficace.

Une technique spécifique d'optimisation des performances est appelée sémantique


de streaming, une propriété des expressions de liste et de table. La sémantique de
streaming implique l'énumération répétée de lignes de table ou d'éléments de liste.
Au lieu d'itérer dans la table ou la liste pour chaque transformation de données, la
sémantique de flux évalue chaque ligne de la table ou élément de la liste pour toutes les
transformations de données et les résultats sont collectés dans le résultat de l'expression. La
sémantique de flux permet de transformer des ensembles de données qui ne tiennent pas
dans la mémoire disponible. Une autre technique d'optimisation des performances
est le repliement des requêtes. Cependant, le repliement des requêtes n'est pas une
propriété du langage M lui­même. Il est utilisé dans Power Query pour renvoyer les
transformations de données vers les systèmes de données sources. En substance, les
expressions de transformation dans M sont traduites en instructions de transformation
équivalentes disponibles dans les systèmes sources tels que SQL Server. Cela renvoie le
traitement des transformations vers les systèmes sources plutôt que vers le système client
qui exécute la requête M. Cela peut améliorer les performances et l'efficacité en minimisant
le transfert de données et en réduisant la quantité de données traitées par Power Query.
En comprenant les principes sous­jacents de M et ses considérations de
performance, vous pouvez écrire du code optimisé et améliorer les performances
globales de vos workflows de données. En résumé, M est un langage polyvalent et
expressif, spécialement conçu pour la transformation et la manipulation de données
dans Power Query. Sa nature fonctionnelle, son vaste ensemble de fonctions et son
intégration avec l'éditeur Power Query en font un outil puissant pour l'extraction, le
nettoyage et le remodelage de données provenant de sources diverses. En maîtrisant M,
vous acquérez la capacité de gérer efficacement des transformations de données
complexes, de personnaliser vos workflows de données et d'optimiser les
performances, libérant ainsi tout le potentiel de Power Query pour vos besoins
de manipulation de données. Examinons ensuite un bref historique du langage M.

Histoire de M
L'histoire du langage M est étroitement liée à l'évolution des technologies de transformation
et d'intégration de données de Microsoft. Voici un bref aperçu de l'histoire de M :

1. Projet « Data Explorer » ­ Les origines de M remontent à


Le projet « Data Explorer » de Microsoft vise à fournir de puissantes fonctionnalités
d'exploration et de transformation des données. Ce projet visait à simplifier l'accès, le
nettoyage et la préparation des données provenant de diverses sources.
Machine Translated by Google

Le langage de requête a été pensé comme un langage de mashup (d'où le M pour mashup).

1. Power Query ­ En 2013, Microsoft a lancé Power Query comme module complémentaire pour
Excel. Power Query proposait une interface conviviale permettant aux utilisateurs d'effectuer
des transformations de données à l'aide d'un éditeur visuel.
Dans les coulisses, Power Query a utilisé le langage M comme langage de formule
sous­jacent pour piloter les transformations de données.
2. Intégration à Power BI – Suite au succès de Power Query dans Excel, Microsoft a intégré Power
Query à Power BI, sa plateforme de business intelligence et de visualisation de données. Cette
intégration a apporté la puissance de M à Power BI, permettant aux utilisateurs d'extraire, de
transformer et de charger des données provenant de diverses sources directement dans Power
BI Desktop.
3. Normalisation et adoption généralisée – Avec la popularité croissante de Power Query, il est
devenu nécessaire de normaliser le langage de formules sous­jacent. En 2016, Microsoft a
soumis la spécification du langage de formules Power Query à l'organisation internationale
de normalisation Ecma. Cet effort visait à établir une spécification formelle du
langage, garantissant la compatibilité et l'interopérabilité entre les différentes implémentations.

4. Changement de nom en M – Bien que le langage fût appelé familièrement « Power Query
Formula Language », il est devenu communément connu sous le nom de « M » au sein de la
communauté des utilisateurs. Ce nom informel a gagné en popularité et est
désormais largement utilisé pour désigner le langage.

5. Développement continu – Microsoft continue d'améliorer et de perfectionner le langage M


dans le cadre de ses investissements continus dans les technologies d'intégration et
de transformation des données. De nouvelles fonctionnalités et améliorations sont régulièrement
introduites pour offrir aux utilisateurs des moyens plus puissants et plus efficaces de manipuler
et de préparer leurs données.

Tout au long de son histoire, le langage M a évolué pour devenir un composant clé des outils
de transformation et d'intégration de données de Microsoft, notamment Power Query, Power
BI, Excel, etc. Sa polyvalence et son extensibilité en ont fait un langage précieux pour les
professionnels des données à la recherche de capacités de manipulation de données efficaces. Voyons
maintenant à qui devrait apprendre M.

Qui devrait apprendre M ?

M est un outil puissant pour les professionnels des données et les personnes qui travaillent
régulièrement avec des données. Sa polyvalence et ses fonctionnalités en font un langage
précieux à apprendre pour divers rôles et secteurs. Dans cette section, nous explorons les personnes
qui peuvent tirer profit de l'apprentissage de M. La liste suivante répertorie les principaux rôles qui
devraient envisager de l'apprendre :

1. Analystes de données – Les analystes de données qui s'occupent des tâches


d'extraction, de transformation et de préparation des données peuvent grandement bénéficier de
Machine Translated by Google

Apprendre M. M fournit un ensemble complet de fonctions et d'opérateurs


permettant aux analystes de données de manipuler et de structurer efficacement des
données provenant de sources diverses. En maîtrisant M, les analystes de données
peuvent automatiser les tâches répétitives, gérer des transformations de données complexes
et garantir la qualité des données, pour des analyses précises et fiables.
2. Professionnels de la Business Intelligence – Les professionnels de la Business Intelligence
(BI) peuvent considérablement améliorer leurs compétences en apprenant M. M est un
composant essentiel de Power Query, un outil d'intégration et de transformation de données
largement utilisé dans l'écosystème BI. En maîtrisant M, les professionnels de la BI
acquièrent la capacité de se connecter à diverses sources de données, d'effectuer
des transformations de données complexes et de créer des workflows de préparation de
données réutilisables. Cette maîtrise leur permet de fournir des informations exploitables et
de favoriser la prise de décisions éclairées pour leur organisation.

3. Ingénieurs de données – Ingénieurs de données impliqués dans la conception et


La mise en œuvre de pipelines de données et de processus d'intégration de données peut
bénéficier de l'apprentissage de M. M permet aux ingénieurs données d'extraire, de transformer
et de charger (ETL) efficacement des données provenant de différentes sources dans
des entrepôts ou des lacs de données. Il offre la flexibilité et la puissance nécessaires
pour gérer des scénarios de données complexes, définir des transformations personnalisées
et optimiser les flux de traitement des données. En maîtrisant M, les ingénieurs données
peuvent rationaliser les processus d'intégration de données et garantir la cohérence et la
qualité des données.
4. Data Scientists – Data scientists qui effectuent des analyses de données exploratoires
Les spécialistes de l'analyse, du développement de modèles et de l'analytique avancée
peuvent exploiter les capacités de M pour préparer efficacement leurs données. M offre un
ensemble robuste de fonctions de nettoyage, de mise en forme et d'agrégation des données,
permettant aux data scientists de se concentrer sur les aspects analytiques de leur
travail. En intégrant M à leurs workflows de préparation des données, les data scientists
peuvent rationaliser le processus de transformation des données en insights et consacrer
plus de temps à l'analyse et à la modélisation des données.
5. Utilisateurs expérimentés d'Excel – Les utilisateurs expérimentés d'Excel qui manipulent
beaucoup de données et effectuent des manipulations complexes peuvent tirer profit
de l'apprentissage de M. M est intégré à Excel via Power Query, permettant ainsi
d'effectuer des transformations de données avancées au sein de l'interface familière d'Excel.
En maîtrisant M, les utilisateurs expérimentés d'Excel peuvent étendre leurs capacités de
manipulation de données, automatiser les tâches répétitives et améliorer la précision
et la fiabilité de leurs analyses. De plus, les performances globales du classeur Excel
peuvent être améliorées, car les transformations ne sont pas effectuées dans le
moteur de formules Excel.

6. Personnes occupant des rôles axés sur les données – Au­delà des rôles spécifiques
mentionnés ci­dessus, les personnes occupant divers rôles axés sur les données, tels
que les chefs de projet, les consultants, les chercheurs et les experts du domaine, peuvent
acquérir des compétences précieuses en apprenant M. M leur donne la capacité de gérer
de manière indépendante des tâches liées aux données, d'extraire des informations
significatives et de prendre des décisions éclairées basées sur des données fiables.

En conclusion, M est un langage précieux pour un large éventail de professionnels


des données et de personnes travaillant avec des données. Que vous soyez analyste de données,
professionnel de la veille stratégique, ingénieur de données, data scientist,
Machine Translated by Google

Utilisateur expérimenté d'Excel ou occupant un poste axé sur les données, apprendre M
vous permet de manipuler, transformer et préparer efficacement les données pour
l'analyse. En maîtrisant M, vous gagnez un avantage concurrentiel, améliorez vos
compétences en données et maîtrisez la puissance de Power Query pour vos workflows.
Maintenant que nous avons identifié les profils de personnes souhaitant apprendre M,
explorons les raisons pour lesquelles ces personnes pourraient vouloir l'ajouter à leur
répertoire de langages.

Pourquoi apprendre M ?

Dans un monde axé sur les données, transformer et analyser les données de manière
efficace et efficiente est une compétence précieuse. Power Query, puissant
outil de transformation et de préparation des données, a acquis une immense popularité
grâce à son intégration transparente avec un grand nombre de sources de données et à
sa simplicité d'utilisation. Au cœur de Power Query se trouve M, le langage de
formules Power Query. Ce chapitre vise à mettre en évidence les principales raisons
pour lesquelles l'apprentissage de M peut considérablement améliorer vos capacités
de manipulation de données et faire de vous un professionnel plus compétent. Voici sept
raisons d'apprendre M :

1. Exploitez toute la puissance de Power Query – M est la pierre angulaire des


capacités de transformation de données de Power Query. En maîtrisant M,
vous maîtrisez pleinement le processus de transformation des données,
vous permettant d'extraire, de nettoyer, de transformer et de remodeler des
données provenant de sources diverses. M offre une vaste gamme de
fonctions, d'opérateurs et d'expressions qui simplifient les manipulations de
données complexes. Dans le livre de Gil Raviv, « Collect, Combine, and Transform
Data Using Power Query in Excel and Power BI », M.
Raviv estime que l'interface utilisateur graphique (GUI) pour la création de requêtes
M (voir Où est utilisé M plus loin dans ce chapitre) vous permet de résoudre
seulement 40 % des défis liés à la transformation des données, mais la
maîtrise de M vous permet de porter ce chiffre à 99,99 %.
2. Automatisation des tâches répétitives – L'une des principales raisons d'apprendre
M est d'automatiser les tâches répétitives de transformation de données. Les
professionnels de l'informatique et des affaires sont souvent chargés de recevoir
des données de manière récurrente, puis de générer des rapports à partir de ces
données. Au lieu de transformer manuellement ces données à chaque fois (souvent
dans Excel) pour les préparer à des fins de reporting, renvoyer cette transformation
vers M permet d'implémenter la logique de transformation une seule fois, puis
de l'exécuter automatiquement à chaque réception de nouvelles données.

3. Flexibilité et personnalisation – Bien que Power Query offre une interface conviviale
pour les tâches de transformation de données, elle présente néanmoins des
limites. En apprenant M, vous pouvez étendre les fonctionnalités de Power Query
et surmonter ces limitations. M vous permet d'écrire des fonctions personnalisées,
des transformations avancées et des logiques complexes qui vont au­delà
des capacités intégrées de l'interface Power Query. Cette flexibilité vous permet
d'adapter précisément vos transformations de données aux exigences spécifiques
de vos sources de données et de vos analyses.
Machine Translated by Google

4. Efficacité et optimisation des performances – M est un


Langage efficace et optimisé pour les transformations de données. Le moteur Power
Query traite intelligemment les expressions M, optimisant ainsi les performances
en réduisant les chargements et transformations de données inutiles.
Lorsque vous travaillez avec de grands ensembles de données ou des
transformations complexes, la connaissance de M vous permet d'écrire du code efficace
qui accélère considérablement le traitement de vos données. En comprenant les
principes sous­jacents de M et ses considérations de performance, vous pouvez
optimiser vos workflows de données et gagner un temps précieux. Enfin, l'utilisation
de M peut réduire et simplifier considérablement les formules et le code DAX (Data
Analysis eXpressions) dans les applications en aval comme Excel et Power BI Desktop.
5. Nettoyage et transformation avancés des données – M offre un ensemble complet de
fonctions de nettoyage et de transformation des données qui vont bien au­delà des
opérations de base des tableurs traditionnels. Avec M, vous pouvez facilement gérer les
problèmes de qualité des données, comme la suppression des doublons, la gestion
des valeurs manquantes, le fractionnement des colonnes, la fusion des ensembles
de données et la réalisation de calculs avancés. Apprendre M vous permet d'effectuer
efficacement des tâches complexes de nettoyage et de transformation des données,
pour une analyse précise et fiable des données.
6. Intégration avec d'autres langages de programmation – M est non seulement un
langage autonome, mais s'intègre également parfaitement à d'autres langages
de programmation tels que SQL, R et Python. Cette intégration vous permet d'exploiter
les capacités de ces langages dans vos workflows Power Query. Vous pouvez
combiner du code M avec des requêtes SQL natives, appeler des scripts R ou
Python, et intégrer facilement des bibliothèques et fonctions externes à votre processus
de transformation de données. En approfondissant vos connaissances avec M,
vous exploitez pleinement les fonctionnalités de différents langages de programmation
pour la manipulation de données.

7. Évolution de carrière – La maîtrise de M et de Power Query est devenue une


compétence recherchée dans le secteur des données. Alors que les organisations
s'appuient de plus en plus sur les données pour prendre des décisions, les personnes
capables de les transformer, de les nettoyer et de les analyser efficacement sont très
recherchées. En investissant du temps et des efforts dans l'apprentissage de M,
vous devenez un atout précieux pour les organisations qui s'appuient sur des
informations fondées sur les données. La maîtrise de M peut ouvrir de nouvelles
perspectives de carrière, améliorer vos perspectives d'emploi et vous permettre de
mener à bien des projets ambitieux liés aux données.

Apprendre M, le langage de formules Power Query, vous permet d'acquérir les outils et
techniques nécessaires pour manipuler, transformer et analyser efficacement des données
provenant de sources diverses. Il offre flexibilité, personnalisation et optimisation des
performances qui étendent les fonctionnalités de Power Query. En maîtrisant M, vous
bénéficiez d'un avantage concurrentiel dans le secteur des données et vous ouvrez de
nouvelles perspectives de carrière. Alors, exploitez la puissance de M et libérez votre potentiel
de manipulation de données. Nous espérons que vous êtes désormais enthousiaste à l'idée
d'apprendre M ; examinons maintenant quelques cas d'utilisation courants de M.

Comment M est­il utilisé ?


Machine Translated by Google

M trouve des applications dans divers domaines et scénarios où la transformation et la


manipulation des données sont essentielles. Sa polyvalence et son intégration à l'écosystème
Power Query en font un outil précieux pour les professionnels des données de différents secteurs. Dans
cette section, nous explorons quelques domaines clés où M est largement utilisé. M est couramment utilisé
dans les scénarios suivants :

1. Analyse et reporting des données – M est largement utilisé dans les données
Analyse et reporting. Il permet aux professionnels des données d'extraire des données de sources
multiples, de les transformer en un format clair et structuré, et d'effectuer des calculs et des
agrégations avancés.
Que vous analysiez des données de vente, des rapports financiers ou des mesures marketing, M
vous permet de préparer et de façonner efficacement les données pour une analyse plus approfondie
dans des outils tels qu'Excel, Power BI ou Power BI Report Server (PBRS).

2. Business Intelligence et entrepôt de données – Dans le domaine de la Business Intelligence (BI) et de


l'entreposage de données, M joue un rôle crucial dans le processus ETL (Extraction, Transformation,
Chargement). M permet aux ingénieurs données et aux développeurs BI de se connecter à
diverses sources de données, d'effectuer des transformations complexes et de charger les
données transformées dans des entrepôts de données ou des plateformes BI. Son intégration avec SQL,
R et Python renforce son utilité pour la création de pipelines de données complets et de workflows
d'intégration de données.

3. Intégration et nettoyage des données – M est largement utilisé dans les scénarios d'intégration de
données nécessitant la consolidation de données provenant de sources disparates. Il permet
de combiner, nettoyer et standardiser des données provenant de différents systèmes, bases de
données et formats de fichiers. Grâce à M, les professionnels des données peuvent gérer les problèmes
de qualité des données, comme la suppression des doublons, la gestion des valeurs manquantes, la
correction des erreurs de formatage et l'application de règles métier pour garantir l'exactitude et la
cohérence des données.
4. Web Scraping et extraction de données – Le Web Scraping, le processus d'extraction de données de
sites web, est un autre domaine où M est fréquemment utilisé. Avec M, vous pouvez définir des requêtes
web, naviguer dans des structures HTML et extraire des données de pages web. Cette
fonctionnalité est particulièrement utile pour collecter des informations à partir de sources
en ligne, telles que des données d'études de marché, des analyses de médias sociaux ou des ensembles
de données accessibles au public. M vous permet d'automatiser le processus d'extraction de données
et de transformer des données web non structurées en un format exploitable.

5. Transformation et préparation des données – M est une référence


Langage pour les tâches de transformation et de préparation des données. Il fournit un ensemble
complet de fonctions et d'opérateurs pour remodeler, filtrer, trier, agréger et faire pivoter les données.
Que vous ayez besoin de fractionner des colonnes, de fusionner des ensembles de données, de
transposer des données ou d'effectuer des calculs avancés, M offre la flexibilité et la puissance
nécessaires pour manipuler les données selon vos besoins spécifiques. Il vous permet de gérer
efficacement des transformations de données complexes et de préparer les données pour l'analyse et
le reporting en aval.
6. Solutions personnalisées et automatisation – L’une des solutions notables
L'un des avantages de M réside dans son extensibilité. Les professionnels des données
peuvent écrire des fonctions personnalisées, des extraits de code réutilisables et des logiques complexes
pour créer des solutions sur mesure pour des scénarios de données uniques. L'intégration de M avec
Machine Translated by Google

D'autres langages de programmation, tels que SQL, R et Python, étendent encore


ses capacités, permettant une intégration transparente avec des bibliothèques
externes et des techniques d'analyse avancées. En exploitant la puissance de M,
vous pouvez créer des solutions personnalisées de manipulation de données et
automatiser les tâches répétitives.

Il est désormais évident que M trouve de nombreuses applications dans divers domaines
liés aux données. Son utilisation couvre l'analyse de données, la business intelligence,
l'intégration de données, le web scraping, la transformation de données et
l'automatisation. En maîtrisant M, les professionnels des données peuvent améliorer leur
capacité à gérer des scénarios de données complexes, à améliorer la qualité des
données et à rationaliser les flux de traitement des données. Que vous soyez analyste de
données, développeur BI, ingénieur de données ou utilisateur métier, apprendre M vous
permet d'extraire des informations précieuses de vos données et de prendre des décisions
éclairées. Maintenant que vous comprenez comment M est utilisé, explorons ses applications.

Où est utilisé M ?
M est un langage polyvalent qui trouve son application dans divers outils et
plateformes où la transformation et la manipulation de données sont essentielles. Son
intégration à l'écosystème Power Query permet aux utilisateurs d'exploiter les capacités de M
dans différents environnements. Dans cette section, nous explorons quelques domaines clés
où M est largement utilisé.

Expériences

Avant de discuter de produits spécifiques où M est utilisé, il est important de comprendre


les différentes expériences disponibles pour la création de M. Il existe deux expériences
disponibles pour la création de M. Ces expériences sont les suivantes :

1. Power Query Desktop – Power Query Desktop est l'expérience Power Query que l'on
retrouve dans des applications de bureau telles que Power BI Desktop et Microsoft
Excel. Bien que les expériences soient similaires, il existe des différences. Par
exemple, les intégrations d'intelligence artificielle (IA) et de machine learning (ML),
ainsi que les intégrations avec R et Python présentes dans Power BI Desktop, ne
sont pas disponibles dans Microsoft Excel. Inversement, les options de colonnes
structurées disponibles dans Excel ne sont pas disponibles dans Power BI Desktop.

2. Power Query Online – Power Query Online, un service cloud, permet aux utilisateurs de
créer et de gérer des transformations de données depuis un navigateur web. M est
largement utilisé dans Power Query Online pour définir des transformations de
données, se connecter à des sources de données et effectuer des manipulations de
données complexes. Les utilisateurs peuvent accéder aux requêtes M et les modifier
directement depuis l'interface du navigateur, ce qui facilite la collaboration et le
travail sur les transformations de données depuis n'importe quel endroit disposant d'une connexion internet.
Power Query Online est intégré à une variété de produits Microsoft, notamment le
service Power BI, Power Apps, Power Automate, etc.
Machine Translated by Google

Il est important de noter que même si deux expériences différentes pour la création de M existent,
toutes deux offrent presque exactement la même expérience utilisateur.

Produits et services
M est omniprésent dans l'écosystème Microsoft, notamment dans les logiciels et services
suivants :

1. Dataflows – Les dataflows sont des requêtes M cloud, indépendantes des produits,
réutilisables sur plusieurs produits. Ils permettent aux utilisateurs de créer et de
gérer des processus de préparation et de transformation de données réutilisables.
Ils exploitent l'expérience Power Query Online.

2. Power BI Desktop – M est un composant fondamental de Power BI Desktop, un outil de


décisionnel de premier plan. M permet aux utilisateurs de se connecter à différentes
sources de données, d'effectuer des transformations de données et de créer des
visualisations et des rapports interactifs. M permet également d'extraire, de nettoyer
et de mettre en forme des données provenant de sources diverses, telles que des bases de
données, des fichiers Excel, des services web, etc. Avec M, les utilisateurs peuvent
définir des étapes de transformation de données et créer des requêtes réutilisables
qui actualisent et mettent à jour automatiquement les données lorsque la source sous­jacente change.

Dans Power BI Desktop, M est utilisé dans l'éditeur Power Query, un sous­programme lancé
depuis Power BI Desktop. L'éditeur Power Query offre une interface utilisateur graphique
performante pour travailler avec le langage de formule M, comme illustré dans la figure 1.1 ci­
dessous :

Figure 1.1 : Éditeur Power Query dans Power BI Desktop

L'éditeur Power Query est décrit plus en détail dans le chapitre 2, Utilisation de Power Query/
[Link] BI Desktop prend également en charge l'utilisation de flux de données.
Machine Translated by Google

1. Service Power BI – Le service Power BI ([Link]) est le


Composant cloud de Power BI permettant le partage de rapports, de tableaux de bord et
d'autres contenus. Le service prend en charge l'utilisation du code M via la création de
flux de données via l'interface Power Query Online.

Pour créer un flux de données dans le service Power BI, accédez à n'importe quel espace de
travail autre que Mon espace de travail et choisissez Nouveau, puis Flux de données comme indiqué
dans la figure 1.2 :

Figure 1.2 : Créer un flux de données dans le service Power BI

1. Serveur de rapports Power BI – Serveur de rapports Power BI (PBRS)


prend en charge l'expérience Power Query Desktop, permettant aux utilisateurs de
créer des transformations de données riches via M.
2. Excel (Windows et Macintosh) – M s'intègre parfaitement à Excel, permettant aux utilisateurs
d'effectuer des transformations de données avancées au sein de l'interface
familière d'Excel. Power Query, le moteur des fonctionnalités de transformation de données
d'Excel, est optimisé par M. Les utilisateurs peuvent accéder à l'éditeur Power Query dans
Excel pour appliquer des transformations M, filtrer et trier les données, supprimer les
doublons, fusionner et ajouter des tables, et effectuer d'autres tâches de préparation des
données. M permet aux utilisateurs de nettoyer, remodeler et enrichir les données dans
Excel, améliorant ainsi la précision et la fiabilité de leurs analyses.

Dans Excel, l'interface de l'éditeur Power Query est accessible via l'onglet Données du ruban et en
choisissant Obtenir les données comme illustré dans la figure 1.3 :
Machine Translated by Google

Figure 1.3 : Obtenir des données dans Microsoft Excel

Une fois la source de données choisie, l'interface de l'éditeur Power Query est accessible en
choisissant de transformer les données comme dans la figure 1.4 :
Machine Translated by Google

Figure 1.4 : Option Transformer les données dans Microsoft Excel

Les versions Windows et Macintosh d'Excel prennent également en charge l'accès et l'utilisation
des flux de données.

1. Power Apps ­ Power Apps est la plateforme low code de Microsoft pour
Création d'applications. L'expérience Power Query Online et l'utilisation de flux de
données sont prises en charge. Un cas d'utilisation courant consiste à exploiter
M, via Power Query Online ou des flux de données, pour permettre aux utilisateurs
d'intégrer facilement leurs données dans Dataverse (anciennement Common
Data Service).
2. Power Automate – Power Automate est le low code de Microsoft
Plateforme d'automatisation des workflows. Power Automate permet d'automatiser les
workflows et processus répétitifs pouvant impliquer des tâches de manipulation et
d'intégration de données. M peut être utilisé dans Power Automate pour effectuer des
transformations de données et gérer des scénarios de données complexes dans le
cadre de workflows automatisés via l'expérience Power Query Online. En intégrant
M à Power Automate, les utilisateurs peuvent créer des solutions sophistiquées
d'intégration et d'automatisation de données qui rationalisent leurs processus métier. De
plus, les flux de données peuvent être exploités dans Power Automate via le connecteur
de flux de données Power Query. Ce connecteur permet de déclencher des
actions une fois un flux de données terminé et de le lancer en tant qu'action au sein
d'un flux Power Automate.

3. Data Factory – Data Factory est un service cloud géré spécialement conçu pour les
projets d'intégration complexes d'extraction, de transformation et de chargement
(ETL) et d'extraction, de chargement et de transformation (ELT). Data Factory permet la création
Machine Translated by Google

et l'orchestration de workflows pilotés par les données, ainsi que le déplacement


et la transformation des données à grande échelle. Azure Data Factory et Data Factory
dans Microsoft Fabric prennent en charge le code M via l'expérience Power Query
Online et les flux de données.
4. SQL Server – SQL Server Integration Services (SSIS) prend en charge le moteur M
principal tandis que SQL Server Analysis Services (SSAS) prend en charge
l’expérience Power Query Desktop.
5. Dynamics 365 Customer Insights – Customer Insights, intégré à Dynamics 365, est
la plateforme de données clients (CDP) de Microsoft qui offre une vue globale
des clients et permet des expériences client personnalisées. Customer Insights prend
en charge les flux de données ainsi que l'expérience Power Query Online.

6. Visual Studio – Visual Studio permet à M d’être intégré en tant que


Langage. Cette opération s'effectue via le service de langage Power Query pour VS
Code et est disponible sur la Marketplace de Visual Studio Code. Ce service de
langage offre la saisie semi­automatique floue, le survol, des conseils de fonction et
d'autres fonctionnalités pour l'écriture de code M dans Visual Studio.

Il existe également le kit de développement logiciel (SDK) Visual Studio Power Query.
Ce SDK comprend un ensemble d'outils conçus pour faciliter la création de connecteurs
de sources de données Power Query personnalisés. Le SDK Visual Studio Power Query est
décrit plus en détail au chapitre 14, « Activation des extensions ».

1. Autres scénarios d’intégration de données – M ne se limite pas à


Les logiciels et services susmentionnés. M peut également être utilisé dans des
applications personnalisées et des environnements de programmation utilisant
les bibliothèques Power Query.

Comme vous pouvez le constater, M est largement utilisé dans différents outils et plateformes
de l'écosystème Microsoft, tels que Power BI Desktop, Excel, Dataflows et Power
Automate. M permet aux utilisateurs d'effectuer des transformations de
données avancées, de se connecter à diverses sources de données et d'automatiser
les workflows d'intégration de données. En maîtrisant M, les utilisateurs peuvent extraire
des informations précieuses de leurs données, créer des processus de transformation
de données réutilisables et améliorer leurs capacités de manipulation de données dans un
large éventail de scénarios. Intéressons­nous maintenant aux bases du langage M.

Notions de base du langage M

M est un langage puissant conçu pour la transformation et la manipulation de


données au sein de l'écosystème Power Query. Comprendre les bases du langage M est
essentiel pour exploiter efficacement ses capacités. Dans cette section, nous explorons les
éléments et concepts fondamentaux du langage M. Voici quelques principes fondamentaux
concernant le langage M :

1. Expressions et fonctions – Dans M, les expressions constituent les éléments constitutifs


des transformations de données. Une expression représente un calcul ou
une opération qui aboutit à une valeur. M propose un large éventail de fonctions
intégrées permettant d'effectuer des opérations sur
Machine Translated by Google

Données. Les fonctions en M sont appelées selon une syntaxe où le nom de la fonction
est suivi d'arguments entre parenthèses. Par exemple, la fonction [Link]("Hello, World!", 5)
renvoie la sous­chaîne « Hello » du texte d'entrée.

2. Types de données – M prend en charge divers types de données, notamment le texte,


Nombres, dates, heures, listes, tableaux et enregistrements. Comprendre les types de
données dans M est essentiel pour réaliser des transformations précises. M propose des
fonctions permettant de convertir différents types de données et de manipuler les
données en fonction de leurs caractéristiques intrinsèques. Par exemple, la fonction [Link]
convertit une valeur en texte, tandis que la fonction [Link] extrait l'année
d'une date ou d'une date/heure.

3. Variables et constantes – M vous permet de définir des variables et des constantes pour
stocker et réutiliser des valeurs lors des transformations de données.
Les variables sont créées dans une expression let , suivie d'une liste d'affectations de
variables séparées par des virgules. Les constantes, quant à elles, sont des valeurs fixes qui
restent constantes tout au long de l'exécution.
Les variables et les constantes aident à améliorer la lisibilité du code, permettent la réutilisation
et rendent les transformations complexes plus gérables.
4. Opérateurs – M prend en charge divers opérateurs pour effectuer des calculs
mathématiques, des comparaisons logiques et des manipulations de texte. Les
opérateurs arithmétiques (+, ­, *, /, etc.) sont utilisés pour les calculs numériques, tandis
que les opérateurs de comparaison (>, <, =, etc.) évaluent les conditions logiques.
L'opérateur de combinaison « & » permet de concaténer des valeurs textuelles, d'ajouter des
listes et des tableaux, ou de fusionner des enregistrements.

5. Processus de transformation étape par étape – M suit un processus de transformation étape


par étape, chaque étape définissant une opération de transformation de données.
L'éditeur Power Query fournit une interface visuelle pour définir ces étapes et génère le code
M correspondant. Ces étapes peuvent inclure des opérations telles que le filtrage de lignes,
la suppression de doublons, le fractionnement de colonnes, la fusion de tables et l'agrégation
de données.
6. Repliement des requêtes – Le repliement des requêtes est une technique d'optimisation de
Power Query qui pousse les transformations de données vers la source de données autant
que possible. Avec M, il est important de connaître le repliement des requêtes pour garantir un
traitement efficace des données. Le repliement des requêtes peut améliorer les performances en
réduisant le transfert de données entre la source de données et Power Query. Cependant,
toutes les transformations ne peuvent pas être repliées ; il est donc essentiel de comprendre
quelles opérations peuvent l'être et lesquelles ne le peuvent pas. Par exemple, avec
DirectQuery ou le mode de stockage double pour les tables, toutes les requêtes M doivent être
repliées, ce qui peut limiter certaines opérations de transformation.

7. Gestion des erreurs et débogage – M fournit des mécanismes de gestion des erreurs pour
détecter et gérer les exceptions lors des transformations de données. Grâce
à des fonctions telles que « try », « otherwise » et « error », vous pouvez contrôler le flux
d'exécution et gérer les erreurs potentielles avec élégance. De plus, M prend en charge les
fonctionnalités de débogage, comme la possibilité de parcourir le code pas à pas pour
identifier et résoudre les problèmes liés aux transformations complexes.

8. Sensibilité à la casse – M est sensible à la casse. Ceci s'applique à toutes les fonctions.
expressions, variables, constantes et autres aspects du langage M.
Machine Translated by Google

9. Commentaires – Les commentaires en M suivent le style de commentaire du langage C.


Les commentaires en ligne sont précédés de doubles barres obliques ( // ), tandis que les
commentaires en bloc utilisent le modèle barre oblique­astérisque, astérisque­barre oblique
( /* et */ ).

Maintenant que nous avons une bonne compréhension des composants principaux
du langage M, explorons ensuite le composant le plus fondamental du langage
M, l' expression let .

Laisser

Au cœur du langage M se trouve l' expression let , qui doit être associée à une
expression in . En termes simples, l' expression let contient l'entrée et les transformations,
tandis que l' expression in contient la sortie. Un simple « Hello World » en M
ressemble à ceci :

laisser

Bonjour = "Bonjour tout le monde" en

Bonjour

Ce code renverrait le texte omniprésent « Hello World ». Il est important de noter que
chaque expression dans une instruction let doit être suivie d'une virgule ( si
l'expression, ) sauf la dernière expression précédant l' expression in . Ainsi, si
let se compose de plusieurs sous­expressions, le code pourrait alors ressembler
à ce qui suit :

laisser

Bonjour = "Bonjour",
Monde = "Monde",
Retour = Bonjour & " " & Monde
dans

Retour

Ce code renvoie également « Hello World » en sortie. Comprendre les bases de M,


notamment les expressions, les fonctions, les types de données, les variables, les
opérateurs et le processus de transformation étape par étape, est essentiel pour
manipuler et préparer efficacement les données. En maîtrisant ces concepts
fondamentaux, vous serez capable d'effectuer des transformations complexes,
d'optimiser les flux de données et d'exploiter tout le potentiel du langage M.

Résumé
Le langage M constitue l'épine dorsale des capacités de transformation de
données de Microsoft Power Query. M est largement utilisé au sein de l'écosystème
Microsoft, notamment dans de nombreuses applications logicielles et services
web. De nombreux professionnels des données peuvent tirer profit de
l'apprentissage de M pour ingérer et transformer efficacement des données dans un
large éventail de scénarios. En maîtrisant M, vous maîtriserez efficacement des
transformations de données complexes, personnaliserez vos workflows et optimiserez
vos performances, libérant ainsi tout le potentiel de Power Query pour vos besoins de
manipulation de données. Dans ce chapitre, nous avons exploré les
Machine Translated by Google

Les fondamentaux du langage de formules Power Query (M) : définition,


histoire, public et intérêts. Nous avons également exploré comment et
où utiliser M. Enfin, nous avons présenté au lecteur certains composants
et constructions de langage fondamentaux de M. Ces éléments
fondamentaux présentés dans ce chapitre sont importants à comprendre
tout au long de ce livre. Le chapitre suivant aborde l'utilisation de M dans
l'interface de l'éditeur Power Query de Power BI Desktop. Il est important
de comprendre que presque partout où M est utilisé, à quelques
exceptions près comme Visual Studio, Microsoft a fourni une
interface utilisateur graphique (GUI) extrêmement similaire pour travailler
avec le langage M.
Machine Translated by Google

2 Travailler avec Power Query/M

Rejoignez notre communauté de livres sur Discord

[Link]

Dans le chapitre 1, « Présentation de M », nous avons présenté les aspects


fondamentaux du langage M, notamment les bases de la syntaxe M, ses
caractéristiques formelles et informelles, son histoire, ainsi que les personnes et
les raisons pour lesquelles il est recommandé d'apprendre M, son utilisation et
ses utilisations. Dans la section « Où M est­il utilisé ? », nous avons brièvement
présenté les expériences Power Query, notamment Power Query Desktop et
Power Query Online. Ce chapitre détaille l'utilisation de M dans Power Query
Desktop avec Power BI Desktop. Les connaissances acquises ici vous permettront
de commencer à écrire du code M via l'interface utilisateur graphique (GUI)
conviviale fournie par l'éditeur Power Query et directement transposable à
d'autres expériences bureautiques, telles que celles d'Excel et de Power Query Online
sur des sites web comme [Link].
Étant donné que ce livre est principalement axé sur le langage M, ce chapitre ne
fournit pas une couverture complète de l’expérience Power Query.
Cependant, il est important de comprendre les bases de l'endroit où le code M est
écrit et ce chapitre couvre donc les sujets suivants :

• Visite de l'expérience de bureau Power Query •


Ajustement du code généré par l'expérience
• Création de colonnes
personnalisées • Utilisation de l'éditeur avancé

Exigences techniques

• Power BI Desktop

Visite de l'expérience Power Query Desktop

Power BI Desktop intègre un puissant sous­programme appelé Éditeur Power


Query. Pour accéder à l'Éditeur Power Query, vous devez d'abord le télécharger.
Machine Translated by Google

et installez Power BI Desktop. Power BI Desktop peut être installé depuis le Microsoft
Store. Ouvrez simplement l'application Microsoft Store sur votre PC Windows et
recherchez « Power BI Desktop », comme illustré à la figure 2.1 :

Figure 2.1 : Application de bureau Power BI dans le Microsoft Store

Assurez­vous que le nom de l'application est Power BI Desktop et non Power BI. Si elle
n'est pas déjà installée, le bouton Ouvrir de la figure 2.1 indiquera « Installer ». Cliquez
sur le bouton Installer ; une fois l'application installée, le bouton Installer affichera
« Ouvrir ». Cliquez sur le bouton Ouvrir pour lancer Power BI Desktop. Pour accéder à
l'éditeur Power Query depuis Power BI Desktop, assurez­vous que l'onglet Accueil est
sélectionné dans le ruban, puis cliquez sur l'icône « Transformer les données »
dans le ruban, comme illustré à la figure 2.2 :
Machine Translated by Google

Figure 2.2 : Transformer les données dans Power BI Desktop

Maintenant que Power BI Desktop est installé et que l’éditeur Power Query est lancé,
examinons brièvement l’interface graphique de l’éditeur Power Query et les paramètres
associés.

Une brève visite

L'interface de l'éditeur Power Query présente des caractéristiques similaires à celles de


Power BI Desktop et partage des éléments communs. L'interface utilisateur de l'éditeur
Power Query se compose de sept zones principales. Reportez­vous à la figure 2.3
pour en savoir plus sur ces sept zones dans les sections suivantes.

Figure 2.3 : Expérience Power Query Desktop dans Power BI Desktop

En­tête (barre de titre et barre d'outils d'accès rapide)

Presque identique à Power BI Desktop, l'en­tête est la petite bande en haut de la fenêtre
de l'éditeur Power Query. Cette zone est standard pour les applications Windows. Un clic
gauche sur l'icône de l'application dans le coin gauche permet d'accéder aux
commandes de dimensionnement et de sortie standard, telles que
Machine Translated by Google

Réduire, Agrandir et Fermer. À côté de cette icône se trouve la barre d'outils Accès rapide.
Cette barre d'outils peut être affichée au­dessus ou en dessous du ruban, et des commandes
peuvent y être ajoutées en faisant un clic droit sur une icône du ruban et en sélectionnant « Ajouter à la
barre d'outils Accès rapide ». Par défaut, seule l' icône Enregistrer est affichée. À droite de la barre
d'outils Accès rapide se trouve le nom du fichier actuellement ouvert, suivi du nom de l'application,
Power Query Editor. Enfin, à l'extrême droite se trouvent les icônes standard « Réduire », « Restaurer/
Agrandir » et « Fermer ».

Barre de formule

La barre de formule permet à l'utilisateur de visualiser, de saisir et de modifier le code M d'une étape de
requête spécifique. Comme vous l'avez appris au chapitre 1, « Présentation de M », M est un langage
de programmation fonctionnel composé de fonctions, d'opérateurs et de valeurs permettant de se
connecter aux données et de les transformer. M est le langage des requêtes dans Power BI Desktop.
Lorsque vous créez une requête dans l'éditeur Power Query à l'aide de l'interface utilisateur
graphique, en arrière­plan, vous créez un script M qui s'exécute pour se connecter à vos données, les
transformer et les importer. Chaque étape appliquée (voir le volet « Paramètres de requête » ci­dessous)
d'une requête est en réalité une ligne de code en langage M. Vous n'avez pas à vous en préoccuper pour
l'instant, mais nous l'explorerons plus loin dans ce chapitre.

Ruban

Sous l'en­tête (Accès rapide et barre de titre) se trouve le ruban. Les utilisateurs familiers avec les versions
modernes de Microsoft Office reconnaîtront la fonction de cette zone, bien que les commandes
affichées soient légèrement différentes. Le ruban se compose de sept onglets principaux et
d'un onglet conditionnel :

1. Fichier – L' onglet Fichier affiche un menu déroulant permettant d'enregistrer des fichiers Power
BI Desktop, de fermer l'éditeur Power Query et d'appliquer les modifications apportées. De plus,
le menu Fichier donne accès aux Options et aux Paramètres de la source de données.

2. Accueil – L’ onglet Accueil fournit une variété des fonctionnalités les plus courantes
opérations, telles que la connexion aux sources, la gestion des paramètres et les fonctions de
transformation courantes telles que la suppression de lignes et de colonnes, le
fractionnement de colonnes et le remplacement de valeurs.
3. Transformer – L' onglet Transformer propose des fonctions de manipulation de données
permettant la transposition de lignes et de colonnes, le pivotement et le dépivotement
de colonnes, la fusion de colonnes, l'ajout de scripts R et Python, ainsi que de nombreux calculs
scientifiques, statistiques, trigonométriques, de date et d'heure. Il est important de
comprendre que les fonctions de l' onglet Transformer modifient une colonne
existante, contrairement aux fonctions similaires de l' onglet Ajouter une colonne qui
ajoutent une nouvelle colonne avec la transformation de données spécifiée.

4. Ajouter une colonne – L' onglet Ajouter une colonne propose des opérations axées sur l'ajout de
colonnes calculées, conditionnelles et d'index. De plus, de nombreuses fonctions disponibles
dans l' onglet Transformer , telles que
Machine Translated by Google

Bien que les calculs scientifiques, statistiques, trigonométriques et de


date et d'heure soient également disponibles dans l' onglet « Ajouter une colonne » ,
il est important de comprendre que leur fonctionnement diffère sensiblement
d'un onglet à l'autre. Dans l' onglet « Transformer » , ces fonctions transforment la
colonne sélectionnée, tandis que dans l' onglet « Ajouter une colonne » , elles
ajoutent une colonne calculée supplémentaire aux données.
5. Affichage – L’ onglet Affichage inclut des commandes permettant de contrôler la
disposition de l’interface Power Query, par exemple si le volet Paramètres
de requête est affiché ou non et si la barre de formule est affichée.

6. Outils – L’ onglet Outils donne accès aux outils de diagnostic et


options.
7. Aide – L’ onglet Aide inclut des liens utiles pour obtenir de l’aide sur Power
BI, notamment des liens vers le site de la communauté Power BI, la
documentation, l’apprentissage guidé, les vidéos de formation et bien plus encore.
8. Outils, Transformation – L' onglet Outils, Transformation s'affiche lorsque le type
de retour de la requête n'est pas une table. Cet onglet propose des options de
conversion de la valeur en table, ainsi que des options contextuelles selon
le type de données renvoyé. Par exemple, une expression renvoyant du
texte aura des options différentes de celles d'une expression renvoyant un nombre.
L' onglet Outils, Transformation d'une requête renvoyant un nombre est illustré à la
figure 2.4 :

Figure 2.4 : Outils contextuels, onglet Transformer

Maintenant que nous avons examiné le ruban, passons maintenant au volet Requêtes.

Volet Requêtes

Le volet Requêtes affiche la liste des différentes requêtes associées au fichier Power BI
actuel. Les requêtes créées sont affichées ici. De plus, si des erreurs sont générées
lors de l'exécution, cette zone affiche les ensembles de lignes correspondants. Un clic
droit sur une requête permet d'accéder à diverses options, telles que la suppression, la
copie, la duplication, le référencement et le regroupement. Certaines de ces options
méritent d'être approfondies.
Machine Translated by Google

explication:

• Copier – Cela revient à sélectionner la requête et à appuyer sur Ctrl­C.


Copier une requête crée une copie de la requête ainsi que de toutes
les requêtes et paramètres référencés/associés. Par exemple, si une requête utilise
un paramètre pour définir la source de données, comme le nom d'un serveur SQL,
d'une base de données ou le chemin d'accès à un fichier, et/ou s'il s'agit d'une
requête qui fusionne ou ajoute plusieurs autres requêtes, des copies de toutes
ces requêtes et paramètres associés
sont également créées. • Dupliquer – Créer un doublon d'une requête crée une copie
de la requête elle­même. Essentiellement, tout le code M de la requête est
copié et collé dans une nouvelle requête. Les requêtes et paramètres associés
ne sont pas dupliqués comme avec l'option Copier.
• Référence – Créer une référence crée une nouvelle requête dont la source de
données est la requête d'origine. Les références sont souvent utilisées dans les
requêtes de base qui effectuent les opérations de transformation de données
courantes requises par plusieurs requêtes/tables.
• Activation du chargement – Le chargement des requêtes peut être activé ou
désactivé dans la destination client finale, comme Microsoft Excel ou Power BI
Desktop. La désactivation du chargement maintient la requête dans l'interface
Power Query, mais elle ne crée plus de table dans l'application cliente. Il arrive
souvent que le chargement des requêtes référencées soit désactivé, car elles
effectuent des étapes intermédiaires de transformation des données.

Examinons une application pratique de ces fonctionnalités. Imaginez que vous


collectez des activités à partir d'un système de gestion de la relation client (CRM)
tel que Dynamics 365. Vous pouvez créer un paramètre définissant le point de terminaison
du système de données source. Ce paramètre sera ensuite utilisé dans une requête
« E­mails » se connectant à la table/entité E­mail sous­jacente pour importer des
données. Sélectionnez ensuite les colonnes « Utilisateur » et « Créé le » et ajoutez une
étape pour supprimer toutes les autres colonnes.
De plus, vous ajoutez une colonne Type personnalisée qui renvoie simplement « E­mail »
pour chaque ligne. Vous souhaitez maintenant importer également les rendez­vous.
Une bonne solution consiste à dupliquer votre requête E­mail et à renommer la
requête dupliquée « Rendez­vous ». Évitez de copier la requête, car cela créerait également
un doublon de votre paramètre. Modifiez ensuite la requête pour qu'elle renvoie « Rendez­
vous » comme type, toutes les autres transformations de données restant inchangées.
Vous souhaitez enfin obtenir une table finale unique appelée « E­mails et Rendez­vous ».
Cette requête ajoute simplement les requêtes E­mails et Rendez­vous. Ces requêtes de
base sont référencées par cette nouvelle requête d'ajout. Faites ensuite un clic droit
sur les requêtes E­mails et Rendez­vous et désactivez le chargement, car votre table
finale contient toutes les lignes des deux requêtes de base.

Volet Paramètres de requête

Le volet « Paramètres de requête » donne accès aux propriétés de la requête, comme son
nom. Par défaut, le nom de la requête devient celui de la table dans le modèle de données.
Plus important encore, le volet « Paramètres de requête » inclut la liste des étapes
appliquées à une requête. Une requête n'est en réalité qu'une série d'étapes
appliquées, ou transformations, aux données. À mesure que vous transformez les données,
Machine Translated by Google

Pour les données importées par une requête, une étape est créée pour chaque transformation.
Ainsi, l'exécution d'une requête visant à actualiser les données d'une source de données consiste
simplement à réexécuter ces étapes, ou opérations de transformation.

Volet d'aperçu

Le volet d'aperçu offre un aperçu des données en cours de chargement et de


transformation. Cette zone contextuelle affiche la table de données correspondant à l'étape
sélectionnée d'une requête. Les en­têtes de colonnes du volet d'aperçu permettent de renommer
les colonnes et d'accéder à un large éventail d'opérations de transformation et de nettoyage.

Barre d'état

La barre d'état est contextuelle et dépend de la requête sélectionnée dans l'éditeur Power Query.
Elle affiche des informations utiles, telles que le nombre de lignes et de colonnes d'un tableau et la
date du dernier aperçu des données.

Votre première question

Pour créer votre première requête, vous aurez besoin du fichier « Chapitre 2 – Inventaire
des [Link] » disponible avec le contenu supplémentaire de ce livre.
Ce fichier contient une exportation de l'exemple de base de données AdventureWorks DW et peut
être téléchargé à partir du référentiel Packt GitHub pour ce livre. Pour créer la requête, procédez
comme suit :

1. Dans l'éditeur Power Query, choisissez l' onglet Accueil , puis cliquez sur l'icône Nouvelle
source pour afficher la fenêtre Obtenir des données comme illustré dans la figure 2.5 :
Machine Translated by Google

Figure 2.5 : Obtenir des données dans l'éditeur Power Query

2. Choisissez Texte/CSV dans la liste de Toutes les sources de données, puis cliquez sur le bouton
Bouton de connexion .
3. Accédez à l'emplacement du « Chapitre 2 – Produit
Fichier « [Link] » , sélectionnez le fichier puis cliquez sur le bouton Ouvrir afin d'afficher
un aperçu des données comme indiqué dans la Figure 2.6 :
Machine Translated by Google

Figure 2.6 : Aperçu des données

Selon la source de données sélectionnée, cette interface change et propose différentes


options. Pour les fichiers texte/CSV, vous pouvez choisir l'origine du fichier (jeu de
caractères), le délimiteur de colonnes, ainsi que la détection des types de données et si cette
détection s'applique à l'ensemble ou à un sous­ensemble de l'ensemble de données. Comme
indiqué par l'icône d'information (i), l'aperçu est généralement réduit à un sous­ensemble des
lignes de l'ensemble de données.

1. Cliquez sur le bouton OK pour charger un aperçu plus grand (jusqu'à 1 000 lignes)
dans l'éditeur Power Query.

Après avoir cliqué sur le bouton OK, la fenêtre de l'éditeur Power Query devrait ressembler
à la figure 2.7 :
Machine Translated by Google

Figure 2.7 : Éditeur Power Query avec aperçu des données

Notez que le volet « Requêtes » affiche le nom de la requête, basé ici sur le nom du fichier
source. Le volet « Aperçu » affiche les colonnes et les données importées du fichier. Le
volet « Paramètres de la requête » affiche également le nom de la requête ainsi que trois étapes
appliquées :

• Source – Il s’agit de l’étape de la requête qui accède au fichier CSV • En­têtes


promus – Cette étape a promu la première ligne de valeurs comme
les noms des colonnes
• Type modifié – Cette étape a modifié les types de données des colonnes à l'aide de la
détection automatique basée sur les 200 premières lignes de données

La barre d'état indique un total de 8 colonnes et plus de 999 lignes de données, et le profilage des
colonnes (abordé plus loin dans ce chapitre) est basé sur les 1 000 premières lignes de données. À
droite de la barre d'état, vous trouverez également des informations sur la date de chargement de
l'aperçu. Enfin, la barre de formule affiche le code M correspondant à la dernière étape de la requête,
« Changed Type ». On peut voir que la fonction M utilisée pour modifier le type de données des
colonnes est la fonction [Link] . Les types de données choisis pour chaque
colonne sont reflétés dans les en­têtes de colonne du volet d'aperçu : les nombres entiers ( [Link] )
ont une icône 123, les dates ( type date ) une icône de calendrier et les devises ( [Link] )
une icône $. Félicitations, vous avez écrit votre première requête et votre premier code M ! Maintenant que
nous disposons d'une requête avec laquelle travailler dans Power Query Editor, examinons ensuite les
différentes options disponibles lorsque vous travaillez avec des requêtes ainsi que les paramètres de la
source de données.

Options et paramètres de la source de données


Machine Translated by Google

Plusieurs options permettent de contrôler l'apparence et le comportement de l'éditeur


Power Query, ainsi que le chargement des données dans le système. De plus,
la création d'une requête se connectant à une nouvelle source de données crée
également une source de données sur l'ordinateur local. Cette source de données peut
être gérée via l'éditeur Power Query. Commençons par les options.

Options

Pour accéder aux options qui contrôlent l'apparence et le comportement de l'éditeur


Power Query, cliquez sur Fichier dans le ruban, puis sur Options et paramètres, et
enfin sur Options comme indiqué dans la Figure 2.8 :

Figure 2.8 : Accès aux options dans l'éditeur Power Query

L'exécution de cette séquence d'actions affiche la fenêtre Options comme illustré dans
la Figure 2.9 :
Machine Translated by Google

Figure 2.9 : Options dans Power BI Desktop/Power Query Editor

La fenêtre Options de la figure 2.9 répertorie toutes les options disponibles pour Power BI
Desktop. Seule une partie de ces options affecte l'éditeur Power Query et les requêtes de
transformation de données, notamment les catégories « Chargement de données » et « Éditeur
Power Query » répertoriées dans le volet de navigation de gauche. Il est également important de
noter que les options de l'expérience Power Query Desktop dans d'autres outils, tels que
Microsoft Excel, peuvent être légèrement différentes de celles présentées ici. Cependant, dans
l'ensemble, les options des autres expériences Power Query Desktop sont très similaires et
constituent généralement des sous­ensembles des options présentées ici. De plus, les expériences
Power Query Online n'offrent généralement pas les options décrites dans cette section, car elles
sont fournies en tant que service. La figure 2.9 présente les options GLOBALES de chargement de
données . Les options globales affectent tous les fichiers, bien que certains paramètres puissent être
remplacés au niveau du rapport (FICHIER ACTUEL).

Ces options GOBAL incluent :

• Détection de type – Cela contrôle si les types de données sont


Détection automatique des types de données pour les sources de données non structurées
(telles que les fichiers texte ou Excel). Pour les sources de données structurées, les types
de données sont hérités de la source. Par défaut, les types de données des colonnes
sont détectés ( étape « Type modifié » de la figure 2.7) et les en­têtes sont détectés
automatiquement (étape « En­têtes promus » de la figure 2.7) dans les sources de
données non structurées, selon les paramètres de chaque fichier. Rappelons, comme illustré
à la figure 2.6 , comment le paramètre « Détection des types de données » nous permettait de contrôler si et
Machine Translated by Google

Comment la détection des types de données s'est produite pour votre source de données de
fichier CSV non structuré. De nombreux professionnels des données recommandent de modifier
ce paramètre pour ne jamais détecter automatiquement les types de données.
Cependant, il est certainement pratique pour l'utilisateur professionnel occasionnel, car la détection
automatique des types de Power Query
est assez efficace. • Données d'arrière­plan – Ce paramètre contrôle si les données sont
prévisualisées dans l'éditeur Power Query et téléchargées en arrière­plan. Le téléchargement des
aperçus en arrière­plan permet à l'utilisateur de continuer à travailler dans l'éditeur Power
Query sans être obligé d'attendre que les aperçus des données soient complètement
chargés. En règle générale, il est conseillé de laisser ce paramètre par défaut, autorisant le
chargement en arrière­plan des aperçus des données en fonction des paramètres de
chaque fichier. • Chargement parallèle des
tables – Pour les fichiers contenant plusieurs requêtes, Power BI charge les requêtes en parallèle
pour optimiser les performances.
Toutefois, dans certaines situations, les utilisateurs peuvent souhaiter ajuster ces
paramètres, notamment le nombre maximal d'évaluations simultanées et la mémoire maximale
utilisée par évaluation simultanée (Mo). Pour plus d'informations sur ces paramètres, consultez
la documentation Microsoft : Paramètres de configuration d'évaluation pour Desktop ­ Power BI
| Microsoft Learn. • Time Intelligence – Par défaut, Power BI Desktop crée automatiquement
une table de dates masquée pour chaque colonne de
date ou de date/heure. Bien que cela puisse être pratique pour l'utilisateur occasionnel, la plupart
des professionnels des données recommandent vivement de désactiver cette fonctionnalité. Son
activation peut souvent entraîner des modèles de données gonflés et beaucoup plus
volumineux que nécessaire. • Gestion du cache de données – L'éditeur Power Query
met en cache les résultats d'aperçu des requêtes afin d'optimiser les performances pour une
visualisation plus
rapide. Ces paramètres indiquent la quantité d'espace disque actuellement consommée par
ce cache et permettent à l'utilisateur de définir la quantité maximale d'espace disque utilisé, puis de
vider le cache si nécessaire.

Comme indiqué précédemment, les paramètres GLOBAUX peuvent être modifiés fichier par fichier, en
utilisant les paramètres du FICHIER ACTUEL pour les options de chargement des données . Les
options de chargement des données du FICHIER ACTUEL sont présentées dans la figure 2.10 :
Machine Translated by Google

Figure 2.10 : Options de chargement de données pour le FICHIER ACTUEL

Les options de chargement des données du FICHIER ACTUEL permettent de remplacer les
paramètres globaux de détection de type, d'intelligence temporelle, de données d'arrière­plan et de
chargement parallèle des tables. Deux paramètres supplémentaires sont également disponibles :

• Relations – Contrôle l’importation et la détection automatique des


Relations entre les tables chargées via des requêtes. Les valeurs par défaut de ces paramètres sont
présentées dans la figure 2.10. De nombreux professionnels des données recommandent de
désactiver la détection automatique des relations. Pour plus d'informations sur ces paramètres,
consultez Créer et gérer des relations dans Power BI Desktop ­ Power BI | Microsoft Learn.
• Questions­réponses – Active ou désactive la fonctionnalité de
questions­réponses en langage naturel de
Power BI. Ce paramètre est désactivé dans la figure 2.10 , car aucune requête n'a été chargée
dans le modèle de données. Pour plus d'informations sur ces paramètres, consultez les questions­
réponses sur les sources de données en langage naturel ­ Power BI | Microsoft Learn.

Outre les options de chargement des données pour les fichiers GLOBAL et CURRENT FILE, des
options permettent de contrôler l'apparence et le comportement de l' éditeur Power Query. Ces options
sont présentées dans la figure 2.11 :
Machine Translated by Google

Figure 2.11 : Options de l'éditeur Power Query dans Power BI Desktop

Les options répertoriées dans la figure 2.11 incluent les suivantes :

• Disposition – Contrôlez si le volet Paramètres de requête et


La barre de formule s'affiche dans l'éditeur Power Query. •
Importation de données : l'activation de cette option exploite la fonction
[Link] lors de la récupération de données à partir de pages Web. Cette
fonction peut détecter des motifs répétitifs dans le contenu, ce qui dépasse la simple
détection de tableaux HTML.
• Aperçu des données – Contrôle l'apparence du contenu de l'aperçu. • Paramètres –
Ce paramètre peut s'avérer très utile dans les environnements où les rapports passent
par les phases de développement, de test et de production. Sans ce paramètre
activé, les développeurs avaient deux choix : modifier les paramètres de la source de
données (voir la section « Paramètres de la source de données » de ce chapitre) ou
créer manuellement des paramètres de requête (voir le chapitre 6) pour des éléments tels
que les noms de serveur et de base de données, puis modifier manuellement les requêtes
pour utiliser ces paramètres. Lorsque ce paramètre est activé, la création de
paramètres est intégrée aux boîtes de dialogue de source de données et de
transformation.

Par exemple, lors de la connexion à une base de données SQL Server, l'activation de cette
fonctionnalité fournit une nouvelle option de dialogue permettant de définir un nouveau paramètre
pour le serveur et la base de données , comme illustré dans la figure 2.12 :
Machine Translated by Google

Figure 2.12 : Option de dialogue Nouveau paramètre

• Formule – Active ou désactive M Intellisense (Microsoft


technologie propriétaire de saisie anticipée).

Maintenant que nous avons exploré les options permettant de contrôler l’apparence et le
comportement de l’éditeur Power Query, discutons brièvement des paramètres de
la source de données.

Paramètres de la source de données

Tout comme la plupart des tables d'un modèle de données sont basées sur des requêtes en
langage M, la plupart des requêtes sont basées sur une source de données. Ces
définitions de sources de données sont stockées dans le fichier Desktop (Power BI Desktop ou
Excel). De plus, les identifiants d'authentification de ces sources de données sont mis
en cache localement sur l'ordinateur où Power Query Desktop est exécuté. Il est important de
noter que ces identifiants de source de données ne sont pas stockés dans le fichier
Desktop lui­même. Cela signifie que si vous ouvrez le fichier Desktop sur un autre ordinateur,
les identifiants d'authentification de la source de données doivent être saisis à nouveau. Une
fois une ou plusieurs sources de données créées,
Machine Translated by Google

généralement via la création d'une requête, les paramètres de ces sources de données peuvent être visualisés
et modifiés en choisissant de cliquer sur Fichier dans le ruban, puis sur Options et paramètres, et enfin
sur Paramètres de la source de données comme illustré dans la Figure 2.8. L'exécution de cette séquence
d'actions affiche la fenêtre Paramètres de la source de données illustrée dans la Figure 2.13 :

Figure 2.13 : Fenêtre des paramètres de la source de données

Le bouton radio « Sources de données du fichier actuel » affiche uniquement les sources de données du
fichier de bureau actuel, tandis que l' option « Autorisations globales » affiche les sources
de données utilisées pour tous vos fichiers de bureau. L' option « Sources de données du fichier actuel »
affiche les boutons « Modifier la source… », « Exporter les PBIDS », « Modifier les autorisations… »
et « Supprimer les autorisations » , tandis que l' option « Autorisations globales » n'affiche que ces trois
derniers boutons. Cliquer sur le bouton « Modifier la source… » de la requête créée dans ce chapitre vous
permet d'afficher et de modifier les options de configuration de la source de données, comme illustré à la
figure 2.14.
Machine Translated by Google

Figure 2.14 : Fenêtre des paramètres de la source de données des valeurs séparées par des virgules

Le bouton Exporter PBIDS enregistre la source de données au format JSON. Par exemple, la source de
données créée dans ce chapitre, dans la section « Votre première requête », se présente comme suit une
fois exportée :

{ "version": "0.1", "connections":


[ { "details": { "protocol": "file",
"address":
{ "path": "c:\\users\\gdeck\\onedrive\
\books\\the definitive guide to power query\\ },
"authentication": null, "query": null },
"options": {}, "mode": null } ] }

Selon le type de source de données, le bouton « Modifier les autorisations… » vous permet d'afficher et
de modifier des éléments tels que les informations d'authentification, le niveau de confidentialité, le
chiffrement et les requêtes de base de données natives approuvées pour des sources de données telles que
SQL Server. Ceci conclut notre présentation de Power Query Desktop. Passons maintenant à la modification
du code M généré avec l'éditeur Power Query.

Ajuster le code généré par l'expérience


Machine Translated by Google

Comme indiqué dans la section « Votre première requête » de ce chapitre, l'utilisation de


l'interface graphique (GUI) de Power Query Desktop pour se connecter aux données
et les transformer génère du code en langage M. Ce code peut être modifié via la barre
de formule. Par exemple, dans la zone « Étapes appliquées » du volet « Paramètres
de la requête » , en cliquant sur l' étape source de la requête, puis sur la flèche vers le bas
à l'extrême droite de la barre de formule, vous pouvez afficher le code M complet de
l'étape source, comme suit :

= [Link]([Link]("C:\Users\gdeck\OneDrive\Books\Le guide définitif de Power Q

Comme vous pouvez le voir dans ce code, deux fonctions imbriquées sont utilisées
pour se connecter au fichier CSV : [Link] et [Link] . La
fonction [Link] ne possède qu'un seul paramètre : le chemin d'accès et le nom du
fichier CSV. La fonction [Link] possède deux paramètres : le premier correspond
aux résultats de la fonction [Link] et le second à un enregistrement composé de
trois paires clé/valeur. Les enregistrements sont abordés plus en détail au chapitre 4,
« Éléments constitutifs de M ». Vous pouvez modifier le code de langue M dans la
barre de formule pour y apporter les modifications nécessaires. Par exemple, une
modification courante pour les fichiers CSV consiste à supprimer complètement la
deuxième paire clé/valeur de l'enregistrement, comme suit :

= [Link]([Link]("C:\Users\gdeck\OneDrive\Books\Le guide définitif de Power Q

Pour effectuer cette modification, cliquez simplement à l'intérieur de la barre de formule, effectuez
les modifications nécessaires, puis cliquez hors de la barre de formule ou appuyez sur la touche Entrée.
Cette modification est souvent effectuée pour aider à pérenniser les requêtes qui accèdent aux fichiers csv.
Par exemple, si une neuvième colonne est ajoutée à la source de données, la version
originale du code M ignorera cette colonne supplémentaire, car seules huit colonnes sont
spécifiées. À l'inverse, si la paire clé/valeur « Columns=8 » est supprimée de
l'enregistrement qui constitue le deuxième paramètre de la fonction [Link] ,
la colonne supplémentaire sera automatiquement reconnue et incluse dans les
données lors de l'actualisation de la requête. Une autre modification possible
concerne la fonction « Type modifié ». Cliquer sur l'étape « Type modifié » dans la
section « Étapes appliquées » du volet « Paramètres de la requête » affiche le
code de langue M suivant dans la barre de formule :

= [Link](#"En­têtes promus",{{"ProductKey", [Link]}, {"DateKey", I

La colonne MovementDate a été identifiée comme un type de données de date.


Vous pouvez également inclure un horodatage. Pour ce faire, modifiez le code dans la
barre de formule comme suit :

= [Link](#"En­têtes promus",{{"ProductKey", [Link]}, {"DateKey", I

Cette action ajoute un horodatage de 00:00:00 à toutes les dates de la colonne


MovementDate. Comme vous pouvez le constater, la barre de formule est le premier
endroit, le plus évident, où vous pouvez écrire votre propre code M personnalisé. Nous
explorerons ensuite une autre option pour saisir du code M personnalisé : l'ajout de
colonnes personnalisées.
Machine Translated by Google

Création de colonnes personnalisées

La création de colonnes personnalisées est une opération courante de transformation


de données avec Power Query et le langage M. Dans cette section, nous explorerons
plusieurs façons de créer des colonnes personnalisées à l'aide de l'interface graphique
de l'éditeur Power Query et en écrivant du code M personnalisé.

Ajout d'une colonne d'index

Une colonne d'index fréquemment ajoutée aux requêtes M numérote les lignes par ordre
séquentiel. Pour ajouter une colonne d'index à la requête existante créée dans la
section « Votre première requête » de ce chapitre, procédez comme suit :

1. Cliquez sur l' onglet Ajouter une colonne du ruban, puis cliquez sur la flèche
déroulante à droite de l' option Colonne d'index , et enfin choisissez comme indiqué
dans la Figure 2.15 :

Figure 2.15 : Ajout d'une colonne d'index commençant à 1

Cette action ajoute une étape « Index ajouté » dans la zone « Étapes appliquées » du panneau
« Paramètres de Power Query » . La barre de formule affiche le code M suivant : « Index
ajouté » = [Link](#"Changed Type",
"Index", 1, 1, [Link]). Dans ce cas, la fonction [Link] est utilisée pour ajouter une
colonne appelée « Index » (deuxième paramètre) à la table renvoyée par l' étape
« #Changed Type » (premier paramètre). Cette colonne « Index » commence à 1
(troisième paramètre), s'incrémente de 1 (quatrième paramètre) et est un type de données
entier ([Link]). Voyons maintenant comment ajouter des colonnes à l'aide d'exemples.

Ajout de colonnes par des exemples

L'ajout de colonnes via des exemples s'appuie sur une méthode avancée
d'apprentissage automatique (ML) pour identifier la signification des données
d'exemple saisies par l'utilisateur dans les nouvelles lignes et écrire
automatiquement le code M correspondant pour effectuer la transformation de
données appropriée. Un exemple classique est la présence d'une colonne prénom et d'une colonne nom.
En utilisant l'ajout de colonnes par exemple, on peut entrer le prénom et le nom dans un
Machine Translated by Google

nouvelle colonne séparée par un espace et Power Query créera automatiquement le code M pour
concaténer les valeurs dans les deux colonnes d'origine. Nous pouvons tester l'ajout de
colonnes par exemple en suivant ces étapes :

1. Cliquez sur l' onglet Ajouter une colonne du ruban, puis sur la fonction « Colonne à partir
d'exemples » dans la zone « Général ». Le volet d'aperçu s'affiche alors comme illustré
à la figure 2.16 :

Figure 2.16 : Ajouter une colonne à partir d'exemples

2. Comme indiqué dans la figure 2.16, saisissez 166,25 dans les deux premières lignes.
Power Query détermine automatiquement que ce nombre est la multiplication des
colonnes UnitsCost et UnitsBalance .
3. Cliquez sur le bouton OK.

Une nouvelle colonne est créée appelée « Multiplication » avec la formule suivante :

= [Link](addIndex, "Multiplication", chaque [UnitCost] * [UnitsBalance], type nombre

Allez­y et supprimez cette colonne Multiplication en cliquant avec le bouton droit sur l'en­tête de
la colonne et en choisissant Supprimer, ou en cliquant simplement sur l' icône X à gauche de l'
étape « Multiplication insérée » qui a été ajoutée à la zone Étapes appliquées du volet
Paramètres de requête . Passons maintenant à la création/modification de colonnes à l'aide
d'opérations mathématiques.

Opérations mathématiques

Les données de la requête créée dans la section « Votre première requête » de ce


chapitre comprennent une colonne « Coût unitaire » et une colonne « SoldeUnités » . Au lieu de
conserver ces deux colonnes dans les données, vous pouvez les consolider en une seule, les
multipliant par deux. Pour ce faire, procédez comme suit :

1. Dans le volet d'aperçu, cliquez sur l'en­tête de colonne pour le coût unitaire
colonne.
2. Tout en maintenant la touche Ctrl du clavier enfoncée, sélectionnez ensuite le
en­tête de colonne pour la colonne UnitsBalance.
3. Cliquez sur l' onglet Ajouter une colonne du ruban, puis cliquez sur le bouton
Option standard dans la section À partir du numéro du ruban, puis choisissez enfin
Multiplier comme indiqué dans la figure 2.16 :
Machine Translated by Google

Figure 2.16 : Multiplication de deux colonnes

Ces actions ajoutent une étape « Multiplication insérée » dans la zone « Étapes appliquées » du
panneau « Paramètres de Power Query » . La barre de formule affiche le code M suivant, avec l' étape
« Multiplication insérée » sélectionnée :

= [Link](#"Index ajouté", "Multiplication", each [UnitCost] * [UnitsBalance], Curre

Ici, la fonction [Link] permet d'ajouter une colonne appelée Multiplication


(deuxième paramètre) à la table renvoyée par l' étape #« Added Index » (premier paramètre).
Pour chaque ligne, la colonne UnitCost est multipliée par la colonne UnitsBalance (troisième
paramètre) et le type de données de la colonne est [Link] (quatrième paramètre).
Ne vous inquiétez pas si certaines syntaxes, comme l'utilisation du mot­clé each, ne vous
semblent pas claires pour le moment. Cette syntaxe sera expliquée en détail
dans les prochains chapitres. Nous avons exploré deux méthodes permettant de créer
des colonnes personnalisées via l'interface graphique de l'éditeur Power Query.
Cependant, aucun de ces scénarios ne nécessitait d'écrire du code M. Dans les deux cas,
le code M a été généré automatiquement. Voyons maintenant comment ajouter une
colonne personnalisée en écrivant nous­mêmes un peu de code M.

Ajout de colonnes de code M personnalisées

Dans l'exemple suivant, nous allons saisir nous­mêmes du code M simple. Cependant,
nous utiliserons encore l'éditeur Power Query pour écrire la majeure partie du code M. Pour
créer une colonne de code M personnalisée, procédez comme suit :

1. Cliquez sur l' onglet Ajouter une colonne du ruban, puis cliquez sur le bouton
Option Colonne personnalisée dans la section Général du ruban afin d'afficher la boîte
de dialogue Colonne personnalisée comme illustré dans la Figure 2.17 :
Machine Translated by Google

Figure 2.17 : Boîte de dialogue Colonne personnalisée

2. Remplacez le mot Personnalisé sous Nouveau nom de colonne par le texte MovementBalance

3. Sous l' invite de formule de colonne personnalisée , entrez ce qui suit


code:

( [UnitésEntrées] ­ [UnitésSorties] ) * [CoûtUnitaire]

1. Cliquez sur le bouton OK

Comme notre colonne « Multiplication » précédente , cette colonne effectue des opérations mathématiques
simples sur plusieurs colonnes. Dans ce cas, pour chaque ligne de données, la colonne « UnitésSorties »
est soustraite de la colonne « UnitésEntrées » , puis le résultat est multiplié par la colonne « CoûtUnit » .
La colonne résultante, nommée « SoldeMouvement » , contient le coût positif ou négatif de la
différence entre les unités entrées et sorties sur chaque ligne. Ces actions ajoutent une étape
personnalisée ajoutée dans la zone « Étapes appliquées » du panneau « Paramètres de
Power Query » . La barre de formule affiche le code M suivant avec l' étape personnalisée ajoutée
sélectionnée :

= [Link](#"Multiplication insérée", "MovementBalance", each ( [UnitsIn] ­ [UnitsO

Cette formule est extrêmement similaire à notre colonne Multiplication précédente.


Une différence notable réside dans l'absence d'un quatrième paramètre spécifiant le type de
données de la nouvelle colonne. En examinant attentivement l'en­tête de notre nouvelle colonne,
nous pouvons constater que l'icône de type de données à gauche affiche ABC123,
indiquant que cette colonne n'a pas de type de données spécifique. Pour corriger ce problème,
Machine Translated by Google

situation, utilisez la barre de formule pour modifier le coût comme suit :

= [Link](#"Multiplication insérée", "MovementBalance", each ( [UnitsIn] ­ [UnitsO

Nous avons maintenant spécifié que le type de données de notre colonne


MovementBalance est [Link] et l'icône de type de données de notre colonne
affiche désormais un $. Jusqu'à présent, nous avons progressivement introduit l'écriture
de code M personnalisé, tout en nous appuyant fortement sur l'éditeur Power Query pour écrire
la majeure partie du code. Voyons maintenant comment accéder pleinement au code M
pour les requêtes et y apporter des modifications sans recourir à l'éditeur Power Query
pour les tâches les plus complexes.

Utilisation de l'éditeur avancé


Alors que la plupart des novices s'appuient fortement sur l'interface graphique et l'éditeur
Power Query pour écrire la totalité ou la majeure partie de leur code M, les utilisateurs
avancés souhaiteront progressivement accéder directement au code M, comme le code
source est créé et modifié dans la plupart des autres langages de programmation.
Heureusement, l'éditeur Power Query propose une telle interface : l'éditeur avancé. Pour
y accéder, cliquez sur l'onglet « Accueil » du ruban, puis sélectionnez « Éditeur avancé »
dans la section « Requête », comme illustré à la figure 2.18.

Figure 2.18 : Accès à l'éditeur avancé

Cela lance la boîte de dialogue Éditeur avancé comme illustré dans la Figure 2.19 :
Machine Translated by Google

Figure 2.19 : L'éditeur avancé

La figure 2.19 présente l'intégralité du code M constituant la requête « Inventaire des


produits » du chapitre 2. Toutes les étapes de la requête sont contenues dans l'expression
« let » présentée au chapitre 1, « Principes de base du langage M ». De plus, la liste déroulante
« Options d'affichage » permet d'afficher les numéros de ligne et d'activer le retour
automatique à la ligne. Cliquer sur l'icône en forme de point d'interrogation ( ? ) ouvre
la page de référence de la fonction Power Query M dans un navigateur web. Le site web
[Link], géré par Rick de Groot, offre une excellente source d'informations,
notamment pour les énumérations de code M (ensembles définis et fixes de valeurs
possibles pour un argument de fonction). Par exemple, [Link] contient
une liste exhaustive d'énumérations de code M (ensembles de valeurs possibles pour un
argument de fonction), alors que ces informations sont quasiment absentes de la
documentation officielle du langage M de Microsoft. Parmi les sites web utiles, en dehors de
la documentation officielle du langage M de Microsoft, le site [Link] est
un excellent site web pour formater automatiquement le code M conformément aux
meilleures pratiques. Bien que l'éditeur avancé inclue des fonctionnalités de saisie semi­
automatique et de formatage des couleurs, il ne dispose d'aucune fonctionnalité de
formatage automatique. Les touches de raccourci suivantes sont disponibles pour effectuer un zoom avant et arrière :

• Zoom avant – Ctrl + Maj + = •


Zoom arrière – Ctrl + Maj + ­

Notez que ces raccourcis clavier pour le zoom fonctionnent également dans l'éditeur Power
Query lui­même, et pas seulement dans l'éditeur avancé. Grâce à l'éditeur avancé,
l'intégralité du contenu de la requête peut être modifiée pour permettre une indentation
correcte du code afin d'en améliorer la lisibilité, ainsi que pour simplifier les noms d'étapes,
par exemple en implémentant la casse Camel. Comme illustré à la figure 2.18, les noms
d'étapes contenant des espaces doivent être préfixés par un hashtag (#), puis le nom
de l'étape entre guillemets. Par exemple, l'intégralité du code de l'éditeur avancé peut
être remplacée par ce qui suit :
Machine Translated by Google

laisser

Source =
[Link]( [Link]("C:
\Users\gdeck\OneDrive\Books\Le guide définitif de Power Quest [Delimiter=",",Encoding=1252, QuoteStyle=[Link]] ), promoteHeaders = [Link](Source,
[PromoteAllScalars=true]), changeTypes = [Link]( promoteHeaders, { {"ProductKey", [Link]}, {"DateKey",
[Link]},
{"MovementDate", type datetime}, {"UnitCost", [Link]}, {"UnitsIn", [Link]}, {"UnitsOut", [Link]}, {"UnitsBalance", [Link]},
{"EnglishProductName", type
text} } ), addIndex = [Link](changeTypes, "Index", 1,
1, [Link]), addInventoryBalanceColumn =
[Link]( addIndex,
"InventoryBalance", each [UnitCost] * [UnitsBalance], [Link] ),
addMovementBalanceColumn =

[Link]( addInventoryBalanceColumn,
"MovementBalance", each ( [UnitsIn] ­ [UnitsOut] ) * [UnitCost], [Link] )
dans addMovementBalanceColumn

Avec ces changements, le code devient beaucoup plus propre et plus facile à lire
comme le montre la figure 2.20 :
Machine Translated by Google

Figure 2.20 : Éditeur avancé avec modifications de code personnalisées

Il est important de noter que si vous utilisez l'Éditeur avancé pour renommer les étapes,
il est nécessaire d'ajuster manuellement toutes les autres expressions qui y font référence.
Pour cette raison, il peut être préférable d'utiliser la zone « Étapes appliquées » du
volet « Paramètres de requête » pour renommer les étapes en faisant un clic droit sur le
nom de l'étape et en choisissant « Renommer ». Une fois le code M modifié dans l'Éditeur
avancé, vous pouvez appliquer les modifications en cliquant sur le bouton « Terminé ». Pour
charger les données dans le modèle Power BI ou dans Excel, cliquez sur le bouton
« Fermer et appliquer » à l'extrême gauche de l'onglet « Accueil » du ruban, comme illustré à
la figure 2.18. Ceci termine notre exploration de l'Éditeur avancé dans Power Query
Desktop.

Résumé
Les expériences Power Query Desktop et Online fournissent l'interface principale pour
l'écriture de code M. Ces expériences évitent en grande partie à l'utilisateur d'avoir à écrire
directement la totalité ou la majeure partie du code M qui compose les requêtes.
Cependant, à mesure que votre maîtrise du langage M se développera, vous serez
amené à écrire plus fréquemment du code M directement. Dans ce chapitre, nous avons
présenté l'expérience Power Query en utilisant Power Query Desktop dans Power
BI Desktop. Nous avons notamment présenté les principaux composants de l'interface de
l'éditeur Power Query, ainsi que les options qui contrôlent son apparence et son
comportement.
Machine Translated by Google

et comment visualiser et modifier les paramètres des sources de données. Nous


avons également abordé plusieurs façons de modifier ou d'écrire du code M,
notamment l'utilisation de la barre de formule et l'ajout de colonnes personnalisées.
Enfin, nous avons exploré l'éditeur avancé pour effectuer des modifications
massives et écrire du code M plus avancé. Dans les chapitres suivants, nous
approfondirons le langage M, en commençant par une exploration du moteur de typage intégré.
Machine Translated by Google

3 Comprendre les valeurs et


Expressions

Rejoignez notre communauté de livres sur Discord

[Link]

Maintenant que nous avons couvert un aperçu de M, examiné les éléments de l'interface
utilisateur de Power Query et discuté de la façon d'accéder à vos données et de les
combiner, nous sommes prêts à plonger dans les composants spécifiques du
langage M. Le premier de ces composants est « valeurs », ce qui découle
naturellement de notre chapitre précédent, car chaque fois que vous ingérez des fichiers
dans Power Query, chaque élément de données individuel est une valeur. Si vous considérez
Power Query et M comme le « laboratoire » où vous allez nettoyer et façonner vos données
afin qu'elles soient bien préparées pour la modélisation et le reporting des données, alors
les valeurs sont les « atomes » du code M – les plus petites unités individuelles.
Ces valeurs sont combinées pour former des expressions, constituant ainsi les « molécules »
de notre laboratoire. Une ou plusieurs expressions sont ensuite intégrées pour former
des « composés » extrêmement puissants (c'est­à­dire des requêtes) qui vous
permettent de transformer vos données d'une infinité de façons. Dans ce chapitre, nous
examinerons en détail ces valeurs atomiques, en examinant les différents types que
vous rencontrerez et en examinant leur impact direct sur ce que vous pouvez (ou ne
pouvez pas) en faire. Nous examinerons également la structure de base des expressions
et des requêtes, ainsi que les « liens » qui unissent les valeurs au sein d'une
expression : les opérateurs et les structures de contrôle. Vous découvrirez les
différents types de valeurs, y compris les points clés à prendre en compte lors de l'utilisation
de chaque type de valeur, comment les opérateurs et les structures de contrôle sont
utilisés pour combiner des valeurs dans des expressions et des requêtes, et enfin
comment les énumérateurs sont utilisés pour définir le fonctionnement de certaines
valeurs de fonction. Ce chapitre aborde les sujets suivants :

• Introduction aux valeurs •


Introduction aux expressions et aux requêtes •
Opérateurs •
Structures de contrôle
Machine Translated by Google

• Recenseurs

Commençons par examiner de plus près les valeurs dans M.

Présentation des valeurs

Le langage M reconnaît 15 types de valeurs différents, répartis dans les catégories


suivantes :

• Valeurs primitives – Éléments de données individuels que M traite comme une seule unité à
des fins de traitement et d'opérations. Dans le contexte DAX, on les appelle valeurs scalaires.
• Valeurs structurées – Elles peuvent contenir plusieurs valeurs
avec une structure spécifique, bien qu'il soit possible qu'une valeur structurée donnée ne contienne
qu'une seule valeur ou aucune valeur du tout. Les trois types de valeurs structurées sont les
listes, les enregistrements et les tables, qui seront abordés en détail au chapitre XX. Les valeurs
structurées qui contiennent d'autres valeurs structurées (également appelées « structures
imbriquées ») seront abordées en profondeur au chapitre XX. • Valeurs de fonction – Une fonction
est une valeur qui représente un mappage d'un ensemble de valeurs d'argument vers une
valeur unique. Le
langage M comprend plus de 700 fonctions définies, et les utilisateurs ont la possibilité de développer
leurs propres fonctions personnalisées qui peuvent être réutilisées et appliquées à
plusieurs requêtes. Le développement de fonctions personnalisées sera abordé au chapitre
XX. • Valeurs de type : Elles peuvent être considérées comme des « méta »­valeurs qui fournissent
des informations sur le type de données d'une autre valeur.

La classification des valeurs dans leur type de données approprié est un


processus qui sera traité en détail dans le chapitre XX.

Vous trouverez ci­dessous un bref résumé de chacune des 15 valeurs reconnues dans ces
quatre groupes. Notez que les « littéraux » représentent des valeurs spécifiques qu'une
valeur d'un type particulier peut prendre.

Gentil Littéral Description


Primitif
Date #date( 2023, 12, 29 )
Les valeurs de date sont
spécifiées au format :

#date(année, mois, jour)


Machine Translated by Google

Binaire #binaire( « QRST » ) Les données binaires sont

représenté comme un
séquence de valeurs d'octets.
Le plus fréquemment utilisé dans
ingérer du contenu Web,
contenu multimédia et
pour connecteurs personnalisés
Date et heure #datetime( 2023, 11, 26, Les valeurs de date sont spécifiées
24, 59, 01 ) au format :
#datetime( année, mois,
jour, heures, minutes,
secondes)
DateTimeZone #datetimezone( 2023, Les valeurs de date sont spécifiées
11, 26, 24, 59, 1, 08, 00) au format :
#datetime( année, mois,
jour, heures, minutes,
secondes, heures décalées,
minutes décalées)
Durée #duration( 1, 5, 30, 0 ) Valeurs de durée
représenter un spécifique
période, définie comme
#durée(jours, heures,
minutes, secondes)
Logique vrai faux L'une des deux valeurs de vérité,
vrai ou faux, généralement
utilisé dans les comparaisons
et conditions
Nul nul Un inconnu ou manquant
valeur, notée null
Nombre ­1 0 1 1,5 2,3e­5 Les valeurs numériques peuvent être

entiers ou décimaux
Texte "Canada" Les données textuelles sont

représenté au sein
guillemets doubles
Temps #temps( 23, 59, 15 )
Les valeurs temporelles sont

spécifié dans le format :

#temps( heures, minutes,


secondes).

Valeurs structurées
Liste { 1, 2, 3 } Une séquence de valeurs
défini entre accolades
Enregistrer [ A = 2023, B = Une collection de noms
« Argentine » ] valeurs regroupées dans
crochets
Tableau #table( { « a », « b »}, Une collection de lignes,
Machine Translated by Google

{{1,2},{3,4}}) où chaque ligne est un


enregistrement

Valeurs de fonction
* 2
Fonction (x) => x Une expression qui prend une
ou plusieurs valeurs
d'entrée et renvoie une
valeur

Valeurs de type
Taper tapez date, tapez table Les types sont utilisés
pour classer les valeurs en
fonction de leur nature

Tableau 3.1 : Types de valeurs dans MMaintenant que vous avez été initié aux types de
valeurs que vous rencontrerez dans M, nous allons les explorer chacune plus en détail.

Structure et utilisation de chaque type de valeur

Chacun des 15 types de valeurs possède une structure unique, des utilisations différentes et un
accès à différentes fonctions du code M. Outre ces caractéristiques pour chaque type de valeur,
cette section mettra également en évidence les subtilités liées à chaque type de valeur, qui
peuvent vous perturber si vous n'en avez pas conscience.

Valeurs binaires
Les valeurs binaires sont celles stockées sous forme d'octets (séquences de zéros et de uns).
Il s'agit généralement de fichiers lisibles par des programmes spécifiques, tels que des images.
Les données binaires sont traitées par Power Query dans trois cas d'utilisation principaux :

• Ingestion de données locales (via la fonction [Link]) • Ingestion


de données depuis le Web (via la fonction [Link]) • Ingestion de données via
des connecteurs personnalisés

De plus, lorsque l'utilisateur saisit des valeurs via le bouton « Saisir des données », celles­ci sont
converties en binaire lors de leur enregistrement. Par exemple, si nous saisissons
manuellement les données suivantes via l'option « Saisir des données », elles seront converties
en binaire, puis encodées en texte :
Machine Translated by Google

Figure 3.1 Données

Figure 3.2 : Création d'une valeur binaire via l'option Saisir des données

Structure

#binaire( valeur comme n'importe quelle ) comme n'importe quelle

Crée une valeur binaire à partir d'une liste de nombres ou d'une valeur de texte codée en
base 64.

Exemples

Les deux exemples suivants produiront la même valeur binaire :

Figure 3.3 : Création directe d'une valeur binaire à partir d'un texte et d'une liste de nombres

Fonctions associées

Il existe 40 fonctions binaires liées, réparties dans les sept catégories suivantes :

• Mise en mémoire tampon et compression – les fonctions mettent en mémoire tampon


les valeurs binaires et compressent et décompressent les valeurs binaires.
• Ordre des octets – cette fonction spécifie l'ordre des octets d'un binaire.
valeur
Machine Translated by Google

• Création et conversion – ces fonctions créent et convertissent des valeurs


binaires vers et depuis d'autres types de valeurs •
Informationnelles – ces fonctions renvoient des informations sur la longueur et le
type de contenu déduit des valeurs binaires •
Lecture – cette catégorie représente plus de la moitié du total des fonctions
binaires associées et spécifie comment différentes valeurs binaires doivent être lues

• Transformation – ces fonctions combinent, divisent et extraient des parties spécifiées


de valeurs binaires • Affichage
– ces fonctions sont utilisées pour créer et manipuler des vues de données binaires sans
modifier le contenu binaire sous­jacent

Considérations particulières

• Structure de données unique – Les images, le texte, les données numériques et de


nombreux autres types peuvent être traités comme des données binaires dans M.
Comprendre comment chacun de ces différents types de valeurs est structuré, codé
et encodé est essentiel pour travailler avec succès avec des valeurs binaires.

L'utilisation de valeurs binaires dans les connecteurs personnalisés sera abordée en détail
dans le chapitre XX, tandis que le rôle des valeurs binaires et des fonctions dans l'ingestion
de données locales et Web sera développé dans le chapitre XX.

La famille de valeurs Date/Heure


La plupart des valeurs de données que vous rencontrerez sont probablement liées,
d'une manière ou d'une autre, à des moments précis. Que vous analysiez les tendances
des ventes de produits, l'amélioration des capacités des modèles d'IA, l'évolution de
l'intensité des tempêtes ou les résultats du 100 mètres olympique, le moment où ces
événements se sont produits sera très pertinent, d'où cette « famille » de valeurs qui
répondent toutes à la question « quand ? ». sera parmi les types de valeurs les plus
importants et les plus fréquents que vous rencontrerez lorsque vous travaillerez avec M. De
plus, être capable de manipuler habilement ces valeurs est une compétence essentielle
pour les développeurs Power BI, car toute analyse avec un élément temporel nécessitera
une table Date/Calendrier dans votre modèle de données Power BI, et si cette table ne
provient pas d'une source en amont telle qu'un entrepôt de données, nous croyons
fermement que la création de cette table de dimension dans Power Query à l'aide de
M représente une bonne pratique (beaucoup plus sur ce sujet à venir dans le chapitre XX,
qui se concentre sur des sujets avancés relatifs aux dates, heures et durées. Ainsi,
parce que ces fonctions aident toutes à caractériser l'aspect temporel de vos données,
nous aborderons les valeurs Date, Heure, DateTime, DateTimeZone et Durée ensemble
dans cette section. Notez, cependant, que la discussion des calculs impliquant les
valeurs Date, Heure, DateTime, DateTimeZone et Durée peut être trouvée dans la section
suivante traitant des opérations.

Valeurs de date

Les dates sont de loin la granularité la plus courante à laquelle les données sont collectées,
et donc si vous comprenez comment Power Query gère les dates et comment les
manipuler dans M, vous maîtriserez le reste des types de valeurs dans
Machine Translated by Google

cette famille est simple, car de nombreux concepts et modèles généraux s'appliquent aux
autres.

Structure

Les valeurs de date peuvent être créées à l’aide de la structure suivante :

#date

(année comme nombre,


mois comme nombre, jour
comme nombre,)
comme date

Les entrées ont les restrictions supplémentaires suivantes, sinon l'expression renverra une erreur :

• 1 ≤ an ≤ 9999 • 1 ≤
mois ≤ 12 • 1 ≤ jour ≤
31

L'expression littérale #date est sensible à la casse et ne présente aucune spécification alternative.
Par conséquent, #Date et #DATE renverront des erreurs.

Exemples

date(2023, 11, 1) renvoie une valeur représentant le 1er novembre 2023.

Fonctions associées

Il existe près de 60 fonctions permettant de manipuler les valeurs de date. Elles se répartissent
généralement comme suit :

• Fonctions [Link] (par exemple, [Link]) – ces fonctions acceptent une valeur
Date, DateTime ou DateTimeZone, ainsi qu'un nombre, et ajoutent le nombre spécifié de
périodes à la valeur d'origine. Notez que le nombre peut être négatif pour remonter dans
le temps. • Fonctions de composant de date – elles acceptent tout
type de valeur de date et renvoient le composant spécifié sous forme de nombre (par
exemple, [Link]) ou de texte (par exemple, [Link]). • Fonctions [Link]
et [Link] (par exemple, [Link])
– ces fonctions acceptent une valeur Date, DateTime ou DateTimeZone et renvoient le
même type de valeur pour la date qui remplit la fonction. Par exemple, en reprenant notre
exemple précédent, [Link]( # date(2023, 11, 1)) renvoie le 30 novembre
2024.

Fonctions [Link] (par exemple, [Link]) : ces fonctions acceptent une


valeur Date, DateTime ou DateTimeZone et renvoient un résultat logique. Le composant
datetime utilisé pour évaluer la valeur logique de l'expression est basé sur la valeur
système à la date/heure d' évaluation. Par exemple, si l'expression [Link]( #
date(2023, 11, 1)) est évaluée le 1er août 2023, l'instruction finale à évaluer sera 2022
(année précédente de l'expression d'entrée) =
Machine Translated by Google

2023 (année de la date d'entrée) et sera évaluée comme


fausse. • Fonctions [Link] et [Link] : ces fonctions transforment une valeur de
date en un autre type de valeur ou extraient une valeur de date d'un autre type.
Par exemple, [Link]( # date(2023, 11, 1)) renvoie le 11/1/2023 sur mon
ordinateur, en fonction de la culture locale par défaut (nous aborderons en détail
l'impact du paramètre de culture dans le chapitre suivant).

La fonction [Link] possède également un paramètre de format facultatif qui


vous permet de personnaliser le format de sortie. Ainsi, alors que [Link]( # date(2023,
11, 1)) renvoie 1/11/2023, [Link]( # date(2023, 11, 1), [Format=“dd MMM yyyy”])
renvoie 1er novembre 2023.

Considérations particulières

Système de date dans Power Query – Bien que la structure #date(année, mois, jour)
soit le principal moyen de spécifier des dates dans Power Query, il est très utile de
connaître le système de date sous­jacent utilisé par Power Query (dans Excel et
Power BI Desktop). Les dates sont calculées comme des nombres entiers représentant
le nombre total de jours écoulés depuis le 30 décembre 1899.

Ceci est très pratique pour les fonctions qui n'acceptent pas les dates en entrée, mais les
nombres. Par exemple, l'expression de génération de liste, abordée en détail au chapitre XX,
renverra une erreur si vous saisissez directement les dates en entrée. Or, comme illustré à la
figure 3.4 ci­dessous, si vous convertissez d'abord les dates en leurs numéros de série sous­
jacents, évaluez l'expression avec des nombres entiers, puis convertissez la liste
résultante en dates, cela fonctionne parfaitement.

Figure 3.4 : Transformation d’une date en son numéro de série sous­jacent avant de
générer une liste.

Ceci conclut notre aperçu des valeurs de date, mais les concepts avancés et les
applications impliquant la famille de valeurs Date/Heure seront abordés de manière
beaucoup plus détaillée dans le chapitre XX.
Machine Translated by Google

Valeurs temporelles

Les valeurs temporelles en M représentent un point particulier d'une journée, exprimé à l'aide d'un
cycle de 24 heures.

Structure

Les valeurs temporelles peuvent être créées à l’aide de la structure suivante :

#date

(année comme nombre,


mois comme nombre, jour
comme nombre,)
comme date

Les entrées ont les restrictions supplémentaires suivantes, sinon l'expression renverra une erreur :

• 0 ≤ heure ≤ 24 • 0
≤ minute ≤ 59 • 0 ≤
seconde < 60 • si l'heure
est 24, alors la minute et la seconde doivent être 0

De plus, comme avec l’expression littérale #date, l’expression #time est sensible à la casse.

Exemples

time( 7, 23, 30) renvoie 7:23:30 AM time(23, 59, 59) renvoie


23:59:59 PM time(24, 0, 0) renvoie 00:00:00 AM

Fonctions associées

Contrairement à #date, qui possède près de 60 fonctions associées, #time n'en possède que 9,
qui se répartissent en trois catégories :

• Fonctions [Link] et [Link] – ces fonctions vous permettent de convertir une valeur de
temps en un enregistrement ou une valeur de texte, et d'extraire des valeurs de temps à partir
d'autres types de valeurs appropriés. •
[Link] et TimeStartOfHour – ces fonctions vous permettent de déterminer les heures
de début et de fin du composant horaire d'une valeur de temps donnée. • Time Hour, [Link]
et Time Second – vous
permettent d'extraire les composants respectifs sous forme de valeurs numériques à partir
d'une valeur de temps.

Considérations particulières
Machine Translated by Google

• Localisation : #time n'inclut aucune information sur le fuseau horaire. Si vous


devez exprimer l'heure par rapport à la localisation, utilisez plutôt #datetimezone
et, si nécessaire, le composant horaire peut être extrait de cette valeur. •
Précision : Power Query prend en charge le suivi et le
calcul des valeurs temporelles jusqu'à la microseconde (millionième de seconde),
mais il est peu probable que la plupart des utilisateurs aient besoin d'une précision
supérieure à la milliseconde.

Valeurs DateTime

Les valeurs DateTime représentent la concaténation des valeurs Date et Heure.

Structure

Les valeurs DateTime peuvent être créées à l'aide de la structure suivante :

#datetime (année

comme nombre, mois comme


nombre, jour comme nombre,
heure comme nombre,
minute comme nombre,
seconde comme nombre) comme
datetime

Les entrées ont les restrictions supplémentaires suivantes, sinon l'expression renverra une erreur :

• 1 ≤ année ≤ 9999 •
1 ≤ mois ≤ 12 • 1 ≤
jour ≤ 31 • 0 ≤
heure ≤ 23 • 0 ≤
minute ≤ 59 • 0 ≤
seconde < 60

De plus, comme avec l’expression littérale #date, l’expression #datetime est sensible à la
casse.

Exemples

datetime( 2023, 11, 1, 7, 15, 0 ) renvoie une valeur de 11/1/23 7:15:00 AM

Fonctions associées

#datetime possède 25 fonctions associées, dont la plupart reflètent les catégories


Component, IsIn et To/From des valeurs #date. Cependant, il existe également trois
fonctions #datetime qui n'ont pas d'équivalent dans les fonctions liées à #date.
Machine Translated by Google

• [Link] et [Link] – tous deux


Les fonctions renvoient une valeur datetime définie sur la date et l'heure actuelles du système. La
différence réside dans le fait que la première peut changer au cours de l'exécution d'une
expression, tandis que la seconde reste constante.

Il est important de noter que ces fonctions renvoient la valeur datetime associée au système sur lequel
la requête est exécutée. Ainsi, si votre jeu de données est actualisé en Australie, mais que vous
êtes au Canada, la fonction affichera l'heure australienne. Si vous souhaitez afficher l'heure
canadienne, vous devrez ajouter un décalage horaire pour ajuster l'heure en fonction du décalage
horaire.

• [Link] – cette fonction prend une valeur #datetime valide, une valeur d'heure et
une valeur de minutes nullable comme entrées et renvoie une valeur #datetimezone, afin
d'ajouter un élément de localisation à la valeur #datetime pour ajuster l'heure locale et/
ou l'heure d'été.

Considérations particulières

• Les valeurs DateTime doivent être utilisées avec prudence et uniquement lorsque cela est
absolument nécessaire, car elles présentent deux inconvénients majeurs par rapport à Date,
Valeurs Heure et DateTimeZone :

1. L'utilisation de valeurs datetime peut augmenter considérablement la cardinalité des colonnes


qui les contiennent, ce qui peut accroître la taille du fichier nécessaire pour stocker toutes ces
valeurs distinctes et impacter négativement les performances et l'utilisation de la
mémoire. Dans la plupart des cas, il est préférable de scinder la valeur datetime en champs
date et heure distincts, chacun étant lié par une relation un­à­plusieurs à des tables date et
heure distinctes dans les modèles de données Power BI (ou Excel).

2. Les valeurs DateTime ne contiennent aucune information concernant les fuseaux horaires.
Par conséquent, si vous comparez les valeurs DateTime entre différents emplacements, vous
devrez prendre en compte la différence de fuseau horaire.

Valeurs DateTimeZone

Les valeurs DateTimeZone sont très similaires à DateTime, à la seule différence qu'elles incluent un
décalage exprimé en heures et éventuellement en minutes, qui représente la différence entre
l'heure locale et le Temps Universel Coordonné (UTC). L'UTC est la norme mondiale, basée
sur le temps atomique, utilisée pour la navigation et les mesures scientifiques du temps. Elle a
remplacé l'ancienne norme, le temps moyen de Greenwich, et tous les fuseaux horaires peuvent
être exprimés sous forme de décalage par rapport à l'UTC.

Structure

Les valeurs DateTimeZone peuvent être créées à l'aide de la structure suivante :


Machine Translated by Google

#datetimezone (année

comme nombre, mois


comme nombre, jour
comme nombre, heure
comme nombre, minute
comme nombre, seconde
comme nombre, offsetHours
comme nombre, offsetMinutes comme
nombre nullable, ) comme datetimezone

Les entrées ont les restrictions supplémentaires suivantes ou l'expression sera


renvoyer une erreur :

• 1 ≤ année ≤ 9999 • 1
≤ mois ≤ 12 • 1 ≤ jour
≤ 31 • 0 ≤ heure
≤ 23 • 0 ≤ minute ≤
59 • 0 ≤ seconde < 60 •
­14 ≤ décalage­heures
+ décalage­minutes / 60 ≤ 14

De plus, comme avec l’expression littérale #datetime, l’expression #datetimezone est


sensible à la casse.

Exemples

datetimezone( 2023, 11, 1, 7, 15, 0, ­5, 0 ) renvoie une valeur de 11/1/2023 7:15:00 AM ­05:00

Fonctions associées

#datetimezone possède 15 fonctions associées, dont la plupart reflètent les catégories


Component, LocalNow/FixedLocalNow et To/From des valeurs #datetime. Cependant, quatre
fonctions #datetimezone n'ont pas de correspondance parmi les fonctions associées à #datetime.

• [Link] et [Link] –
Les deux fonctions renvoient une valeur datetimezone définie sur la date et l'heure actuelles du
système. La différence réside dans le fait que la première peut changer au cours de l'exécution
d'une expression, tandis que la seconde reste constante.

• [Link] et [Link] – ces fonctions permettent de


manipuler les valeurs de décalage horaire, permettant respectivement à l'utilisateur
de supprimer le composant de fuseau horaire, convertissant ainsi la valeur en une valeur
datetime, ou de changer les valeurs de décalage horaire pour correspondre à une zone
différente.

Considérations particulières

• Heure d'été : le décalage horaire dans une valeur DateTimeZone ne s'ajuste pas
automatiquement à l'heure d'été, et différents pays qui observent l'heure d'été peuvent
s'ajuster
Machine Translated by Google

saisonnièrement à des dates différentes. Nous aborderons une approche


globale pour résoudre ce problème au chapitre XX. •
Conversion : Lors de la conversion de valeurs DateTimeZone, il est important de
connaître la manière dont M gère la conversion du décalage. Par exemple,
lorsqu'une valeur DateTimeZone est convertie en valeur DateTime, le décalage
du fuseau horaire est ignoré, ce qui convertit effectivement l'heure en UTC.

Valeurs de durée

Les valeurs de durée en M sont utilisées pour représenter des durées exprimées en
jours, heures, minutes et secondes (fractionnaires).

Structure

durée (jours
sous forme de nombre,
heures sous forme de
nombre, minutes sous forme de
nombre, secondes sous forme
de nombre,) sous forme de durée

Exemples

duration(0,1,2,3) renvoie 0.01:02:03 duration(9,8,7,6.543210)


renvoie 9.08:07:06.5432100 duration(3,32,74,82) renvoie 4.09:15:22

Fonctions associées

Les 12 fonctions liées aux valeurs de durée sont réparties uniformément et de manière
assez prévisible sur trois catégories :

• Extraction de composants – Les fonctions vous permettent d'extraire la valeur du


jour, de l'heure, de la minute ou de la seconde à partir d'une valeur de
durée. • Calcul – Ces fonctions calculent les jours, les heures,
minutes ou secondes dans une valeur de durée donnée.
• Création et conversion – Ces fonctions fournissent une
signifie convertir des valeurs de durée vers ou depuis un autre type de valeur.

Considérations particulières

• Valeurs négatives – Les durées peuvent prendre des valeurs négatives, soit
directement lors de leur création, soit lorsqu'une valeur de durée plus grande est
soustraite d'une valeur plus petite.
Calculs arithmétiques – Les durées représentant des périodes de temps plutôt que des
instants précis, elles offrent un plus large éventail d'opérations arithmétiques. Ce
sujet est traité en détail dans la section ci­dessous consacrée aux opérateurs.

Valeurs logiques
Machine Translated by Google

Les valeurs logiques sont essentielles pour effectuer des opérations logiques sur vos données,
ainsi que pour contrôler le flux de données via des expressions via des structures de contrôle,
comme nous le verrons en détail plus loin dans ce chapitre.

Structure

Les valeurs logiques sont très simples, ne prenant que des valeurs vraies ou fausses.

Exemples

vrai, faux

Fonctions associées

Les valeurs logiques n'ont que trois fonctions liées, qui se rapportent toutes à la conversion :

• [Link] – Convertit toute valeur qui peut être évaluée comme vraie ou
faux à la valeur logique appropriée
• [Link] ­ Crée une valeur logique à partir des valeurs de texte
« vrai » et « faux »
• [Link] ­ Renvoie le texte « vrai » ou « faux » en fonction d'une valeur logique
valeur

Considérations particulières

• Conversion – Les valeurs logiques ont des modèles de conversion uniques qu’il est important
de connaître afin d’utiliser de manière optimale ce type de valeur : ◦ faux équivaut à 0, vrai
à1–
cela peut être démontré par :

[Link]( true ) renvoie 1 [Link]( false )


renvoie 0

• Lors de la conversion de nombres en valeurs logiques, 0 se convertit en faux, et tout autre


nombre se convertit en vrai – cela peut être démontré par :

[Link]( 0 ) renvoie false [Link]( ­2 )


renvoie true [Link]( “csv”) renvoie [Link]:
Nous n'avons pas pu convertir en Logical.

Évaluation en court­circuit – Comme beaucoup d'autres langages, M utilise cette méthode d'évaluation
des expressions logiques : le second argument n'est exécuté ou évalué que si le premier est
insuffisant pour déterminer la valeur de l'expression. Cela signifie que dans une expression
logique utilisant « and », si la première condition est fausse, la seconde condition n'est pas
évaluée. Pour une expression « or », si la première condition est vraie, la structure se
termine avant l'évaluation de la seconde condition.
Machine Translated by Google

Cela peut entraîner des problèmes lorsque la deuxième condition est spécifiée de telle
sorte qu'elle déclenche une erreur si elle est atteinte, mais peut rester indétectable
jusqu'à ce moment. Prenons un exemple concret ci­dessous :

Figure 3.5 : Pièges potentiels liés à l’évaluation des courts­circuits

Dans cette expression, nous savons, grâce à notre discussion sur la conversion des expressions
logiques ci­dessus, que [Link](true) sera évalué à 1, et donc que la première condition de
l'expression Result sera évaluée à false. Étant donné que Result nécessite que les deux conditions
de l'expression soient vraies pour être évaluées à true, la structure de contrôle se ferme
immédiatement après l'évaluation de la première condition et renvoie la valeur false pour l'expression
entière. Cependant, nous constatons que lorsque x est de type valeur logique,
cette seconde expression renvoie systématiquement une erreur, car elle tente de diviser un nombre (pi) par
une valeur logique (x), plutôt que par son équivalent numérique (défini dans cette expression par
xNum). Cependant, M nous permet d'essayer de le faire, car l'expression utilise la syntaxe correcte,
et si les valeurs que nous évaluons pour x sont telles que xNum est >= 1 pour toutes les valeurs, alors
nous ne déclencherons pas l'erreur et celle­ci pourrait passer inaperçue. Nous explorerons des techniques
au chapitre XX sur les types de données pour éviter ce type de problème.

Valeurs nulles

Une valeur nulle est utilisée pour représenter l'absence d'une valeur, ou une
valeur d'état indéterminé ou inconnu (c'est­à­dire dans le cas d'une valeur manquante).

Structure

Une valeur nulle est écrite en utilisant le littéral null . Il est essentiel de noter que null est
différent de 0. Le premier est l'absence de valeur, tandis que 0 est une valeur numérique
spécifique, tout comme 1 ou 732.

Exemples
si [Valeur] = null alors « NA » sinon [Valeur]
Machine Translated by Google

Fonctions associées

Null n'a pas de fonctions directement liées dans M, mais les fonctions liées à de nombreuses autres valeurs
prennent explicitement en compte les valeurs nulles.

Considérations particulières

• Comparaisons d'égalité – Null possède des propriétés uniques quant à la manière dont les
expressions impliquant l'opérateur de qualité sont évaluées. Par exemple, null est
strictement égal à lui­même.

null = null renvoie vrai null = vrai renvoie


faux
null = false renvoie false null <= null renvoie
null
null >= null renvoie null null <> null renvoie null

null < 0 renvoie null

• Concaténation avec des valeurs nulles ­ La concaténation de valeurs avec des valeurs nulles
renvoie une valeur nulle. Par exemple :

null et « orange » renvoie null

• Propagation des valeurs nulles – ce terme M fait référence au fait qu'une valeur nulle plus une
valeur compatible avec l'opérateur + renvoie la valeur nulle. Par exemple :

null + type numérique, type numérique + null renvoie null null + datetime, datetime + null
renvoie null null + type de durée, type de durée + null renvoie null

• Nullabilité ­ Tous les types de données en M, à l'exception du type abstrait anynonnull, sont
« nullables », c'est­à­dire compatibles avec une valeur nulle. Nous explorerons ce concept plus
en détail au chapitre XX sur les types de données. • Coalesce ­ le langage M inclut un opérateur de
coalescence spécifique
pour faciliter la gestion des valeurs nulles, indiqué par un double point d'interrogation « ?? ».

Coalesce vous permet de renvoyer une valeur différente de null. Lorsque la valeur à gauche de
l'opérateur est null, la valeur à droite est renvoyée.

Par exemple, regardons l’instruction « if » suivante dans M :

si [PremièreLettre] <> null alors [PremièreLettre] sinon si [SecondeLettre] <>


null alors [SecondeLettre] sinon

L'opérateur Coalesce nous permet d'écrire cette expression beaucoup plus simplement
comme:

[PremièreLettre] ?? [DeuxièmeLettre] ?? « ZZ »
Machine Translated by Google

Le chapitre XX sur la gestion des erreurs approfondira beaucoup plus la manière de gérer
correctement les valeurs nulles.

Valeurs numériques

Les valeurs numériques de M servent à exprimer des quantités numériques et à effectuer


des calculs mathématiques. Bien que la notion de « nombre » soit familière à tous, les valeurs
numériques de M présentent les formes littérales les plus variées de toutes les valeurs.

Structure et exemples

Toutes les expressions ci­dessous représentent des valeurs numériques valides dans M :

Figure 3.6 : Valeurs numériques dans M

Fonctions associées

En raison de la large gamme d'opérations mathématiques qui peuvent être effectuées sur des valeurs
numériques, il existe 52 fonctions numériques différentes liées dans M, réparties dans les six
catégories suivantes :

• Au niveau du bit – Ces fonctions manipulent directement les bits d’un nombre.
Cependant, comme M est un langage fonctionnel et n'implique généralement pas de
transformations binaires de bas niveau, les opérations au niveau du bit ne sont pas bien
documentées ni couramment utilisées dans M. • Création
et conversion – Ces fonctions sont utilisées pour créer
valeurs numériques ou les convertir vers ou à partir de types de valeurs compatibles. •
Informationnelles – Les fonctions déterminent si une valeur numérique est paire, impaire ou NaN.
• Mathématique – Ces
fonctions effectuent des calculs mathématiques sur des valeurs numériques. Près de la moitié des
fonctions mathématiques se rapportent à des calculs trigonométriques.

• Aléatoire – Ces fonctions sont utilisées pour créer des nombres aléatoires
dans des plages définies. •
Arrondi – Ces fonctions contrôlent le nombre de décimales auxquelles une valeur numérique sera
exprimée.
Machine Translated by Google

Considérations particulières

Types de données et formats : l'un des concepts les plus importants à comprendre concernant les
nombres en M est que, si le type de données d'un nombre est défini dans Power Query/M, son
format l'est dans la couche visuelle de Power BI (ou Excel), et non dans Power Query. La principale
conséquence de cette différence est que le type contrôle la manière dont un nombre est stocké (ce qui
peut affecter sa précision et ses besoins en mémoire), tandis que le format contrôle uniquement son
apparence visuelle. Ce point sera abordé en détail au chapitre XX consacré aux types
de données.

• Facettes – Le type de données numérique de M comprend une série de sous­types (également


appelés « facettes ») qui reflètent différentes options de stockage, telles que la devise, le
nombre décimal et le nombre entier. Les facettes limitent les plages de nombres définies ; ainsi, toute
valeur hors de cette plage renverra une erreur. L'utilisation et les implications des facettes
numériques seront abordées au chapitre XX sur les types de données. • Division par zéro – Dans M,
la division par zéro produit des résultats différents.

résultats en fonction du numérateur. ◦ Diviser un


nombre positif par 0 renverra l'infini positif (∞) ◦ Diviser un nombre négatif par l'infini renverra
l'infini négatif (­∞) ◦ Diviser 0 par 0 renvoie Pas un nombre (NaN)

Dans de nombreux calculs en M, la division par zéro provoque une erreur d'exécution ; il est donc important
de prendre des mesures pour éviter ce scénario. Ce problème sera traité en détail au chapitre XX sur la
gestion des erreurs.

Valeurs de texte

Dans M, les valeurs de texte sont des séquences de caractères, qui sont utilisées pour représenter des
données de texte.

Structure

Les valeurs de texte dans M sont indiquées par « »

Exemples
« Basket­ball »
« 23 »
« 9 novembre 1993 »

Fonctions associées

Étant donné que tous les types de valeurs non abstraits et non structurés, à l'exception de null, peuvent être
convertis vers et depuis des valeurs textuelles, il n'est pas surprenant qu'il existe 45 fonctions liées au texte,
réparties dans les catégories suivantes :
Machine Translated by Google

• Conversion et création – Fonctions qui créent des caractères de texte


et des valeurs, et de les convertir en d'autres types de valeurs
• Extraction et position – Fonctions qui déterminent la position des caractères dans les
valeurs de texte et permettent d'extraire différents sous­ensembles à partir des valeurs
de texte
• Formatage – Fonctions qui nettoient les caractères indésirables et
contrôler la casse du texte et d'autres caractéristiques de formatage
• Informations – Fonctions qui déterminent la longueur et le contenu du texte
valeurs
• Transformation – Fonctions qui combinent, divisent, insèrent ou suppriment
texte ou sous­ensembles de valeurs

Considérations particulières

• Concaténation – Les valeurs textuelles en M sont concaténées à l'aide de


l'opérateur &. Par exemple :

Phrase = « Le code M n'est pas si difficile » et « si vous connaissez les principes de base. » renvoie

Le code M n'est pas si difficile si vous connaissez les principes de base.

Caractères d'échappement ­ Certains caractères et codes réservés à des fins spécifiques dans le
langage M, tels que les sauts de ligne (lf) et les retours chariot (cr), nécessitent une séquence de
« caractères d'échappement » les précédant pour indiquer au programme de les lire
comme des caractères de texte littéral. Par exemple, #(lf) et #(cr) pour les sauts de ligne et les
retours chariot.

Évaluation des opérateurs de comparaison : les valeurs textuelles prennent en charge tous
les opérateurs de comparaison courants, qui sont sensibles à la casse par défaut.
Cependant, la casse n'est pas évaluée comme on pourrait le penser : les
minuscules reçoivent une valeur supérieure à leurs majuscules.

« gza » < « rza » renvoie vrai « rza » = « Rza » renvoie


faux « rza » > « Rza » renvoie vrai

« RZA » < « Rza » renvoie vrai

En cas de doute sur l'ordre d'évaluation des valeurs textuelles, vous pouvez utiliser la
fonction [Link] pour renvoyer la valeur numérique (sur laquelle l'évaluation est
basée) de n'importe quel caractère. Pour comparer des valeurs textuelles sans tenir compte
de la casse, utilisez l'option [Link].
Par exemple : [Link]([Link], « rza », « RZa ») renvoie true.
Bien qu'à première vue, les valeurs textuelles semblent assez simples, elles peuvent
présenter des problèmes subtils et complexes de nettoyage des données, qui seront
abordés au chapitre XX. De plus, pour les titulaires de licences Power BI Premium et Premium
par utilisateur, Power Query inclut des analyses de texte IA qui offrent des fonctionnalités
avancées, notamment le traitement de texte et l'analyse des sentiments. Ces fonctionnalités
seront présentées au chapitre ??.
Machine Translated by Google

Liste des valeurs

Une liste est une série de valeurs. En M, une seule colonne de valeurs constitue une liste, et
les listes peuvent contenir tout type de valeurs primitives ou structurées.

Structure

Les listes sont initiées par des accolades « { } »

Exemples
{ 1, 2, 3 }
{ « Chat », « Chien », « Singe » }
{ { 1, 2, 3 }, { « Chat », « Chien », « Singe » } }

Fonctions associées

Les listes sont l'un des types de valeurs les plus flexibles et les plus puissants de M ; il n'est
donc pas surprenant qu'il existe un large éventail de fonctions de listes associées. Ces 71
fonctions associées se répartissent en cinq catégories :

• Génération – fonctions qui créent des listes avec différentes caractéristiques


spécifiées, par exemple, des listes de dates, de nombres, de nombres aléatoires, ainsi
que des fonctions plus complexes qui vous permettent de créer des listes de
manière récursive • Informationnelle – principalement des fonctions qui génèrent une
valeur logique en fonction du contenu d'une liste
donnée • Sélection – fonctions qui sélectionnent un élément ou un groupe d'éléments d'une
liste en fonction de critères
spécifiés • Statistique – fonctions qui renvoient les résultats de calculs sur une liste
donnée (par exemple, somme, médiane, max,
etc.) • Transformationnelle – fonctions qui prennent une liste en entrée et créent une
nouvelle liste en modifiant la structure et/ou les éléments de la liste d'origine

Considérations particulières

• Index à base zéro – Une caractéristique essentielle des listes en M est leur base zéro.
Cela signifie que l'index définissant la position des éléments dans une liste commence
à 0. Notez que cela diffère de DAX, qui utilise un index à base un , où le premier élément
d'une liste se trouve à la position 1.

Par exemple, pour trouver la troisième lettre du mot « Méthode » en M, vous pouvez utiliser
[Link](« Méthode », 2), qui renvoie « t », le caractère en troisième position (0, 1, 2) de la chaîne
de texte. Inversement, pour obtenir le même résultat en DAX, vous pouvez utiliser
MID(« Méthode », 3, 1), qui renvoie un caractère en commençant à la troisième position (1, 2, 3).
Les listes seront abordées en détail dans les chapitres suivants, à commencer par le
chapitre XX sur les valeurs structurées.
Machine Translated by Google

Valeurs record
Un enregistrement est une liste de valeurs nommée. On peut également le considérer comme une ligne unique dans
une table, où chaque champ de la ligne possède un nom de colonne et une valeur.
Comme les listes, les enregistrements peuvent contenir des valeurs primitives ou structurées.

Structure

Les enregistrements sont initiés par des crochets « [ ] »

Exemples
[Planète = « Terre », MilesFromSun = 92960000, Planètes adjacentes = { « Vénus », « Mars » }]

Figure 3.7 : Création d'un enregistrement dans M, montrant également les valeurs dans une liste imbriquée

Fonctions associées

Les 23 fonctions liées aux enregistrements sont réparties en cinq catégories, largement similaires à celles des
fonctions de liste. Cependant, aucune fonction d'enregistrement statistique n'est disponible, et une nouvelle
catégorie a été ajoutée :

• Conversion – fonctions qui créent un enregistrement à partir d’une liste ou d’une table, ou d’un
table ou liste à partir d'un enregistrement

• Géospatial – fonctions qui gèrent les données géospatiales en points ou en puits


forme de texte connu (WKT)
• Informationnel ­ fonctions qui génèrent une valeur en fonction du contenu d'une liste donnée • Sélection ­
fonctions qui sélectionnent un
champ ou la valeur d'un champ spécifié à partir d'un enregistrement en fonction de critères spécifiés •
Transformationnel ­ fonctions qui modifient la structure ou le
contenu
d'un enregistrement

Considérations particulières

• Accès aux champs – Tout comme { } avec la valeur d'index positionnel donne accès à un seul élément avec
une liste, [ ] contenant un nom de champ donne accès à un seul champ avec un enregistrement.
Machine Translated by Google

Les enregistrements seront abordés en détail dans les chapitres suivants, en commençant
par le chapitre XX sur les valeurs structurées.

Valeurs du tableau

Une table est une valeur structurée composée de : 1) Lignes, où chaque ligne
représente un enregistrement ; 2) Colonnes, où chaque colonne représente un champ d'un
enregistrement et a un type de données spécifique ; et 3) En­têtes, qui sont les noms de
chaque colonne. Les tables peuvent être créées de différentes manières dans M, notamment
en utilisant le constructeur #table, ou à partir de valeurs, de listes, d'enregistrements, de
colonnes ou de lignes en utilisant la fonction M appropriée.

Structure
table( colonnes

comme n'importe lesquelles, lignes

comme n'importe lesquelles, )

comme n'importe lesquelles

Exemples
laisser

Source = #table( type table [ProductID


= texte, ProductQuantity = nombre, Column3 = date], {

{“P001”, 10, #date(2023, 8, 13)},


{“P002”, 25, #date(2023, 8, 14)},
{“P003”, 30, #date(2023, 8, 15)} } ) dans

Source

Il existe de nombreuses façons de construire des tables à l'aide de #table, ainsi que
d'autres fonctions permettant de créer des tables à partir d'autres types de valeurs primitives
et structurées. Ces méthodes seront détaillées au chapitre XX consacré aux
valeurs structurées. Fonctions connexes – Les tables étant les types de valeurs structurées
les plus complexes et les plus fréquemment utilisés, il n'est pas surprenant qu'elles possèdent
de loin le plus grand nombre de fonctions connexes (116) de tous les types de valeurs.
Ces fonctions sont réparties en cinq grandes catégories qui définissent leur
utiliser:

• Création et conversion – Comme mentionné ci­dessus, il existe de nombreuses façons


dans M de créer des tables et de les transformer à partir d’autres types de valeurs.

• Informatif – Les tables sont caractérisées par de nombreux attributs différents,


tels que les dimensions, le schéma, les relations et le contenu.
Les fonctions peuvent extraire des informations sur l'un des attributs spécifiques
d'une table donnée. • Spécifique
à la colonne – Les fonctions permettent de manipuler les champs et les en­têtes d'une
table.
Machine Translated by Google

• Fonctions spécifiques aux lignes – Ces fonctions permettent de manipuler des


enregistrements individuels ou groupés dans
une table. • Autres fonctions – Ces fonctions contrôlent la mise en mémoire tampon, le
repliement des requêtes et les gestionnaires définis par l'utilisateur pour les opérations de
requête. À l'exception de [Link], elles sont rarement utilisées.

Considérations particulières

• Sélection et projection ­ Un aspect essentiel de l'utilisation des tables est la possibilité de


filtrer une table pour n'en retenir que les lignes (sélection) et les colonnes (projection)
nécessaires à une transformation donnée. La manière dont vous effectuez la sélection et
la projection a des implications sur les performances et la lisibilité de votre code M. En
particulier lorsque vous commencez à utiliser des structures imbriquées dans M, la sélection
et la projection peuvent devenir assez complexes. Ce problème sera abordé en détail
dans le chapitre XX sur l'utilisation des structures imbriquées. • Performances ­ Comme la
plupart des étapes d'une requête renvoient
une valeur de table, une grande partie de l'optimisation des performances dans Power
Query se concentre sur l'optimisation de la création et de la transformation des tables.

Les tableaux seront abordés en détail dans les chapitres suivants, à commencer par le chapitre
4 sur les valeurs structurées.

Valeurs de fonction

Les valeurs de fonction sont celles qui, lorsqu'elles sont invoquées avec un ensemble de valeurs d'entrée (c'est­à­
dire des arguments), produisent une nouvelle valeur.

Structure

En M, les fonctions sont spécifiées en listant les paramètres d'entrée de la fonction entre
parenthèses, puis l'opérateur « va à » =>, puis l'expression qui définit la fonction.

Exemples

Concaténateur = (paramètre1, paramètre2) => (paramètre1 & paramètre2)


DifferentDistinct = (x) => [Link]érence(x,[Link](x))

Fonctions associées

Compte tenu de leur puissance et de leur flexibilité inhérentes, les valeurs de fonction n'ont que
cinq fonctions liées : deux relatives à la création de fonctions, deux relatives à l'appel de fonctions
personnalisées et une fonction d'information pour déterminer si une fonction donnée est une source
de données.

Considérations particulières
Machine Translated by Google

• Flexibilité et puissance – Les fonctions peuvent être affectées à des variables, transmises
en tant qu'arguments et renvoyées par d'autres fonctions, ce qui en fait certains des
types de valeurs les plus polyvalents et les plus puissants de M. • Importance des types de
données – Pour éviter les erreurs dans M, il est essentiel que les fonctions soient appelées
à l'aide de paramètres des types de données appropriés.
Nous aborderons la question de l'application de types de données appropriés dans le
chapitre suivant, ainsi que dans le chapitre XX sur la gestion des erreurs et le chapitre XX,
qui est spécifiquement dédié aux fonctions personnalisées. • Performances
– Lors de l'appel de fonctions complexes, en particulier
Les fonctions récursives et les fonctions d'ordre supérieur qui prennent une ou plusieurs
fonctions comme arguments et/ou renvoient une fonction doivent être conscientes des
impacts négatifs potentiels sur les performances que ces fonctions peuvent imposer.

Les fonctions définies par l'utilisateur sont l'un des éléments les plus puissants de M et sont traitées en
détail dans le chapitre XX.

Valeurs de type

Les valeurs de type peuvent être considérées comme des « méta »­valeurs qui fournissent des
informations sur le type de données d’une autre valeur.

Structure

Parce qu'ils classent les types de valeurs, ils peuvent prendre n'importe lequel des descripteurs des
valeurs, c'est­à­dire date, binaire, datetime, datetimezone, durée, logique, null, nombre, texte, heure,
liste, enregistrement, table, fonction ou type.

Exemples

Dans M, la fonction [Link] renvoie une valeur qui reflète le type de données de la valeur entrée
dans la fonction :

[Link]( 400 ) = nombre


[Link]( « Livre » ) = texte
[Link]( { 2, 3, 5, 7, 11, 13 } ) = liste

Fonctions associées

• Il existe 22 fonctions liées aux valeurs de type. Puisque les valeurs de type
Représentent des informations sur d'autres valeurs, plutôt que sur les structures elles­
mêmes. Ces fonctions sont principalement informatives et renvoient des informations de
type supplémentaires sur une valeur donnée. Par exemple, [Link] et
[Link] renvoient des valeurs de type pour des lignes ou des colonnes
spécifiques, respectivement, dans une table donnée.

Considérations particulières
Machine Translated by Google

• Intégrité des données – Les valeurs de type sont essentielles pour garantir l'intégrité des
données d'entrée et de sortie des fonctions. De plus, elles sont essentielles pour attribuer
des types de données aux données non structurées et pour convertir les types de données
de l'un à l'autre lors des transformations.

Valeurs de type abstrait : il existe plusieurs types « abstraits » qui ne classent aucune valeur
de manière unique. Il s'agit notamment des types de données « any », « anynonnull » et
« none », qui englobent respectivement toutes les valeurs, toutes les valeurs non nulles et
aucune valeur. Ces classifications abstraites servent principalement à tester la compatibilité
des entrées et sorties de fonctions. Valeurs de type personnalisé : tout type de
données hors de l'union de
Les types de données primitifs et abstraits sont considérés comme des types de données
« personnalisés », principalement utiles à la création de connecteurs Power Query
personnalisés, utilisés pour importer des données dans Power Query à partir de
sources externes ne disposant pas actuellement de connecteur dédié intégré à Power BI
Desktop. Les types de données personnalisés et leurs valeurs associées seront abordés
plus en détail au chapitre XX.

Ceci conclut notre examen des différents types de valeurs que vous rencontrerez dans M.
Nous allons maintenant examiner en profondeur la manière dont les valeurs peuvent être
combinées dans des expressions.

Expressions
Comme nous l'avons vu au chapitre 1, les expressions en M sont des calculs ou des
opérations évalués pour produire une valeur unique. Elles peuvent être aussi simples qu'une
constante ou aussi complexes qu'une instruction contenant des centaines d'expressions
intermédiaires, mais au final, chaque expression en M doit produire soit une valeur, soit une erreur.
Ce chapitre nous a également présenté l'expression Let, la structure fondamentale des requêtes M.
Si au chapitre 1 nous avons étudié une expression Let simple, nous allons en examiner une
plus complexe qui inclut tous les éléments majeurs que nous aborderons dans la suite
de ce livre. « Palindromes » est une requête composée d'une expression Let imbriquée. Son objectif
est d'évaluer une colonne de mots, de déterminer lesquels sont des palindromes (c'est­à­dire des
mots qui se lisent de la même manière à l'envers et à l'endroit), puis de renvoyer un tableau des
mots originaux identifiés comme palindromes, classés par ordre alphabétique croissant.

Figure 3.8 : Une requête plus complexe contenant des expressions, des valeurs,
Machine Translated by Google

opérateurs, structures de contrôle et énumérations.

Analysons le fonctionnement de cette requête étape par étape. La structure globale est une
instruction let qui produit une table appelée « SortPalindromes ». Cette instruction let est
imbriquée dans une autre instruction let composée de trois expressions qui produisent
une valeur pour chaque mot, indiquant s'il s'agit d'un palindrome (vrai) ou non (faux).

• Source – cette expression fournit les données sources de l'expression – une table à colonne
unique identifiée comme « Source ». Comme indiqué au chapitre 3, ces données proviennent
généralement d'une source externe, structurée ou non. Cependant, par souci de clarté,
nous générons nos données sources dans l'expression let.

• AddCheckPalindrome – cette expression ajoute une colonne nommée


« CheckPalindrome » dans notre table source à l’aide d’une instruction let imbriquée.
Cette instruction est composée de trois expressions intermédiaires. La première,
« Lettres », convertit chaque mot en minuscules, puis en une liste de lettres. La deuxième,
« Inversé », crée une liste temporaire dans l'ordre inverse de la liste des lettres. Enfin, la
troisième expression, « Palindrome », utilise une structure de contrôle « if
then else » pour déterminer les mots palindromes et renvoie ensuite ces valeurs
logiques comme résultats dans chaque ligne de la colonne « Vérifier le palindrome ».

• Cette expression marque également l'apparition de l'opérateur « différent de » (< >). Nous
reviendrons plus en détail sur les opérateurs dans la section suivante.

• FilterResult – cette expression filtre la table AddCheckPalindrome


produit à l'étape précédente uniquement sur les lignes où la colonne
« CheckPalindrome » contenait des valeurs égales à true. • SortResult –
enfin, cette expression renvoie le résultat final souhaité, la liste triée des mots de notre liste
d'origine qui sont des palindromes.
L'ordre croissant dans cette étape marque également la première apparition des
énumérations – des ensembles de valeurs que nous aborderons en détail plus loin dans
ce chapitre.

Notez que dans le panneau « Étapes appliquées » à droite du code de l'éditeur avancé, chacune
de nos expressions de niveau supérieur apparaît répertoriée comme une étape distincte, mais les
expressions intermédiaires dans notre expression let imbriquée ne le sont pas. Si nous n'avions pas
imbriqué les expressions « Lettres », « Inversé » et « Palindrome » dans cette deuxième
instruction let, elles seraient apparues dans les étapes appliquées.
Comme il s'agissait de sous­étapes du processus nécessaires à la production des
résultats « CheckPalindrome » et non nécessaires à d'autres fins dans l'expression, nous
avons choisi de les imbriquer dans cette deuxième instruction let, réduisant ainsi le nombre
d'étapes affichées dans la liste des étapes appliquées de trois à une. Notez également qu'une
petite icône en forme d'engrenage apparaît à côté des étapes « AddCheckPalindrome » et
« FilterResult ». Sa présence indique que vous pouvez cliquer dessus (ou double­cliquer sur le
nom de l'étape) et la modifier via l'interface utilisateur de Power Query. Par exemple, si nous
cliquons sur l'engrenage à côté de l'étape « FilterResult », l'écran suivant s'affiche : nous
pouvons modifier nos conditions de filtrage via l'interface utilisateur, et Power Query réenregistre
les modifications.
Machine Translated by Google

à notre expression de code M.

Figure 3.9 : Exemple d'options qui apparaissent lorsque vous cliquez sur l'icône d'engrenage
à côté d'une étape spécifique

Une fois que vous serez à l'aise pour écrire du code M directement dans l'éditeur avancé,
vous constaterez peut­être que ces modifications sont plus rapides et plus simples à réaliser
par codage qu'avec l'interface utilisateur. Cependant, les icônes d'engrenage vous indiquent
que vous pouvez au moins utiliser l'interface utilisateur si vous le souhaitez. Autre point important :
nous aurions pu écrire l'expression let externe comme dans la figure 3.10 ci­dessous,
l'expression finale complète pour trier les résultats filtrés après l'opérateur « in » au lieu de l'avant.
Cette révision aurait tout de même produit le résultat souhaité, mais regardez ce qui
arrive à la liste des étapes appliquées : elle se réduit à une seule étape identifiée par le
nom de notre requête, « Palindromes2 » :

Figure 3.10 : Le déplacement de l’expression finale réduit la liste des étapes appliquées.

Étant donné que l’un des principaux atouts de Power Query est la possibilité de parcourir les
expressions individuelles dans la liste des étapes appliquées et de voir la valeur résultante
de chaque expression, coder vos requêtes de la manière précédente avec un seul nom
d’étape après le « in » final est considéré comme une bonne pratique.
Machine Translated by Google

Meilleures pratiques de codage pour les expressions

En plus d'écrire votre expression let la plus externe avec un seul identifiant après l'opérateur
« in » pour éviter que la liste des étapes appliquées ne s'effondre, voici quelques autres
recommandations pour écrire des expressions que nous considérons comme les meilleures
pratiques :

• Utilisez des identifiants descriptifs – Il peut être tentant d'utiliser uniquement des lettres,
des acronymes ou des abréviations pour les identifiants de vos expressions. Cependant,
cela risque de rendre votre code beaucoup plus difficile à comprendre pour les autres (ou
même pour vous­même dans un mois ou deux).

• Évitez d’utiliser des espaces dans vos identifiants – il existe deux


raisons d'éviter les espaces :

1. Si votre identifiant comporte des espaces, lorsque vous le référencez dans les
Pour les expressions, vous devrez utiliser des hashtags et des guillemets (par
exemple, #« Résultat du filtre ») afin d'indiquer à Power Query qu'il s'agit d'un identifiant
unique, et non de plusieurs expressions. Cette exigence supplémentaire rend
votre code encombré et difficile à lire, et constitue également une source d'erreurs
potentielles inutile.
2. Power Query permet d'appeler des scripts Python et R directement depuis une expression
de code M. Cette capacité confère à M des superpouvoirs : la possibilité d'effectuer des
analyses statistiques très avancées, du machine learning complexe, et bien plus encore.
Cependant, aucun de ces langages n'apprécie les espaces dans les identifiants. Si
vous souhaitez exploiter cette fonctionnalité, privilégiez les identifiants sans
espaces.

• Utiliser une casse cohérente pour les identifiants – Si vous choisissez de suivre la
recommandation ci­dessus, il est préférable de choisir une casse spécifique pour vos
identifiants et de vous y tenir pour des raisons de cohérence et de lisibilité. Le choix de
la casse (par exemple, PascalCase, camelCase, snake_case, etc.) est une question
de préférence personnelle. • Commentaires – Il
existe deux façons de commenter votre code M au niveau de chaque expression :

1. Vous pouvez utiliser « // » au début d'une ligne pour la commenter et fournir des
commentaires descriptifs sur l'expression correspondante. Alternativement,
« /* » et « */ » peuvent être utilisés pour ouvrir et fermer un bloc de commentaires
multilignes.
2. Si vous faites un clic droit sur une expression dans la liste des étapes appliquées, vous
pouvez sélectionner « Propriétés » et la boîte de dialogue suivante s'affichera pour vous
permettre de saisir des commentaires concernant cette expression.
Machine Translated by Google

Figure 3.11 : Utilisation des propriétés d'étape pour documenter les expressions

Dans les deux cas, votre commentaire s'affichera en vert dans l'éditeur avancé et une
petite icône d'information entourée apparaîtra désormais sur le côté droit de l'étape
concernée dans la liste des étapes appliquées. Maintenant que nous avons couvert
la structure de base des expressions, explorons les opérateurs, les « liaisons » qui lient
les valeurs entre elles au sein des expressions.

Opérateurs
Tout comme il existe différents types de liaisons reliant les atomes, il existe également
différentes catégories d'opérateurs dans M reliant les valeurs. Le tableau ci­dessous
présente les différentes catégories et les opérateurs spécifiques inclus dans chacune
d'elles.

Catégorie d'opérateur Opérateurs inclus Description


Arithmétique Effectue des opérations
Addition (+) mathématiques

Soustraction (­)

Multiplication (*)

Division (/)
Machine Translated by Google

Comparaison (aussi connue Compare deux valeurs


comme opérateurs communs, Égal à (=) (renvoie un résultat
car ils sont utilisés par tous booléen)
les opérateurs de Pas égal à (<>)
valeur primitive)
Moins de (<)

Inférieur ou égal à (<=)

Supérieur à (>)

Supérieur ou égal à (>=)

Logique Effectue une logique


Et opérations (booléennes)

Ou

Pas

Texte Concaténation (&) Joint des chaînes de texte


Liste Utilisé pour créer,
Égal à (=) comparer, combiner et
accéder à des listes
Pas égal à (<>)

Concaténation (&)

Indexeur de liste ({})

Enregistrer Utilisé pour créer,


Égal à (=) comparer, combiner et
accéder aux enregistrements
Pas égal à (<>)

Concaténation (&)

Recherche d'enregistrement ([])

Tableau Utilisé pour comparer et


Égal à (=) combiner des tableaux

Pas égal à (<>)

Concaténation (&)

Fonction Va à (=>) Utilisé pour mapper les


entrées aux sorties dans
Machine Translated by Google

définitions de fonctions.

Compatibilité des types et Utilisé pour vérifier le


Affirmation est type de données et affirmer le
type d'une valeur
comme

Figure 3.12 : Catégories d'opérateurs dans MTout comme le type de valeur détermine
les fonctions qui fonctionneront ou non avec une valeur donnée, le type de valeur détermine
également l'ensemble des opérateurs compatibles. La figure 3.13 ci­dessous mappe les types
de valeurs abordés précédemment dans ce chapitre avec les catégories d'opérateurs et les
opérateurs spécifiques qui leur sont applicables.

Figure 3.13 : Correspondance des types de valeurs avec les catégories d'opérateurs et les
opérateurs

L'application d'opérateurs arithmétiques et de concaténation aux valeurs Date, DateTime,


DateTimeZone, Durée et Heure présente de nombreux cas particuliers résumés ci­dessous dans la
figure 3.14
Machine Translated by Google

Figure 3.14 : Liste des opérations arithmétiques et de concaténation valides et des types de
valeurs résultants pour les valeurs Date, DateTime, DateTimeZone, Duration et Time

En général, les règles suivantes s'appliquent aux opérations arithmétiques impliquant


Valeurs Date, Heure, DateTime et DateTimeZone :

• Lorsque vous soustrayez deux valeurs de même nature l'une de l'autre,


le résultat est une durée positive ou négative •
Lorsque vous ajoutez ou soustrayez une durée de l'un de ces types de valeurs,
le résultat est le même type de valeur • L'ajout ou la
soustraction de deux durées produira une durée • La multiplication ou la
division d'une durée par une valeur numérique produira une
Durée
• La concaténation d'une valeur Date et d'une valeur Heure produira une valeur DateTime
valeur.

Un dernier cas particulier à noter concerne les opérations arithmétiques. Les opérations
numériques en M suivent l'ordre mathématique standard des opérations, abrégé en
PEMDAS (Parenthèses, Exposants, Multiplication et Division, Addition et Soustraction).
Cependant, contrairement à de nombreux langages qui utilisent le signe circonflexe (^) pour
indiquer l'exponentiation, M nécessite l'utilisation de la fonction [Link]
pour élever une valeur numérique à une puissance.

Structures de contrôle

Alors que nous continuons à décomposer les composants des requêtes et des expressions
permettant d'utiliser les valeurs de différentes manières, nous examinerons brièvement le
rôle des structures de contrôle dans M. Les structures de contrôle sont des constructions qui
manipulent le flux d'exécution, permettant à un programme de se ramifier dans différentes
directions et de boucler sur des sections de code en fonction de l'évaluation des
conditions. Cette section est brève, non pas parce que les structures de contrôle sont sans
importance, mais parce que (comme nous l'avons vu au chapitre 1), M est un langage
fonctionnel et possède donc beaucoup moins de structures de contrôle qu'un langage
procédural comme C, des langages orientés objet comme Python ou C++, ou
des langages événementiels comme JavaScript. En fait, M ne possède qu'une seule
structure de contrôle formelle : l'instruction if­then­else. Son fonctionnement est exact. Si
une condition est vraie, elle renvoie Valeur1, ou sinon (c'est­à­dire si elle est fausse) renvoie
Valeur2, et si elle n'est ni vraie ni fausse, elle renvoie une erreur. Vous pouvez également imbriquer des instructions.
Machine Translated by Google

Ainsi, si la condition est vraie, renvoyer Value1, ou exécuter une seconde instruction if­then­else,
et ainsi de suite. Malheureusement, M ne dispose pas de structure de contrôle Switch ou Case, comme
DAX ou SQL, permettant de prendre en compte plus de deux résultats pour une condition donnée. Par
conséquent, ces scénarios sont généralement traités à l'aide de plusieurs instructions if­then­else
imbriquées. L'exemple suivant, illustrant l'utilisation de structures de contrôle if­then­else
imbriquées, s'inspire d'un défi de programmation classique appelé FizzBuzz, couramment utilisé pour
évaluer les candidats aux postes de développeur.

La tâche consiste à créer une liste d'entiers de 1 à 100. Pour chaque nombre divisible par 3, la
valeur « Fizz » est attribuée. S'il est divisible par 5, la valeur « Buzz » est attribuée. Enfin, si les deux
nombres sont divisibles par 5, la valeur « FizzBuzz » est attribuée. Les lignes ne remplissant aucune
de ces conditions renvoient simplement le nombre correspondant.

Figure 3.15 : Illustration des instructions imbriquées if­then­else dans le défi FizzBuzz

[Link] est une fonction qui prend deux valeurs de type numérique, divise la première par la
seconde et renvoie le reste. Ainsi, en utilisant cette fonction dans les structures de contrôle
imbriquées, ce problème devient relativement simple :

• Ligne 1 : initie notre expression avec « let ». • Ligne 2 :


crée notre liste d’entiers en utilisant l’opérateur de liste et convertit
cette liste dans une table.
• Ligne 3 : Ajoute une colonne appelée « FizzBuzz » au tableau pour contenir les résultats de notre
évaluation.
Ligne 4 : Ceci est le début de notre structure de contrôle if­then­else. Nous évaluons d'abord la
condition la plus stricte (FizzBuzz) afin que la structure de contrôle ne se termine pas prématurément
lorsque les deux conditions sont vraies. Si les deux conditions sont vraies, la valeur de
« FizzBuzz » est renvoyée et le programme quitte la structure de contrôle. Sinon, il passe
à la ligne suivante.

• Ligne 5 : Comme cette ligne est en cours d'exécution, nous savons que les deux conditions ne
sont pas vraies, nous testons donc chaque condition individuellement. Tout d'abord, nous testons
[Link] avec un diviseur de 3. Si cela divise uniformément notre valeur, nous renvoyons une
valeur de « Fizz », sinon, continuez à la ligne 6. • Ligne 6 : Ici, nous testons [Link]
avec un diviseur de 5. Si cela divise uniformément notre valeur, nous renvoyons une valeur de
« Buzz », sinon, continuez à la ligne 7.
Machine Translated by Google

• Ligne 7 : Ceci est notre « fourre­tout » si aucune des instructions ci­dessus n'est
évaluée à vrai. Si la structure de contrôle atteint ce point, nous renvoyons simplement
la valeur numérique d'origine. •
Ligne 8 : Cela définit le type de données de notre colonne « FizzBuzz » ajoutée au type
Texte, car elle contient un mélange de valeurs de texte et de valeurs numériques.
Nous aborderons ce processus, appelé « attribution de type de données », en détail
dans notre prochain
chapitre. • Lignes 9­10 : Celles­ci ferment simplement notre expression let initiale et
renvoient la valeur finale de notre expression.

Ce problème représente un scénario extrêmement courant dans de nombreuses


applications concrètes, ce qui explique sa fréquence d'utilisation. Notez que la condition
initiale de notre structure de contrôle peut être très simple, comme [couleur] = « rouge »,
ou une expression let imbriquée extrêmement complexe. Il suffit que la condition initiale
renvoie une valeur logique. Bien que M ne possède qu'une seule structure de
contrôle formelle, cela ne signifie pas qu'il ne soit pas un langage puissant. Il dispose
d'autres fonctions et capacités permettant de reproduire les actions des structures de
contrôle d'autres langages :

• la fonction [Link] peut exécuter une expression plusieurs fois


spécifiées, de la même manière qu'un contrôle de boucle FOR typique
structure
• la fonction [Link] peut exécuter une expression de manière répétée un
nombre indéterminé de fois tant qu'une condition d'évaluation reste vraie de
la même manière qu'un contrôle de boucle WHILE typique
structure
• M réserve également le symbole @ à la création de fonctions récursives
personnalisées capables de reproduire le comportement des boucles FOR ou
WHILE. • Enfin, de nombreux programmes, comme R, incluent une fonction MAP qui
agit comme une structure de contrôle, appliquant une fonction spécifiée à toutes les
lignes d'une colonne. M propose plusieurs méthodes pour ce faire,
notamment les fonctions [Link] et [Link].

Ces structures de boucle et de récursivité plus complexes seront le seul sujet du chapitre
XX, car elles sont très flexibles et puissantes, avec un large éventail d'applications
courantes et pratiques. Nous arrivons maintenant au dernier de nos composants
liés aux valeurs, appelés énumérations.

Énumérations
Les énumérations sont des ensembles de valeurs nommées qui fournissent des informations
supplémentaires spécifiant le fonctionnement d'une fonction. Nous les avons déjà vues – rappelons­
nous, lors de notre discussion sur les expressions plus haut dans ce chapitre, que nous testions des mots
pour déterminer s'ils étaient des palindromes. À la fin de la requête, nous souhaitions trier les résultats
par ordre croissant. Pour ce faire, nous avons créé l'expression suivante : SortPalindromes =
[Link](FilterResult, {“Word”, [Link]}) ; [Link] fournit les informations
sur le tri de la table FilterResult créée à l'étape précédente. Il existe une autre façon d'écrire
ce code pour fournir ces informations.
Machine Translated by Google

exactement le même résultat, qui est montré dans la figure 3.16 ci­dessous :

Figure 3.16 : Méthode alternative pour spécifier une valeur d'énumération à l'aide de
nombres. Ce code fonctionne car, en M, chaque option d'énumération possède un équivalent
entier que nous pouvons utiliser à la place de la valeur textuelle correspondante de cette
énumération. Un rapide coup d'œil à la documentation en ligne de Microsoft pour cette
énumération indique que nous pouvons utiliser 0 pour la valeur d'énumération si nous souhaitons
un tri croissant et 1 pour un tri décroissant.

Figure 3.17 : Valeurs autorisées pour l'énumération [Link]

Mais quel est l'avantage de cette approche par rapport à l'utilisation de


[Link], étant donné sa transparence bien moindre ? Il est vrai que si vous spécifiez
directement l'option d'énumération, il est recommandé d'utiliser la valeur texte. Cependant, au lieu
de saisir directement cette valeur d'énumération, nous pouvons la remplacer par une expression
renvoyant un entier compris dans la plage définie, dans ce cas 0 ou 1. Supposons
maintenant que nous souhaitions faire varier l'ordre de tri des résultats en fonction du nombre
de palindromes trouvés dans la liste d'origine, par exemple en ordre décroissant si le
nombre de palindromes est pair et en ordre croissant s'il est impair. En repensant à notre
discussion sur les valeurs logiques, rappelons que 0 est l'équivalent numérique de false
et 1 l'équivalent numérique de true pour un type de valeur logique. Nous pouvons donc d'abord
utiliser [Link] pour compter le nombre de palindromes dans notre table FilteredResults.
Nous devrons ensuite trouver un moyen de déterminer si le nombre de lignes est pair ou impair.
Nous pourrions utiliser l'approche [Link] combinée à une structure de contrôle if­then­
else, comme celle utilisée précédemment dans le défi FizzBuzz, mais il existe une solution plus
directe. La fonction [Link] est presque parfaite. Il suffit de l'encapsuler dans une fonction
[Link] pour qu'elle renvoie l'équivalent entier de false ou true. La figure ci­dessous
montre que cela a donné exactement le résultat recherché, les résultats étant désormais classés
par ordre décroissant, sachant que la liste contenait trois palindromes.
Machine Translated by Google

Figure 3.18 : Substitution d’une expression pour l’option d’énumération directe.

Cette approche nous fournit un autre outil puissant dans notre boîte à outils en expansion,
car il existe 30 énumérations différentes dans M, dont beaucoup sont utilisées dans plusieurs
fonctions.

Figure 3.19 : Énumérations dans M Source : [Link]


m/enumerations

Ceci conclut notre discussion directe sur les valeurs, mais étant donné que chaque
expression dans M doit renvoyer soit une valeur, soit une erreur, nous verrons évidemment
beaucoup plus de valeurs dans chacun des chapitres à venir.

Résumé
Dans ce chapitre, vous avez acquis une grande partie des bases nécessaires à la création
de requêtes M personnalisées pour nettoyer et transformer efficacement vos
données. Nous avons abordé :

• Quelles sont les valeurs et les expressions et pourquoi sont­elles si importantes


dans M
Machine Translated by Google

• Les quatre catégories de valeurs primitives dans M, et les 15 différents types de valeurs
au sein de ces catégories • Connaissance
détaillée de chaque type de valeur, y compris leur structure, les catégories de
fonctions liées pour chacune (et combien d'entre elles s'appuient les unes sur les
autres), • Considérations
spéciales qui doivent être prises en compte lors de l'utilisation de chaque type de
valeur pour éviter les erreurs subtiles et les inexactitudes potentielles

• Les « liens connectifs » qui sont utilisés pour lier les valeurs entre elles dans les
expressions, y compris les opérateurs, les structures de contrôle et les énumérateurs

Dans les deux chapitres suivants, nous continuerons sur cette voie pour collecter les deux
éléments fondamentaux restants, les types de données (chapitre XX) et les valeurs structurées
(chapitre XX), qui nous équiperont bien pour le voyage plus avancé à venir, au cours
duquel nous apprendrons à assembler ces éléments fondamentaux dans des
structures de plus en plus complexes pour répondre à presque tous les défis de données
que nous pourrions rencontrer impliquant des données qui ne sont pas dynamiques dans le
contexte d'une session de reporting Power BI (les calculs et transformations qui sont
dynamiques dans une session de reporting donnée sont gérés par DAX).
Machine Translated by Google

5 Gestion des erreurs et débogage

Rejoignez notre communauté de livres sur Discord

[Link]

La gestion des erreurs dans le langage M de Power Query implique des techniques de
gestion et de résolution des erreurs pouvant survenir lors de l'évaluation d'une expression.
L'utilisation d'expressions et de fonctions telles que « try », « otherwise » et « catch » vous
permet de gérer efficacement les erreurs potentielles et de contrôler efficacement le flux
d'exécution. De plus, l'éditeur Power Query propose une fonctionnalité intégrée pratique, le volet
« Étapes appliquées », qui vous permet de parcourir le code pas à pas et d'identifier plus
facilement les problèmes dans votre requête. Ce chapitre présente les fonctionnalités
de gestion des erreurs et les stratégies de débogage de Power Query. Il vise à vous fournir les
connaissances nécessaires pour traiter efficacement les erreurs et garantir la pérennité de
vos requêtes. En comprenant les erreurs courantes du langage M et en appliquant les
techniques présentées ici, vous établirez des bases solides pour gérer les erreurs et créer des
requêtes plus robustes. Ce chapitre aborde les sujets suivants :

• Qu'est­ce qu'une
erreur ? • Confinement
des erreurs • Détection
des erreurs •
Génération d'erreurs
• Gestion des erreurs • Stratégies
de débogage • Erreurs
courantes • Mise en place du tout

Pour tirer le meilleur parti de ce chapitre, nous vous encourageons à ouvrir votre éditeur Power
Query préféré et à tester les exemples fournis. En exécutant et en explorant ces scripts,
vous approfondirez votre compréhension.// Veuillez vous assurer que le code M de ce
chapitre n'est pas coupé par un trait d'union et que tous les guillemets sont droits. Tous les
blocs de code sont exécutables et devraient pouvoir être copiés sans problème dans un éditeur
Power Query (à l'exception du code détaillé de la section « Assemblage » qui est précédé de
numéros de ligne).
Machine Translated by Google

Merci!

Qu'est­ce qu'une erreur ?

Dans le langage M de Power Query, l'un des éléments fondamentaux est


« l'expression », qui est responsable de la production d'une valeur lors de l'évaluation.
Lorsqu'une erreur survient, cela indique que l'évaluation de l'expression a
échoué et n'a pas pu aboutir. Les erreurs peuvent avoir diverses causes, telles que
des identifiants ou des opérations invalides, des types de données incompatibles, etc.
Comprendre, prévenir et gérer efficacement les erreurs est crucial pour créer des
requêtes plus robustes et fiables. Lors de l'évaluation d'une expression M, deux
résultats sont possibles :

1. La production d’une valeur unique.

Cela indique que le processus d’évaluation a réussi et que l’expression a


pu générer un résultat.

laissez le résultat = 1 / 0

dans le résultat

La division par zéro ne génère pas d'erreur mais renvoie l'infini.

1. Déclencher une erreur.

Lorsqu'une erreur est générée, elle indique que l'évaluation d'une expression n'a
pas produit de valeur. L'erreur elle­même n'est pas considérée comme une valeur
dans le langage Power Query M. L'enregistrement d'erreur contient des détails sur
la cause du problème lors de l'évaluation. Cela permet d'identifier l'opération
responsable et de faciliter le dépannage.

laissez le résultat = 1 / "0" dans

résultat

La division par un opérande de type texte renvoie une [Link]. Avant


d'aborder la gestion des erreurs, il est important de comprendre comment les
erreurs peuvent être contenues, détectées et signalées, ce qui posera les bases
d'une gestion efficace des erreurs. Combiner des techniques de prévention et de
gestion des erreurs vous permet de créer des requêtes plus fiables et résilientes,
produisant le résultat escompté.

Confinement des erreurs

Le langage M de Power Query intègre les principes de programmation par


confinement. Explorons deux aspects et découvrons ce que cela implique pour
l'évaluation des expressions :
Machine Translated by Google

1. Inférence de type

Il s'agit de la capacité d'un langage de programmation à déduire automatiquement et à deviner


les types de données des valeurs en fonction de leur contexte et de leur utilisation dans le code. Par
exemple, si une colonne contient des valeurs telles que 1, 2,5 et 5, Power Query en déduit que
le type de données de cette colonne est numérique. Cela permet un code plus flexible et
concis, car il n'est pas nécessaire de déclarer explicitement les types de données de chaque
variable ou expression, ce qui améliore le processus de transformation des données.
Cependant, il est important de noter que l'inférence de type n'est pas parfaite, car Power Query
n'analyse que les 200 premières lignes. Si ces données diffèrent de celles situées après la ligne
200, un type incorrect est déduit. Sachez qu'un type incorrect ne génère pas systématiquement
d'erreurs. Parfois, les valeurs sont simplement incorrectes, par exemple lorsque les 200
premières lignes contiennent des valeurs entières et que des décimales apparaissent après la
ligne 200, ce qui entraîne des parties décimales tronquées. Heureusement, Power Query
inclut des fonctions permettant de définir et de convertir un type de valeur. Ces fonctions
peuvent être utilisées pour remplacer le comportement d'inférence de type par défaut ou pour
spécifier explicitement le type de données souhaité, par exemple :

• [Link](valeur comme n'importe quelle) comme nombre •


[Link](valeur comme n'importe quelle) comme date
• [Link](valeur comme n'importe quelle) comme texte

Apprenez tout sur ces fonctions de conversion de type et d’autres dans le chapitre xx.

1. Confinement et propagation

Cette fonctionnalité signifie que même si une erreur survient lors de l'évaluation d'une valeur ou
d'une expression membre particulière, elle n'interrompt pas nécessairement le
processus d'évaluation. L'erreur peut être « contenue » sans se propager
automatiquement à l'expression de niveau supérieur. Lorsqu'une erreur survient, l'évaluation de
l'expression membre actuelle est interrompue, ce qui interrompt la pile d'évaluation des
expressions. Cependant, tant qu'une erreur peut être contenue, elle ne se propage pas à
l'expression de niveau supérieur ; une valeur peut néanmoins être générée. Imaginez une table
contenant une cellule erronée ; cette erreur peut être contenue dans un champ d'enregistrement.
Cependant, l'entrée sera marquée comme erronée et l'enregistrement d'erreur sera enregistré
afin d'être propagé si nécessaire. Ainsi, chaque tentative d'accès à cette cellule génèrera
exactement la même erreur.

laisser

A = 1 / "0",
B = [a = A] dans

Une erreur contenue dans la valeur du champ d'enregistrement « a » ne se propage que


lors de l'accès. Les expressions membres de liste, d'enregistrement et de table, ainsi
que les expressions « let », sont évaluées par une évaluation différée. Autrement dit, si
rien ne tente d'accéder à une valeur erronée, son expression risque de ne jamais être trouvée.
Machine Translated by Google

Le langage M de Power Query intègre plusieurs mécanismes pour contenir les erreurs.
L'un d'eux est l'inférence de type. Cette fonctionnalité permet de traiter différents
types de données sans avoir à spécifier manuellement les types, améliorant ainsi le flux global
du développement des requêtes et du processus de transformation des données. Un autre
mécanisme est le confinement et la propagation. Cela signifie que même si une
erreur se trouve dans une partie des données, elle n'entraîne pas nécessairement l'arrêt
complet du processus d'évaluation. Si une erreur peut être confinée, l'évaluation de
l'expression se poursuit. Cependant, l'erreur se propagera toujours à travers les expressions qui
y accèdent.

Détection d'erreur

Lorsque vous travaillez avec Power Query, la rencontre d'erreurs fait partie intégrante du
processus de développement, que vous conceviez des requêtes via l'interface utilisateur
graphique (GUI), que vous modifiiez du code existant ou que vous écriviez du code M de
toutes pièces. Avec l'ajout de données réelles, les erreurs deviennent monnaie courante, et il
faut les gérer, ce qui commence par leur détection. Les erreurs sont classées en deux
types :

1. erreurs au niveau des étapes et 2.


erreurs au niveau des cellules

Ce qui les distingue, c'est leur confinement. Les erreurs d'étape se propagent à l'expression de
niveau supérieur et provoquent l'arrêt de l'évaluation de la requête entière, entraînant son
échec. Pour corriger ces erreurs, il est essentiel de déterminer où elles ont été
générées. La section « Étapes appliquées » du panneau Paramètres de la requête vous
permet d'évaluer votre requête étape par étape. En sélectionnant chaque étape et en
l'évaluant, du haut vers le bas, vous pouvez identifier l'emplacement exact (étape) où l'erreur
s'est produite et analyser le(s) problème(s) sous­jacent(s). Cette approche permet d'identifier
efficacement ce type d'erreurs. Les erreurs d'étape les plus courantes sont dues à :

• erreurs de source de
données, • identifiants inconnus ou
manquants, • erreurs de
syntaxe et • erreurs de référence cyclique (ou de référence circulaire).

Identifier les erreurs au niveau des cellules est une toute autre affaire. Par défaut, une fine ligne
apparaît directement sous l'en­tête de colonne, faisant partie des options de profilage des
colonnes (voir Figure 5.1). Si cette ligne est d'un vert uniforme, cela signifie qu'aucune erreur
n'est détectée. Le problème est que la plage d'analyse standard du profilage des colonnes
est limitée aux 1 000 premières lignes.
Vous pouvez toutefois facilement passer à l'analyse de l'ensemble de données dans la barre
d'état. Pour l'instant, vous n'avez pas à vous soucier de la compréhension du code M suivant.
Ce script vise uniquement à illustrer les effets de la plage d'analyse du profilage des
colonnes. Saisissez ce code dans une nouvelle requête vide pour le vérifier et l'essayer par
vous­même.
Machine Translated by Google

laissez t = [Link]( { [Link]( {1..2500},


each si
[Link](_, 68) =0 alors ... sinon _ ) } ) dans

L'analyse des 1 000 premières lignes, inchangée, affiche 14 erreurs au survol de la


petite ligne de profil de colonne. Cependant, n'hésitez pas à sélectionner une autre vue
d'aperçu des données dans l'onglet Affichage (voir la figure 5.1) , comme Qualité des
colonnes, Distribution des colonnes ou Profil de colonne. Modifier la plage d'analyse du
profil de colonne dans la barre d'état, des 1 000 premières lignes à l'analyse de
l'ensemble de données, peut avoir des conséquences sur la détection des erreurs et les
performances. Dans cet exemple, le nombre d'erreurs est passé de 14 à 36 lorsque la
plage d'analyse a été étendue. Cela souligne l'importance de la vigilance lors de
la validation des données. À première vue, les données peuvent sembler
exemptes d'erreurs jusqu'à l'exécution de la requête, où des erreurs inattendues se
produisent. Il est important d'en être conscient, car l'impression initiale de données
exemptes d'erreurs peut être trompeuse.

Figure 5.1 : Onglet Affichage avec options d’aperçu des données et qualité et profil
de colonne activés.
Machine Translated by Google

Une fois la présence d'erreurs au niveau des cellules confirmée, vous pouvez prendre les
mesures nécessaires en sélectionnant « Conserver les erreurs » dans la section « Réduire
les lignes » de l'onglet « Conserver les lignes » de l'onglet « Accueil ». La fonction M
[Link] est alors appelée depuis l'interface utilisateur graphique
(GUI), générant ainsi un nouveau tableau incluant uniquement les lignes contenant au moins
une erreur dans chacune de ses cellules. Si vous fournissez éventuellement une liste
avec les noms de colonnes, la fonction se concentrera sur la recherche d'erreurs uniquement
dans les cellules de ces colonnes. Cette approche permet d'isoler rapidement les lignes
problématiques pour une analyse plus approfondie. Pour afficher les détails d'une erreur
générée, cliquez simplement sur l'espace vide dans une cellule contenant une valeur d'erreur.
Cette action affichera un aperçu secondaire, dans le volet d'aperçu ( Figure 5.2) , qui présente
les informations de l'enregistrement d'erreur.

Figure 5.2 : Vue détaillée de l'erreur

Ces informations incluent la cause du problème lors de l'évaluation, le message d'erreur, ainsi
que les opérateurs et valeurs impliqués. Ces détails aident à identifier l'opération responsable de
l'erreur et à la résoudre. Plus d'informations sur la résolution des erreurs dans les sections
suivantes de ce chapitre. En explorant diverses techniques et en faisant preuve de créativité, il
devient envisageable de concevoir un tableau de rapport d'erreurs au niveau des
cellules.
Cependant, avant d'aborder un sujet plus avancé, d'autres concepts essentiels doivent être
abordés. Rassurez­vous, un exemple de tableau de rapport d'erreurs au niveau des cellules sera
abordé dans la section « Mise en forme ». Des erreurs peuvent survenir lors de l'évaluation de
n'importe quelle partie de l'expression. Cependant, elles peuvent également être traitées
directement au sein d'une expression.
Les erreurs au niveau des étapes surviennent lors de l'évaluation des différentes étapes d'une
requête. Si elles ne sont pas gérées correctement, elles se propagent à l'expression de
niveau supérieur, interrompant ainsi l'exécution de la requête. En revanche, les erreurs au
niveau des cellules concernent des cellules spécifiques d'une table, indiquant des problèmes de
qualité des données ou des transformations plus précises. En détectant efficacement les
erreurs, vous pouvez optimiser le processus de débogage et vous concentrer sur la résolution
efficace des problèmes.
Machine Translated by Google

Erreurs de soulèvement

Le langage M de Power Query permet de définir des erreurs personnalisées. Ceci est utile
pour fournir des messages d'erreur plus précis et pertinents, gérer les cas exceptionnels,
appliquer des règles de validation de données personnalisées ou améliorer l'expérience
utilisateur globale, par exemple. L'expression d'erreur : pour générer une erreur, appelez
simplement l'expression de génération d'erreur « error » et utilisez une valeur texte pour
fournir le message d'erreur souhaité. Par exemple, cette expression générera
"
une erreur avec le message [Link] : Données non valides,
vous n'avez pas fourni de table.

erreur « Données non valides, vous n'avez pas fourni de tableau. »

Les erreurs génèrent un enregistrement d'erreur ; vous pouvez donc spécifier un


enregistrement pour inclure plus d'informations sur l'erreur. Cet enregistrement doit contenir
des champs tels que « raison », « message » et « détails ». Voici un exemple de
génération d'erreur avec un enregistrement d'erreur personnalisé :

erreur
[ Raison = "Données non valides, vous n'avez pas fourni de tableau.", Message = "Les données
fournies ne sont pas valides.", Détail = [Opérateur = "&", Gauche = "123", Droite =
"321"] ]

Cependant, vous pouvez également créer un enregistrement d'erreur à partir de valeurs de texte
pour « raison », « message » et « détail » comme n'importe quelle autre, en exploitant la bibliothèque
standard, la fonction [Link] .

erreur [Link]( "Données


non valides, vous n'avez pas fourni de tableau.", "Les données fournies ne sont pas
valides.", [Operator = "&", Left = "123", Right = "321"] )

Cela renvoie le même enregistrement d'erreur que celui illustré dans


l'exemple précédent. La définition d'erreurs personnalisées en langage M a été
améliorée avec l'introduction des messages d'erreur structurés, mi­2022. Cette mise à jour
comprenait l'ajout de deux nouveaux champs à l'enregistrement d'erreur :
[Link] et [Link] fournit une structure
permettant de générer un message d'erreur concaténé à afficher à l'utilisateur. Dans
une chaîne, une paire de guillemets simples permet d'accéder aux éléments de la liste
[Link], sous la forme suivante : « #{0} », où x est l'index de base zéro de
la valeur du paramètre à insérer. Par exemple, « #{0} » représente le premier élément
de la liste [Link] est une liste
contenant des valeurs à partir desquelles des éléments peuvent être demandés et insérés
dans la chaîne du message d'erreur à des positions spécifiées.
Ne vous inquiétez pas si vous ne comprenez pas encore parfaitement le code suivant.
Saisissez ce code M dans une nouvelle requête vide, puis renommez­la
fxDivision pour l'essayer.

(dividende comme nombre, diviseur comme nombre) comme nombre =>


laisser
IsZero = diviseur = 0,
Machine Translated by Google

Division = si est nul


alors ( erreur [ [Link] =
"Rencontré : '#{0}', résolution : '#{1}'", [Link] = { "erreur de division par zéro", "seuls les nombres <> 0 sont
autorisés comme diviseurs.", dividende, diviseur}

] ) [Erreur] sinon dividende / diviseur dans

Division

Passer une valeur d'argument de 0 au diviseur de cette fonction personnalisée, comme


ceci : fxDivision(3, 0), génère l'erreur suivante : Une erreur s'est produite dans la requête
« [Link] : Erreur de division par zéro rencontrée », résolution : « Seuls les
nombres <> 0 sont autorisés comme diviseurs. » comme illustré à la figure 5.3.

Figure 5.3 : Message d'erreur personnalisé

De plus, ces champs de message d'erreur structurés permettent d'obtenir rapidement et


facilement toutes les informations relatives à l'erreur, sans analyse de texte personnalisée.
Les valeurs d'entrée peuvent être obtenues à partir du champ d'erreur « Détail » et de
toute entrée de chaîne du message d'erreur de la liste « [Link] »,
ce qui peut s'avérer utile pour le signalement et l'analyse des erreurs.

laisser

myErr = error [ [Link]


= "Rencontré : '#{0}', résolution : '#{1}'", [Link] = { "erreur de division par zéro", "seuls les nombres
<> 0 sont autorisés comme diviseurs" } ], CatchErr = try myErr, Detail = CatchErr[Error]
[[Link]]{1}

dans

Détail

Cette option renvoie « Seuls les nombres <> 0 sont autorisés comme diviseurs », mais
vous pouvez renvoyer n'importe quel élément avec son index de base zéro. Par
exemple, pour créer des rapports de gestion des erreurs plus complexes, vous pouvez
extraire un ou plusieurs éléments. Lors de l'affichage des valeurs d'entrée dans les
messages d'erreur, toutes les valeurs primitives sont affichées sous forme de texte. Toutes
les valeurs structurées sont affichées avec leur nom de type littéral (tel que Table,
Enregistrement ou Liste). Lorsque les deux champs d'erreur Message et [Link]
sont spécifiés, [Link] est prioritaire et est utilisé pour générer une chaîne qui
remplacera Message dans l'erreur propagée. La spécification d'un [Link]
sans [Link] est valide tant qu'aucun paramètre n'est attendu dans la
chaîne de format fournie. La spécification de [Link] sans [Link]
génèrera une valeur nulle au lieu d'une liste de paramètres dans l'erreur propagée. Enfin,
[Link] et [Link] n'ont aucun effet sur les champs
d'erreur Motif et Détail. Globalement, les messages d'erreur structurés en langage
M de Power Query
Machine Translated by Google

Simplifient considérablement le processus de journalisation et de reporting des erreurs, car


elles offrent un moyen systématique et prédéfini d'obtenir les détails essentiels des erreurs
sans analyse textuelle. Grâce à ces fonctionnalités, vous pouvez créer des messages
d'erreur pertinents pour les utilisateurs et améliorer l'analyse des problèmes de données
dans vos workflows. L'opérateur « … » (points de suspension) : outre l'expression d'erreur,
le langage M inclut également l'opérateur « … » (trois points). Il est important de comprendre
que cela génère non seulement une erreur, mais génère également un message
d'erreur prédéfini. Cependant, selon la version de votre moteur M (mashup), ce message
peut ressembler à : « [Link] : Non implémenté » ou « [Link] : Valeur
non spécifiée ».

laissez complexCode = si 1 + 1 = 2
alors ...

sinon "¯\_( )_/¯ Ce n'est pas correct."


dans

code complexe

Ce raccourci peut être particulièrement utile lors du développement d'expressions


complexes. Affectez les points de suspension à une branche de code en cours de
développement ; vous pouvez les considérer comme un espace réservé pour la partie sur
laquelle vous travaillez encore. Cela vous permettra d'exécuter et de tester l'autre branche
de votre code. La création d'erreurs personnalisées offre de nombreuses possibilités,
comme la fourniture de messages d'erreur plus informatifs, la gestion des cas exceptionnels,
voire l'application des règles de validation des données de l'entreprise, et l'amélioration
de l'expérience utilisateur globale.

Gestion des erreurs

La mise en œuvre de stratégies de gestion des erreurs ne se limite pas à la seule


résolution des erreurs. Il s'agit de faire des choix et d'utiliser les techniques disponibles
en langage M pour atténuer efficacement les erreurs et garantir la robustesse de vos
workflows de transformation de données. Lorsque vous travaillez avec des données, il
est courant de rencontrer des erreurs telles que des valeurs manquantes, des types de
données incompatibles, des calculs inattendus ou invalides. Pour relever ces défis, toutes
les techniques doivent être envisagées. L'objectif est de mettre en œuvre des
stratégies de gestion des erreurs qui permettront d'éviter, de gérer et de résoudre les
erreurs là où elles se produisent, garantissant ainsi un résultat prévisible. Voici ce que
vous trouverez dans votre boîte à outils.

1. Coalesce, gestion des valeurs nulles

Le langage M de Power Query prend en charge la propagation des valeurs nulles. Autrement
dit, si une valeur est nulle dans une séquence d'opérations, le résultat sera également nul.
Le champ « a » de myRecord illustre ce phénomène. Ce comportement permet d'éviter les
erreurs pouvant survenir lors d'opérations sur des valeurs nulles.

laisser

monEnregistrement = [ a = 1
+ null, b =
[Link]( {1, null} ),
Machine Translated by Google

c = [Link]( null ), d = [Link]( x ?? y ?? {} ), x = null, y = null ]


dans

monRecord

Cependant, lorsqu'une valeur nulle est passée en argument à une fonction qui attend un autre
type, elle peut devenir la cause première d'une erreur, comme le montre le champ « c » de
myRecord. La logique conditionnelle pourrait être une solution, mais vous avez déjà appris
au chapitre xx que le langage M inclut également un opérateur de coalescence, un double point
d'interrogation. Coalesce opère sur deux valeurs, renvoyant la valeur de gauche si elle
n'est pas nulle, et la valeur de droite sinon. D'autres arguments peuvent être inclus pour former une
chaîne de valeurs ou d'expressions, en les séparant par l'opérateur de coalescence. Si toutes les
valeurs de la chaîne sont nulles, une valeur nulle est renvoyée. L'implémentation de coalesce
rend le code plus concis et plus lisible .

, seules trois valeurs composent la chaîne, x, y et une liste vide.


Étant donné que la liste vide est la première valeur non nulle, cette valeur est renvoyée comme
argument à la fonction [Link] .

1. Accès facultatif aux éléments ou aux champs

La valeur par défaut du langage M est l'accès aux éléments et aux champs « obligatoire », ce qui
signifie que lorsque vous référencez quelque chose qui n'est pas là, une erreur sera générée.
Cependant, vous pouvez rapidement passer d'un accès obligatoire à un accès facultatif à un
élément ou à un champ en ajoutant un (unique) point d'interrogation à la fin.

laisser

itemThree = {1..3}{3}? dans

articleTrois

La liste à laquelle nous accédons contient 3 valeurs, l'index de base zéro pour le dernier élément de la
liste est donc 2. Étant donné que nous appliquons un accès aux éléments facultatif, cette
expression ne générera pas d'erreur mais renverra une valeur nulle à la place. La même chose
s'applique à l'accès aux champs, pour illustrer.

laissez fieldThree = [Un = 1, Deux = 2][Trois]? dans fieldThree

L'enregistrement auquel nous accédons contient deux champs. Aucun d'entre eux ne porte le nom
« Trois », ce qui signifie que l'accès obligatoire à un champ générera une erreur. Puisque nous
appliquons un accès facultatif à un champ, cette expression ne générera pas d'erreur, mais
renverra une valeur nulle.

1. Énumérateur [Link]

Lorsque vous voyez : « champ manquant facultatif comme nombre nullable » dans la liste
des paramètres d’une fonction M de la bibliothèque standard, cela signifie que cette fonction
vous permet de contrôler le comportement lorsqu’elle rencontre des champs d’enregistrement manquants.
Machine Translated by Google

ou colonnes de table. Par défaut, tous les champs ou colonnes spécifiés sont
« obligatoires » et tout champ ou colonne manquant génère une erreur.
Cependant, les fonctions avec un paramètre [Link] offrent une
solution flexible pour gérer ces situations. Trois options sont disponibles : [Link]
(0 ou null) : c'est l'option par défaut qui indique que si des champs ou colonnes sont
manquants, une erreur sera générée. [Link] (1) : lorsque cette option est
sélectionnée, les champs ou colonnes manquants sont simplement ignorés. Ils ne
génèrent pas d'erreur et sont exclus de la sortie. [Link] (2) : la sélection
de cette option inclut les champs ou colonnes manquants dans la sortie, mais leurs valeurs
sont définies sur null. Cela vous permet de conserver un ensemble complet de
données tout en indiquant l'absence d'informations spécifiques. Diverses fonctions
Record et Table fournissent ce paramètre [Link] facultatif, vous permettant
d'adapter le comportement de ces fonctions à vos besoins spécifiques, tels que :
[Link], [Link], [Link],
[Link], [Link], [Link],
[Link], [Link], [Link] et
[Link]. Être conscient du [Link] vous permet de gérer
efficacement les problèmes potentiels, en remplaçant le comportement par défaut qui
génère des erreurs et en choisissant d'ignorer les champs manquants ou d'utiliser des valeurs nulles à la place.

1. Expression si, logique conditionnelle

Vous pouvez utiliser l'instruction conditionnelle « if­then­else » pour vérifier des


conditions spécifiques. Par exemple, vous pouvez vérifier si une valeur ou une
combinaison de valeurs répond à certains critères avant d'effectuer des calculs, évitant
ainsi d'éventuelles erreurs.

laissez a = null ?? {}, b = si ( a <> null


et a <> {} ) alors [Link]( a ) sinon 1 dans

La logique conditionnelle vous permet de créer une branche dans votre code.

1. Essayez l'expression

Une expression « try » tente d’évaluer une expression et crée un enregistrement.


Selon que l'expression try a géré une erreur ou non, elle produit soit la valeur de
sortie de l'expression, soit l'erreur à partir de l'enregistrement qui a été généré.

laisser

triedExpressions = [ validExpression = essayer


1/0,
invalidExpression = essayer 1/"0" ] dans

Expressions essayées

Il est important de comprendre que la portée d'une expression try est limitée à l'expression
qui la suit directement.
Machine Translated by Google

1. Essayer et autrement

Une construction « try­otherwise » vous permet de tenter une opération et de fournir une expression par
défaut en cas d'erreur. Considérez ceci :

laisser

a = "24­2­2024", b = essayez
[Link]( a, [Culture="en­us"]) sinon "aucune date valide" dans

L'expression par défaut n'est évaluée que lorsque l'expression try renvoie une erreur. Elle permet de
gérer les erreurs de manière claire et concise.
manière.

1. Essayez et attrapez

Cela simplifie l'implémentation de la gestion adaptative des erreurs. En effet, contrairement à « otherwise »,
une fonction catch à un paramètre a accès à l'enregistrement d'erreur renvoyé par « try ». Ce qui élimine
le besoin d'une approche plus détaillée avec des fonctions personnalisées. Examinons cet
enregistrement :

[ myInput = error "A", newValue =


myInput + 1, catchMyError = try newValue
catch (e)=> if e[Message] = "A" then "Oh non, vous avez détecté l'erreur myInput !" else e[Reason] & "
message: " & e[Message], somethingElse = 1 + 1 ]

Lorsque l'erreur est générée par « myInput », elle se propage à « newValue », puis à
« catchMyError ». En fonction du message d'erreur renvoyé, un scénario de gestion des erreurs spécifique
sera appliqué dans cette clause catch. Cependant, une fonction catch sans paramètre ne reçoit pas
les détails de l'enregistrement d'erreur de « try » et est, en ce sens, équivalente à la construction try­
otherwise. Il est important de comprendre que cette approche n'est adaptée que lorsque toutes les erreurs
doivent être traitées de la même manière.

1. Essayer et personnaliser la fonction

Cette technique est devenue courante avec l'introduction du mot­clé « catch » dans le langage M en
juin 2022. Elle est toutefois encore utilisée dans les scripts M antérieurs à l'introduction de « catch ». La
fonction catch à un paramètre est désormais la méthode standard pour la gestion adaptative des
erreurs.

1. Fonctions de la bibliothèque standard

Le langage M propose également deux fonctions de bibliothèque standard facilitant la gestion des erreurs :
[Link] et [Link] , qui
permettent de remplacer ou de supprimer des valeurs d'erreur dans les tables. Comprendre la portée et les
limites de ces fonctions permettra de :
Machine Translated by Google

Vous aide à prendre des décisions éclairées lors de leur application dans vos workflows de transformation
de données. [Link] : remplace les valeurs d'erreur dans les colonnes spécifiées de la
table par une nouvelle valeur issue d'une liste contenant des listes errorReplacement. Le format de cette liste est le
suivant : { {column1, value1}, ... }. Une seule valeur de remplacement par colonne est autorisée. Spécifier plusieurs
fois une colonne dans la liste avec des listes errorReplacement générera une erreur. [Link] :
cette fonction crée une table en supprimant les lignes contenant au moins une valeur
d'erreur dans l'une de ses cellules. Si vous fournissez à cette fonction un argument pour son second paramètre
facultatif, qui prend une liste avec les noms de colonnes, elle inspectera uniquement les cellules de ces colonnes
spécifiées à la recherche d'erreurs et supprimera les lignes correspondantes de la table. En résumé, le
langage M de Power Query offre diverses méthodes de prévention et de gestion des erreurs. Il est important de
noter que le choix dépend du cas d'utilisation spécifique et des exigences du workflow de transformation de données.
En général, une combinaison de méthodes et de techniques est nécessaire pour garantir l’intégrité et la fiabilité
des données.

Stratégies de débogage
Le débogage fait partie intégrante du processus de développement, et il est inévitable de rencontrer des situations
où le code se comporte de manière inattendue. Des stratégies de débogage efficaces jouent un rôle crucial
dans l'identification et la correction des erreurs, tout en améliorant la compréhension du code. Les bonnes
pratiques générales pour le débogage du code M incluent l'utilisation de commentaires, le renommage
des étapes pour plus de lisibilité, la décomposition des expressions complexes et les tests.

1. Les commentaires ne sont pas seulement des espaces réservés pour des réflexions ou des descriptions de
code ; ils servent de repères essentiels pour guider le processus de débogage. Ils peuvent vous aider, vous
et d'autres, à comprendre l'objectif et la fonctionnalité des différentes sections de code, facilitant ainsi la
localisation et la résolution des problèmes.
De plus, les commentaires peuvent être utilisés pour marquer les zones de code qui nécessitent une
révision plus approfondie ou qui sont sujettes à des erreurs.
2. Par défaut, Power Query attribue des noms génériques à chaque étape. Ces noms ne fournissent pas
beaucoup d'informations sur leur fonction. En renommant les étapes avec des noms plus descriptifs,
vous simplifiez la lecture et la compréhension du code. Cela peut être particulièrement utile lorsque
vous ou quelqu'un d'autre essayez de déboguer le code, car cela permet de mieux comprendre le rôle
de chaque étape. Des noms d'étapes descriptifs facilitent également la maintenance et la mise à jour du
code. Si vous devez modifier votre requête ultérieurement, il est beaucoup plus facile de retrouver les
étapes lorsque celles­ci sont bien nommées.

3. Décomposez les expressions complexes en parties plus petites et plus faciles à gérer. Le langage
M, de par sa nature fonctionnelle, permet la création d'expressions imbriquées complexes. Si ces
expressions peuvent être puissantes, elles peuvent aussi être difficiles à déboguer en cas de problème.
En décomposant les expressions complexes, vous pouvez isoler et examiner chaque partie
individuellement, facilitant ainsi l'identification de la cause première d'un problème. Cette approche
simplifie non seulement le débogage, mais améliore également la lisibilité et la maintenabilité du code
lorsqu'elle est associée à des outils bien conçus.
Machine Translated by Google

variables nommées.
4. Tester votre code M est une approche proactive de débogage qui permet d'identifier
les erreurs avant qu'elles ne deviennent problématiques et de garantir le bon
fonctionnement de votre code. De plus, des tests seront nécessaires à chaque
modification du code.
5. À côté de ces bonnes pratiques génériques, il existe un puissant outil de débogage
Stratégie qui mérite votre attention. Vous connaissez les concepts de let­ et d'expression
record, tous deux utilisés pour créer des expressions plus complexes en langage
M. Cependant, pour la résolution de problèmes et le débogage, l'expression record est
extrêmement puissante.

Les expressions d'enregistrement permettent d'écrire les noms de champs sans guillemets
(dans la plupart des cas), ce qui est pratique et améliore la lisibilité du code. Plus important
encore, elles sont très flexibles. En effet, vous pouvez rapidement modifier leur valeur de retour,
par exemple renvoyer l'enregistrement entier, ce qui vous permet de visualiser tous les
champs et leurs valeurs d'un seul coup d'œil. Si l'un d'eux affiche une erreur, vous saurez
immédiatement par où commencer le débogage.

[ NumE = Nombre.E, Arrondi au


supérieur = [Link] au supérieur( NumE, 0), Fois Deux =
Arrondi au supérieur *2 ]

Ou vous pouvez renvoyer une sélection d'un ou plusieurs champs avec sélection et
projection.

[ NumE = Nombre.E, Arrondi au


supérieur = [Link] au supérieur( NumE, 0), Fois Deux =
Arrondi au supérieur *2 ] [ [Arrondi au
supérieur], [Fois Deux] ]

Enfin, vous pouvez renvoyer une valeur unique en appliquant l’accès au champ.

[ NumE = Nombre.E, Arrondi au


supérieur = [Link] au supérieur( NumE, 0), Fois Deux =
Arrondi au supérieur *2 ] [Fois Deux]

Les enregistrements offrent de meilleures capacités de débogage par rapport à l'expression let.
Bien que l'expression let ne renvoie qu'une seule valeur, même structurée, l'enregistrement permet
de visualiser tous les champs et toutes les valeurs simultanément. Cette fonctionnalité est
particulièrement utile pour résoudre les problèmes d'expressions complexes ou imbriquées.
Machine Translated by Google

Figure 5.4 : Examinez tous les champs d’enregistrement pour faciliter le débogage

D'un seul coup d'œil, vous pouvez visualiser tous les champs de l'enregistrement, il affiche trois erreurs, les
champs RoundUp et Times Two contiennent l'erreur propagée soulevée par One lors de la division d'un
texte par un type de nombre, ce qui rend l'erreur facile à tracer et à corriger. Un débogage efficace est
obtenu par une conception de requête réfléchie, la mise en œuvre d'un mélange de mesures telles
que l'ajout de commentaires, le changement de nom des étapes, la décomposition d'expressions
complexes, l'utilisation de l'expression d'enregistrement et l'intégration de la gestion des erreurs, tous ces
éléments combinés contribuent non seulement à un code plus robuste mais également plus maintenable.

Erreurs courantes
Lorsque vous rencontrez et gérez des erreurs dans vos workflows Power Query, il est essentiel d'analyser
les schémas et d'en tirer des enseignements. L'analyse des erreurs courantes et la compréhension de leur
cause profonde peuvent vous aider à affiner votre approche de gestion des erreurs. Cette section se
concentre donc sur certaines des erreurs les plus courantes que vous êtes susceptible de rencontrer.
De plus, il est important de comprendre que plusieurs erreurs peuvent survenir lors du débogage et que
les erreurs de syntaxe seront toujours signalées en premier, car elles empêchent le moteur M (mashup)
d'analyser le code fourni. Erreurs de syntaxe : les erreurs de syntaxe dans une expression sont généralement
identifiées lors de la phase d'écriture du code.

Ces erreurs indiquent qu’il y a un problème avec le modèle ou la structure de l’expression fournie.

laisser

A = 1,
B = 0 résultat
= A / B dans le résultat

Une virgule manquante sur la ligne 3 renvoie : [Link] : Jeton ',' attendu.
Machine Translated by Google

laissez maxValue = [Link]( {1, 4, 6, 8, } ) dans maxValue

Une virgule supplémentaire à l'intérieur de la liste sur la ligne 2


renvoie : [Link] : Un ',' ne peut pas précéder un '}'. Cependant, sachez
que les messages d'erreur de syntaxe peuvent parfois être trompeurs...

laisser

maxValue = [Link]( {1, 4, 6, 8 } dans

maxValue

Une parenthèse fermante manquante renvoie : [Link] : Jeton ',' attendu.

laisser

maxValue = [Link]( {1, 4, 6, 8 })) dans

maxValue

Et il en va de même pour une parenthèse fermante supplémentaire : [Link]:


Token ',' [Link], lors de l'ajout d'une virgule à la fin de la ligne 2, la parenthèse
fermante reste manquante.

laisser

maxValue = [Link]( {1, 4, 6, 8 }, dans

maxValue

Elle renverra : [Link] : Token Literal attendu. Et dans ce cas, pas le plus
évident : [Link] : Un « , » ne peut pas précéder un « in ». Les causes les
plus courantes d'une [Link] sont : des virgules, des parenthèses et des
crochets supplémentaires ou manquants, entre autres. Par conséquent, la façon de les
résoudre est d'examiner méticuleusement l'expression pour détecter toute virgule,
parenthèse, crochet, etc. supplémentaire ou manquant. Gérer les erreurs, une priorité absolue.
Chaque fois qu'une étape génère des erreurs dans votre requête, nous vous recommandons
de les traiter en premier avant d'entreprendre toute action ultérieure.
Laisser des erreurs non traitées peut avoir un impact sur votre requête. L'implémentation de
Power Query peut entraîner l'ignorance d'erreurs par des fonctions comme
[Link]. Par exemple, cette requête génère intentionnellement des
erreurs lors de la conversion de types de colonnes de types mixtes. À la ligne 17, les lignes
vides sont supprimées de la table à l'aide de [Link]. Cependant, cette opération
ne corrige aucune des erreurs au niveau des cellules survenues en raison d'une conversion
de types incompatible. Lorsque la fonction [Link] est appliquée à la
ligne 21 pour supprimer les lignes erronées, les erreurs persistent et la table résultante
inclura une ligne erronée.

laissez Source = [Link]( { {123, 34, 12, "txt",


null},
{123, "txt", 34, 12, null}, {"txt", 123, 34, 12, null}, {123, "txt", "34",
12, null}
Machine Translated by Google

} ),
ChType
= [Link]( Source, { {"Colonne1", [Link]}, {"Colonne2",

[Link]}, {"Colonne3", [Link]}, {"Colonne4",


[Link]} }), RemoveBlanks = [Link]( ChType,
each not [Link]( [Link]( [Link](_),
{"", null}) )), RemoveErrors =

[Link]( RemoveBlanks ) dans

Supprimer les erreurs

Bien que nous ayons demandé à Power Query de supprimer toutes les erreurs, des erreurs
persistent. La solution réside dans l'ordre des opérations. La meilleure pratique consiste à traiter les erreurs
immédiatement. En faisant un clic droit sur l'étape « RemoveErrors » dans la section
« Étapes appliquées » du volet « Paramètres de la requête » et en sélectionnant « Déplacer avant »,
vous modifiez l'ordre des opérations. Ce réglage garantit que [Link] est
exécuté avant [Link] pour supprimer les lignes vides. Ainsi, les erreurs causées par la
conversion de type sont correctement éliminées et la requête renvoie une seule ligne de données valide
sans erreur persistante. [Link], source introuvable. Cette erreur se produit lorsque la source de
données est inaccessible. Les causes courantes incluent : l'utilisateur n'a pas accès à la source de
données ou la source a été déplacée.

laisser

Source = [Link]([Link]( "C:


\[Link]"), null, true ) dans

Source

[Link] : Fichier « C:\ [Link] » introuvable. Identifiant inconnu ou


manquant. Un identifiant sert à désigner une valeur spécifique, telle qu'une requête, une variable
(étape) ou un nom de champ d'enregistrement. Les identifiants peuvent être classés en identifiants
standard et identifiants entre guillemets. Les identifiants entre guillemets autorisent l'utilisation de
n'importe quelle séquence de caractères, y compris des mots­clés, des espaces, des opérateurs et des
ponctuations, par exemple : #« logique d'erreur ». Les identifiants standard, quant à eux, servent
à nommer et à accéder aux champs. Ils sont également appelés identifiants généralisés, et ne nécessitent
pas cette notation entre guillemets. Un message d'erreur similaire à « Le nom 'xxxxx' n'a pas été
reconnu. Vérifiez son orthographe. » indique que vous avez référencé un identifiant introuvable. Pour
résoudre ce problème, vous devez identifier l'emplacement d'utilisation de cet identifiant inconnu et
déterminer à quelle valeur il doit faire référence afin de le mettre à jour correctement. Vous pouvez
également créer une variable portant ce nom si elle n'existe pas et lui attribuer la valeur appropriée.
Lorsqu'elle fait spécifiquement référence au nom « _ », le problème est dû à un mot­clé « each »
manquant . Une fonction inconnue. Cette erreur génère le même message. [Link] : Le nom
« [Link] » n'a pas été reconnu. Vérifiez son orthographe correcte, comme dans le cas d'un identifiant
inconnu ou manquant. Les causes courantes sont :
Machine Translated by Google

fautes d'orthographe et casse incorrecte.

laisser

maxValue = [Link]( {1, 4, 6, 8 } ) dans

maxValue

Les noms de fonctions M suivent un modèle cohérent, composé d'une catégorie de


fonction suivie d'un point et d'un nom. Lorsqu'un nom est composé de mots
composés, la convention consiste à mettre en majuscule la première lettre de
chaque mot ajouté. Par exemple, prenons une fonction de sélection de lignes dans
une table, appartenant à la catégorie de fonctions « table » et nommée
« SelectRows ». La fonction qualifiée est donc désignée par :
[Link]. Le respect de cette convention permet de repérer plus rapidement
les erreurs dans les noms de fonctions. L'introduction d'IntelliSense dans Power
Query a marqué une amélioration significative de l'expérience de développement pour les
utilisateurs de Power BI Desktop (version de septembre 2018), d'Excel 365 et des
versions ultérieures d'Excel 2019. Avec IntelliSense activé, les développeurs peuvent
saisir le nom d'une fonction ou d'une variable et une liste déroulante de saisies automatiques
possibles s'affiche. Les utilisateurs peuvent rapidement sélectionner la fonction ou
la variable souhaitée parmi les suggestions sans avoir à la saisir complètement,
réduisant ainsi le risque d'erreurs et de fautes de frappe. // ci­dessous, appelez la boîte de
conseils, veuillez formater en conséquence, merci !.

• Cependant, les utilisateurs devaient être conscients d'un problème lié à IntelliSense.
Cela pouvait entraîner des doublons. Par exemple, lorsqu'on saisissait « list. »
pour rechercher « [Link] », IntelliSense pouvait compléter automatiquement la
sélection de l'utilisateur avec « [Link] ». Si vous rencontrez ce problème,
voici deux solutions :

1. Omettez le point lors de la saisie de la fonction, pour illustrer : « TableSelectR »


ou
2. Saisir par exemple uniquement les lettres majuscules d'une fonction
Nom. Vous pouvez également saisir d'autres informations, comme : « tsrow » pour « [Link] ».

• Les deux méthodes donneraient la fonction souhaitée sans duplication de


termes.

Référence de colonne inconnue. Lorsque vous rencontrez un message d'erreur du type


« [Link] : La colonne « xxxxx » de la table est introuvable », cela indique
que vous avez une référence de colonne codée en dur qui ne correspond à aucun des
noms de colonne présents dans la table. Plusieurs raisons peuvent expliquer cette erreur.
Par exemple, une erreur de saisie utilisateur, comme une faute d'orthographe lors de
la définition de la référence, peut­être ; des modifications ont peut­être été apportées aux
noms de colonnes dans la source de données après la conception initiale de la requête,
entraînant des références incohérentes. Il est possible que des colonnes aient été
omises de la source de données, et que, par conséquent, les références à ces colonnes
manquantes soient à l'origine de l'erreur. Il est également possible qu'un utilisateur ait
modifié une étape précédente de la requête, ce qui a entraîné une référence de colonne incorrecte.
sur.

laisser

Source = #table(2, {{1, 2}}),


Machine Translated by Google

RenameCols = [Link]( Source, { {"Colonne 1", "ColonneA"}, {"Colonne


2", "ColonneB"} } )
dans

Renommer les colonnes

Pour résoudre cette erreur, examinez attentivement le code et comparez les références
de colonnes avec les noms réels de la table. Vérifiez que les noms de colonnes sont
présents, orthographiés correctement et respectent la casse. Lorsque vous modifiez
la source de données ou les étapes précédentes, veillez à mettre à jour toutes les
références de colonnes concernées en conséquence, plus loin dans le code. Cette erreur
persistera jusqu'à ce que tous les problèmes de noms de colonnes soient résolus.
Vous pouvez également adopter une autre stratégie pour atténuer cette erreur. Si
possible, envisagez d'utiliser des fonctions M qui autorisent un paramètre facultatif
« missingField ». Ce paramètre vous permet de contrôler le comportement
lorsqu'un champ manquant est détecté, offrant ainsi plus de flexibilité dans la gestion
de ces situations. De plus, vous pouvez envisager d'utiliser des références de
colonnes dynamiques plutôt que des noms codés en dur. En utilisant des références
de colonnes dynamiques, vos requêtes peuvent s'adapter aux changements au fur
et à mesure qu'ils se [Link] référence de champ inconnueCela est très similaire
à « l'erreur de référence de colonne inconnue », mais se produit lors d'une tentative
d'accès, de sélection ou de recherche de champ, et le nom de champ spécifié ne
correspond à aucun des noms de champ réels dans l'enregistrement (ou la ligne de
table).La raison et la résolution sont similaires à la gestion de « l'erreur de référence
de colonne inconnue » avec l'ajout important, que si cette erreur est générée lors de
l'exécution d'un accès ou d'une recherche de champ (obligatoire), cela signifie que le
nom de champ spécifié est censé être présent.

laisser

GetName = [Initial = "M", Name="Mashup"][Name2] // requis, erreur dans

Obtenir le nom

Vous pouvez passer à l'accès facultatif aux champs en ajoutant un point d'interrogation
après l'opérateur d'accès ou de recherche, comme ceci : [Nom2] ? Cela renverra une
valeur nulle au lieu de générer une erreur si le champ est introuvable dans l'enregistrement.

laissez GetName = [Initial = "M", Name="Mashup"][Name2]? // facultatif, null


dans

Obtenir le nom

Pour résoudre cette erreur, examinez attentivement le code et comparez les références
de champ aux noms de champ réels de l'enregistrement. Vérifiez que les noms de champ
sont présents, orthographiés correctement et respectez la casse. Si possible, envisagez
d'utiliser des fonctions M autorisant un paramètre facultatif « missingField ». Ce
paramètre vous permet de contrôler le comportement lorsqu'un champ manquant
est détecté, offrant ainsi plus de flexibilité dans la gestion de ces situations. De plus,
vous pouvez envisager d'utiliser des références de champ dynamiques plutôt que
des noms codés en dur. Grâce à ces références, vous pouvez vous adapter
aux changements de noms de champ. Nombre insuffisant d'éléments dans
l'énumération. Le langage M utilise un index de base zéro pour les tables et les listes.
Apprenez­en plus sur les listes et l'accès aux éléments, ce qui vous permet de
Machine Translated by Google

Extraire un élément de liste en fonction de sa position, au chapitre xx. Comme l'accès aux
champs ou la recherche, l'accès aux éléments est également requis par défaut, ce qui
signifie que la position spécifiée est censée être présente.

laissez ItemAccess = [Link]( 1, 3, 1 ){3} // requis, erreur dans

Accès aux articles

Considérez cette requête, la fonction [Link] génère une liste avec 3 éléments
ou éléments de liste { 1, 2, 3 } en appliquant l'accès aux éléments et en passant la valeur 3
comme numéro d'index tentera d'extraire le 4ème élément de la liste de valeurs.
Augmentation de l'[Link] : il n'y avait pas assez d'éléments dans
l'énumération pour terminer l'opération.

laissez ItemAccess = [Link]( 1, 3, 1 ){3}? // facultatif, null dans

Accès aux articles

Vous pouvez passer à un accès facultatif aux éléments en ajoutant un point d'interrogation
après l'opérateur d'accès, comme ceci : {3}? Cela renverra une valeur nulle au lieu de générer
une erreur lorsque la position d'index demandée n'est pas présente dans la liste.

laissez ItemAccess = [Link]( [Link]( 1, 3, 1 ), 3, 1 ) // {} dans

Accès aux articles

Vous pouvez également adopter une stratégie différente. Envisagez d'utiliser une fonction
de bibliothèque standard telle que : [Link] : cette fonction renverra une liste vide au
lieu de générer une erreur lorsque le décalage dépasse le nombre d'éléments de la liste.
Formule. Erreur de pare­feu : ces erreurs sont le résultat du pare­feu de confidentialité des
données de Power Query. Son objectif est simple : il empêche Power Query de divulguer
involontairement des données entre les sources. Elles génèrent une erreur du type : Formule.
Pare­feu : la requête « Requête 1 » (étape « Source ») fait référence à d'autres requêtes
ou étapes, elle ne peut donc pas accéder directement à une source de données. Veuillez
reconstruire cette combinaison de données. Ou : Formule. Pare­feu : la requête « Requête 1 »
(étape « Source ») accède à des sources de données dont les niveaux de confidentialité
ne peuvent pas être utilisés ensemble. Veuillez reconstruire cette combinaison de données.
Vous trouverez souvent deux méthodes pour résoudre cette erreur sans désactiver
le pare­feu : vous pouvez combiner Requête 1 et Requête 2 en une seule requête. Vous
pouvez également transformer ces requêtes en fonction sans paramètre pour éviter
l'erreur Formula Firewall. Bien que cette dernière soit compatible avec Power BI Desktop
et Excel, elle ne fonctionne pas avec le service Power BI. Pour en savoir plus
sur l'erreur [Link], cliquez ici : [Link]
query/data­privacy­firewall [Link]
formula­firewall/[Link] : The key didn't match any rows in the table. Cette erreur
se produit lorsque Power Query ne trouve pas le « nom » recherché. Les causes courantes
incluent un nom mal orthographié ou modifié, des privilèges insuffisants pour le compte
utilisé pour accéder à la table ou plusieurs informations d'identification pour une même
source de données, ce qui n'est pas pris en charge par le service Power BI.
Machine Translated by Google

laissez Source = [Link]( { {"VotreTable",


"Table", #table(2,
{{1, 2}}) }, {"VotreTable2", "Table", #table(2, {{1, 2}}) }

}, {"Élément", "Type", "Données"} ), Navigation = Source{[Élément= "maTable",

Type="Table"]}

[Données] dans Navigation

L'erreur [Link] ici est causée par des valeurs de clés de table non correspondantes
dans l'expression de recherche. Pour résoudre l'erreur dans cet exemple, vous devez
remplacer « myTable » par « YourTable » sur la ligne 8 du code M. Cette erreur est
fréquemment rencontrée lors de l'utilisation du connecteur Dossier pour combiner des fichiers.
Lors de l'utilisation du connecteur Dossier, tous les fichiers sont traités selon la structure d'un
fichier d'exemple sélectionné. Par exemple, si vous sélectionnez un fichier Excel avec une
table nommée « tData », tous les autres fichiers du dossier seront traités comme des fichiers
Excel avec une table nommée « tData ». En cas de variations dans la structure des fichiers,
comme une table mal orthographiée ou nommée différemment, l'erreur [Link]
peut survenir lors de la combinaison des données. Pour éviter toute erreur ou perte
de données, il est essentiel d'examiner et de vérifier attentivement la structure des fichiers et
de garantir leur cohérence avant de les combiner avec cette
technique spécifique. [Link] : La clé correspond à plusieurs lignes de la table. Un
message d'erreur du type « [Link] : La clé correspond à plusieurs lignes de la table »
indique que la recherche renvoie plusieurs lignes. Cette erreur survient lors de l'utilisation
de l'opérateur d'accès aux éléments { } pour rechercher une ligne dans une table, avec
des champs et des valeurs clés entre crochets [ ]. Le moteur Power Query M (mashup) utilise
cette syntaxe spécifiquement pour les tables avec des clés primaires en cas de navigation ou
d'exploration, tous les champs de clés de la table et les valeurs de champ correspondantes sont
répertoriés pour identifier de manière unique la ligne souhaitée.

laisser

Source = [Link]( { {"VotreTable", "Table",


#table(2, {{1, 2}}) },
{"VotreTable2", "Table", #table(2, {{1, 2}}) }

}, {"Élément", "Type", "Données"} ), Navigation = Source{[Type="Tableau"]}

[Données]

dans

Navigation

L'erreur [Link] est due à l'absence de spécification de valeurs pour toutes les clés
de l'expression de recherche. Pour corriger l'erreur de l'exemple, vous devez inclure le champ
« Élément » et lui attribuer une valeur correspondante à la ligne 8 du code M. Cette erreur
survient lorsque des modifications manuelles sont apportées au code M généré par
l'interface graphique. Elle peut également survenir lorsque la méthode de recherche est
appliquée manuellement à des tables manquant de valeurs de clé correspondantes
suffisantes ou lorsque la table contient des lignes en double. Pour éviter cette erreur,
utilisez la fonction [Link] pour vérifier si la table possède des clés primaires. Elle renvoie
une liste avec un enregistrement contenant deux champs : « Colonnes » (liste des noms
de colonnes constituant les clés primaires de la table, le cas échéant) et « Primaire » (valeur
booléenne). S'assurer qu'une valeur correspondante est fournie pour chaque champ clé permet d'éviter ce problème.
Machine Translated by Google

générer cette [Link] : l'évaluation a entraîné un dépassement de pile et ne peut


pas continuerUne erreur de dépassement de pile se produit lorsque l'évaluation de votre code M
épuise la mémoire disponible dans la pile d'appels.
Cela peut se produire en raison d'un bug dans votre code, comme l'évaluation d'une fonction
récursive sans condition de fin. Les fonctions récursives peuvent entraîner un débordement de pile
lorsqu'elles se rappellent elles­mêmes de manière répétée sans condition de fin appropriée.

laisser
NoEnd = (x) => @NoEnd (x + 1) dans

Sans fin(0)

Les méthodes courantes pour résoudre un dépassement de pile incluent l'implémentation d'une
structure de contrôle. Pour illustrer l'instruction « if­then­else » de la ligne 2, elle vérifie si « x » est
inférieur à 100. Si la condition est vraie, la fonction s'appelle elle­même récursivement avec
l'opération « x + 1 » comme nouvelle entrée. Sinon, si « x » est supérieur ou égal à 100, la
fonction renvoie la valeur de « x », mettant fin aux appels récursifs.

laisser
NoEnd = (x) => si x <100 alors @NoEnd(x + 1) sinon x dans

Sans fin(0)

L'essentiel est de s'assurer que la condition de terminaison sera finalement remplie lors de
l'exécution de la fonction. Sans condition de terminaison appropriée, la fonction
s'appellera indéfiniment, ce qui entraînera une erreur de dépassement de pile. Vous pouvez
également envisager de remplacer la récursivité par l'itération à l'aide de fonctions telles que
[Link], [Link] ou [Link]. Ces fonctions itératives peuvent
effectuer les mêmes tâches que les fonctions récursives, mais de manière plus économe en
mémoire, réduisant ainsi le risque d'erreurs de dépassement de pile. Pensez à vérifier les
conditions de terminaison et à optimiser le code M pour de meilleures performances et une
meilleure fiabilité.

Mettre tout cela ensemble


Tout au long de ce chapitre, vous avez découvert les différents aspects de la gestion des
erreurs dans Power Query. Vous avez découvert la nature des erreurs, comment les générer
intentionnellement, ainsi que la manière dont elles sont contenues, détectées et finalement
traitées. Fort de ces connaissances fondamentales, il est temps de consolider vos
connaissances en analysant deux exemples pratiques illustrant des scénarios concrets de
gestion des erreurs. Ces exemples vous permettront de mieux comprendre comment prévenir les
erreurs, faire des choix réfléchis et les traiter lorsqu'elles surviennent. N'hésitez pas à concevoir
votre propre approche pour ces scénarios avant de vous lancer. Si vous n'êtes pas à l'aise
avec la transposition en M­code, ce n'est pas un problème. Vous pouvez néanmoins créer un plan
et réfléchir aux obstacles à surmonter. Cela vous permettra de comparer votre stratégie à celle
proposée ici. Cependant, n'oubliez pas qu'il existe une multitude de solutions à un problème
donné ; ce livre n'en présente qu'une seule : Scénario 1.

La tâche. Une tâche très courante consiste à sélectionner des colonnes dans une table. Cela peut
Machine Translated by Google

La sélection des colonnes peut être facilement effectuée via l'interface graphique.
Cependant, existe­t­il une méthode pour faciliter la sélection des colonnes et rendre ce
processus plus convivial, robuste et fiable ? Scénario 1 : Une solution.
Concentrons­nous d'abord sur la convivialité. Le langage M étant sensible à la casse, il
est facile de faire des fautes d'orthographe. Voyons comment fournir une liste avec les
numéros de colonnes plutôt qu'avec les noms de colonnes.
Cependant, un point important à considérer : les numéros de colonnes ne doivent pas
être à base zéro. Intuitivement, nous avons l'habitude de compter à partir de 1. Il serait
également plus convivial de proposer une option permettant de sélectionner ou de
supprimer des colonnes. Imaginez un scénario où un utilisateur souhaite conserver
toutes les colonnes sauf une ou quelques­unes. Demander aux utilisateurs de fournir la
liste de toutes les autres positions de colonnes serait fastidieux et source d'erreurs.
Pour simplifier le processus, inclure une option permettant de basculer entre la
conservation et la suppression des colonnes spécifiées améliorerait considérablement la
convivialité et réduirait les risques d'erreurs. Compte tenu de ces considérations, nous
avons identifié trois paramètres d'entrée clés pour notre fonction personnalisée.
Premièrement, nous avons besoin d'une table sur laquelle effectuer l'opération.
Deuxièmement, une liste des positions de colonnes (au format à base 1) indiquera les colonnes spécifiques nécessi
Et enfin, un booléen qui sert d'option de bascule pour déterminer s'il faut conserver ou
supprimer les colonnes fournies ajoutera un niveau de facilité d'utilisation pour les utilisateurs.

( myTable comme table, colPositions facultatif, keepOrDelete facultatif comme logique ) comme table =>

Les paramètres explicites spécifient l'entrée d'une fonction et son type de données
requis. Par conséquent, l'utilisation de paramètres explicites dans les fonctions
personnalisées est une bonne pratique, servant de première ligne de défense pour garantir
que la fonction n'accepte que les arguments du type spécifié. Cependant, pour le
paramètre « colPositions », le typage explicite a été volontairement omis. Bien que la
documentation des paramètres soit une approche courante pour informer les utilisateurs
des types d'arguments attendus, une logique d'erreur personnalisée a été implémentée ici
pour fournir des informations spécifiques à l'utilisateur lorsqu'un argument transmis n'est
pas du type attendu, en particulier une liste. En personnalisant le message d'erreur,
nous pouvons offrir un retour plus pertinent à l'utilisateur, l'aidant à respecter les exigences
de valeur des arguments.

// Erreur personnalisée, fournissez des informations plus spécifiques à l'utilisateur. l = if not


[Link]( colPositions, type nullable list ) then error "Passez une liste avec des positions de
colonne, le numéro de départ est 1.
Par exemple : { 1, 3, 5 } conservera ou supprimera les colonnes 1, 3 et 5 de la table d'entrée. else colPositions ?? {},

La gestion des paramètres optionnels dans les fonctions personnalisées est essentielle
pour éviter que les valeurs « null » ne deviennent une cause d'erreur. Lorsqu'un
paramètre optionnel est omis, sa valeur par défaut est « null ». Pour éviter tout problème
potentiel, coalesce est utilisé à la ligne 7 pour garantir que, lorsque le paramètre
« colPositions » est « null », il sera remplacé par une liste vide « {} ». Ainsi, la variable
« l » est toujours garantie d'avoir une valeur valide lorsqu'elle est transmise à
[Link], soit la liste fournie par l'utilisateur, soit une liste vide si elle
est omise. De plus, coalesce est utilisé pour définir une valeur par défaut pour le
paramètre optionnel « keepOrDelete ». Ainsi, si l'utilisateur ne passe pas d'argument
pour « keepOrDelete », la valeur par défaut sera « Keep ». Ainsi, la fonction est conçue
pour être plus intuitive et prévisible, car elle évite aux utilisateurs de fournir
explicitement une valeur s'ils le souhaitent.
Machine Translated by Google

conserver les colonnes spécifiées.

// Coalesce définit la valeur par défaut pour sélectionner et non supprimer des colonnes. inclOrExclCols =
keepOrDelete ?? true,

Pour gérer efficacement les noms de colonnes d'une table, nous allons tous les affecter à une variable.
Power Query M utilise un index de base zéro, ce qui signifie que nous devons convertir la saisie
utilisateur, car il lui a été demandé de fournir un index de base un. La spécification des positions des
colonnes à partir de un au lieu de zéro rend l'opération plus intuitive. Avant de procéder à la
soustraction, nous devons nous assurer que le type de données de l'élément de la liste
« colPositions » correspond à un nombre. Pour ce faire, nous inclurons une gestion des erreurs pour les
cas où une valeur ne peut pas être convertie en nombre. En utilisant une construction « try­otherwise »,
nous pouvons tenter de convertir chaque élément de la liste en nombre. En cas de succès, nous
effectuons la soustraction de un pour ajuster l'index de base zéro. Si une valeur de la liste ne peut
pas être convertie en nombre, la clause « otherwise » prend effet, pour laquelle nous avons fourni une valeur
« null ». Par souci de simplicité, les saisies erronées sont ignorées.

allCols = [Link]( myTable ), // try­otherwise


protège l'évaluation du deuxième argument, renvoyant une valeur null par défaut baseZero = [Link]( l, each try [Link](_)­1 otherwise
null ),

Pour générer une liste de noms de colonnes réels à partir des entrées utilisateur et garantir que l'accès
aux éléments facultatifs n'entraîne pas d'erreurs, nous allons imbriquer trois fonctions. Nous allons
d'abord construire la logique de l'intérieur vers l'extérieur, en filtrant la liste « baseZero » et en ne
conservant que les valeurs supérieures ou égales à zéro. Cette précaution garantit que l'accès aux éléments
facultatifs ne générera jamais d'erreur due à un index négatif. Ensuite, dans [Link], nous
appliquerons l'accès aux éléments facultatifs pour obtenir le nom de colonne correspondant dans la liste
« allCols ». Enfin, nous supprimerons les valeurs « null ». En supprimant les valeurs nulles de la liste,
nous pouvons déterminer le nombre de noms de colonnes valides restants.

colNames =
[Link]( [Link]( [Link]( baseZero, each _ >=0 ), each allCols{_}? ) ),

Grâce à ces étapes, nous pouvons générer une valeur de sortie en toute confiance. Pour y parvenir, nous
allons :

• Exploiter une double instruction « if­then­else » pour contrôler le déroulement de la fonction. La


condition « if » externe vérifie s'il reste des noms de colonnes valides dans la liste « colNames ».
• S'il n'y a pas de noms de colonnes valides, la fonction renvoie la
table d'entrée telle quelle, sans aucune modification. Inversement, s'il existe des noms de
colonnes valides, la deuxième instruction « if­then­else », basée sur la valeur « inclOrExclCols »,
détermine si les colonnes spécifiées doivent être conservées ou supprimées de la table
d'entrée.

Grâce à ces structures de contrôle, nous garantissons que la fonction peut gérer efficacement divers
scénarios. Si les utilisateurs fournissent des positions de colonne non valides ou ne spécifient
aucune colonne à inclure ou à exclure, la fonction
Machine Translated by Google

fournit toujours des résultats cohérents, évitant les erreurs inattendues et offrant une
expérience utilisateur fluide.

newTbl = si [Link]( colNames ) >0 alors [Link]( myTable,


si inclOrExclCols alors colNames

sinon [Link]( allCols, colNames ) ) sinon maTable

Voici le script de code M complet, y compris la documentation.

laisser

fxSelectColumns = ( myTable as table, optional colPositions, optional keepOrDelete as l let // Logique d'erreur personnalisée pour fournir des informations plus spécifiques à l'utilisateur.
cols = if not
[Link]( colPositions, type nullable list ) then error "Transmettez une liste avec les positions des colonnes, le numéro de départ est 1. Par exemple : { 1, 3, 5 }
conservera ou supprimera les colonnes 1, 3 et 5 de l'entrée else colPositions ?? {}, // Coalesce pour définir la valeur par défaut sur
la sélection des colonnes, sans les supprimer. inclOrExclCols = keepOrDelete ?? true, allCols = [Link]( myTable ), // try­otherwise protège l'évaluation
du deuxième argument, renvoyant une valeur nulle f baseZero = [Link]( cols, each try [Link](_)­1 otherwise null ), colNames =
[Link]( [Link]( [Link]( baseZero, each _ >=0 ),
e // une double instruction if­then­else contrôle le flux pour la sortie de la table expressio newTbl = if [Link]( colNames ) >0 then [Link]( myTable, if
inclOrExclCols then colNames

sinon [Link]( allCols, colNames ) ) sinon maTable

dans
newTbl, fnDocumentation =
[ [Link] = " Sélectionner les colonnes
par position ", [Link] = " Sélectionne ou supprime des colonnes de la table d'entrée. 'colPositions' prend
une liste avec des numéros de position de colonne basés sur un. 'keepOrDelete' prend un booléen, 'true' = conserver et 'false' = supprimer les colonnes.

Renvoie une table avec moins de colonnes ou telle quelle lorsqu'aucune valeur valide n'a été transmise [Link] = " Melissa de Korte ", [Link] = " 1.0 "

] dans

[Link]( fxSelectColumns, [Link]( [Link]( fxSelectColumns ), fnDocumentation ) )

Cet exemple présente diverses techniques de prévention et de gestion des erreurs,


illustrant leur rôle dans les tâches de transformation de données. En intégrant
des choix clairs pour les développeurs, des erreurs personnalisées, la fusion, l'accès
facultatif aux éléments, les instructions try­otherwise et if­then­else, nous avons créé une
méthode puissante et conviviale pour sélectionner les colonnes d'une table. Chacune de
ces techniques a un objectif spécifique, contribuant à la robustesse et à la fiabilité
globales de la fonction. Scénario 2. La tâche. Garantir la qualité et la validité des données
est une étape cruciale du processus de préparation des données, mais la gestion des
erreurs au niveau des cellules est primordiale pour préserver l'intégrité de vos ensembles
de données. Bien que [Link] puisse sembler être une tâche complexe,
Machine Translated by Google

Bien qu'il s'agisse d'une option pratique pour supprimer les lignes contenant
des erreurs, elle n'est pas sans conséquences. En particulier, si vous ne savez pas quelles
lignes ont été supprimées et pourquoi. Pour préserver la transparence des données,
vous permettre de prendre des décisions éclairées et d'agir en cas de problème, nous
allons vous expliquer comment créer une table de rapport d'erreurs pour votre requête.
Scénario 2 : Une solution . La plupart des tables contiennent une ou plusieurs colonnes
clés, qui servent d'identifiants uniques pour des entrées spécifiques de la table. Il
est donc important de permettre aux utilisateurs d'identifier les colonnes clés et de les
conserver comme identifiants de ligne dans la table de sortie. De plus, nous pouvons
permettre aux utilisateurs de limiter la détection des erreurs à une sélection spécifique
de colonnes, garantissant ainsi une approche plus ciblée et efficace. Compte tenu de ces
considérations, nous avons identifié trois paramètres d'entrée pour notre
fonction personnalisée. Ces paramètres incluent la table d'entrée sur laquelle
l'opération sera effectuée, une liste facultative contenant les noms des colonnes clés et
une liste facultative spécifiant les noms des colonnes à analyser pour détecter les
erreurs. En fournissant ces paramètres, les utilisateurs disposent d'un contrôle précis
sur le processus de détection des erreurs. Pour garantir que seuls les arguments valides
sont acceptés, des paramètres explicites ont été déclarés. La définition explicite des types
de données attendus pour chaque paramètre ajoute une couche de protection, empêchant
la fonction d'accepter des types de données incompatibles en entrée.

(myTable comme table, keyCols facultatif comme liste, scanCols facultatif comme liste) comme enregistrement =>

Rendre l'argument « keyCols » facultatif offre une plus grande flexibilité aux
utilisateurs, mais nécessite également une gestion appropriée lorsqu'une valeur
n'est pas fournie. En effet, lorsque « keyCols » est omis, sa valeur est « null ». Pour
éviter une erreur de type lors de la transmission d'un argument à une autre
fonction attendant un type liste, l'opérateur de coalescence est utilisé pour remplacer
« null » par une liste vide. En tenant compte des éventuelles fautes d'orthographe
dans les « keyCols » fournis par l'utilisateur, nous pouvons les valider par rapport aux
noms de colonnes de la table d'entrée (« colNames »). Cela permet d'identifier les noms de
colonnes clés valides et de les stocker dans une nouvelle variable appelée « validKeys ».
Cette étape de validation permet non seulement d'éviter les erreurs potentielles,
mais aussi de fournir à l'utilisateur une liste de noms de colonnes clés mal
orthographiés ou inexistants dans la sortie. Enfin, la variable « hasKeys » renvoie « true »
ou « false » selon la présence ou non d'une colonne clé valide.

colNames = [Link]( maTable ), validKeys =


[Link]( { colNames, keyCols ?? {} } ), hasKeys = [Link]( validKeys ) >0,

La même méthode de coalescence et de validation est utilisée pour l'argument


facultatif « scanCols », fourni par l'utilisateur. Si « scanCols » est omis, sa valeur par
défaut est « null ». La coalescence remplace « null » par une liste vide, garantissant
ainsi la disponibilité d'un type de liste pour un traitement ultérieur. Pour optimiser les
performances de la fonction, nous prenons les devants dans la préparation des
données. Toutes les colonnes non requises sont immédiatement supprimées de la
table d'entrée et stockées dans la variable « newTable ». En éliminant
rapidement les colonnes inutiles, nous réduisons la charge de calcul et optimisons l'exécution.

selCols = [Link]( { colNames, scanCols ?? {} } ), newTable = [Link]( myTable,


si [Link]( selCols ) >0 alors validKeys & sel
Machine Translated by Google

Ensuite, une option de développement consiste à définir une liste de noms de colonnes
réservés. Autrement dit, les noms de la liste « reservedNames » ne doivent pas figurer
dans la table d'entrée. Toute violation détectée sera stockée dans la liste
« nameViolations ». Cela nous permet de fournir un retour d'information à l'utilisateur.

reservedNames = { "Nom", "Erreurs", "Raison", "Message", "Détail", "rowIndex", "newCol" } nameViolations = [Link]( { colNames, reservedNames } ),

Plongeons au cœur de cette solution et créons un composant essentiel dans la construction d'une « table
de rapport d'erreurs », en exploitant plusieurs instructions if­then­else.

Tout d'abord, nous vérifions s'il existe des violations de noms de colonnes. Dans le
cas contraire, nous utilisons une expression let imbriquée pour gérer deux
scénarios différents en fonction de la présence de clés
valides. Si des clés valides existent, nous conservons toutes les erreurs contenant
des lignes de la table
d'entrée modifiée. En revanche, en l'absence de clés valides, nous ajoutons une
colonne d'index de ligne de base zéro, appelée « rowIndex », à la table d'entrée
modifiée avant d'appeler la fonction [Link] .

runLogic = si [Link]( nameViolations ) alors laissez t = si hasKeys = true alors

[Link]( newTable ) sinon


[Link]( [Link]( newTable, "rowIndex", 0, 1, In

La variable « t » contient désormais un tableau contenant des lignes comportant une ou


plusieurs erreurs dans ses cellules. Cependant, nous nous concentrons uniquement sur les
erreurs elles­mêmes. Nous allons ajouter une nouvelle colonne appelée « newCol » à
l'aide de [Link](_) pour générer un tableau à deux colonnes par ligne. La première
colonne, « Name », contient les noms des champs, tandis que la seconde, « Value », contient
les valeurs correspondantes. Nous pouvons maintenant invoquer à nouveau la fonction
[Link] , en ciblant cette fois la colonne « Values » pour
récupérer uniquement les erreurs. Notre objectif final est de générer un rapport
d'erreurs indiquant la cause, le message et les détails de l'erreur. Pour ce faire, nous créons
une colonne supplémentaire dans la table imbriquée, en utilisant la construction try­
catch pour extraire les informations pertinentes de la valeur d'erreur : try [Value] catch (e) => e
et en enregistrant ces informations dans une nouvelle colonne nommée « Errors ». Maintenant
que nous avons extrait avec succès les données nécessaires, il n'est plus nécessaire
de conserver la valeur d'erreur réelle stockée dans la colonne « Value » de la table
imbriquée. En utilisant la projection requise, pour créer une table avec moins de
colonnes : [[Name], [Errors]]. Enfin, nous pouvons également optimiser la table externe
en omettant toutes les colonnes, à l'exception des colonnes « newCol », des colonnes clés ou de la colonne « rowInde

getErrors = [Link]( [Link]( t, "newCol", each [Link]( [Link]( [Link](_),


{"Valeur"}), "Erreurs", each try [Valeur] catch (e)=> e )[[Nom], [Erreurs]] ), si hasKeys alors validKeys & {"newCol"} sinon {"rowIndex", "newCol"} ),

Après avoir optimisé les colonnes de notre table, nous allons maintenant développer la table
imbriquée dans « newCol », qui contient les colonnes « Nom » et « Erreurs ». Cette extraction
entraînera à la fois l'élargissement et le développement de la table.
Machine Translated by Google

nous permettant d'exposer une valeur d'enregistrement dans la colonne « Erreurs »


nouvellement ajoutée. L'extraction des champs « Raison », « Message » et « Détail » de la
valeur d'enregistrement dans la colonne « Erreurs » élargit encore plus le tableau, offrant aux utilisateurs
des informations détaillées sur chaque erreur rencontrée.

errorTable = [Link]( [Link]( getErrors,


"newCol", {"Nom", "Erreurs"} ), "Erreurs", {"Raison", "Message", "Détail"} ) dans errorTable

Nous devons compléter la branche finale à partir de la première instruction if­then­else. Autrement dit,
si nous constatons des violations de noms de colonnes, nous générerons une erreur personnalisée.
Le message d'erreur demande à l'utilisateur de renommer les colonnes listées et de réessayer.

sinon erreur « Veuillez


d'abord renommer ces colonnes dans votre table : » & [Link]( nameViolations, ", "

Enfin, cette fonction génère une valeur d'enregistrement qui contient 4 champs : un nombre pour le
« Nombre d'erreurs », une table de rapport d'erreurs « Données », une liste avec des « Colonnes clés
non valides » et une liste avec des « Colonnes d'analyse non valides ».

[ Nombre d'erreurs = [Link]( runLogic ), Données = runLogic, Colonnes clés


non valides = [Link]( keyCols ??
{}, validKeys), Colonnes d'analyse non valides = [Link]( scanewCols ?? {}, selCols) ]

Voici le script de code M complet, y compris la documentation.

laisser

fxErrorReport = (myTable comme table, keyCols facultatif comme liste, scanCols facultatif comme liste) let

colNames = [Link]( myTable ), validKeys = [Link]( { colNames,


keyCols ?? {} } ), hasKeys = [Link]( validKeys ) >0, selCols = [Link]( { colNames, scanCols ?? {} } ), nTable =
[Link]( myTable, if [Link]( selCols ) >0 then validKeys & sel
reservedNames = { "Nom", "Erreurs", "Raison", "Message", "Détail", "rowIndex", "nCol" } nameViolations =
[Link]( { colNames, reservedNames } ), runLogic = if [Link]( nameViolations ) then let t = if hasKeys = true then [Link]( nTable ) else
[Link]( [Link]( nTable, "rowIndex", 0, 1, getErrors = [Link]( [Link]( t, "nCol", each
[Link]( [Link]( [Link](_), {"Valeur"}), "Erreur each try [Valeur] catch (e)=> e )[[Nom],
[Erreurs]] ), if hasKeys then validKeys & {"nCol"} else {"rowIndex", "nCol"} ), errorTable =

[Link]( [Link]( getErrors,


"nCol", {"Nom", "Erreurs"} ), "Erreurs", {"Raison", "Message", "Détail"} ) dans errorTable

sinon erreur « Veuillez d'abord


renommer ces colonnes dans votre table : » & [Link]( nameViolations, in

[ Nombre
d'erreurs = [Link]( runLogic ), Données = runLogic, Colonnes clés non valides =
[Link]( keyCols ?? {}, validKeys ),
Machine Translated by Google

Colonnes d'analyse non valides = [Link]( scanCols ?? {}, selCols ) ], fxDocumentation = [ [Link]
= " Créer un
rapport d'erreur ", [Link]
= " Renvoie un enregistrement contenant 4 champs.

Le champ « Nombre d'erreurs » indique le nombre d'erreurs détectées dans la table d'entrée. Le champ « Données » contient le tableau de rapport
d'erreurs. Le champ « Colonnes clés non valides » renvoie une liste des colonnes clés non valides
spécifiées si un champ « Colonnes d'analyse non valides » renvoie une liste des colonnes d'analyse non valides spécifiées si [Link] = « Melissa de Korte »,
[Link] = « 1.0 »

]
dans
[Link]( fxErrorReport, [Link]( [Link]( fxErrorReport ), fxDocumentation

))

La gestion des erreurs est un aspect complexe de la conception de requêtes robustes. Elle
nécessite une compréhension approfondie des différents types d'erreurs et de
leurs méthodes de confinement, de détection, de prévention et de résolution. En adoptant
des mesures préventives, vous pouvez développer des compétences en gestion des
erreurs qui non seulement traitent les erreurs lorsqu'elles surviennent, mais les minimisent également.
Des choix judicieux, voire la mise en œuvre d'une gestion dynamique des erreurs, vous
permettront de créer des requêtes plus fiables. En peaufinant vos stratégies de gestion des
erreurs, vous découvrirez les possibilités infinies d'approches créatives et de
résolution de problèmes offertes par le langage Power Query M.

Résumé
Ce chapitre a débuté par la création des bases : une compréhension commune de ce qu'est
une erreur, et de la manière dont elle peut être signalée, contenue et détectée.
Exploration des différents aspects de la gestion des erreurs, soulignant l'importance d'une
approche globale. Au­delà de la simple réaction aux erreurs, il est crucial d'intégrer
proactivement des mesures préventives à la conception de vos requêtes. En combinant
judicieusement ces techniques, vous pouvez créer des requêtes plus résilientes, réduisant
ainsi le risque d'erreurs et améliorant la qualité globale des données.
Machine Translated by Google

6 Travailler avec des valeurs structurées

Rejoignez notre communauté de livres sur Discord


[Link]

Dans ce chapitre, nous nous concentrons sur un concept important du langage Power
Query M : les valeurs structurées. Si nous avons présenté les valeurs et les types de données
dans les chapitres précédents, les valeurs structurées sont plus complexes et nécessitent une
attention particulière. Contrairement aux valeurs simples ou primitives, elles peuvent inclure
plusieurs autres valeurs, ce qui en fait un type de données plus complexe. Cette complexité
leur permet de contenir une plage de valeurs primitives, voire d'autres valeurs structurées,
ouvrant ainsi un large éventail de possibilités de manipulation et d'analyse des
données. L'importance des valeurs structurées dans le langage M est telle que nous
leur consacrons un chapitre entier. Les constructions que vous apprendrez contribuent non
seulement à un code plus efficace, mais constituent également la base de nombreuses
opérations en langage M. Ce chapitre aborde les sujets suivants :

Présentation des valeurs structurées

Listes

Enregistrements

Tableaux : dans chaque section, nous expliquerons clairement les concepts, les clarifierons
à l'aide d'exemples pertinents et mettrons en évidence leurs cas d'utilisation. Cette approche
structurée vous permettra de mieux comprendre ces concepts, de voir leurs liens et
de les appliquer efficacement dans votre travail.

Présentation des valeurs structurées

En approfondissant notre compréhension du langage Power Query M, nous abordons l'un


des concepts les plus importants : les valeurs structurées. Ces valeurs constituent la base
de la mise en forme et de la manipulation des données dans Power Query M. Mais qu'est­ce que
Machine Translated by Google

Que voulons­nous dire exactement lorsque nous parlons de « valeurs structurées » ?

Importance des valeurs structurées

Les valeurs structurées peuvent être considérées comme un conteneur ou un package pouvant contenir
une ou plusieurs valeurs. Ces conteneurs sont organisés de manière à permettre des transformations. En
tant que développeur, une compréhension approfondie de l'utilisation des valeurs structurées vous permet
de réaliser plus facilement des transformations de données complexes. Les valeurs structurées
permettent de gérer la complexité en divisant les données en blocs gérables.

Chaque valeur structurée – qu'il s'agisse d'une liste, d'un enregistrement, d'une table ou d'une fonction –
possède des caractéristiques et des applications uniques. Comprendre quand utiliser chacune d'elles permet
d'écrire du code efficace. Au fil de ce chapitre, certains concepts pourraient vous sembler plus complexes
que d'autres. Mais en prenant le temps de comprendre ces concepts fondamentaux, vous poserez des bases
solides et pourrez gérer avec assurance des tâches Power Query M plus complexes par la suite. Ce
chapitre vise à clarifier les valeurs structurées et à vous fournir une compréhension complète de leur rôle
et de leur application dans Power Query M. Nous approfondirons les spécificités des listes, des
enregistrements, des tables et des fonctions, en expliquant leur nature, leur fonctionnement et leur importance
dans les tâches de transformation de données.

Listes

En commençant notre compréhension des valeurs structurées, nous rencontrons d’abord les listes.
Alors, qu'est­ce qu'une liste ?

Introduction aux listes

Une liste est une valeur contenant une séquence de valeurs séparées par des virgules. Elle peut contenir
n'importe quel type de valeur. Cela inclut des valeurs primitives (comme du texte, un nombre, une date, une
heure), mais aussi des valeurs structurées (listes, enregistrements ou tables). Alors, pourquoi les listes
devraient­elles vous intéresser ? Vous constaterez que les listes sont largement utilisées dans Power Query.
Par exemple, la sélection d'une colonne renvoie ses valeurs sous forme de liste.

De même, lorsque des fonctions prennent plusieurs valeurs en entrée (comme [Link]) ou renvoient
plusieurs valeurs en sortie (comme [Link]), elles utilisent souvent des listes. Voyons comment
créer une liste. Créer une liste est simple. Vous pouvez définir une valeur de liste en plaçant les valeurs
entre accolades { }, ce qu'on appelle officiellement l'initialisation de liste. Chaque valeur de la liste est séparée
par une virgule. Par exemple, vous pouvez créer une liste de trois valeurs numériques comme suit :

{1, 2, 3}
Machine Translated by Google

Figure 6.1. Initialiser une liste dans Power Query avec {}

Une liste peut également contenir plusieurs valeurs. L'instruction suivante crée une liste contenant
un nombre, du texte et une valeur logique.

{1, "Bonjour", vrai}

Et de la même manière, vous pouvez inclure d’autres valeurs structurées dans une liste.
L'expression suivante renvoie une liste contenant un texte, une liste, un enregistrement et une
valeur de table.

{ « a »,
{4,5,6},
[Colonne1 = 1, Colonne2 = "a"], #table( { "ID",
"Produit" }, {{ 1, "Apple" }} ) }

Nous aborderons les enregistrements et les tables plus loin dans ce chapitre. Lorsqu'une liste
ne contient aucun élément, elle est considérée comme vide. Pour renvoyer une liste vide, vous
pouvez écrire :

{} // Sortie : liste vide

Pour vérifier le nombre d'éléments dans une liste, vous pouvez utiliser une fonction
comme [Link].

[Link]( {1, 2, 3} ) // Sortie : 3 [Link]( {} ) // Sortie : 0

Pour en savoir plus sur les fonctions de liste disponibles et leurs types de données d'entrée et de
sortie attendus, nous vous recommandons de consulter la présentation des fonctions de liste à
l'adresse : [Link]
Machine Translated by Google

Opérateurs de liste

Pour approfondir notre compréhension des listes, intéressons­nous aux opérateurs.


Les listes prennent en charge les opérateurs suivants :

Notation de l'opérateur Description Égal Différent


= Vérifie si deux listes sont identiques.
Concaténation <> Vérifie si deux listes sont différentes.
et fusion ?? Ajoute deux listes.
Renvoie la première valeur non nulle parmi deux
options.

Égal

L'opérateur égal (=) vérifie si deux listes sont identiques, à la fois en termes d'ordre dans
lequel elles apparaissent et si les valeurs sont égales. Lors de la comparaison des
listes suivantes, l'opérateur renvoie « vrai » puisque les deux listes correspondent
parfaitement :

{1, 2, 3} = {1, 2, 3}

Cependant, réorganiser les éléments comme ci­dessous renvoie false.

{1, 2, 3} = {3, 2, 1}

Cela montre que l'ordre des éléments est important lors de la comparaison de listes.
L'opérateur d'égalité fonctionne, que la liste contienne des valeurs primitives ou
structurées (comme les listes imbriquées). Par exemple :

{ {1,"a","b"}, 2, 3} = { {1,"a","b"}, 2, 3} // Sortie : vrai

Pas égal

L'opérateur « différent » effectue l'exact opposé de l'opérateur « égal ». Il vérifie si deux listes
diffèrent d'une quelconque manière. Une modification par rapport à notre exemple précédent :

{1, 2, 3} <> {3, 2, 1} // Sortie : vrai

Bien qu'ils contiennent des éléments identiques, la différence d'ordre de la liste les rend « non
égaux », d'où la sortie « vrai ».

Enchaîner

L'opérateur de concaténation permet de combiner deux listes, en ajoutant une liste à


la fin d'une autre. Par exemple, vous pouvez combiner deux listes comme suit :

{1, 2} et {4, 5} // Sortie : {1, 2, 3, 4}


Machine Translated by Google

C'est un excellent moyen de combiner vos listes. Si vous préférez utiliser une fonction, vous
pouvez utiliser la fonction [Link].
[Link] nécessite de fournir les listes à combiner au sein d'une liste. Il s'agit de deux
listes au sein d'une liste, comme suit :

[Link]( { {1, 2}, {4, 5} } ) // Sortie : {1, 2, 3, 4}

Se fondre

L'opérateur de coalescence est un outil moins connu, mais extrêmement utile dans Power Query
M. Il permet de renvoyer la première valeur non nulle d'une série d'expressions.
Autrement dit, il renvoie la première valeur non nulle de la série. Par exemple, si l'on considère
une liste contenant « fourchette », « couteau », « cuillère » ou « null », pour renvoyer tous les éléments
lorsque la valeur actuelle est « null », vous pouvez écrire :

null ?? {« Fourchette », « Couteau », « Cuillère »}

L'instruction ci­dessus renvoie {« Fourchette », « Couteau », « Cuillère »}. Cet opérateur est
pratique pour manipuler des données susceptibles de contenir des valeurs manquantes ou nulles.
Maintenant que nous savons comment créer des listes et quels opérateurs peuvent les utiliser, voyons
comment générer facilement des listes de valeurs.

Méthodes pour créer une liste

Jusqu'à présent, vous avez vu les bases d'une liste sur la façon d'utiliser les opérateurs sur eux.
Ce chapitre montre les différentes manières d’en créer un.

Création de listes à l'aide de l'initialiseur de liste

La première méthode pour créer une liste consiste à utiliser l'initialiseur de liste, comme indiqué
précédemment. La simplicité de la création manuelle d'une liste constitue son principal atout. Voici
comment combiner différentes valeurs pour former une liste :

{ 1, vrai, #date( 2023, 12, 31 ) }

Créer des listes à l'aide de fonctions

Si la création manuelle n'est pas votre truc, des fonctions génératrices comme [Link],
[Link], [Link], [Link], [Link] et [Link] sont faites pour
vous. Elles suivent un modèle similaire et nécessitent trois ingrédients clés : une autre façon
simple de créer une liste de valeurs est d'utiliser des fonctions génératrices. Les fonctions suivantes
génèrent une liste de toutes pièces :

[Link]

[Link]

[Link]
Machine Translated by Google

[Link]ées

[Link]éros

[Link] fonctions suivent un modèle similaire nécessitant trois ingrédients clés :

1. Une valeur de départ pour la liste 2.


Le nombre de valeurs à créer dans la liste 3. Un incrément
qui est ajouté à chaque valeur pour chaque étape

Créer une liste de nombres est facile avec la fonction [Link]. Avec 1 comme valeur de départ,
créons 5 valeurs, chacune incrémentée de 1 :

[Link]( 1, 5, 1) // Renvoie { 1, 2, 3, 4, 5 }

Avec un incrément de 2, et la même valeur de départ et le même nombre, vous obtenez :

[Link]( 1, 5, 2 ) // Renvoie { 1, 3, 5, 7, 9 }

La magie des listes s'étend également aux dates. La fonction [Link] vous permet de créer une liste
de dates, par exemple cinq dates commençant le 31 décembre 2023, chacune incrémentée d'un jour :

[Link]( #date(2023,12,31), 5, #durée(1,0,0,0) ).

Si vous souhaitez créer une liste de nombres aléatoires, vous pouvez utiliser [Link]. Par
exemple, l'expression suivante crée une liste de trois nombres aléatoires :

[Link]éatoire( 3 )

Lorsque nous avons exécuté cette requête, la sortie a renvoyé cette liste :

{0,42290808419832404,0,76420168008850964,0,75750946894172089}

Alternativement, il existe de nombreuses autres fonctions prédéfinies dans le langage M qui renvoient
une liste, par exemple :

• Noms de champs : vous pouvez trouver des fonctions qui renvoient les noms de champs
trouvés dans les tables ([Link] ou [Link]) ou dans les
enregistrements ([Link]). •
Remodeler les valeurs structurées : D'autres fonctions transforment un
Valeur structurée dans une liste. Vous pouvez remodeler des tables en liste avec des
fonctions comme [Link], [Link], [Link] ou [Link]. Ou
vous remodelez des enregistrements avec [Link]. • Fractionner du texte :
lorsque vous travaillez avec des chaînes, les fonctions [Link] et [Link] peuvent
fractionner une chaîne en fonction d'un délimiteur spécifié et renvoyer le résultat sous forme de
liste.
Machine Translated by Google

Outre ces fonctions courantes, il existe deux autres fonctions puissantes permettant de créer une liste
avec une logique personnalisée : [Link] et [Link]. Nous les aborderons au chapitre 11,
« Mise en œuvre de la récursivité ».

Référencer une colonne de table

Une autre façon élégante d'obtenir une liste consiste à référencer une colonne de tableau. Imaginez une
table « Produit » avec « Produit » comme première colonne.

Figure 6.2. Ensemble de données avec trois colonnes.

Si l'étape Power Query renvoyant cette table s'appelle Source, vous pouvez renvoyer les valeurs de la
colonne Produit sous la forme d'une liste en utilisant l'expression suivante :

Source[Produit] // Sortie : {"Chaussure", "Chapeau", "Chemise", "Ceinture"}

Ce processus, connu sous le nom de sélection de champ, sera exploré plus en détail dans les prochains
chapitres sur les enregistrements et les tables.

En utilisant la forme A..B

Une fonctionnalité utile pour les listes est la possibilité de générer une liste d'éléments séquentiels en
utilisant la forme « a..b » . Ceci est particulièrement utile pour créer une liste de nombres, de lettres ou de
caractères spéciaux consécutifs. Dans sa forme la plus simple, la syntaxe « a..b » génère une série de
valeurs dans une plage de nombres spécifiée. Par exemple, pour créer une liste de nombres de
1 à 10, vous pouvez utiliser :

{1..10} // Sortie : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

Cela indique à Power Query de générer une liste d'entiers, commençant à 1 et se terminant à 10. Une telle
liste peut être utile pour des tâches telles que les boucles, les itérations, la génération de données
ou même la création de calendriers. Vous pouvez également utiliser cette construction pour créer des
séries de valeurs non continues. Voici deux exemples :

{ 1..3, 11..13 } // Sortie : { 1, 2, 3, 11, 12, 13}


{ ­1..1, 5, 8..10 } // Sortie : { ­1, 0, 1, 5, 8, 9, 10 }
Machine Translated by Google

Il est toutefois important de noter que cette fonctionnalité est conçue pour incrémenter
des listes. Si vous tentez de créer une liste décrémentée avec cette syntaxe, Power
Query renverra une liste vide :

{10..1} // Sortie : {}

Pour créer une liste décroissante de 10 à 1, deux méthodes simples impliquent l'utilisation des
fonctions [Link] ou [Link] :

[Link]( {1..10} )
[Link]( 10, 10, ­1 )

Tout comme nous avons généré une suite de nombres, vous pouvez produire une suite de lettres.
Par exemple, pour générer une liste contenant les six premières lettres de l'alphabet, vous pouvez
utiliser :

{"a".."f"} // Sortie : {"a", "b", "c", "d", "e", "f}

Mais n'oubliez pas que le langage M est sensible à la casse. Par conséquent, changer la
casse en {"A".."F"} produit la liste des six premières lettres majuscules de l'alphabet :

{"A".."F"} // Sortie : {"A", "B", "C", "D", "E", "F}

Vous vous demandez peut­être si la forme « a..b » a plus de sens. En effet !


Pour comprendre le fonctionnement de cette fonctionnalité, il est essentiel de comprendre ce
qui se passe en coulisses. Lorsque Power Query génère ces listes, il utilise des caractères
Unicode, que vous ayez spécifié un chiffre, une lettre ou une majuscule .
Prenons cet exemple : si vous deviez générer des valeurs commençant par la lettre « Y »
jusqu'à « b », vous obtiendriez :

{ "Y" .. "a"} // Sortie :


{ "Y", "Z", "[", "\", "]", "^", "_", "`", "a" }

Que se passe­t­il ici ? La lettre « Y » correspond au nombre décimal Unicode 89, tandis que
« a » correspond au nombre 98. Vous pouvez le vérifier en écrivant :

[Link]( "Y" ) // Sortie : 89 [Link]( "a" ) //


Sortie : 97

Lorsque vous n'avez que le décimal Unicode, vous réalisez l'inverse en utilisant :

Caractè[Link]( 97 ) // Sortie : « a »

Ainsi, pour bien comprendre la séquence dans laquelle les caractères sont générés, il est
utile de se référer à la norme Unicode : https://
[Link]/wiki/List_of_Unicode_characters#Latin_script

Accéder aux éléments d'une liste

Une fois que vous avez compris comment créer des listes, l'étape suivante consiste à
apprendre à accéder à leurs valeurs, un processus appelé « sélection ». Le langage M
utilise les mêmes accolades que celles utilisées pour définir une liste pour effectuer la sélection.
Machine Translated by Google

Cela prête souvent à confusion. Pour extraire un élément d'une liste par sa position, appliquez
un numéro d'index entre accolades après la liste. Gardez toutefois à l'esprit :

Les listes dans Power Query M suivent un système d'indexation « à base zéro », ce qui signifie
que le premier élément de votre liste a un index de 0.

Tenter de sélectionner un élément à une position inexistante entraînera une erreur. Illustrons
ces deux points avec quelques exemples.

Accès aux valeurs de liste par index

Supposons que nous ayons une liste incrémentée par pas de 10, de 10 à 50 : {10, 20, 30, 40, 50}.
Accéder à une valeur est aussi simple que de spécifier son index.
Par exemple, pour obtenir le premier élément, vous utiliseriez myList{0}, ce qui donne 10.
De même, myList{4} renverra 50, le dernier élément de la liste. Voici comment vous utiliseriez
l'expression d'accès à l'élément dans le code :

{10, 20, 30, 40, 50}{0} // Sortie : 10


{10, 20, 30, 40, 50}{4} // Sortie : 50

Les accolades jouent ici un double rôle. L'ensemble initial construit la liste, tandis que le second
identifie l'index de la valeur à extraire. N'oubliez pas que l'instruction de sélection représente
toujours une seule valeur numérique : l'index. Notez que nous pouvons obtenir le même
résultat avec la fonction [Link]. L'instruction suivante extrait la deuxième valeur d'une
liste :

[Link]( {1,2,3}, 1, 1 ) // Sortie : 2

Le concept de sélection va encore plus loin. Lorsque vous travaillez avec des listes imbriquées
(des listes dans des listes), vous pouvez sélectionner des valeurs dans plusieurs calques.
Considérons une liste dont le premier élément est une liste. Pour renvoyer le premier élément,
qui est lui­même une liste, utilisez le code suivant :

{{1,2,3}, "a", "b"}{0} // Sortie : {1, 2, 3}

Mais que se passe­t­il si nous cherchons à extraire la deuxième valeur de cette liste imbriquée ?
Rien ne vous empêche de sélectionner cette valeur en ajoutant une autre série d'accolades :

{{1,2,3}, "a", "b"}{0}{1} // Sortie : 2

Le {1} ajouté ici signifie que nous sélectionnons la deuxième valeur (rappelez­vous,
nous utilisons l'indexation de base zéro) de la première liste de notre liste parent.

Gestion des positions d'index inexistantes

Voyons maintenant ce qui se passe lorsque nous essayons de récupérer un élément à une position
d'index qui n'existe pas dans notre liste. Imaginons que notre code tente d'accéder à la sixième
valeur d'une liste de cinq éléments : {10, 20, 30, 40, 50}{5}Power
Machine Translated by Google

La requête renverra une erreur d'expression indiquant : « Il n'y avait pas assez
d'éléments dans l'énumération pour terminer l'opération. » Pour éviter cette erreur, le
langage M propose un opérateur qui demande la sélection d'éléments facultatifs.
Pour ce faire, il suffit d'ajouter un point d'interrogation à la fin d'une expression tentant
d'accéder à une liste. Si la position d'index n'existe pas dans la liste, la valeur renvoyée
sera nulle :

{10, 20, 30, 40, 50}{4}? // Sortie : 50 {10, 20, 30, 40, 50}{5} //
Sortie : Erreur d'expression {10, 20, 30, 40, 50}{5}? // Sortie : null

Maintenant que vous savez comment créer des listes et accéder à leurs valeurs, quand
sont­elles réellement utiles ?

Opérations courantes avec les listes

Les listes jouent un rôle important dans de nombreuses opérations. Pour illustrer leur
utilisation, examinons quelques exemples concrets qui illustrent leur applicabilité
à vos tâches de transformation de données. Imaginons que vous travaillez avec un
tableau composé de trois colonnes. Vous souhaitez déterminer la valeur maximale de ces
colonnes. Ici, la fonction [Link] avec un argument de liste atteint efficacement cet
objectif :

[Link]( { [Colonne1], [Colonne2], [Colonne3] } )

Dans ce code, la liste entoure les colonnes qui vous intéressent, vous permettant d'extraire
la valeur maximale de chacune d'elles. Que faire si vous souhaitez évaluer si une valeur de
« Colonne1 » correspond à l'une des trois couleurs spécifiques ? Le langage M de
Power Query ne possède pas d'opérateur « IN » traditionnel, contrairement à SQL ou
DAX. Cependant, une réplication simple peut être réalisée en utilisant une liste
associée à la fonction [Link] :

[Link]( { « Bleu », « Vert », « orange » }, [Colonne1] )

Le code ci­dessus teste si [Colonne1] contient au moins une des couleurs


spécifiées. C'est un bon exemple de la façon dont les listes facilitent la logique
conditionnelle. Prenons un autre scénario : « ISBN : 978­3­16­148410­0 ». Vous
souhaitez uniquement extraire les chiffres et les traits d'union. Vous pouvez gérer
cela efficacement en utilisant la forme « a..b » pour générer les caractères requis :

[Link]( "ISBN: 978­3­16­148410­0", {"0".."9","­"} )

Dans cet exemple, la liste permet de spécifier le jeu de caractères à conserver, en


extrayant uniquement le texte souhaité. Les listes peuvent également servir à fournir
des valeurs pour créer un tableau. Par exemple, vous pouvez générer un tableau avec une
seule colonne contenant trois valeurs, comme suit :

[Link]( { "Pomme", "Poire", "Banane" } )

Enfin, la fonction [Link] est un autre exemple où les listes sont largement
utilisées. Elle utilise des listes pour spécifier des colonnes à regrouper et pour
Machine Translated by Google

définition des agrégations :

[Link]( Source,
{"Colonne1",
"Colonne2"}, {{"Nombre", chaque
[Link](_), [Link]}} )

Dans ce code, les listes servent à regrouper les données (par « Colonne 1 » et
« Colonne 2 ») et à fournir les détails nécessaires à la création d'une colonne d'agrégation
avec un nombre de lignes. Ces exemples illustrent le rôle polyvalent des listes en langage M.
Comprendre comment manipuler et utiliser les listes est essentiel pour devenir un meilleur
programmeur M. Comme ce chapitre l'a montré, les listes peuvent contenir n'importe quelle
valeur. Comment pouvons­nous alors utiliser les types de données dans une liste ?

Attribution de types de données à une liste

Comme mentionné au chapitre 5, chaque valeur a un type de données qui lui est associé.
Cela s'applique aux valeurs primitives, mais aussi aux listes. Lorsqu'une liste contient des
valeurs appartenant à un seul type de données, vous pouvez spécifier leur type de
données lors de la création d'une colonne. À titre d'exemple, rappelons les étapes de création
d'une liste décrites précédemment dans ce chapitre. Une fois cette liste créée, vous pouvez
l'intégrer dans une colonne personnalisée grâce à la fonction [Link].

Figure 6.3 : Ajout de valeurs de liste dans une colonne sans attribuer de type de données

La fonction [Link] n'a reçu aucune instruction de type spécifique ; elle a donc créé
une colonne de type « any ». Ainsi, lorsque vous développez cette colonne, elle conserve
son type « any ».

Figure 6.4 : Les colonnes restent de type « any » lorsqu'elles sont développées sans type
de données pré­attribué
Machine Translated by Google

La bonne nouvelle, c'est que vous pouvez attribuer un type de données aux valeurs de
votre liste. Pour ce faire, il suffit de renseigner l'argument facultatif columnType
de la fonction [Link]. Comme pour toute autre valeur, vous pouvez spécifier le
type en utilisant n'importe quel type de données disponible. La seule différence pour les
listes est qu'elles sont placées entre accolades. Ainsi, pour spécifier une liste contenant des
nombres entiers, écrivez :

Figure 6.5. Ajout de valeurs de liste dans une colonne avec un type de données attribué

Lorsque vous développez cette colonne, elle apparaît comme une colonne de type
« Nombre entier ».

Figure 6.6 : Une fois développée, la colonne Liste inclut le type de données attribué

L'illustration ci­dessus illustre l'affectation d'un type de données à une liste lors de l'opération
[Link]. Mais que faire si vous disposez déjà de tables contenant des listes
auxquelles vous souhaitez affecter un type de données ? Supposons que vous ayez une
table nommée « Source » avec une colonne intitulée « MaListe » contenant des valeurs de
liste. Vous pouvez convertir cette colonne en une liste de valeurs de type « Nombre entier ».
Pour ce faire, utilisez la fonction [Link].

Figure 6.7 : [Link] attribue un type de colonne à une valeur de liste

Assurez­vous simplement d'effectuer une opération sur la liste sous­jacente. Dans le cas
contraire, [Link] n'attribuera pas de type de données. En conclusion,
l'avantage d'attribuer un type à une liste est que, lorsque vous étendez la liste à de
nouvelles lignes, un type de données sera attribué à la colonne. Cela vous évite
Machine Translated by Google

de la nécessité d'ajouter une étape de type de modification distincte pour définir le type de données.
Maintenant que nous avons exploré les listes, abordons un autre type de données structurées : les enregistrements.

Enregistrements

Au fur et à mesure que nous progressons dans les valeurs structurées dans le langage M de Power Query, nous
rencontrons des enregistrements.

Introduction aux enregistrements

Un enregistrement est une liste de valeurs nommée. Alors que les listes sont un ensemble simple et
ordonné de valeurs, les enregistrements associent un nom de champ ou une clé à chaque valeur. Cela donne une
structure de données plus complexe, mais organisée. Un enregistrement est comparable à une ligne unique
dans une table, où chaque champ possède un nom de colonne et une valeur uniques. Comme les listes, les
enregistrements peuvent contenir tout type de valeurs, qu'elles soient primitives (texte, nombre ou date) ou structurées
(listes, enregistrements ou tables). Voyons comment en créer un. Vous pouvez créer un enregistrement
avec l' opérateur d'initialisation d'enregistrement . Cela implique de spécifier des paires de clés et de valeurs
entre crochets [], également appelé initialisation d'enregistrement. Il est important de se rappeler que :

• Chaque enregistrement est entouré d'accolades. • Une clé (le nom du


champ) est suivie d'un signe égal (=). Les enregistrements vous permettent de fournir les noms de champs
sans guillemets. • La valeur du champ suit le signe égal. • Les paires de clés et de
valeurs sont séparées par une virgule.

Considérez cet exemple de création d’un enregistrement avec des détails sur une personne :

[ Nom = "John Doe", Âge = 30, Ville = "Seattle" ]

Figure 6.8 : Initialiser un enregistrement dans Power Query en utilisant []


Machine Translated by Google

Dans l'exemple ci­dessus, « Nom », « Âge » et « Ville » sont les clés (noms de champs) et « Jean Dupont », « 30 » et
« Seattle » sont les valeurs de champs correspondantes. Voici quelques points à prendre en compte lors de la création
d'un enregistrement :

Les combinaisons de clés et de valeurs sont séparées par des virgules.

Chaque nom de champ spécifié doit être unique, en tenant compte de la casse. Une erreur est
renvoyée si le même nom de champ est répété, comme dans cet enregistrement erroné : [Nom = "Jean
Dupont", Âge = 30, Âge = 31] Le message d'erreur indique que le nom « Âge » est défini plusieurs
fois en raison de plusieurs définitions du champ « Âge ». Un enregistrement, étant une valeur structurée,
peut contenir d'autres valeurs primitives ou structurées. Voici un exemple d'enregistrement avec un
enregistrement imbriqué et une liste :

[ Nom complet = "John Doe",


Âges = { 20, 30, 49 },
Nom = [ Initiales = "J", Nom de famille = "Doe" ] ]

Figure 6.9 : Un enregistrement peut contenir des valeurs primitives et structurées

Vous pouvez renvoyer un enregistrement vide comme suit :

[ ] // Sortie : enregistrement vide

Et pour compter le nombre de champs dans un enregistrement, vous pouvez utiliser la fonction
[Link] :

[Link]( [ Nom = "Jean Dupont", Âge = 30 ] ) // 2 [Link]( [] ) // 0

Méthodes pour créer un enregistrement

Ce chapitre dévoilera les méthodes de création et de récupération d’enregistrements, chacune adaptée à des
scénarios spécifiques.

Création d'enregistrements à l'aide de l'initialiseur d'enregistrements


Machine Translated by Google

Créer un enregistrement manuellement est souvent la solution la plus simple. Conformément à ce que nous
avons vu au chapitre précédent, l' opérateur d'initialisation d'enregistrement permet de créer un enregistrement
rapidement. Prenons l'exemple suivant :

[ Nom = "John Doe", Âge = 30, Ville = "Seattle" ].

Et voilà, nous avons un record.

Création d'enregistrements à l'aide de fonctions

Outre la création manuelle, vous pouvez également créer des enregistrements à l'aide de certaines fonctions.
Prenons l'exemple de la fonction [Link]. Cette fonction pratique permet de créer un enregistrement
à partir de valeurs et de champs donnés, comme suit :

[Link]( {"John Doe", 30,


"Seattle" }, { "Nom", "Âge", "Ville" } )

La fonction [Link] offre une autre alternative pour transformer une table en enregistrement :

[Link]( #table( { "Nom",


"Valeur" } , { {"Nom", "John Doe" }, {"Âge", 30 }, {"Ville",
"Seattle" } } ) )

Récupérer un enregistrement en référençant une ligne de table

La troisième méthode pour acquérir un enregistrement consiste à se référer à une ligne de table,
appelée sélection de champ. Par exemple, si vous avez une table nommée Source, la première ligne de
cette table peut être renvoyée comme enregistrement avec l'expression suivante :

Source{0}

Alternativement, lorsque vous utilisez la fonction [Link], vous pouvez référencer une ligne du
tableau en utilisant un trait de soulignement (_). Chaque cellule de la nouvelle colonne contient alors un
enregistrement contenant les valeurs de la ligne actuelle.
Machine Translated by Google

Figure 6.10 : Le trait de soulignement fait référence à la ligne actuelle dans un tableau

L'objectif de cette section est simplement de présenter la sélection de champs comme troisième
méthode. Nous explorerons plus en détail les tables et leurs caractéristiques dans les sections
suivantes. Power Query propose différentes méthodes et fonctions pour accomplir la même tâche.
Le choix dépend largement du scénario. La création manuelle d'enregistrements, à l'aide de
crochets, est généralement la méthode la plus simple. Cependant, lorsque vous référencez des listes
ou des valeurs de colonnes, une fonction comme [Link] peut s'avérer utile. La
connaissance de ces différentes méthodes vous guidera vers le choix le plus efficace pour vos
besoins. Fort de cette nouvelle compréhension de la création d'enregistrements, intéressons­nous
aux opérateurs.

Opérateurs d'enregistrement

Les opérateurs d'enregistrement permettent de manipuler et de comparer des enregistrements,


comme pour les listes. Explorons quelques­uns de ces opérateurs utiles pour travailler avec des
enregistrements.

Égal

L'opérateur égal (=) est utilisé pour évaluer si deux enregistrements sont identiques.
Le langage M considère les enregistrements comme égaux lorsque :

• le nombre total de noms de champs est identique • chaque


nom de champ existe dans les deux enregistrements
• les noms de champs correspondants ont des valeurs identiques.

en tenant compte à la fois des noms de champs et des valeurs associées. Par exemple :

[ Nom = "John", Âge = 32 ] = [ Nom = "John", Âge = 32 ]

Le résultat sera « vrai », car les deux enregistrements sont identiques. Vous pouvez déplacer
librement les noms de champs dans les enregistrements. Lors du test d'égalité, la comparaison
Machine Translated by Google

renvoie vrai si les ensembles de noms de champs et de valeurs sont identiques dans
chaque enregistrement, quel que soit l'ordre.

[ Nom = "John", Âge = 32 ] = [ Âge = 32, Nom = "John" ]

Mais s'il y a une différence entre les noms de champs ou les valeurs, la valeur renvoyée sera
« false ». Par exemple :

[ Nom = "John", Âge = 32 ] = [ Nom = "Jane", Âge = 32 ]

Dans ce cas, le champ Nom des deux enregistrements est différent, ce qui conduit à la
valeur « Faux ». Il est essentiel de noter que la comparaison est indépendante de l'ordre et
sensible à la casse, tant pour les noms de champs que pour les valeurs.

Pas égal

L'opérateur différent (<>) est l'opposé logique de l'opérateur égal. Il renvoie « vrai » si les
enregistrements ne sont pas identiques et « faux » dans le cas contraire.

[ Nom = "John", Âge = 32 ] <> [ Nom = "Jane", Âge = 32 ]

Dans ce cas, le résultat est « vrai » car le champ Nom diffère dans les deux enregistrements.

Enchaîner

Vous pouvez utiliser l'opérateur de concaténation pour combiner des enregistrements. L'exemple
suivant renvoie : [Nom = « Jean », Âge = 32, Sexe = « Homme »] :

[ Nom = "John", Âge = 32 ] & [ Sexe = "Homme"]

En cas de chevauchement entre les champs, la concaténation prend le champ de l'enregistrement


de droite pour écraser la valeur du champ de gauche. Dans ce contexte, l'expression suivante
renvoie [Nom = "John", Âge = 45] :

[ Nom = "John", Âge = 32 ] & [ Âge = 45 ]

Vous pouvez obtenir le même résultat avec la fonction [Link] en fournissant les
enregistrements à combiner sous forme de liste :

[Link]( { [ Nom =

"John", Âge = 32 ], [ Âge = 45] } )

Accéder aux champs d'un enregistrement

Les enregistrements en langage M contiennent différents champs et leur accès nécessite la


compréhension de deux méthodes fondamentales : la sélection de champs et la projection
d'enregistrements.
Machine Translated by Google

Sélection de champ

Pour accéder à un seul champ d'un enregistrement, vous pouvez référencer la clé associée à cette
valeur. On parle alors de sélection de champ. Par exemple, pour récupérer la valeur du champ « Nom » d'un
enregistrement, écrivez :

[Nom = « John Doe », Âge = 30, Ville = « Seattle »][Nom]

Remarquez l'utilisation de crochets ici ? C'est similaire à l'accès aux éléments d'une liste, mais au
lieu d'une position d'index entre accolades {}, vous spécifiez un nom de champ entre crochets. Vous pouvez
obtenir le même résultat en utilisant [Link] comme suit :

[Link]( [Nom = "John Doe",

Âge = 30, Ville = "Seattle"], "Nom" )

À mesure que vos enregistrements deviennent plus complexes, vous pourriez rencontrer des
enregistrements imbriqués dans d'autres enregistrements. Par exemple, un deuxième enregistrement dans
le champ « Info » peut inclure des informations supplémentaires comme « Âge » ou « Sexe ». Pour
extraire les données « Sexe » de ces structures imbriquées, écrivez­les comme suit :

[Info = [Âge = 20, Sexe = « Homme »]][Info][Sexe]

La différence essentielle entre la création et la sélection de champs dans un enregistrement réside dans la
notation entre crochets. La définition d'un enregistrement inclut un nom de champ, un signe égal (=) et une
valeur, tandis que la sélection d'un champ spécifie uniquement le nom du champ entre crochets. Repérer la
différence peut demander un peu de pratique, mais vous vous y habituerez. Soyez toutefois prudent lors de
la sélection de champs. Si vous essayez de sélectionner un champ inexistant, vous rencontrerez une
erreur.

[Nom = "John", Âge = 30][Ville] // erreur

Cela vous donnera l'erreur [Link] : « Le champ « Genre » de l'enregistrement est introuvable. ».
Pour éviter ce message d'erreur, vous pouvez utiliser l' opérateur de sélection de champ facultatif (?) pour
renvoyer une valeur nulle et contourner l'erreur.

[Nom = "John", Âge = 30] [Ville] // erreur [Nom = "John", Âge = 30] [Ville]? //
null

Ceci est identique à l'utilisation de la fonction [Link].

[Link]( [Nom = "John", Âge = 30], "Ville", null )

Les exemples précédents renvoient la valeur d'un champ. Cependant, les enregistrements permettent
également de renvoyer une partie de l'enregistrement, ce qui permet de récupérer plusieurs valeurs
simultanément, ce que nous allons voir maintenant.

Projection record
Machine Translated by Google

La projection d'enregistrements étend le concept de sélection de champs et permet d'accéder à


plusieurs champs simultanément. Elle permet de sélectionner plusieurs champs et de les « coller »
ensemble. Un nouvel enregistrement est alors créé avec les champs sélectionnés de l'enregistrement
d'origine. Pour ce faire, il suffit de saisir les noms des champs à récupérer, séparés par des
virgules et entre crochets, comme suit :

[Ab=1,Bo=2,Ed=3][[Ab],[Ed]] // Sortie [Ab=1,Ed=3]


[Ab=1,Bo=2,Ed=3][[Ab]] // Sortie [Ab=1]

Lorsque vous essayez de sélectionner un champ inexistant, Power Query génère une erreur.
Pour contourner ce problème, vous pouvez utiliser l' opérateur de projection d'enregistrement
facultatif (?) comme vous l'avez fait avec la sélection de champ, et il renverra une valeur nulle
pour le champ manquant.

[Ab=1,Bo=2,Ed=3][[Ab],[Z]] // Erreur de sortie [Ab=1,Bo=2,Ed=3]


[[Ab],[Z]]? // Sortie [Ab=1, Z=null]

Vous pouvez reproduire ce comportement en utilisant [Link] :


[Link]([Ab=1,Bo=2,Ed=3], {"Ab", "Z"},
[Link] )Dans ce chapitre, nous avons appris davantage sur l'accès aux éléments
dans les enregistrements, mais quand sont­ils utiles ?

Opérations courantes avec les enregistrements

Maintenant que vous êtes familiarisé avec la création d'enregistrements et l'accès aux champs par
sélection et projection, vous vous interrogez peut­être sur leur utilité pratique. Dans ce chapitre,
nous explorerons des applications et des scénarios concrets où les valeurs d'enregistrement sont
utiles à la manipulation de données.

Structure des variables

Un premier cas d'utilisation des enregistrements est leur utilisation comme structure pour les
variables. En DAX, vous savez peut­être qu'une variable est préfixée par le mot VAR et se
termine par le texte RETURN. L'éditeur avancé utilise la construction « let..in » qui fait la même
chose. Quel est le rapport avec les enregistrements ? L'instruction « let..in » de l'éditeur
avancé est essentiellement un enregistrement. Et vous pouvez les utiliser à votre avantage comme
variables. Alors, pourquoi utiliser des variables ? Pour trois raisons :

• Lorsque vous réutilisez des parties de votre code, vous avez moins de répétitions et
code éventuellement plus efficace lors de l'enregistrement du résultat d'une expression dans
une variable.
• En divisant une instruction complexe, votre code devient plus facile à lire. • Pour le dépannage
des variables, aidez­vous car vous pouvez renvoyer des calculs intermédiaires comme
résultat.

Prenons un exemple. Imaginez que votre cellule contienne la valeur texte « 31­12­2023 » et que
vous souhaitiez créer le code permettant d'indiquer dynamiquement le jour de la semaine où tombe
le réveillon du Nouvel An. Voici les étapes à suivre :
Machine Translated by Google

1. Transformez la valeur texte en date 2. Récupérez


l'année et le nom du jour de la semaine de cette date 3. Créez une chaîne pour combiner
ces informations.

Vous pouvez le faire manuellement en ajoutant le code suivant à une colonne personnalisée :

"Nouvelle année "


& [Link]([Link]([Link]([Date]))) & " est sur un "

& [Link]([Link]([Date]))

Le résultat de cette instruction est : « Le Nouvel An 2023 tombe un dimanche ». Notez que cette
instruction convertit deux fois la valeur texte de la colonne Date en type de données « date ». Si vous
préférez utiliser une structure d'enregistrement et manipuler des variables, vous pouvez écrire :

[ _Date = [Link]([Date]), _DoW = [Link](_Date),


_Year = [Link]([Link](_Date)), _Result = "Nouvelle année " & _Year & "
est sur un " & _DoW ][_Result]

La dernière ligne spécifie de renvoyer uniquement le champ [_Result]. Cependant, en cas d'erreur, vous
pouvez facilement le remplacer par n'importe quel autre champ de l'enregistrement.

Référencement de la ligne actuelle

Les enregistrements sont également utiles pour effectuer des calculs sur les valeurs des lignes actuelles.
Imaginez une table contenant une colonne contenant les noms des magasins et toutes les autres colonnes
contenant les mois de l'année.

Figure 6.11. Ensemble de données permettant de récupérer la ligne actuelle comme enregistrement

Si vous souhaitez ajouter une colonne avec les ventes moyennes dans toutes les colonnes sauf
celle du magasin, vous pouvez écrire manuellement :

[Link]( { [janvier], [février], [mars], [avril] } )

Cependant, les structures d'enregistrement permettent de référencer les valeurs d'une ligne de
manière plus dynamique. Pour obtenir le même résultat sans coder en dur les colonnes, vous pouvez écrire :

[Link](Enregistrement.ÀListe(
Machine Translated by Google

[Link]( _, "Store") ) )

Ce code récupère toutes les valeurs de la ligne actuelle sous forme d'enregistrement à
l'aide du trait de soulignement. La fonction [Link] supprime le champ
« Store » de cet enregistrement. [Link] transforme ensuite l'enregistrement en liste
afin que [Link] puisse calculer la moyenne de toutes les valeurs restantes.

Fournir des options pour les fonctions

Les enregistrements sont également couramment utilisés pour fournir des options dans les paramètres de fonction.
Utiliser un enregistrement comme entrée pour un argument de fonction permet de spécifier
facilement l'entrée de plusieurs options. Prenons l'exemple de la fonction [Link]. Pour
spécifier le format de sortie et la culture, écrivez :

Figure 6.11 : Les enregistrements sont utilisés dans les arguments de fonction

Dans ce cas, le nom abrégé du mois affiche un résultat différent selon le code culturel utilisé.

Suivi des résultats intermédiaires

Les enregistrements jouent également un rôle important pour la sauvegarde des résultats
intermédiaires dans les fonctions complexes. [Link] est une fonction qui peut
utiliser les enregistrements pour des calculs plus complexes. Cette fonction génère une liste
de valeurs à partir d'un point de départ, d'une condition déterminant le moment où les valeurs
doivent être générées et d'une fonction décrivant comment générer chaque valeur suivante.
Sans l'utilisation d'enregistrements, cette fonction peut par exemple générer une liste de
valeurs croissantes de 1 à 5 :

[Link]( () =>
1, // la valeur de départ est 1 chaque _ <= 5, // jusqu'à ce que la valeur
atteigne 5 chaque _ + 1 // incrémenter la valeur initiale de 1 )

La fonction [Link] génère une liste de valeurs. Cependant, cette opération


reste relativement simple ; c'est là qu'interviennent les enregistrements. Ces derniers jouent un
rôle important dans les itérations multivariables dans [Link]. Un
enregistrement peut contenir l'état actuel de toutes les variables impliquées dans l'itération. En
générant une liste d'enregistrements, vous pouvez stocker plusieurs valeurs requises. Par
exemple, l'exemple suivant crée un total cumulé en augmentant la valeur x d'une unité à
chaque étape, puis
Machine Translated by Google

en ajoutant cette nouvelle valeur à la valeur précédente dans la variable RT (total cumulé) :

[Link]( () => [ x
= 1, RT = 1 ], chaque [x] <= 5, chaque [ x = [x] + 1, RT =
[RT] + [x] + 1 ], chaque [RT] )

Notez que cette illustration est uniquement destinée à vous montrer où les enregistrements sont
utiles. [Link] est une fonction complexe, que nous aborderons au chapitre 11, consacré à la
récursivité. Nous aborderons ensuite l'attribution de types de données aux enregistrements.

Attribution d'un type de données aux enregistrements

Un enregistrement est une valeur structurée pouvant contenir une ou plusieurs valeurs
distinctes. Comme pour les listes, lorsque vous générez ces enregistrements, Power Query
utilise par défaut le type « any » si aucun type de données spécifique n'est attribué.

Figure 6.12 : Génération d’une colonne d’enregistrement sans attribuer de type de données spécifique.

L'extension de la colonne d'enregistrement ajoute ensuite les nouvelles colonnes et attribue le type
de données « any ».

Figure 6.13 Développement d’une colonne d’enregistrement à laquelle aucun type de données
n’est attribué.

Pour attribuer un type de données à un enregistrement, vous pouvez saisir un type d'enregistrement
définissant le type de données de chaque champ. La syntaxe utilisée reflète celle de la création de
l'enregistrement, à la seule différence qu'elle spécifie le type de données plutôt que la valeur du
champ.
Machine Translated by Google

Figure 6.14 : Création d'une colonne d'enregistrement avec des types de données attribués

Lorsque vous étendez la colonne d’enregistrement qui a un type attribué, elle crée de nouvelles
colonnes qui reflètent ces types de données.

Figure 6.15 : L'extension de cette colonne d'enregistrement conserve les types de données attribués

Comme cette section l'a montré, les enregistrements offrent un moyen structuré de conserver
et de manipuler des données. Leur polyvalence est évidente dans les scénarios nécessitant le
traitement simultané de plusieurs points de données connexes. Dans cette optique, nous arrivons
maintenant à la valeur structurée restante : la table.

Tableaux

Maintenant que nous avons approfondi les listes et les enregistrements, il est temps d'approfondir
notre compréhension des valeurs de table. Tout comme les listes et les enregistrements, les tables
occupent une place importante dans le langage M en raison de leur rôle dans la structuration et
l'organisation des données. Alors, qu'est­ce qu'une table ?

Introduction aux tableaux

À la base, une table est une valeur structurée qui organise les données en lignes et en colonnes. On
pourrait aussi dire qu'une table est une liste d'enregistrements où chaque enregistrement
représente une ligne. Grâce à sa forme bidimensionnelle, il est facile de prévisualiser les données dans
une table et vous constaterez que la plupart des requêtes chargées dans Power BI ou Excel génèrent
une valeur de table en sortie. Comment créer une table ? La création d'une table dans Power Query M
s'effectue souvent en appelant une fonction d'accès aux données, comme décrit au chapitre 3. Par
exemple, lorsque vous importez un fichier Excel ou CSV, Power Query crée automatiquement une
table. Cependant, pour illustrer les caractéristiques d'une table, ce chapitre utilise la fonction #table qui
crée manuellement une table. Cette fonction
Machine Translated by Google

prend en compte deux arguments :

• une liste de noms de colonnes.


• une liste de listes, où chaque liste interne forme une ligne.

Prenons un exemple :

#tableau(
{"ID", "Nom", "Pays"},
{ {1, "John Doe", "États­Unis"},
{2, "Jane Doe", "États­Unis"},
{3, « Jane Doe », « Canada »} } )

La structure de ces données se présente comme suit :

Figure 6.15 : Une table créée à l'aide de la fonction #table

Dans l'exemple ci­dessus, la fonction #table crée une table avec trois colonnes (ID,
Nom, Pays) et trois lignes de données. Notez que les colonnes n'ont aucun type de
données défini. Nous aborderons ce sujet plus loin dans ce chapitre.
Ensuite, nous verrons comment différents opérateurs se comportent avec les tables.

Opérateurs de table

Pour approfondir notre compréhension des tables, intéressons­nous aux opérateurs.


Les tables prennent en charge les opérateurs suivants :

Description de la notation des opérateurs


Égal = Vérifie si deux tables sont identiques.

Pas égal <> Vérifie si deux tables sont différentes.


Concaténation et Ajoute deux tableaux.
Se fondre ?? Renvoie la première valeur non nulle parmi deux
options.

Égal

L'opérateur d'égalité (=) vérifie si deux tables sont identiques, tant par leur structure que
par leurs valeurs. Lors de la comparaison, elles sont considérées comme égales si :
Machine Translated by Google

• avoir le même nombre de colonnes •


chaque nom de colonne est disponible dans les deux
tableaux • les tableaux ont un nombre identique de
lignes • les lignes ont des valeurs identiques dans les cellules correspondantes

Par exemple, même si les deux tables suivantes fournissent des noms de colonnes dans un
ordre différent, elles sont considérées comme identiques et l'expression renvoie « true » :

#table( {"ID", "Nom", "Pays"},


{{1, "John Doe", "USA"}, {2, "Jane Doe", "USA"}}) = #table( {"Nom", "Pays", "ID"},

{{"John Doe", "États­Unis", 1}, {"Jane Doe", "États­Unis", 2}})

Cela démontre que l’ordre des noms de colonnes n’est pas pertinent lors de la
comparaison de tables.

Pas égal

L'opérateur « différent » effectue l'exact opposé de l'opérateur « égal ». Il vérifie si deux


tables diffèrent d'une quelconque manière. Une modification de notre exemple précédent
modifie le pays de « USA » à « US » :

#table( {"ID", "Nom", "Pays" },


{{1, "John Doe", "USA", {2, "Jane Doe", "USA"}}) = #table( {"ID", "Nom", "Pays" },

{{1, "John Doe", "US", {2, "Jane Doe", "USA"}})

L'expression ci­dessus renvoie « faux » car le nom du pays dans la troisième colonne de la
première ligne est différent. Il est important de savoir que l'opérateur d'inégalité
fonctionne, que les valeurs comparées soient primitives ou structurées.

Fusionner

L'opérateur de fusion permet de combiner deux tables, en ajoutant une table à la fin d'une
autre. Par exemple, vous pouvez fusionner deux tables comme suit :

Figure 6.16 : Fusionner deux tables avec des colonnes identiques

C'est une excellente méthode pour fusionner vos tables. Si une table contient des colonnes
qui ne sont pas incluses dans l'autre, la fusion ajoute des valeurs nulles pour compléter les
éléments manquants.
Machine Translated by Google

Figure 6.17 : La fusion de deux tables avec des colonnes différentes ajoute des valeurs nulles

Si vous préférez utiliser une fonction, vous pouvez utiliser la fonction [Link]. Elle nécessite
de fournir les tables à combiner dans une liste. Il s'agit de deux tables dans une liste, comme suit :

[Link](Table1, Table2)

Se fondre

Tout comme pour les listes et les enregistrements, vous pouvez utiliser l'opérateur de
coalescence ?? avec les tables. Il permet de renvoyer une valeur alternative lorsque la valeur
principale est nulle. Sachant cela, l'instruction suivante est parfaitement valide :

null ??#table( {"ID", "Nom"}, {{1, "John Doe"}})

Cette instruction renvoie la valeur #table qui suit l'opérateur de coalescence.


Maintenant que vous savez comment créer des tables et utiliser des opérateurs sur celles­ci, le
chapitre suivant se concentre sur l'accès aux éléments d'une table.

Méthodes pour créer une table

Les tableaux sont un concept fondamental du langage M. Ce chapitre vous guidera à travers différentes
méthodes de création de tableaux, ouvrant ainsi un monde de possibilités.

1. Récupérer des données à partir d'une source

La méthode la plus courante pour créer un tableau consiste à se connecter à une source de données.
Vous pouvez vous connecter à diverses sources de données, notamment des fichiers Excel, des fichiers
CSV, des pages web et des bases de données. Une fois connecté à une source de données, Power
Query M crée automatiquement un tableau à partir de ces données. Par exemple, pour créer un
tableau à partir d'un fichier Excel, procédez comme suit :

1. Dans l'éditeur Power Query, cliquez sur le bouton Nouvelle source dans le
ruban.
2. Sélectionnez Classeur Excel.
3. Dans la boîte de dialogue Ouvrir , sélectionnez le fichier Excel auquel vous souhaitez vous connecter.
4. Sélectionnez le tableau ou la feuille que vous souhaitez importer.
5. Cliquez sur le bouton OK .
Machine Translated by Google

Power Query M créera automatiquement un tableau à partir du fichier Excel à l'aide de la


fonction [Link] avec [Link].

2. Saisir manuellement les données dans les fonctions

La deuxième façon de créer des valeurs de table consiste à les créer manuellement à l'aide
de fonctions de bibliothèque. Les fonctions permettant de créer des tables manuellement
sont:

• #table •
[Link] •
[Link] •
[Link]
• [Link] •
[Link] •
[Link] •
[Link]

Chaque fonction apporte son propre ensemble de capacités (jeu de mots intentionnel).
La fonction la plus utilisée pour créer manuellement une table est la fonction #table.
Cette fonction prend une liste de noms de colonnes comme premier argument et une liste de
listes comme deuxième argument pour former les lignes. Considérez cet exemple :

Figure 6.17 : La fonction #table créant une table

Le premier argument prend une liste de noms de colonnes, tandis que le second
prend une liste de listes de lignes de la table. Une autre fonction populaire,
[Link], accepte une liste d'enregistrements en entrée. Ces enregistrements
contiennent à la fois les noms de colonnes, représentés par les noms de champs
d'enregistrement, et les valeurs de lignes, représentées par les valeurs de champs d'enregistrement.

Figure 6.18 : Illustration de la création d'une table à l'aide de [Link]


Machine Translated by Google

Le monde de la création de tables en langage M de Power Query est vaste, et couvrir toutes les
fonctions ici peut être complexe. Cependant, devenir un expert en langage M implique de comprendre
les différentes méthodes de création de tables. Imaginez un scénario où vous
générez une liste de valeurs totales cumulées à l'aide de la fonction [Link]. Le résultat
de cette fonction est une valeur de liste. Pour lier les valeurs de cette liste à une table existante, vous
devrez combiner certaines de ces fonctions. Dans un autre cas, vous pourriez être chargé
de créer une table de réconciliation effectuant diverses vérifications pour répondre à des questions
telles que : le nombre de lignes de la table finale est­il identique au nombre initial ?

Le chiffre d'affaires total de la requête 1 correspond­il à celui de la requête 2 ? Dans ces


scénarios, il est utile de savoir comment stocker les valeurs de sortie de ces contrôles dans une table.
De plus, vous disposez de toutes ces fonctions pour créer une table adaptée à vos besoins
spécifiques.

3. Réutiliser les tables/requêtes existantes

Maintenant que vous connaissez les méthodes pour créer des tables manuellement, il est temps
d'explorer deux autres manières importantes d'ajouter des tables dans Power Query : le référencement
et la duplication de requêtes.

Référencement de tables/requêtes

Référencer des tables consiste à pointer vers le résultat d'autres tables ou requêtes. Cette approche
permet d'utiliser des tables ou requêtes existantes sans modifier ni affecter leur contenu d'origine. Le
référencement est comparable à une liaison. Ce processus permet de créer un lien vers le
résultat d'une table ou requête existante et de continuer à travailler dessus sans perturber ni modifier
la source. Comment procéder ? Référencer des tables ou des requêtes est simple. Prenons l'exemple
d'une table appelée Calendrier. Vous souhaitez utiliser le résultat de ce Calendrier comme base
d'une nouvelle requête. Il vous suffit de faire un clic droit sur la requête Calendrier et de cliquer sur
Référence.
Machine Translated by Google

Figure 6.18 : Illustration de l'opération de requête de référence

Cela crée ensuite une nouvelle requête qui fait référence (établit un lien vers) la table Calendrier.

Figure 6.19 : L'opération de requête de référence renvoie à la table d'origine

Outre le référencement, vous pouvez également dupliquer des tables.

Duplication de tables/requêtes

Dupliquer des tables dans Power Query consiste à créer une copie exacte d'une table existante. La
table dupliquée reprend les mêmes étapes de requête et le même contenu que l'original, mais fonctionne
comme une entité distincte. Pour dupliquer une requête, faites un clic droit dessus et cliquez sur
« Dupliquer ».
Machine Translated by Google

Le processus diffère du référencement d'une table : alors que le référencement crée un lien vers une
table existante, la duplication crée une table entièrement nouvelle, ressemblant simplement à
l'original. Cette copie inclut toutes les étapes de la requête d'origine.

Figure 6.19 : L'opération de duplication de requête copie également les étapes de la requête

4. Utilisation de la saisie de données

Cette liste ne serait pas complète sans mentionner la fonctionnalité « Saisir des
données ». L'éditeur Power Query permet de créer des tables manuellement de manière
conviviale, simplement en saisissant des données à l'écran. Pour « Saisir des données »
manuellement, accédez à l'onglet « Accueil » du ruban. Dans la section « Nouvelle requête » ,
vous trouverez le bouton « Saisir des données » . C'est ici que vous pouvez créer des
tables manuellement sans écrire de code M.
Machine Translated by Google

Figure 6.20 Bouton Saisir les données dans l'onglet Accueil

Après avoir cliqué sur « Saisir les données », une fenêtre apparaît avec un tableau vide,
prêt à être rempli. Les noms et valeurs des colonnes sont modifiables, et vous pouvez saisir
directement vos données. Pour ajouter des lignes, cliquez simplement sur les cellules
(surlignées en gris) à la fin de la dernière ligne pour créer une nouvelle ligne.
De même, pour ajouter des colonnes, cliquez sur l’en­tête de colonne le plus à droite
(également en gris) et une nouvelle colonne sera créée.

Après avoir renseigné votre tableau, cliquez sur « Charger » en bas à droite de la fenêtre.
Cette action fermera la fenêtre et chargera les données dans Power Query comme un
nouveau tableau.
Machine Translated by Google

Figure 6.21 : Code binaire généré avec la fonctionnalité de saisie de données

Comme le montre la figure 17, la fonctionnalité Saisir des données compresse les données en
code binaire et utilise la fonction [Link] pour créer la table.
Cependant, comme il s'agit d'une méthode très simple pour créer un tableau, nous
souhaitions la mentionner séparément. Notez que cette fonctionnalité peut contenir jusqu'à 3 000
cellules contenant des valeurs. Nous allons maintenant examiner l'accès aux différents éléments
d'un tableau.

Accéder aux éléments d'un tableau

Tout comme pour les listes et les enregistrements, accéder aux éléments d'un tableau est une
compétence utile pour travailler avec Power Query. Vous pouvez sélectionner une seule
colonne, plusieurs colonnes, une ligne, voire une seule valeur de cellule. Voyons comment
utiliser les principes de sélection et de projection dans un tableau.

Accès aux articles

Dans le contexte d'une table, l'expression d'accès à l'élément est utilisée pour renvoyer une ligne.
Imaginez que la table de la figure 7 soit créée lors d'une étape appelée « Source ». L'utilisation
de l' opérateur de sélection d'élément dans le contexte d'une table renvoie une ligne sous forme
d'enregistrement. Vous pouvez par exemple renvoyer la première ligne de la table en écrivant :

Source{0} // Sortie : [ID=1, Nom=“John Doe”, Pays=“USA”]

Cela revient à utiliser la fonction [Link] et à spécifier que vous souhaitez renvoyer une
seule ligne : [Link]( Source, 0, 1 )Tout comme avec les listes, essayer de récupérer un
élément où la position demandée n'existe pas dans le tableau génère une erreur que vous
pouvez éviter avec l' opérateur de sélection d'élément facultatif :

Source{3} // La ligne 4 n'existe pas, renvoie une erreur Source{3}? // Renvoie null

Les tableaux vous permettent d'accéder aux lignes d'une manière supplémentaire. Au lieu de
fournir un numéro d'index entre accolades, vous pouvez également rechercher une ou plusieurs
valeurs de champ. Par exemple, pour obtenir la deuxième ligne de la figure 7, vous pouvez utiliser
l'une des expressions suivantes :

Source{1} // Renvoie la deuxième ligne


Source{[ID = 2 ]} // Renvoie la ligne où ID = 2
Machine Translated by Google

Vous pouvez affiner votre recherche en fournissant plusieurs valeurs. Il vous suffit d'ajouter des
champs supplémentaires à votre enregistrement et de les placer entre accolades, comme suit :

Source{[ID = 2, Nom ="Jane Doe" ]}

Il est important de se rappeler que la sélection d'éléments via un enregistrement doit renvoyer une
ligne unique. L'expression suivante correspond à deux lignes et génère l'erreur suivante :

Source{[Nom ="Jane Doe"]}

Figure 6.22 : Erreur lorsque la sélection d'éléments renvoie plusieurs lignes

Ce comportement ressemble beaucoup à l'expression suivante qui attend une seule ligne
comme résultat :

[Link]( [Link]( Source, chaque [Nom] = "Jane Doe" ) )

Si vous souhaitez renvoyer plusieurs lignes, vous pouvez recourir à une fonction telle que :

[Link](Source, each [Nom] = "Jane Doe" )

Accès sur le terrain

Alors que l'opérateur de sélection d'élément renvoie une ligne, l' opérateur de sélection de champ
permet de renvoyer les valeurs d'une colonne sous forme de liste. Pour renvoyer les valeurs de la
colonne « Nom » sous forme de liste, vous pouvez utiliser la même syntaxe que pour les
enregistrements :

Source[Nom] // Sortie : { "John Doe", "Jane Doe" }

Alternativement, vous pouvez utiliser la fonction [Link] pour un résultat similaire :

[Link](Source, "Nom" )

Ce comportement est utile lorsque vous souhaitez référencer toutes les valeurs de colonnes pour
effectuer une opération comme [Link]. Vous pouvez ensuite utiliser le résultat pour indiquer
chaque valeur en pourcentage du total. Imaginons que vous souhaitiez accéder à plusieurs
colonnes de votre table. Comment y parvenir ? L'opérateur de projection de champ permet de
projeter une table vers une table contenant moins de colonnes.
Machine Translated by Google

colonnes.

Source[[Nom],[Pays]] // Renvoie deux colonnes

Figure 6.23 : La projection de champ obligatoire projette un tableau sur moins de colonnes

Une erreur se produit lors de la sélection d'un champ inexistant, mais vous pouvez éviter
l'erreur en utilisant la projection de champ facultative.

Source[[Nom],[Emplacement]] // Erreur Source[[Nom],


[Emplacement]] ? // Renvoie null dans la colonne Emplacement

Figure 6.24 : La projection de champ facultative renvoie null pour les colonnes manquantes

Ce comportement est identique à l'utilisation de la fonction [Link] avec


l'énumération [Link] :

[Link]( Source,
{"Nom",
"Emplacement"}, [Link] )

Jusqu'à présent, nous avons vu comment sélectionner une ligne comme enregistrement
(sélection d'élément) et comment renvoyer une ou plusieurs colonnes d'une table (sélection et
projection de champ). Pour renvoyer une valeur unique d'une table, vous pouvez combiner
ces deux concepts. Imaginons que vous souhaitiez renvoyer une valeur de la troisième ligne de la table.
Machine Translated by Google

Dans la colonne « Nom », vous pouvez utiliser l’une des expressions suivantes :

Source[Nom]{2}
Source{2}[Nom]

Vous savez maintenant comment créer des tables et accéder à leurs éléments. Quand sont­elles utiles ?

Opérations courantes avec les tables

En général, les tableaux sont ce que nous recherchons lorsque nous travaillons avec Power Query.
Cela peut paraître évident, mais voici quelques exemples où les tableaux sont souvent utilisés :

• Tables d'aide ­ Les tables sont utiles pour joindre ou ajouter des données.
Il peut s'agir d'une importation à partir d'un autre fichier ou d'une autre base de données, mais
vous pouvez également créer manuellement des tables d'aide pour enrichir vos données ou
les utiliser pour
fusionner ou joindre. • Inspecter les données et déboguer – Les tables sont souvent les plus efficaces
Structure pour inspecter vos données. Grâce aux colonnes et aux lignes, vous pouvez
visualiser plusieurs cellules simultanément. Et à chaque transformation effectuée, vous
pouvez facilement visualiser l'effet sur votre tableau. • Intégration avec
Power BI et Excel. Après l'exécution
Après avoir effectué des transformations sur vos données, vous obtenez généralement une ou
plusieurs tables propres. Vous pouvez ensuite les charger vers la destination souhaitée, comme
une feuille de calcul Excel ou un ensemble de données Power BI. De là, vous pouvez
continuer à exploiter vos données.

Il existe actuellement plus de 117 fonctions de table, ce qui en fait la catégorie de fonctions la plus
importante du langage M. Dans les chapitres suivants, vous apprendrez des techniques intégrant les
fonctions de table les plus utilisées. Vous savez désormais créer, manipuler et accéder aux valeurs
d'une table. Il ne vous reste plus qu'à apprendre à assigner des types de données aux tables.

Attribution d'un type de données aux tables

Les valeurs d'une table sont des valeurs structurées avec des types de données complexes. Après tout,
elles peuvent contenir d'autres valeurs primitives ou structurées. Et même dans ce cas, vous pouvez
définir des types de données pour chaque colonne de votre table.
Comment gérer les types de données pour les valeurs de tableau ? Imaginez que vous
construisiez manuellement une valeur pour chaque ligne d'un tableau. Pour ce faire, utilisez la fonction
#table avec la fonction [Link].
Machine Translated by Google

Figure 6.25 : Création d'une valeur de table à l'aide de la fonction #table

Conformément à nos attentes, la colonne nouvellement créée reçoit automatiquement le type « any ».
En développant la colonne, des colonnes supplémentaires apparaissent, toutes définies avec le type de
données « any ». Comment attribuer un type de table lors de la création d'une table ? Le
fonctionnement est très similaire à celui de la définition d'un type d'enregistrement, à la différence
près que le mot « type » est suivi du mot « table ».

Figure 6.26 : Création d'une colonne de tableau avec des types de données attribués

L'extension de cette colonne ajoute ensuite de nouvelles colonnes avec des types de données attribués.

Notez que vous pouvez également fournir un type de table dans la fonction #table. Lorsque vous construisez
une table uniquement avec cette fonction, sans utiliser [Link], le type de
table fournit au moteur les informations de type de données nécessaires. Cependant, avec la fonction
[Link], l'ajout du type de table à la fonction #table n'influence pas le type de données de sortie.
Seul le quatrième argument a un impact sur le type de sortie.
Machine Translated by Google

Figure 6.27 : La fonction [Link] détermine le type de données de sortie

Dans ces situations, il est donc important d’ajouter le type de table à


[Link].

Résumé
Dans ce chapitre, nous avons exploré les listes, les enregistrements et les tables,
montrant leur importance dans l'utilisation du langage M. Nous avons appris que les
valeurs structurées servent de conteneurs contenant une ou plusieurs valeurs
primitives ou structurées. Leur connaissance est utile dans de nombreux domaines.
Par exemple, les listes et les enregistrements sont souvent utilisés pour fournir plusieurs
éléments dans les arguments de fonction et ils aident à simplifier votre code en les utilisant.
Les structures d'enregistrement constituent également un excellent moyen de
créer des variables. Nous avons également étudié l'accès aux éléments des différentes
valeurs structurées, par sélection et projection, pour une extraction aisée des valeurs.
Ces compétences vous aideront à comprendre le code créé par l'interface utilisateur, mais
aussi à créer vous­même du code plus court. Nous avons ensuite examiné la création de
ces valeurs et le fonctionnement des opérateurs. Vous avez également découvert les types
de données complexes, soulignant leur importance et leur attribution. Enfin, ce chapitre a
fourni des exemples et des scénarios concrets et concrets. Ces démonstrations
pratiques illustrent la puissance des valeurs structurées, concrétisent l'abstrait et vous
permettent de visualiser vos apprentissages en action. Après ce chapitre, nous aborderons
la gestion des erreurs, un autre sujet important du langage M.
Machine Translated by Google

9 paramètres et fonctions personnalisées

Rejoignez notre communauté de livres sur Discord


[Link]

Le langage M est un langage fonctionnel contenant des centaines de fonctions.


La plupart du temps, les utilisateurs peuvent résoudre leurs problèmes en utilisant les fonctions
de la bibliothèque standard. Cependant, avec plus d'expérience avec le langage M, vous constaterez que
l'écriture de vos propres fonctions personnalisées peut grandement simplifier le processus de
transformation des données et faciliter la répétition de logiques complexes. C'est particulièrement
vrai avec des fonctionnalités comme « Créer une fonction », qui permet de transformer des
requêtes existantes en fonctions dynamiques et réutilisables. Ce chapitre aborde les points
suivants :

• Travailler avec des paramètres •


Créer des fonctions personnalisées •
Transformer des requêtes en fonctions • L'expression
« Each » • Types de données et
paramètres facultatifs pour les fonctions • Fonctions de débogage

Paramètres

Dans Power Query, les paramètres jouent un rôle important dans la dynamisation des
requêtes. Considérez­les comme des variables que vous pouvez modifier pour modifier le comportement
de vos requêtes. Au fil de ce chapitre, vous découvrirez l'utilité des paramètres pour stocker
et gérer les valeurs. Nous les détaillerons, comment en créer un et où et comment les utiliser.

Comprendre les paramètres

Les paramètres servent d'espaces réservés pour des valeurs que vous pouvez utiliser dynamiquement
dans vos requêtes. Ils renvoient des valeurs scalaires telles qu'une date, un nombre ou du texte.
Machine Translated by Google

Valeur. Au lieu de coder en dur les valeurs dans votre requête, un paramètre vous permet d'effectuer
des modifications en dehors de celle­ci. Cela vous permet de modifier facilement votre paramètre et
d'affecter plusieurs requêtes ou plusieurs étapes d'une même requête.
C'est utile pour la maintenance et la collaboration. Un autre avantage des paramètres est que vous
pouvez modifier leurs valeurs en dehors de l'éditeur Power Query. L'interface de Power BI
Desktop offre une option permettant de modifier les paramètres sans ouvrir Power Query. Pour
ce faire, accédez à l'onglet Accueil du ruban, cliquez sur « Transformer les données » et sélectionnez
« Modifier les paramètres ». N'oubliez pas que vous devrez actualiser votre jeu de données
pour que les modifications apportées à votre paramètre prennent effet.

Figure 1. Modification des paramètres dans Power BI Desktop.

Après avoir importé un fichier PBIX dans le service Power BI, vous pouvez également modifier les
paramètres définis depuis l'espace de travail. Accédez simplement au jeu de données,
sélectionnez « Paramètres » et accédez à la section « Paramètres ».

Figure 2. Modification des paramètres à partir des paramètres du jeu de données dans le service
Power BI.

Vous pouvez désormais modifier vos paramètres définis. Ici aussi, les modifications ne sont
visibles qu'après actualisation du jeu de données. L'utilisation de paramètres est souvent utilisée pour
offrir une certaine flexibilité dans le choix du serveur et du nom de la base de données.
Mais vous trouverez également des paramètres utiles pour limiter le nombre de lignes importées
dans l'ensemble de données. Pour un utilisateur, il est beaucoup plus facile de modifier un
paramètre dans le volet de requête que de rechercher dans les étapes de la requête pour trouver le
code pertinent.
Machine Translated by Google

Création de paramètres

Créer un paramètre dans Power Query est simple. Pour ce faire, accédez à l' onglet Accueil ,
sélectionnez « Gérer les paramètres » et cliquez sur « Nouveau paramètre ». Cette
opération ouvre un menu permettant de créer ou de modifier les propriétés de votre
paramètre.

Figure 3. Création d’un paramètre à l’aide de Gérer les paramètres.

C'est ici que vous pouvez ajouter les propriétés suivantes :

• Nom : il s'agit de l'identifiant de votre paramètre. C'est le nom que vous utiliserez
pour faire référence à ce paramètre tout au long de votre requête. Tout comme pour
nommer une variable en programmation, il doit idéalement être suffisamment
descriptif pour comprendre son objectif en
un coup d'œil. • Description : vous pouvez ajouter une brève note ou une
explication sur l'objectif et l'utilisation du paramètre. Cela sert de rappel ou de guide
pour comprendre pourquoi le paramètre a été créé et à quoi il est destiné. • Obligatoire :
indique si une valeur doit être fournie pour ce paramètre pour que la requête
s'exécute. • Type : vous permet de
définir le type de données attendu pour le paramètre. En spécifiant un type
(comme du texte, un nombre ou une date), vous vous assurez que le paramètre
n'accepte que des valeurs de ce type spécifique. Ceci est important pour l'intégrité
des données et pour éviter les erreurs inattendues lors de l'exécution de la
requête.
• Valeurs suggérées : Cette propriété indique les valeurs que le paramètre peut
accepter. Trois options sont disponibles : ◦
Toute valeur : indique que le paramètre peut accepter toute valeur du type
spécifié sans restriction. ◦ Liste
de valeurs : permet de définir un ensemble prédéterminé de valeurs que le
paramètre peut accepter. Par exemple, si votre paramètre ne doit
accepter que les valeurs « Faible », « Moyen » ou « Élevé », utilisez cette
option. ◦ Requête : autorise
les valeurs en fonction du résultat d'une requête. Cette option est utile lorsque
les valeurs autorisées pour un paramètre sont dynamiques et peuvent changer
en fonction d'une autre source de données ou d'une autre logique. Vous pouvez par exemple
Machine Translated by Google

exemple, fournir une liste unique de catégories de produits à partir d'une


base de
données. • Valeur actuelle : il s'agit de la valeur attribuée actuelle au paramètre.
Il s'agit de la valeur que le paramètre utilisera par défaut lors de l'exécution de la
requête, sauf si elle est remplacée. Si le paramètre est marqué comme « Obligatoire »
mais ne possède pas de « Valeur actuelle », la requête ne s'exécutera pas tant qu'une
valeur ne sera pas fournie.

Après avoir configuré les paramètres, votre paramètre est ajouté au volet des requêtes.
L'interface utilisateur ajoute automatiquement trois champs de métadonnées :

• IsParameterQuery : défini sur true pour indiquer qu'il s'agit d'un paramètre. •
IsParameterQueryRequired : indique si le paramètre est obligatoire. • Type : spécifie le type
de données
du paramètre.

Par exemple, lors de la saisie d’une valeur de date requise du 1er janvier 2024, Power
Query ajoute les métadonnées suivantes.

Figure 4. Métadonnées lors de l’ajout d’un paramètre.

Vous pouvez utiliser l'interface utilisateur pour créer et modifier des paramètres, mais vous pouvez
également le faire avec l'éditeur avancé. Pour en savoir plus sur les métadonnées, consultez le
chapitre XX. Comment utiliser un paramètre dans vos requêtes ?

Utilisation de paramètres dans vos requêtes

Vous pouvez intégrer des paramètres dans votre code M en les référençant, comme vous le
feriez pour une table ou une étape spécifique de votre requête. Prenons un exemple pour
clarifier ce point. Vous devez d'abord créer le paramètre souhaité, comme expliqué dans la
section précédente. Dans cet exemple, nous allons créer un paramètre appelé « Pourcentage_TVA ».
Ce paramètre sera de type Nombre décimal et aura une valeur initiale de 0,25 (représentant une
TVA de 25 %).
Machine Translated by Google

Figure 5. Le volet de requête contient une table et un paramètre.

Une fois le paramètre défini, vous pouvez créer une colonne personnalisée nommée
« Montant TTC ». Comment inclure ce paramètre dans votre expression ? Vous pouvez
le référencer comme n'importe quelle autre table ou étape.

Figure 6. Référencement d’un paramètre dans une formule personnalisée.

Soyez vigilant lorsque le nom de votre paramètre contient des caractères spéciaux ou
des espaces. Dans ce cas, il est important d'utiliser une notation spécifique pour garantir une
interprétation correcte par le langage M. Utilisez le format #”<Nom de votre
paramètre>”. Par exemple, si votre paramètre s'appelle « Taux de TVA % », vous le référencerez
comme #”Taux de TVA %”. Pour un code clair, nous vous recommandons d'utiliser des noms
de variables composés uniquement de lettres, de chiffres et de traits de soulignement,
et de vous assurer qu'ils ne commencent pas par un chiffre. En suivant cette convention, aucune
notation particulière n'est nécessaire. Maintenant que vous savez comment référencer un
paramètre, examinons quelques exemples pratiques.
Machine Translated by Google

Mettre tout cela ensemble

Les paramètres peuvent s'avérer utiles dans différents scénarios. Cette section explore trois
scénarios courants et leur utilisation.

Paramétrage des informations de connexion

Travailler avec des bases de données implique souvent de jongler entre les
environnements de développement, de test et de production. Changer de serveur et de nom peut
s'avérer fastidieux. Dans ce cas, les paramètres offrent une solution élégante, simplifiant la
transition entre serveurs et bases de données. Prenons un exemple : se connecter à une
base de données SQL nécessite de spécifier un serveur et une base de données.
Prenons l'expression suivante :

[Link]( « localhost\sqlserver­[Link] », « db­


staging­dev­westeu­001 » )

Nous pouvons les décomposer comme suit :

• Serveur : localhost\sqlserver­[Link] • Base de


données : db­staging­dev­westeu­001

Reconnaissez­vous le mot « dev » dans les deux composants ? Lors de la


configuration des bases de données, les administrateurs cherchent à simplifier la
transition entre les environnements. Il suffit de remplacer « dev » par « test » pour un
environnement de test ou par « prod » pour un environnement de production. Pour résoudre ce
problème avec des paramètres, essayez la solution suivante :

1. Accédez à Gérer les paramètres et créez un nouveau paramètre.


2. Nommez­le « Environnement », assurez­vous qu'il est obligatoire et définissez son type
sur Texte. Choisissez la « Liste de valeurs » pour la saisie suggérée.
3. Utilisez la fonction « Liste de valeurs » pour configurer les options sélectionnables
dans un menu déroulant. Renseignez­le avec « dev », « test » et « prod ».
Machine Translated by Google

Figure 5. Définir les paramètres de connexion à la base de données.

Après avoir configuré les paramètres, il suffit d'ajuster l'expression de connexion initiale à
la base de données. Il suffit de remplacer « dev » par le paramètre Environnement :

[Link]( « localhost\sqlserver­ » & Environnement & « .[Link] », « db­staging­ » & Environnement


& « ­westeu­001 » )

Après avoir enregistré cette modification et chargé le fichier dans le service Power BI, vous pouvez
modifier la valeur du paramètre directement depuis le menu des paramètres du jeu de données.
Vous pouvez ainsi changer de connexion à la base de données sans même ouvrir Power
BI Desktop.

Chemins de fichiers dynamiques

Imaginez que vous préparez des supports de formation et que vous avez choisi d'inclure le fichier
« Prix de l'[Link] » fourni avec ce livre. Pour plus de commodité, enregistrez ce fichier sur votre
disque C: dans un dossier nommé « data ». Pour vous connecter à ce fichier via Power Query,
procédez comme suit :
Machine Translated by Google

1. Choisissez Obtenir des données et sélectionnez Texte/CSV.


2. Accédez à « C:\Data » et sélectionnez le fichier CSV.
3. Le menu d’importation CSV apparaît ; cliquez sur OK.

Cette séquence produira le code :

[Link]( [Link](“C:\Data\Avocado [Link]”), [Delimiter=“,”,


Columns=14, Encoding=1252,
QuoteStyle=[Link]] )

Remarquez le chemin d’accès direct au fichier, « C:\Data\Avocado [Link] », intégré à l’intérieur ?


Bien que cela puisse être pratique pour vous, cela ne convient peut­être pas à tout le monde. Que faire si vos
stagiaires ont stocké leurs fichiers à différents emplacements ? Que faire si vous avez créé d'autres
requêtes utilisant également ce chemin d'accès comme référence ? Un chemin d'accès codé en dur peut
nécessiter des ajustements fréquents, ce qui complique la configuration rapide des participants à votre
formation. Heureusement, vous pouvez utiliser des paramètres pour introduire de la flexibilité
dans vos chemins d'accès. Voici comment mettre en œuvre cette solution :

1. Créer un paramètre : Commencez par créer un paramètre de type texte. Nommez­


le « CSVFilePath » et définissez « C:\Data\Avocado [Link] » comme valeur
actuelle.
Machine Translated by Google

Figure 6. Créez un paramètre appelé CSVFilePath.

2. Intégrez votre paramètre : lors de la liaison initiale du fichier CSV, une étape intitulée
« Source » a été créée dans le volet « Étapes appliquées ». Voici une
méthode simple pour intégrer votre paramètre : A. Cliquez sur
l'icône d'engrenage à côté de l' étape « Source » .
B. Pour le chemin du fichier, déroulez le menu et choisissez Paramètre.
C. Pour terminer, choisissez le paramètre CSVFilePath .

Avec cette modification, votre code ressemble maintenant à :

[Link]( [Link]( CSVFilePath ),


[Délimiteur=“,”, Colonnes=14, Encodage=1252,
QuoteStyle=[Link]] )

Vous remarquerez que le paramètre FilePath direct a été remplacé par le paramètre
CSVFilePath . Ce changement apporte de la flexibilité à vos requêtes. En ajustant simplement
les valeurs des paramètres, votre requête devient flexible sans réécriture ni modification
de la requête principale. Si vous ou quelqu'un d'autre souhaitez modifier le chemin d'accès
au dossier, il vous suffira de mettre à jour le paramètre initial. Conseil de pro : Vous maîtrisez
le code M ? Contournez l'interface et
Machine Translated by Google

Modifiez le code directement pour référencer CSVFilePath. Passer des chemins codés en dur aux valeurs
de paramètres simplifie considérablement votre processus de travail.

Filtrer une plage de dates

Les dates sont incluses dans de nombreux modèles, que vous créiez des rapports de ventes mensuels,
que vous analysiez l'historique des conditions météorologiques ou que vous identifiiez des tendances
financières. Cependant, exploiter l'intégralité de l'historique des dates d'une requête ralentit souvent le
traitement de vos requêtes. C'est là que les paramètres peuvent s'avérer utiles.

Pourquoi utiliser des paramètres pour les dates ?

Les paramètres offrent une flexibilité dans la gestion des plages de dates, permettant de gérer des
périodes fixes et glissantes. Imaginez un scénario où, pour améliorer les performances, vous souhaitez
travailler uniquement avec les données des derniers trimestres. Au lieu d'ajuster manuellement les dates
de début et de fin de chaque trimestre, vous pouvez utiliser des paramètres. Si votre table Transactions
comporte une colonne de date, vous pouvez utiliser une expression comme :

[Link](DataTable,
chaque [Date] >=
StartDate et [Date] <= EndDate)

Lorsque vous passez à un nouveau trimestre, il vous suffit de modifier les paramètres « StartDate » et
« EndDate ». Cependant, il y a un hic : bien que la méthode ci­dessus soit déjà utile, vous devez toujours
définir manuellement les dates de début et de fin pour chaque trimestre.

Paramètre de date dynamique

Les paramètres intégrés du ruban ne prennent pas en charge les valeurs dynamiques basées sur des
expressions, mais cela ne signifie pas que vous n'avez plus d'options. Vous pouvez inclure le résultat
d'une expression dans vos requêtes, même si elle n'est pas formellement étiquetée comme paramètre.
Prenons l'exemple du filtrage des données du trimestre écoulé. Créer une requête vide vous permet d'intégrer
l'expression suivante, déterminant la date de fin :

[Link]( [Link]( [Link]( [Link]() ) ), ­1

Cette fonction récupère la date et l'heure du jour, la convertit en date, puis la ramène à la fin du dernier
trimestre en soustrayant un jour. Ainsi, elle renvoie systématiquement au dernier jour du trimestre précédent.
Pour la date de début, vous pouvez simplement référencer la date de fin et la reporter au début du
trimestre :

Date.DébutDuTrimestre(DateDeFin)

Bien que ces requêtes ne fassent pas partie de l'écran « paramètre » officiel du ruban, elles fonctionnent
de manière similaire et peuvent être référencées en conséquence.
Machine Translated by Google

Fonctions personnalisées dans M

Les fonctions jouent un rôle important dans le langage M. Les fonctions vous permettent de
consolider votre logique, rendant votre code modulaire, réutilisable et efficace.
Considérez une fonction personnalisée comme un outil, chaque fonction étant conçue
pour une tâche spécifique. Grâce à elles, vous pouvez structurer votre code de manière
ordonnée et réutilisable. Bien qu'il existe des centaines de fonctions de bibliothèque
standard, créer sa propre fonction est parfois utile. Les fonctions personnalisées vous
permettent de créer des solutions spécifiques à vos problématiques de données, consolidant
plusieurs étapes personnalisées ou résolvant des problèmes de transformation de
données que les fonctions intégrées ne prennent pas en charge. Une fois créées, ces
fonctions sont facilement réutilisables, ce qui permet aux membres de l'équipe moins
expérimentés d'exploiter plus facilement vos solutions personnalisées. Les sections
suivantes vous guideront pour comprendre ce que sont les fonctions, comment créer
les vôtres et comment les utiliser efficacement. Vous découvrirez également comment
affiner les définitions de fonctions, déboguer et gérer leur portée.

Que sont les fonctions personnalisées ?

Power Query est un langage de programmation fonctionnel. En termes simples, cela


signifie qu'il utilise des fonctions qui prennent une entrée, l'utilisent, puis produisent un
résultat. Lorsque les fonctions intégrées ne répondent pas à vos besoins, vous pouvez
créer les vôtres ; d'où le terme « fonctions personnalisées ». Leurs objectifs peuvent aller
d'opérations simples, comme l'addition de deux nombres, à des opérations plus complexes,
comme l'analyse de modèles de texte complexes. Les fonctions personnalisées sont
comparables à des mini­requêtes. Elles acceptent des entrées, appelées paramètres.
Elles exécutent ensuite une action basée sur ces paramètres et renvoient un résultat.
Alors, comment créer une fonction personnalisée ?

L'anatomie des fonctions personnalisées

Vous pouvez définir une fonction personnalisée en fournissant des paramètres à l'intérieur
d'un ensemble de parenthèses, suivis de => et en concluant par une expression à évaluer.
L'expression définit comment la fonction doit calculer son résultat. Prenons un exemple :
une fonction simple qui ajoute 10 à une valeur peut s'écrire
comme:

(paramètre) => paramètre + 10

Voici comment l’interpréter :

• (paramètre) : Ceci désigne l'entrée ou le paramètre que notre fonction prend en


entrée. Vous pouvez nommer le paramètre comme vous le
souhaitez. • Symbole Goes­to : le symbole => sépare les paramètres de la fonction de
son expression. •
paramètre + 10 : Il s'agit de l'expression (ou du corps de la fonction) qui indique
comment la fonction doit traiter l'entrée pour produire une valeur de sortie.
Machine Translated by Google

Vous pouvez concevoir une fonction fonctionnant avec plusieurs entrées. Par exemple, pour
multiplier deux nombres, procédez comme suit :

(a, b ) => a * b

Bien que « a » et « b » soient les noms choisis pour les paramètres de la fonction ci­
dessus, vous êtes libre de les nommer comme bon vous semble. Il est souvent judicieux d'utiliser
des noms significatifs, surtout lorsque votre code est destiné à un public plus large. Cela permet
de clarifier la fonction du paramètre dès le départ. Les exemples précédents écrivent l'expression
complète de la fonction sans utiliser de variables. Cependant, pour plus de clarté, pensez à
intégrer l'expression « let ». Voici comment :

(MyText) => laissez

TextToNumber = [Link]( MyText ), MultiplyBy3 = TextToNumber * 3,


NumberToText = [Link]( MultiplyBy3 ), OutputString = “3
fois “& MyText & “ est “ & NumberToText dans

Chaîne de sortie

Cette fonction transforme une chaîne de texte en nombre, la multiplie par 3 et génère une chaîne
personnalisée en sortie. Ainsi, si vous nommez cette fonction fxMultiplyText et l'appelez
avec fxMultiplyText(“5”), elle renvoie la chaîne suivante : « 3 fois 5 égale 15 ». De plus,
certaines fonctions ne nécessitent aucun paramètre d'entrée. Par exemple, [Link],
issu de la bibliothèque de fonctions standard, est un exemple. Vous pouvez
créer une fonction renvoyant la valeur du rayon terrestre en écrivant :

() => 6371

Cette instruction ne prend aucun paramètre et renvoie une valeur numérique.


Cependant, ce type d'utilisation est rare. Plutôt que de créer une fonction comme celle­ci, il
est souvent plus pratique de stocker la valeur de sortie sous forme de paramètre ou de variable
dans votre code. Cette section a abordé les bases de la création de fonctions personnalisées,
notamment la définition des paramètres et la création du corps de la fonction. Ce processus
nécessite généralement du codage manuel. Cependant, Power Query offre une
alternative pratique : vous pouvez également convertir une requête existante en fonction
personnalisée.

Transformer une requête en fonction


Power Query dispose d'une fonctionnalité permettant de transformer une requête en fonction.
Contrairement aux fonctions personnalisées écrites manuellement, cette méthode permet de garder
toutes les étapes de la requête visibles et modifiables. Ce chapitre explique comment utiliser cette
fonctionnalité pour créer des fonctions flexibles et réutilisables à partir de vos requêtes.

Qu'est­ce que la fonctionnalité « Créer une fonction » ?


Machine Translated by Google

Dans Power Query, la fonctionnalité « Créer une fonction » transforme une requête en fonction
réutilisable. Comme indiqué précédemment, les fonctions incluent généralement des
paramètres. La fonctionnalité « Créer une fonction » utilise des références de paramètres pour
construire les arguments de la fonction. En général, vous souhaiterez inclure des paramètres dans votre fonction.
Pour ce faire, identifiez les éléments de votre requête qui doivent être variables et connectez­les
aux paramètres correspondants dans votre rapport. La fonctionnalité « Créer une fonction »
s'occupe du reste, en intégrant automatiquement le code requis pour ces paramètres
d'entrée dans votre fonction personnalisée. Si vous souhaitez une fonction sans paramètres,
ignorez simplement la partie « paramètres ».
Chaque fois que vous appelez la fonction, elle renvoie le résultat de votre requête fixe.
Cependant, l'utilisation de cette fonctionnalité sans paramètres est rare ; vous pouvez simplement
référencer la requête d'origine. Cette fonctionnalité « Créer une fonction » présente trois
avantages principaux :

1. La requête reste intacte : la requête d'origine reste visible dans votre projet. Cela signifie
que vous pouvez toujours inspecter, modifier et exécuter votre logique comme une
requête autonome.
2. Mises à jour des fonctions : les modifications apportées à la requête d'origine sont
automatiquement répercutées dans la fonction liée. Vous pouvez ainsi affiner facilement
votre logique sans avoir à mettre à jour la fonction.
3. Facilite la création de fonctions : les utilisateurs peuvent créer des fonctions
personnalisées sans écrire de code M, simplement en utilisant des paramètres.

Alors, comment pouvons­nous créer une fonction en utilisant l'interface utilisateur ?

Comment créer une fonction à partir d'une requête

Pour créer une fonction à partir d’une requête, suivez ces étapes :

1. Paramètres : si vous souhaitez des paramètres, intégrez­les d'abord à votre requête. Il


peut s'agir d'un simple critère de filtre ou d'une valeur contribuant à un calcul.

2. Accédez au panneau « Requêtes » et faites un clic droit sur votre requête.


3. Cliquez sur le bouton « Créer une fonction » . Une boîte de dialogue s'affichera.
boîte.
4. Nommez votre fonction : rendez­la descriptive afin qu'elle soit facile à reconnaître
ce qu'il fait.
5. Terminer : cliquez sur « OK » pour créer la fonction.

En suivant ces étapes, votre nouvelle fonction apparaîtra dans le volet Requêtes et vous
pourrez l'utiliser comme n'importe quelle autre fonction dans Power Query. Voyons comment
l'utiliser avec un exemple pratique. Imaginons que vous créiez une logique pour une table de
calendrier. Avant de créer une fonction, préparez une requête appelée « CalendarLogic »,
qui ressemble à ceci :
Machine Translated by Google

Figure 7. Logique de requête du calendrier

Les utilisateurs devraient pouvoir ajuster la durée d'exécution du calendrier. Vous décidez
donc d'inclure un paramètre « startDate » et un paramètre « endDate » de type date. La requête
« CalendarLogic » ajustée se présente désormais comme suit :

Figure 8. Logique de requête de calendrier avec paramètres.

Une fois ces paramètres définis, nous sommes prêts à transformer la requête en fonction. Pour
cela, faites un clic droit sur votre requête et sélectionnez « Créer une fonction ».
Machine Translated by Google

Figure 9. Le menu « Créer une fonction » dans le volet Requêtes.

Vous pouvez ensuite définir le nom de votre fonction. Comme cette fonction crée une table
de calendrier, nous l'appelons fxCreateCalendar.

Figure 10. Le menu Créer une fonction.

Après avoir appuyé sur OK, Power Query transforme votre requête en une fonction
portant le nom que vous venez de spécifier. Après avoir effectué ces opérations, vous
obtenez 4 requêtes :

• les paramètres startDate et endDate .


Machine Translated by Google

• la requête CalendarLogic avec votre logique de calendrier • La


fonction fxCreateCalendar qui se lie à CalendarLogic
requête.

Figure 11. Composants utilisés dans l'opération « Créer une fonction ».

Maintenant que la fonction est configurée, voyons comment l'utiliser efficacement. Pour cela,
ouvrez une nouvelle requête vide, renommez­la « Calendrier » et saisissez le code suivant :

= fxCreateCalendar( #date( 2024,1,1), #date( 2024,12,31 ) )

Cela produit le tableau affiché ci­dessous :

Figure 12. Utiliser la fonction pour créer un tableau de calendrier

Jusqu'ici, vous pourriez penser que le principal avantage de la fonctionnalité « Créer une fonction »
réside dans l'automatisation de sa création. Cependant, son véritable intérêt apparaît clairement
lorsque vous devez effectuer des ajustements ou résoudre des problèmes.

Simplification du dépannage et améliorations


L'intérêt de la fonctionnalité « Créer une fonction » réside dans sa facilité de modification. Imaginons
que vous ayez besoin d'ajouter une colonne supplémentaire à votre fonction.
Machine Translated by Google

il suffit de naviguer vers la requête CalendarLogic d'origine et d'y insérer la nouvelle colonne.

Figure 13. Lien dynamique : mise à jour de la requête et de la fonction personnalisée ensemble.

Grâce au lien direct entre la fonction fxCreateCalendar et la requête CalendarLogic, toute


modification apportée à la requête est automatiquement répercutée dans la fonction.
Cela simplifie non seulement le processus de dépannage (vous permettant d'inspecter
chaque étape de la requête), mais facilite également l'intégration de nouvelles logiques à
mesure que les besoins évoluent. Lorsque vous essayez d'ouvrir l'éditeur avancé de cette
fonction liée, un message s'affiche. Ce message indique que toute modification de la fonction
rompra le lien entre les requêtes.

Figure 14. Message d’avertissement lors de la tentative de modification de la fonction créée.

Si vous souhaitez simplement inspecter les données, cliquez sur OK et examinez­les. Veillez
simplement à ne pas enregistrer les modifications : le lien sera conservé. Pour interrompre les
mises à jour entre la requête et la fonction, vous pouvez également faire un clic droit sur la
fonction et sélectionner « Propriétés… ». Cet écran contient un bouton « Arrêter les mises
à jour ».
Machine Translated by Google

Figure 15. Écran Propriétés d’une fonction qui se met à jour avec les modifications de la requête.

Après avoir cliqué sur « Arrêter les mises à jour », il est impossible de restaurer les mises à jour de la
fonction actuelle. Vous devrez configurer une nouvelle fonction en utilisant l' opération « Créer une fonction »,
comme expliqué précédemment dans ce chapitre. Comme nous l'avons vu, la fonctionnalité « Créer une
fonction » offre un moyen pratique de transformer des requêtes en fonctions réutilisables et facilement
ajustables. Mais une fois ces fonctions personnalisées créées, comment les utiliser concrètement dans
vos rapports ? Le chapitre suivant examinera les méthodes d'invocation de ces fonctions personnalisées.

Appel d'une fonction personnalisée

Une fois que vous avez créé une fonction, vous pouvez l’invoquer de différentes manières.

Manuellement dans l'éditeur avancé ou la barre de formule

La plupart des utilisateurs avancés invoquent une fonction en la référençant directement. Imaginons que
vous ayez créé une fonction appelée « MaFonction » qui prend un seul paramètre numérique et renvoie ce
nombre plus 10. Vous créez une requête vide et collez « MaFonction( 20 ) » dans la barre de formule.
Machine Translated by Google

Figure 16. Appeler une fonction dans la barre de formule.

Cela appelle une fonction et renvoie 30. Le résultat de cette méthode peut être presque n'importe quoi,

Utilisation de l'interface utilisateur

Power Query permet également de créer une colonne appelant une fonction via l'interface
utilisateur. Pour ce faire, accédez à l' onglet « Ajouter une colonne » du ruban et
sélectionnez « Appeler une fonction personnalisée ».

Figure 17. Bouton d’interface utilisateur pour appeler une fonction personnalisée.

Cela ouvre un menu contextuel affichant les fonctions personnalisées disponibles dans votre fichier. Il
vous permet également de spécifier les paramètres d'entrée de votre fonction personnalisée. La
fonction personnalisée utilisée ci­dessous possède un seul argument.
Le menu propose donc un seul paramètre à renseigner.
Machine Translated by Google

Figure 18. Le menu d'invocation de fonction personnalisée.

Dans la liste déroulante des paramètres, vous avez plusieurs options :

• Saisir une valeur : permet de saisir manuellement une valeur. C'est l'option la moins
dynamique. • Utiliser
les valeurs d'une colonne : permet de sélectionner une colonne sur laquelle appliquer
la fonction. La liste déroulante suggère n'importe quelle colonne de votre tableau.
• Sélectionner un paramètre : permet de référencer un paramètre.
Les paramètres permettent de référencer ou d'ajuster facilement une valeur utilisable
dans vos requêtes. • Sélectionner une requête :
permet de référencer le résultat d'une requête. Attention, une fonction peut nécessiter
des types de données d'entrée spécifiques. En référençant une autre requête, la
valeur de sortie de cette requête doit avoir le type de données requis par votre fonction. Il
peut s'agir de valeurs primitives comme du texte ou des nombres, mais aussi de
valeurs structurées comme un tableau, un enregistrement ou une liste.

Puisque cette méthode appelle une fonction via l'onglet Ajouter une colonne, le résultat de
l'exécution de votre fonction est ajouté à une nouvelle colonne. Bien que Power Query permette
de transformer des requêtes existantes en fonctions, la véritable magie opère dans l'Éditeur
avancé. C'est ici que vous avez la liberté de créer des fonctions personnalisées de toutes
pièces et de les appeler comme bon vous semble. Maintenant que vous connaissez les bases de
l'appel d'une fonction personnalisée, examinons l'expression la plus utilisée pour créer une
fonction en langage M : l'expression « each ».
Machine Translated by Google

L'expression Chaque

Syntaxe Sugar

L'expression each du langage M de Power Query est une syntaxe abrégée qui permet de définir des
fonctions unaires (à un seul argument) sans la complexité des déclarations de fonctions. Alors,
pourquoi l'expression each fait­elle partie du langage M, alors que nous pouvons définir nos propres
fonctions ? La raison principale est que cette expression est plus conviviale et facilite la
lecture du code. Commençons par un exemple simple. Imaginez que vous souhaitiez créer une
fonction qui accepte un nombre et lui ajoute 5. Voici comment vous l'écririez généralement :

( MaValeur) => MaValeur + 5

Dans cette fonction, « MaValeur » est le seul paramètre. Simplifions maintenant :

(_) => _ + 5

Le paramètre est désormais représenté par le trait de soulignement. Ceci est très similaire à la
construction Each. Cette construction est une syntaxe simplifiée pour une fonction prenant un
seul paramètre dont le nom est le trait de soulignement. L'expression each permet d'utiliser une
déclaration simplifiée en écrivant :

chaque MyValue + 5

Les déclarations simplifiées sont utilisées pour améliorer la lisibilité de l'invocation de fonctions
d'ordre supérieur.

Cas d'utilisation courants

Vous trouverez l'expression each utilisée dans diverses fonctions. Les plus courantes sont
[Link], [Link] et, par exemple, [Link]. Dans cette section, nous
examinerons quelques fonctions qui utilisent l'expression each pour définir une fonction.

Ajout automatique de « Chacun » dans les colonnes personnalisées

Par exemple, imaginez que vous ayez une colonne intitulée « Nombres » et que vous souhaitiez
ajouter 5 à chaque valeur. Accédez à « Ajouter une colonne », sélectionnez « Colonne personnalisée »
et ajoutez la formule suivante :

[Nombre] + 5
Machine Translated by Google

Figure 19 Colonne personnalisée

Après avoir cliqué sur OK, vous obtenez l’expression suivante dans la barre de formule :

[Link](Source,
« newColumn »,
chaque [Nombre] + 5)

Attendez, on a oublié le mot « each » ? En fait, non. Lorsque vous ajoutez une colonne
personnalisée via l'interface utilisateur de Power Query, le logiciel effectue une partie du travail
à votre place. Il appelle automatiquement la fonction [Link] et ajoute le mot­clé
« each » comme préfixe à votre formule. Inutile de l'insérer manuellement. C'est pratique,
car le concept de « each » est souvent déroutant pour les débutants. Prêt pour d'autres
exemples ?

Utilisation de « each » dans [Link]

La fonction [Link] permet de manipuler les valeurs des colonnes.


Lorsque vous utilisez cette fonction via l'interface Power Query, vous verrez souvent le mot­
clé each en action. Imaginez que vous souhaitiez ajouter le préfixe « Miss » à une colonne
nommée « Name ». Accédez à l'onglet « Transformation », cliquez sur « Format », sélectionnez
« Ajouter un préfixe » et saisissez « Miss ». Le code généré se présente comme suit :

[Link]( Source,
{{« Nom », chaque « Miss » & _, type texte}} )

Cette expression est identique à :


Machine Translated by Google

[Link]( Source,
{{« Nom », (_) => « Mlle » & _, type texte}} )

Les deux effectuent la même tâche : ajouter le préfixe « Miss » à chaque valeur de la colonne
« Nom ». Passons à un autre exemple pour approfondir votre compréhension.

Ignorer les traits de soulignement dans les références de champ ou de colonne

Dans certains cas, il est acceptable d'omettre le caractère de soulignement pour les
enregistrements ou les champs de table. Imaginons que vous souhaitiez ajouter une nouvelle
colonne qui soustrait 10 aux valeurs d'une colonne [Ventes] existante. La forme longue serait :

[Link](Source, « Personnalisé », (_) => _[Ventes] ­ 10 )

Le trait de soulignement fait alors référence à la ligne entière du tableau, représentée par un enregistrement.
Lorsque vous référencez un nom de champ entre crochets (méthode dite de sélection de
champ), il n'est pas nécessaire de commencer la référence de colonne par un trait de
soulignement. Vous pouvez donc simplement écrire :

[Link](Source, « Personnalisé », (_) => [Ventes] ­ 10 )

L'interface utilisateur utilise un format encore plus court en utilisant la construction each :

[Link](Source, « Personnalisé », chaque [Ventes] ­ 10 )

Les trois expressions aboutissent au même résultat, qui consiste à soustraire 10 de chaque
valeur dans la colonne [Ventes].

Simplification des appels de fonctions à argument unique

De nombreuses fonctions de Power Query M permettent d'incorporer une autre fonction


comme paramètre. La méthode dépend du nombre d'arguments requis par la fonction imbriquée.
Avec une fonction à un seul argument, la procédure est relativement simple. Vous
pouvez omettre les parenthèses et référencer directement le nom de la fonction.
Prenons l'exemple suivant : nous ajoutons 10 à chaque élément d'une liste.

laissez fxAddTen = (MaValeur) => MaValeur + 10, MaListe = { 1 .. 5 }, TransformList


= [Link]( MaListe, fxAddTen )

dans
TransformList

Dans cet exemple, nous avons appelé la fonction fxAddTen dans la fonction [Link]
sans utiliser de parenthèses. Il existe une autre méthode tout aussi valable : nous pouvons
remplacer l'étape TransformList par :

TransformList = [Link]( MaListe, each fxAddTen(_))

Les appels de fonctions multi­arguments nécessitent des parenthèses


Machine Translated by Google

Les exemples ci­dessus illustrent comment simplifier les fonctions à un seul argument. Il est
possible d'omettre le mot­clé « each » et les parenthèses. Cependant, lorsqu'une fonction
nécessite plusieurs arguments, l'approche est différente. Une fonction à paramètres multiples
nécessite :

• Utiliser la construction « Each »


• Rédiger formellement une définition de fonction

Par exemple:

TransformList = [Link]( MaListe, chaque fxAddTen( _, 10) )

Ou l'approche manuelle :

TransformList = [Link]( MaListe, (_)=> fxAddTen( _, 10) )

En résumé, les fonctions à argument unique peuvent être invoquées simplement en indiquant
leur nom, sans parenthèses. Pour les fonctions à arguments multiples, une syntaxe plus
détaillée est nécessaire, impliquant soit le mot­clé each, soit une définition de fonction
personnalisée.

Affiner les définitions de fonctions

Pour créer votre fonction personnalisée idéale, il ne s'agit pas seulement de la créer,
mais de la perfectionner. Une fonction bien définie est claire dans son objectif, flexible dans
son utilisation et résistante aux erreurs. Dans cette section, nous explorons des méthodes
importantes pour affiner les fonctions personnalisées :

• Définition des types de données : cela garantit que les données restent cohérentes et
précis afin que l'entrée de la fonction soit celle attendue.
• Ajout de paramètres facultatifs : cela permet aux utilisateurs une certaine flexibilité dans
la façon dont la fonction est utilisée, répondant à des besoins divers sans
contraintes rigides.

Ces stratégies améliorent non seulement la convivialité des fonctions personnalisées, mais les
rendent également plus résilientes et adaptables à différents scénarios.

Spécification des types de données

Lors de la création de fonctions personnalisées, notre objectif n'est pas seulement de les rendre
opérationnelles, mais aussi de les rendre fiables et moins sujettes aux erreurs. Une façon d'y
parvenir est d'indiquer clairement le type de données que chaque paramètre peut accepter. Ainsi,
nous garantissons que nos fonctions traitent le bon type de données et évitons les
mauvaises surprises. Vous pouvez définir des types de données pour les paramètres d'entrée
et les sorties de fonction. Un paramètre sans type de données défini est appelé paramètre
implicite. Cela signifie qu'il peut accepter des valeurs de n'importe quel type.
Spécifier un type de données pour un paramètre le transforme en paramètre explicite.
Une fois un type de données défini, le paramètre ne peut accepter que des valeurs de ce
type.
Machine Translated by Google

Types primitifs

Voyons d'abord comment attribuer un type de données primitif à un paramètre.


Imaginons une colonne contenant l'âge des personnes et que vous souhaitiez créer une
fonction nommée fxValidAge. Cette fonction vérifie si les âges sont réalistes, c'est­à­dire
compris entre 0 et 125. Voici comment procéder :

(âge en tant que nombre) comme logique => âge


>= 0 et âge <= 125

Dans cet exemple, « âge comme nombre » est un paramètre explicite. Il indique que
la fonction attend une valeur numérique pour l'âge. Après la parenthèse, on trouve le texte
« comme logique », ce qui signifie que la fonction fournira un résultat soit vrai (âge
valide), soit faux (non valide). Imaginez ceci appliqué à une liste d'âges. La fonction vérifie
chaque âge :

Figure 20. La fonction teste si les âges sont valides.

La spécification du type de données force le moteur à vérifier si les valeurs d'entrée


correspondent au type de données défini dans les paramètres. Si vous tentez de fournir du
texte ou une valeur autre qu'un nombre, Power Query affichera une erreur.
Machine Translated by Google

Figure 21 Erreur d'expression

Ce message d'erreur apparaît car notre paramètre explicite indique à la fonction d'accepter uniquement les
valeurs de type numérique. Pour les sorties, la fonction attend actuellement une valeur logique (vrai ou faux).
Celle­ci est définie par « comme logique ». Si vous remplacez « comme logique » par « comme texte »,
mais que le résultat reste une valeur booléenne (vrai ou faux), une erreur s'affichera indiquant que le type de
données n'est pas celui attendu. Les valeurs importantes nécessitant une attention particulière sont les valeurs nulles.

Comme indiqué au chapitre XX, leur comportement est très spécifique et peut facilement perturber vos requêtes. La
fonction ci­dessus ne prend pas en charge les valeurs nulles.
Heureusement, nous pouvons ajouter la prise en charge des valeurs nulles en utilisant des types de données nullables.

Types primitifs nullables

Parfois, vos données peuvent contenir des valeurs manquantes ou inconnues, appelées valeurs « null ». Dans
ce cas, il est courant de définir une valeur comme un type primitif nullable. Nullable ici suggère que la valeur
peut être de type primitif ou null. Vous souvenez­vous de notre fonction de vérification d'âge ? Imaginez que certains
âges soient manquants et marqués comme nuls. Si vous utilisez la fonction telle quelle sur cet ensemble de données,
vous obtenez une erreur :

Figure 22. Une erreur se produit lorsqu'une fonction rencontre une valeur nulle inattendue
Machine Translated by Google

valeur.

Pour chaque paramètre utilisé par votre fonction, celle­ci teste la compatibilité de la valeur
d'entrée avec son type de données défini. Avec la définition actuelle, la fonction attend
une valeur numérique en entrée. Si elle rencontre une valeur incompatible, dans notre cas une
valeur nulle, elle ne sait pas quoi faire et génère une erreur. Pour gérer cela, vous pouvez définir
le type du paramètre sur un « nombre nullable » :

(âge comme nombre nullable) comme logique => si âge >= 0 et


âge <= 125 alors vrai sinon faux

Grâce à cette modification, chaque fois que votre fonction rencontre une valeur nulle non prise
en compte dans son expression, elle tente de renvoyer null. Cependant, le code modifié renvoie
toujours l'erreur : « [Link]: We cannot convert the value null to type Logical ». En
effet, notre fonction impose également une valeur logique en sortie. Et comme la fonction
tente de renvoyer null lorsqu'elle rencontre null dans l'un des paramètres, nous obtenons l'erreur.
Nous pouvons corriger ce problème en modifiant le type de sortie de la fonction pour un type
nullable :

(âge comme nombre nullable) comme logique nullable => si âge >= 0
et âge <= 125 alors vrai sinon faux

En appliquant cela à nos données, on obtient :

Figure 23 Résultats
Machine Translated by Google

Lorsque nous appliquons cette nouvelle fonction à la colonne contenant les âges (y compris les
valeurs nulles), elle fonctionne parfaitement. En bref, en définissant des types de données, vous
ajoutez de la précision à votre fonction, garantissant la validité des entrées et garantissant qu'elle
renvoie une valeur du type de données attendu. Elle sait à quoi s'attendre et comment réagir. Nous
verrons ensuite comment rendre certaines de ces règles facultatives.

Rendre les paramètres facultatifs

Par défaut, une valeur doit être fournie pour chaque paramètre lors de l'appel d'une fonction.
Cependant, la flexibilité peut être un atout majeur pour les fonctions personnalisées. Un moyen
efficace d'introduire de la flexibilité est de rendre certains paramètres facultatifs. Ainsi, lors de
l'appel d'une fonction, il n'est pas toujours nécessaire de fournir une valeur pour chaque
paramètre. Power Query exige que les paramètres facultatifs soient définis après
les arguments obligatoires. Cela signifie qu'une fois un paramètre facultatif défini, tous les
paramètres suivants doivent également être facultatifs. Lorsque vous définissez les
paramètres de votre fonction, vous pouvez les rendre facultatifs en les ajoutant au texte
« optionnel ». Ils ont souvent une valeur par défaut, ce qui garantit l'exécution de la
fonction même si aucune valeur n'est fournie pour ce paramètre spécifique. Prenons un exemple.
Dans notre exemple précédent, nous avons testé la validité d'un âge. Imaginons que nous
souhaitions offrir aux utilisateurs la possibilité de définir un âge maximal valide. Nous pouvons
introduire un paramètre facultatif à cet effet. S'il est omis, un paramètre facultatif renvoie toujours
null.

(âge comme nombre nullable, maxAge facultatif comme nombre) comme logique
nullable => âge >= 0 et âge <=
(maxAge ?? 125)

La fonction ci­dessus possède deux paramètres : un obligatoire et un facultatif. Si le paramètre


facultatif n'est pas fourni par l'utilisateur, la fonction prend par défaut une valeur nulle. Il est
donc important d'anticiper et de gérer cette valeur nulle potentielle. C'est là que l'opérateur de
coalescence, écrit « ?? », prend tout son sens. Cet opérateur vérifie la valeur de gauche ; si elle est
non nulle, il la renvoie. Si elle est nulle, il renvoie la valeur de droite. Dans le contexte de la fonction,
l'opérateur de coalescence renverrait 125 en cas de valeur nulle. Vous pouvez maintenant invoquer
cette fonction avec un ou deux paramètres :

fxValidAge( 100 ) // Sortie : vrai fxValidAge( 100, 90 ) //


Sortie : faux

Dans le premier cas, seul le paramètre obligatoire est fourni. Dans le second, le paramètre facultatif
est inclus. La fonction vérifie si l'âge de 100 ans est compris entre 0 et 90 ans. Si ce n'est pas le cas,
le résultat est faux. Maintenant que vous savez créer des fonctions, définir leurs types de données
et même rendre des paramètres facultatifs, examinons leur portée.

Référencement des noms de colonnes et de champs

Lors de la création de fonctions personnalisées, la définition des paramètres est un élément


important. Ceux­ci permettent aux utilisateurs de saisir des données qui influencent le résultat de
la fonction. Cependant, il arrive que certains objets de vos données ne puissent pas être référencés, comme
Machine Translated by Google

noms de colonnes, de manière simple. La section suivante vous montre des exemples où cela peut se produire et
comment vous pouvez contourner ce problème.

Référence aux noms de champs dans un enregistrement

Imaginez que vous souhaitiez filtrer les lignes d'un tableau. Vous utilisez généralement [Link].
Par exemple, si vous souhaitez filtrer les lignes dont le montant des ventes est inférieur à 1 000, vous écrivez :

[Link](Source, chaque [Ventes] < 1000)

Mais que faire si vous souhaitez une fonction permettant à l'utilisateur de choisir la colonne à filtrer ? Vous
pouvez essayer ceci, mais cela ne fonctionnera pas :

(table comme table, columnName comme texte) comme table => [Link](table, each
[columnName] < 1000)

Lorsque vous exécutez cette fonction, le filtre de la table dans le premier argument est correct. En revanche, le
second argument ne fonctionne pas comme prévu. La fonction recherche une colonne nommée « columnName » au
lieu d'utiliser le nom de colonne saisi. Comment résoudre ce problème ? Tout d'abord, comprenez la signification de
[Sales] dans la formule initiale.
Il peut s'agir du nom d'une colonne dans une table ou d'un champ dans un enregistrement. En cas de doute, voici
une méthode simple pour le tester. Essayez de remplacer la condition par un trait de soulignement ; vous obtiendrez
une erreur, mais celle­ci nous est utile. Elle indique : « Impossible de convertir une valeur de type Enregistrement
en type Logique. » Cela confirme qu'il s'agit d'un enregistrement. Pour référencer dynamiquement une colonne, vous
pouvez utiliser la fonction [Link]. Cette fonction prend deux entrées : l'enregistrement et le nom de
la colonne sous forme de texte. Voici comment réécrire la fonction :

(table comme table, columnName comme texte) comme table => [Link](table, each
[Link](_, columnName) < 1000)

De cette façon, la fonction filtrera les lignes en fonction du nom de colonne fourni par votre utilisateur, obtenant ainsi
le comportement dynamique que nous souhaitions.

Référence aux colonnes d'un tableau

Un autre objet présentant un problème similaire est une colonne de table. Imaginez que
vous souhaitiez vérifier si une valeur de la ligne actuelle existe également dans une
colonne d'une autre table. Prenons l'exemple d'une table nommée « Bonus » avec une
colonne intitulée « Produits ». Si vous n'avez pas besoin de cette colonne comme paramètre,
la formule pourrait ressembler à ceci :

[Link]( Source,
« IsBonusProduct »,
chaque si [Link](Bonus[Products],
[Product]) alors vrai sinon faux

Ici, nous ajoutons une nouvelle colonne intitulée « IsBonusProduct » à la table Source. Le résultat indique si le
« Product » correspondant existe également dans la liste Bonus[Products]. Mais comment rendre cela plus
flexible ?
Machine Translated by Google

Par exemple, vous pouvez laisser l'utilisateur spécifier la table et la colonne de recherche.
Pour ce faire, nous utilisons la fonction [Link], qui renvoie une liste à partir d'une table et d'une
colonne spécifiques. Voici comment écrire une fonction personnalisée pour gérer cela :

(table comme table, newColumnName comme texte, lookupTable comme table, lookupColumnName comme texte) a [Link]( table, newColumnName, each si

[Link]( [Link]( lookupTable,


lookupColumnName), [Link]( table, “Product” ) ) alors vrai sinon faux

Dans cette fonction, vous avez quatre paramètres :

• table : la table principale sur laquelle vous travaillez. •


newColumnName : le nom de la nouvelle colonne que vous ajoutez. • lookupTable : la table
contenant la liste que vous vérifiez. • lookupColumnName : la colonne spécifique dans
lookupTable qui a
la liste.

Pour que cela fonctionne efficacement, vous devez utiliser deux fonctions spécifiques :
[Link] pour cibler les colonnes et [Link] pour cibler les champs. Tout
d'abord, [Link] récupère la liste des valeurs de la table et de la colonne de recherche
désignées. Ensuite, la fonction vérifie si le « Produit » actuel, identifié par la fonction [Link],
existe dans cette liste. Elle renvoie ensuite la valeur « vrai » ou « faux » en fonction de cette
vérification. L'important est que les utilisateurs peuvent désormais saisir une valeur texte pour la
table de recherche et le nom de la colonne de recherche, et la fonction récupérera les valeurs
réelles des colonnes.

Débogage des fonctions personnalisées

Créer des fonctions personnalisées devient simple une fois le processus maîtrisé. Il consiste à
définir des paramètres et à les intégrer à votre code. Ce processus transforme votre requête
en fonction. Mais que se passe­t­il si vous rencontrez une erreur dans une fonction personnalisée ?
Ou si vous adaptez du code trouvé en ligne et rencontrez des problèmes ? Vous avez perdu les étapes
du volet de requête qui vous aident normalement à résoudre votre code. C'est là qu'il est important
de comprendre comment déboguer des fonctions personnalisées. Imaginons que vous utilisiez
une fonction spécifique comme celle ci­dessous :

Liste des numéros de la figure 24


Machine Translated by Google

Le code ci­dessus apparaît dans le volet de requête sous forme de fonction. À chaque
exécution, seul le résultat final est visible. Si vous débutez avec les fonctions personnalisées
ou rencontrez une erreur, vous souhaiterez peut­être comprendre le fonctionnement
de chaque étape. Heureusement, il existe un moyen simple d'intégrer une fonction à
une requête. Pour ce faire :

1. Créez une variable pour chaque paramètre dans votre définition de fonction.
2. Commentez la définition de la fonction.

Voici à quoi cela ressemble.

Figure 25 définition de la fonction

Chaque paramètre défini à la ligne 1 possède désormais sa propre définition dans


l'expression let­expression des lignes 3 à 5. Cela signifie que le reste de la requête
peut toujours référencer les noms des paramètres, mais cette fois, les valeurs sont
extraites du code. Ce faisant, vous retransformez la fonction en requête. Cela vous permet
d'examiner attentivement chaque étape de la logique. Une fois le débogage terminé,
vous pouvez réintégrer votre logique dans une fonction en annulant les modifications :
commentez les variables de débogage et supprimez le commentaire de la ligne
de définition de la fonction.

Portée de la fonction

De la même manière que pour la création de paramètres et de requêtes, il existe des étendues dans lesquelles
vous pouvez définir une fonction.

Expression de niveau supérieur

La plupart des gens utilisent les fonctions personnalisées comme expressions de niveau
supérieur. Pour créer une fonction de niveau supérieur, collez le code de la
fonction dans l'éditeur avancé et cliquez sur OK. Power Query crée automatiquement
la fonction et l'ajoute à vos requêtes dans le panneau « Requêtes ». De là, elle peut être
référencée à partir d'autres requêtes ou fonctions.
Machine Translated by Google

Figure 26. Création d’une fonction personnalisée.

Vous pouvez reconnaître une fonction grâce à son préfixe, le symbole fx. Quel que soit le
nom donné à la requête, votre fonction sera appelée. Par exemple, la fonction ci­dessus s'appelle
« MaFonction ». L'avantage de définir une fonction à ce niveau est que vous pouvez l'appeler
depuis d'autres requêtes en référençant sa fonction.
nom.

En ligne dans une requête

Vous pouvez également définir une fonction en ligne dans l'une de vos requêtes. Après tout, une
fonction est simplement une expression, et votre requête est constituée d'une série
d'expressions. Les fonctions en ligne ne sont disponibles que dans le cadre de la requête
dans laquelle elles sont définies. Par exemple :

laissez Valeur1 = 5, Valeur2


= 10, sqrtDivide = (Nombre1,
Nombre2) => laissez SqrtNumber1 = [Link](Nombre1), SqrtNumber2 =

[Link](Nombre2), Result = SqrtNumber1 / SqrtNumber2 dans Result, Applyfunction


= sqrtDivide(Valeur1, Valeur2) dans

Appliquer la fonction

Ce que nous voyons ici est une expression let telle que vous la connaissez dans vos
requêtes. La troisième étape de la requête définit une fonction personnalisée nommée sqrtDivide.
Plus tard, nous invoquons cette fonction en l’appelant dans l’ étape Applyfunction .

Mettre tout cela ensemble

Ce chapitre vous a présenté différentes perspectives sur la création de fonctions


personnalisées et l'utilisation de paramètres. Vous avez appris en quoi consiste une fonction
personnalisée et comment chaque expression constitue une syntaxe simplifiée pour une fonction
unaire. Nous avons ensuite approfondi la définition des types de données pour les paramètres
d'entrée et de sortie de votre fonction. Enfin, nous avons étudié la création de fonctions personnalisées.
Machine Translated by Google

Les paramètres facultatifs incluent un niveau de flexibilité supplémentaire. Nous allons maintenant voir
comment nous pouvons réunir ces concepts avec quelques exemples pratiques.

Transformer toutes les colonnes en texte

Le premier scénario que nous allons examiner consiste à transformer des colonnes en un type de
données souhaité.

Introduction au problème du type de colonne

Voici le scénario :

• Vous avez un fichier avec plus de 20 requêtes. • La plupart


de ces requêtes ont des colonnes contenant du texte. • De nouvelles
colonnes sont ajoutées de temps en temps, et elles sont également du texte. • Vous souhaitez
éviter de définir manuellement les types de colonnes à chaque fois. • Certaines colonnes
doivent rester inchangées et ne pas être converties en texte.

Votre tâche consiste à créer une fonction qui transforme toutes les colonnes de votre requête en texte.
Une fois cette fonction en place, nous pouvons simplement l'appeler à la dernière étape de chaque
requête. Et quelles que soient les colonnes ajoutées ultérieurement, la fonction les transformera en
texte. Comment procéder ?

Comprendre la transformation des types de données

Supposons que nous travaillions avec le tableau suivant.

Figure 27. Tableau avec des colonnes de type quelconque.

Chaque colonne est actuellement de type « any ». Lorsque vous définissez les deux premières
colonnes comme texte, Power Query utilise la fonction [Link] :

[Link]( Source,
{{« Destination »,
type texte}, {« Pays », type texte}} )

Le code généré montre que la fonction a besoin de deux éléments. Premièrement, elle a besoin d'une table
comme point de départ, dans ce cas Source. Ensuite, elle a besoin d'une liste externe contenant plusieurs
listes internes. Chaque liste interne contient deux éléments :
Machine Translated by Google

Nom de la colonne à modifier et type de colonne à modifier. Dans cet exemple, il s'agit de :

{{« Destination », tapez le texte}, {« Pays », tapez le texte}}

Bien que cet exemple illustre le format souhaité, il n'est pas très flexible. Après tout, les noms de
colonnes sont codés en dur dans l'expression. Cela peut entraîner des erreurs lors de la modification
ou de la suppression des noms de colonnes, et exclut également toute nouvelle colonne susceptible
d'être ajoutée aux données ultérieurement.

Construire la fonction initiale

Pour construire la première version de cette fonction, nous allons :

1. Récupérez les noms de toutes les colonnes du tableau et placez­les dans une liste.
2. Modifiez le nom de chaque colonne de la liste en une paire : le nom et ses données
taper.
3. Utilisez cette liste mise à jour comme entrée pour [Link].

Pour récupérer tous les noms de colonnes d'une table, utilisez la fonction
[Link]. L'instruction suivante renvoie tous les noms de colonnes de la table lors d'une
étape appelée Source :

[Link](Source)

Ce qui renvoie :

{ « Destination », « Pays », « Attractions populaires », « Meilleure période pour visiter », « Description » }

Nous obtenons ainsi une liste de noms de colonnes. Idéalement, nous transformerions chaque
valeur textuelle de la liste en une liste contenant le nom de la colonne et le type de données.
Vous pouvez utiliser la fonction [Link] pour y parvenir :

[Link]([Link](Source),
chaque {_, type texte})

Le trait de soulignement dans l'expression ci­dessus représente chaque nom de colonne de la liste.
L'expression ajoute « , type text » après le nom des colonnes et entoure le résultat d'accolades.
Le résultat est le suivant :

{ {« Destination », tapez texte }


{« Pays », tapez le texte }
{« Attractions populaires », saisissez le texte }
{« Meilleur moment pour visiter », tapez le texte }
{« Description », tapez texte } }

Il ne nous reste plus qu'à passer cet argument à l'argument


[Link]. Voici les étapes à suivre pour réaliser cette opération.
sont:
Machine Translated by Google

Figure 28. Requête qui transforme les colonnes en type texte.

Pour transformer ce code en fonction, la première étape consiste à identifier les paramètres
requis. Dans ce cas, la fonction vise à convertir toutes les colonnes en texte. Par
conséquent, vous avez principalement besoin d'une table d'entrée. Une fois le
paramètre créé, remplacez le nom de la table à la ligne 3 par ce paramètre. Le résultat est :

Figure 28. Fonction qui transforme les colonnes en texte de type.

Appelons cette fonction fxToText. Désormais, pour convertir toutes vos colonnes en texte,
il vous suffit d'ajouter une étape au code :

FxToText ( <étape précédente> )

Figure 29. La fonction fxToText transforme toutes les colonnes en texte.

Amélioration de la fonction avec des paramètres facultatifs

Le code ci­dessus fonctionne et vous pouvez maintenant l'utiliser. Cependant,


la dernière exigence de ce cas est de pouvoir exclure des colonnes spécifiques afin qu'elles
ne soient pas converties en texte. Comme cette fonctionnalité ne sera pas utilisée dans
toutes les requêtes, il est logique de rendre ce paramètre facultatif. Comment devons­nous
alors intégrer cette exigence à la fonction ?
Machine Translated by Google

1. Commencez par ajouter un paramètre facultatif qui prend une liste de colonnes que vous
souhaitez exclure.
2. Ensuite, modifiez le code afin qu'il exclue ces colonnes spécifiées du
conversion.

Commençons par ajouter un paramètre facultatif nommé « Exclusions ». Lorsqu'une fonction requiert
plusieurs éléments, il est souvent utile de les demander sous forme de liste. Cela permet aux
utilisateurs de saisir manuellement une liste ou de se référer aux colonnes pour obtenir des
valeurs. Modifiez vos paramètres d'entrée comme suit :

( InputTable comme tableau, Exclusions facultatives comme liste ) comme tableau

Vous souvenez­vous de ce qui se passe si l'utilisateur ne fournit pas de valeur pour un paramètre
facultatif ? La fonction fournit une valeur nulle pour ce paramètre. Pour fonctionner correctement, la
fonction doit gérer cette valeur nulle. Pour gérer cette valeur nulle, réfléchissez à la façon dont le reste
de votre fonction utilisera les « Exclusions ». Une méthode simple pour exclure des
colonnes spécifiques est la fonction [Link]. Vous pouvez l'utiliser
comme suit :

[Link] les éléments (Toutes les colonnes, Exclusions)

Cependant, si « Exclusions » est nul, l'opération [Link] échoue. Pour éviter cela, vous
pouvez utiliser une liste vide comme solution de secours. Un moyen simple d'y parvenir est d'utiliser
l'opérateur coalesce :

Exclusions ?? {}

Étant donné que la suppression d'une liste vide ne modifie pas la liste d'origine, cette solution
répond à nos besoins. En mettant cela ensemble dans notre fonction finale, nous obtenons alors :

Figure 30. Incorporation d’un paramètre facultatif.

Puisque la suppression d'une liste vide ne modifie pas la liste d'origine, cette solution répond à nos
besoins. Nous pouvons l'appliquer à notre table comme suit :
Machine Translated by Google

Figure 31. Une fonction qui transforme toutes les colonnes, sauf certaines, en texte.

Nous avons créé une fonction qui convertit vos colonnes en texte. Il vous suffit d'ajouter cette
fonction à la dernière étape de votre requête pour qu'elle fonctionne sur les colonnes existantes et
futures. Si vous souhaitez exclure certaines colonnes, vous pouvez le faire avec le deuxième argument
facultatif.

Fusion de tables en fonction de plages de dates

Dans cette section, nous aborderons le défi de la fusion de tables en fonction de plages de
dates.

Exigences fonctionnelles

Imaginez que vous traitez des transactions clients liées à des contrats spécifiques, mais qu'il n'existe
pas d'identifiant de contrat unique pour les relier. Bien que Power Query propose différents types
de jointures, il est insuffisant pour joindre des tables basées sur une plage de dates. Nous allons donc
créer une fonction dédiée. Notre fonction personnalisée répondra aux exigences suivantes :

• La table principale comporte une colonne contenant des dates.


• La table « Contrats » comprend les dates de début et de fin pour chaque
contracter.
• Les types de données de toutes les colonnes doivent rester intacts après la jointure.

Nous commencerons par créer une formule pour réaliser cette jointure spécialisée. Nous la
transformerons ensuite en fonction réutilisable.

Effectuer une jointure basée sur des plages de dates

Pour cet exemple, prenons un ensemble de données simplifié. Nous avons une table
« Transactions » contenant cinq transactions, chacune associée à une date. Il existe également une
table « Contrats » listant les dates de début et de fin de chaque contrat.
Machine Translated by Google

Figure 32. Ensemble de données pour la jointure basée sur la plage.

Notre objectif est d'enrichir la table Transactions avec les données de la table Contrats.
Pour ce faire, il suffit d'ajouter une nouvelle colonne et d'utiliser la fonction [Link].
Pour la première étape :

• Allez dans « Ajouter une colonne » dans le ruban et sélectionnez « Colonne


personnalisée ». • Nommez la nouvelle
colonne « Contrats » • Ajoutez la formule : [Link]( Contracts
, chaque vrai )

Grâce à cette configuration, l'intégralité de la table « Contrats » apparaîtra sur chaque ligne
de la nouvelle colonne. Le code ressemblerait à ceci :

[Link]( Source,
« Contrats »,
chaque
[Link]( Contrats, chaque vrai ) )

Cela nous permet d'avoir accès à toutes les données contractuelles pour chaque transaction.
Nous allons ensuite nous concentrer sur le filtrage de ces informations en fonction des plages de
dates.

Ajuster la formule pour une date spécifique

Dans la fonction [Link], la condition spécifiée affecte uniquement les lignes de la


table Contrats. Pour filtrer uniquement les contrats commençant le 1er juillet 2023, utilisez le
code suivant :

[Link]( Source,
« Contrats »,
chaque
[Link]( Contrats, chaque [Début] = #date(2023,7,1) ) )

Désormais, la nouvelle colonne affichera uniquement les contrats qui respectent cette date de début
spécifique.

Rendre le filtre de date dynamique


Machine Translated by Google

Nous allons ensuite remplacer la date codée en dur par une référence dynamique à la colonne Date
de la table Transactions. Cela pose un problème complexe : la portée, un sujet abordé au
chapitre 7. Si vous essayez de remplacer #date(2023, 7, 1) par [Date], Power Query
renvoie une erreur. Le champ « Date » est introuvable dans le contexte de l'enregistrement actuel.
L'essentiel est de comprendre le rôle du mot­clé each. La première instance de each se trouve
dans [Link], où la colonne Date de la table Transactions est
toujours dans la portée. Cependant, un autre mot­clé each apparaît dans [Link].

N'oubliez pas que each est essentiellement une abréviation pour une fonction à argument
unique, représentée par (_) =>. Pour accéder à la fois à une colonne interne (Début des
contrats) et à une colonne externe (Date des transactions), nous devons transformer l'une des
expressions each en une fonction personnalisée. Cela nous permettra de gérer les différentes
portées impliquées.

Gestion des étendues à l'aide d'une fonction personnalisée

La fonction [Link] peut accepter un paramètre de fonction personnalisé pour gérer le


problème de portée. Cette fonction permet d'accéder aux tables Transactions et Contrats :

[Link]( Source,
« Contrats »,
(x) =>
[Link]( Contrats, chaque x[Date] <= [Début] ) )

Ici, le paramètre « x » permet d'accéder au contexte externe : les transactions. Il est disponible dans
le cadre de [Link]. De la même manière, nous pouvons également inclure le critère de
date de fin, ce qui donne :

[Link]( Source,
« Contrats »,
(x)=>
[Link]( Contrats, chaque x[Date] >= [Début] et
x[Date] <= [Fin] ) )

Résoudre les problèmes de type de données

Nous disposons désormais des lignes correspondantes dans chaque ligne de la nouvelle colonne.
Cependant, un problème subsiste : la colonne ne possède pas de type de données spécifié.
Machine Translated by Google

Figure 33. La colonne de jointure manque un type de données.

La table Contrats possède déjà les types de données corrects. Comment les transférer vers la nouvelle
colonne ? La fonction [Link] est la solution la plus simple. Utilisez­la pour référencer simplement la table et
reprendre la définition du type de données. Le code final, qui définit également le type de données de la nouvelle
colonne, se présente comme suit :

[Link]( Source,
« Contrats »,
(x)=>
[Link]( Contrats, chaque x[Date] >= [Début] et
x[Date] <= [Fin] ), [Link]( Contrats ) )

Désormais, la nouvelle colonne filtre non seulement correctement les données, mais transporte également le type
de données approprié de la table Contrats.

Transformer la logique en fonction

Pour rendre notre code réutilisable, nous allons le transformer en une fonction personnalisée. Notre objectif est de
ressembler étroitement à la fonction [Link]. Nous allons d'abord introduire deux paramètres :

• Le tableau auquel ajouter une colonne (Tableau) • La


colonne à utiliser pour la comparaison de dates (Date)

Comme indiqué précédemment dans ce chapitre, nous pouvons utiliser la fonction [Link] pour convertir une
valeur de texte pour la colonne de date en une référence de champ appropriée :

(Tableau comme tableau, Date comme texte) comme tableau =>


[Link](Tableau,
« Contrats »,
(x)=>
[Link](Contrats, chaque [Link](x, Date) >=
[Début] et [Link](x, Date) <= [Fin]), [Link](Contrats))

Ensuite, nous ajoutons des paramètres pour :


Machine Translated by Google

• La table à joindre (joinTable) • Les dates


de début et de fin utilisées dans la jointure (startDate et endDate) • Le nom de la nouvelle
colonne de jointure (newColumnName)

Pour ce faire, nous développons la liste des paramètres et les références de champ.

(Tableau comme tableau, Date comme texte, joinTable comme tableau, startDate comme texte, endDate comme texte, newC [Link]( Table,
newColumnName, (x)=>

[Link]( Contracts,
each
[Link](x, Date) >= [Link](_, startDate) and
[Link](x, Date) <= [Link](_, endDate) ), [Link]( joinTable ) )

Nous disposons désormais d'une fonction personnalisée complète : fxDateRangeJoin. Pour joindre
des tables basées sur une plage de dates, vous pouvez utiliser cette fonction simplifiée au lieu
d'une formule complexe.

Figure 34. Fonction personnalisée pour les jointures de plages de dates.

Résumé
Ce chapitre a présenté les paramètres. Comme vous l'avez vu, les paramètres sont bien plus que de
simples espaces réservés dans Power Query. Ils offrent flexibilité et s'adaptent à des scénarios variés.
À mesure que vous progresserez dans Power Query, vous utiliserez de plus en plus les paramètres pour
faciliter l'ajustement de vos requêtes. Nous avons également approfondi l'univers des fonctions
personnalisées dans Power Query M. Elles vous permettent de transformer vos requêtes
personnalisées en logique réutilisable. Vous avez appris à transformer une requête en fonction sans
avoir à l'écrire vous­même. Nous avons ensuite abordé les tenants et aboutissants de l'appel de
fonctions et souligné le rôle de l'expression each dans la simplification de leur création. Nous avons
également exploré les différences de syntaxe entre l'appel de fonctions à un ou plusieurs arguments. Dans
les situations plus complexes, où la portée devient un problème, l'utilisation du mot­clé each ne suffit pas.
Dans ce cas, la création de votre propre fonction personnalisée est nécessaire. Nous avons
également abordé les types de données et la polyvalence des paramètres optionnels. Et en cas d'erreur,
vous savez maintenant déboguer vos fonctions.
Machine Translated by Google

11 comparateurs, remplaçants, combinateurs et

séparateurs

Rejoignez notre communauté de livres sur Discord

[Link]

La préparation des données dans Power Query implique fréquemment des techniques de
fractionnement, de combinaison, de comparaison et de remplacement de valeurs.
Les comparateurs déterminent l'égalité et l'ordre, tandis que les remplaçants offrent la
possibilité de substitution pour corriger les irrégularités ou obtenir une uniformité. Les
combinateurs unifient les valeurs, les rassemblant. À l'inverse, les séparateurs séparent
les valeurs en composants plus granulaires. Ce chapitre présente les fonctionnalités de
fractionnement, de combinaison, de comparaison et de remplacement du langage M de
Power Query. Il vise à vous doter des connaissances nécessaires pour appliquer
efficacement ces transformations dans vos workflows. Ce chapitre aborde les sujets
suivants :

• Concepts clés •
Comparateurs
• Critères de comparaison
• Critères d'équation •
Remplaçants
• Remplaçants
personnalisés
• Combineurs
• Séparateurs • Exemples pratiques

Pour tirer le meilleur parti de ce chapitre, nous vous encourageons à ouvrir votre éditeur
Power Query préféré et à tester les exemples fournis. En exécutant et en explorant ces
scripts, vous approfondirez votre compréhension.

Concepts clés
Machine Translated by Google

Avant d'aborder le sujet principal de ce chapitre, il est utile de passer brièvement


en revue quelques points connexes. Premièrement, presque tous les comparateurs,
combinateurs et séparateurs génèrent une valeur de fonction. Ces valeurs
sont ensuite utilisées comme arguments pour d'autres fonctions M. Il est donc
essentiel de comprendre les concepts liés aux fonctions et à leur invocation.
Deuxièmement, quel est le point commun entre les fonctions de comparaison et l'énumération [Link] ?

Invocation de fonction

L'expression d'invocation est composée de parenthèses pouvant éventuellement contenir


une liste d'arguments. Elle déclenche l'exécution d'une fonction, qui renvoie une
valeur ou génère une erreur. Pour une compréhension plus approfondie des fonctions,
reportez­vous au chapitre 9. La manière la plus simple d'appeler une fonction est d'utiliser
son nom complet. Après le nom, ajoutez une expression d'invocation qui liste un
argument pour tous les paramètres requis. Par exemple, dans la fonction [Link],
vérifiez si « hello » fait partie de « Hello World ». Ces deux entrées de texte
correspondent aux paramètres requis de la fonction.

laissez Result = [Link](“Hello World”, “hello”) dans

Résultat

Lorsqu'un appel de fonction génère une nouvelle fonction, le processus de qualification


complète peut être poursuivi en ajoutant des expressions d'appel listant tous les
arguments requis, si nécessaire. Par exemple, la fonction « discountFunction » génère
une nouvelle fonction nécessitant ensuite un argument numérique en entrée. Un appel
entièrement qualifié est présenté à l'étape « Résultat ».

laisser

discountFunction = (discountRate as number) as function => (sales as number) as number => sales * (1 ­ discountRate),
Result = discountFunction(0.1)(100) in

Résultat

Fermetures

Une fermeture est une fonction qui conserve l'accès aux variables de sa portée
externe (parente), même après l'exécution de la fonction externe. Cette capacité à
mémoriser son environnement initial distingue une fermeture d'une fonction classique.
Lorsqu'une fonction est définie dans une autre fonction et accède aux variables de sa
fonction parente, elle forme une fermeture. La fonction interne « ferme » les variables
de la fonction parente, préservant leur état et les rendant accessibles pour de futurs appels,
quel que soit l'environnement d'appel de la fermeture. Vous pourrez approfondir
votre compréhension des fermetures, de la portée, du contexte et des
environnements au chapitre 7, qui conceptualise M.

laisser

makeMultiplier = (x) => (y) => x * y, multiplyBy2 = makeMultiplier(2), multiplyBy3


= makeMultiplier(3),
Machine Translated by Google

Result1 = multiplyBy2(4), // Le résultat sera 8


Result2 = multiplyBy3(4) // Le résultat sera 12 dans

[Résultat1=Résultat1, Résultat2=Résultat2]

Décomposons cet exemple de code pour mieux comprendre ce que cela signifie :

• La fonction makeMultiplier accepte un seul argument, x. C'est une fonction qui


renvoie une fonction. Une fois initialisée, elle renvoie cette nouvelle fonction : (y)
*
=> x et
• multiplyBy2 et multiplyBy3 sont des fermetures générées en appelant la fonction
makeMultiplier avec les arguments « 2 » et « 3 », respectivement.
Chacune de ces fermetures est une fonction qui « mémorise » la valeur de x
depuis sa création : un « 2 » pour multiplyBy2 et un « 3 » pour multiplyBy3. Cette
capacité à mémoriser les variables de l'environnement où elles ont été créées est le
concept fondamental d'une fermeture. • Enfin, ces
fermetures peuvent être invoquées. Par exemple, lorsque
La fonction multiplyBy2(4) est appelée ; elle utilise le x dont elle s'est souvenue (2) et
la nouvelle valeur de y (4) pour renvoyer 8. De même, la fonction multiplyBy3(4)
renvoie 12.

En comprenant les fermetures, vous pouvez créer du code plus modulaire, réutilisable
et dynamique dans vos flux de travail.

Fonctions d'ordre supérieur

Dans le langage M, les fonctions sont des fonctions de premier ordre : elles peuvent être
affectées à des variables, passées en arguments à d'autres fonctions et renvoyées comme
résultats. Cela leur permet d'être manipulées et diffusées comme n'importe quelle
autre valeur. Le terme « fonction d'ordre supérieur » désigne des fonctions qui acceptent
d'autres fonctions comme arguments ou renvoient des fonctions comme résultat, comme
makeMultiplier dans l'exemple précédent. De nombreuses fonctions de la bibliothèque
standard possèdent un paramètre de type fonction, ce qui les qualifie de fonctions d'ordre
supérieur, comme [Link] par exemple, qui prend une liste et une fonction de
transformation comme paramètres. [Link] applique la fonction de transformation
à chaque élément de la liste, ce qui produit une liste avec les nouveaux éléments.

laisser

defaultDiscount = 0.1, discountFunction =


(discountRate as number) as function => (sales as number) as number => sales * (1 ­ discountRate), applyDefaultDiscount =
discountFunction(defaultDiscount), myList = {100, 900, 200, 500}, Result = [Link]( myList, applyDefaultDiscount ) in Result

Les fonctions peuvent modifier des éléments individuels d'une liste ou d'un tableau,
et les fonctions d'ordre supérieur permettent d'appliquer ces transformations à tous les
éléments de manière efficace et concise. Dans ce cas, [Link] transmet
automatiquement l'argument requis à la fermeture applyDefaultDiscount lors de l'appel.
En informatique, ce comportement est souvent appelé « invocation de fonction de rappel »
ou simplement « invocation de rappel ».
Machine Translated by Google

Cependant, la documentation du langage Power Query M ne désigne pas officiellement


ce processus avec un terme spé[Link] un exemple qui montre comment les
fonctions d'ordre supérieur peuvent rendre le code plus facile à lire en simplifiant la
manière dont les valeurs des arguments sont transmises, même lorsqu'il y a plusieurs arguments.

laissez Result = [Link]( « Bonjour tout le


monde », « bonjour », [Link] ) dans

Résultat

Un comparateur est utilisé comme argument pour la fonction d'ordre supérieur


[Link]. Cette fonction fournit automatiquement ses deux paramètres d'entrée au
comparateur, éliminant ainsi la nécessité de les qualifier explicitement comme arguments.
La section suivante de ce chapitre explorera divers comparateurs disponibles dans
le langage M.

Fonctions anonymes

Les fonctions anonymes sont des fonctions sans nom qui peuvent être définies en ligne
dans d'autres fonctions. Elles sont utiles lorsqu'une logique de fonction personnalisée
est requise pour un objectif spécifique et n'a pas besoin d'être réutilisée ailleurs.

laisser

Résultat = ((x, y) => x + y)(3, 4) dans

Résultat

Jusqu'à présent, nous avons abordé des concepts tels que l'invocation de fonctions, les
fermetures et les fonctions d'ordre supérieur. Il est maintenant temps d'examiner
les points communs entre les fonctions d'énumération [Link] et de comparaison.

Ordonner les valeurs

Dans Power Query, les fonctions de comparaison et l'énumération [Link]


sont utilisées pour ordonner les valeurs. Cependant, elles sont différentes…

• Les énumérations définissent un ensemble de valeurs nommées, organisant les valeurs associées
Constantes pour un code plus lisible et maintenable. Ces valeurs nommées
clarifient leur fonction, simplifiant ainsi le processus de définition des options ou des
états dans votre code. Les énumérations sont présentées au chapitre 4 de ce livre.

• L'énumération [Link] est un ensemble prédéfini de valeurs


Représente différents types de tri. Cette option permet de spécifier facilement
l'ordre des valeurs : Ordre croissant (=0) ou Ordre décroissant (=1). Ces options
déterminent le tri en fonction de l'ordre et du sens. Par ordre numérique, du plus petit
au plus grand, du plus grand au plus petit, ou par ordre alphabétique, croissant
ou décroissant.
• Les fonctions de comparaison, quant à elles, permettent d'évaluer deux valeurs et
de renvoyer un entier indiquant leur ordre relatif. Ces fonctions vous permettent
de contrôler la façon dont les éléments sont comparés lors du tri.
Machine Translated by Google

un tableau ou une liste. Cette fonctionnalité est hautement personnalisable et vous permet de
définir des règles et des critères de tri spécifiques.

En résumé, les fonctions de comparaison offrent une méthode complète et


personnalisable pour comparer et trier, tandis que l'énumération [Link] facilite
la définition du sens de tri. Bien que toutes deux servent à organiser les valeurs, elles
remplissent des rôles différents et ne sont pas interchangeables en langage M.

Comparateurs

Le rôle des fonctions de comparaison est de fournir une méthode pour comparer des valeurs et
déterminer leur ordre relatif ou leur égalité. Les fonctions de comparaison sont utilisées dans divers
scénarios, tels que le tri ou la comparaison, par exemple dans les expressions conditionnelles.
Dans Power Query, ces fonctions sont principalement utilisées comme argument facultatif pour les
fonctions d'ordre supérieur nécessitant une comparaison ou une équation. Cela inclut des fonctions telles
que [Link], [Link], [Link], [Link], [Link], [Link],
[Link], [Link], [Link], [Link] et [Link], entre autres, qui incluent un comparateur,
également appelé paramètre equationCriteria ou comparisonCriteria. En langage M, il existe quatre
fonctions de comparaison par défaut. À l'exception de [Link], toutes renvoient une valeur de
fonction.

Comparateur.Égal

Renvoie une valeur logique après avoir évalué l'équivalence entre deux valeurs.
Cette fonction nécessite trois arguments : un comparateur pour guider l'évaluation et les
deux valeurs à comparer. Vous pouvez spécifier un comparateur intégré, tel que
[Link], [Link] ou
[Link].

laisser

myTable = [Link]( { { “APPLE”, “apple” },


{ “apple”, “apple” },
{ “42”, 42.0 }, { 42, 42.0 } } ), equivalenceChecks =
[Link]( myTable, “equivalenceCheck”, each
[Link]( [Link](“en­US”),
[Column1], [Column2] ), type logique ) dans

Vérifications d'équivalence

La colonne equivalenceCheck affiche le résultat booléen de la comparaison de la valeur


de la colonne 1 avec la valeur de la colonne 2.
Machine Translated by Google

[Link]

Renvoie une fonction de comparaison prenant deux valeurs d'argument. Elle applique ensuite
des règles ordinales de comparaison, basées sur les valeurs de code Unicode des caractères concernés.
À titre d'exemple, cette requête génère un tableau de deux colonnes.

laissez myTable = [Link]( { { « A » },


{ « POMME » },
{ « Pomme » }, { « B » }, { « a » },
{ « pomme » } }, type table[ Value1=text] ),
unicodeValue = [Link]( myTable,
« Valeur du code Unicode », each

[Link]( [Link]( [Link]( [Valeur1] ),


(v)=>
[Link]( [Link](v)) ), “, “ ), type texte )

dans

valeur unicode

La première colonne contient une valeur textuelle, tandis que la seconde indique
le code Unicode qui compose les caractères de la chaîne. Cela permet d'établir
un classement relatif des valeurs. Cette requête illustre le processus de
classement des valeurs classées par ordre croissant (du plus bas au plus
élevé).

laisser

myTable = [Link]( { { “POMME”, “pomme” },


{ “pomme”,
“pomme” }, { “pomme”, “POMME” } }, type table[Valeur1=texte,
Valeur2=texte] ), myComparer = [Link], sortValue2 =
[Link]( myTable[Valeur2], [Link] ),
equivalenceChecks
= [Link]( myTable, “equivalenceCheck”, each myComparer( [Valeur1], [Valeur2]

), [Link] ) dans equivalenceChecks

Le processus de comparaison applique ces règles ordinales sur deux valeurs à


la fois et établit leur rang relatif, ce qui donne lieu à l'agencement des valeurs dans
Machine Translated by Google

ordre croissant, en les classant du plus bas au plus élevé (Figure 11.1).

Figure 11.1 comparaison des règles ordinales

[Link] est affecté à la variable myComparer, ce qui produit une fonction


qui prend deux arguments et renvoie une valeur entière indiquant l'ordre des deux
valeurs : ­1, 0 ou 1.

• Si la valeur renvoyée est négative (­1), cela signifie que la première valeur
doit apparaître avant la deuxième valeur dans le résultat trié car elle a un rang
ou une position inférieure dans l'ordre, par rapport à la deuxième valeur. • Si la
valeur renvoyée est zéro (0), cela signifie que la première valeur est
considérée comme égale à la deuxième valeur dans le résultat trié car elle a un
rang ou une position égale dans l'ordre, par rapport à la deuxième valeur.
Par conséquent, leur ordre n'est pas réorganisé.
• Si la valeur renvoyée est positive (1), cela signifie que la première valeur doit venir
après la deuxième valeur dans le résultat trié car elle a un rang ou une position plus
élevée dans l'ordre, par rapport à la deuxième valeur.

Dans le panneau Paramètres de la requête, accédez à la section Étapes appliquées et


sélectionnez l'étape « sortValue2 ». Une liste de valeurs triées en fonction des données
de la deuxième colonne du tableau s'affiche. Le résultat conserve le même ordre que
la première colonne du tableau, aligné sur leurs rangs respectifs, comme indiqué dans
la colonne « equivalenceCheck ».

[Link]

Renvoie une fonction de comparaison prenant deux valeurs d'argument. Elle applique
les règles de comparaison ordinale, mais ignore la casse des caractères. La fonction
classe ces valeurs et détermine leur position relative dans un ordre de tri croissant.
Les éléments ayant le même rang conservent leur ordre d'origine à partir de l'entrée.

laisser

myTable = [Link]( { { “POMME”,


“pomme” },
{ “pomme”, “Pomme” }, { “pomme”, “POMME” } }, type
table[Valeur1=texte, Valeur2=texte] ), myComparer =
[Link], sortValue2 =

[Link]( myTable[Valeur2], [Link] ),

equivalenceChecks = [Link]( myTable, “equivalenceCheck”,


each myComparer( [Valeur1], [Valeur2]
Machine Translated by Google

), [Link] ) dans

Vérifications d'équivalence

Dans un environnement insensible à la casse, les majuscules et minuscules d'un même


mot, comme « apple », « Apple » et « APPLE », sont considérées comme équivalentes.
Par conséquent, leur ordre reste le même dans la liste triée, comme indiqué à l'étape
« sortValue2 ».

[Link]

Renvoie une fonction de comparaison prenant deux arguments. Le premier est


une culture, représentée par une balise de langue connue comme « en­US » pour l'anglais
américain. Cette balise permet de spécifier les paramètres régionaux dans .NET
Framework. Le second argument est une valeur logique pour la sensibilité à la casse. La
valeur par défaut de ce paramètre « ignoreCase » est « false ».

laisser

myTable = [Link]( { { « APPLE », « apple » },


{ « apple »,
« apple » }, { « apple », « APPLE » } }, type table[ Value1=text,
Value2=text] ), myComparer = [Link](“en­US”),
equivalenceChecks = [Link]( myTable,
“equivalenceCheck”,
each myComparer( [Value1], [Value2]

), [Link] ) dans equivalenceChecks

Cette fonction effectue une comparaison culturelle de deux valeurs selon les règles
définies par la culture spécifiée. Elle prend en compte les conventions culturelles
telles que les règles de tri spécifiques à chaque langue et la sensibilité à la casse.
Notamment, dans cet exemple, le mot minuscule est classé et ordonné avant le mot
majuscule, contrairement à la comparaison ordinale vue précédemment, en raison
de la manière dont fonctionnent les comparateurs sensibles à la culture de .NET.
L'impact de l'application de règles spécifiques à la langue devient encore plus
évident lorsque l'on compare le mot danois « Færdig » avec « Faerdig » par exemple.

soit
Danish = [Link](« da­DK »)( « Færdig », « Faerdig » ), English =
[Link](« en­US »)
( « Færdig », « Faerdig » ) in

[DK = danois, US = anglais]


Machine Translated by Google

Cet enregistrement indique qu'en anglais, les caractères « æ » et « ae » sont considérés comme
identiques, ce qui donne une valeur de champ américaine de 0. Cependant, en danois (« da­DK »), ces
caractères sont considérés comme distincts, ce qui donne une valeur de champ DK de 1.

Critères de comparaison

Des critères de comparaison peuvent être utilisés pour organiser les données selon une logique spécifique.
Dans cette section, nous explorerons différentes méthodes offertes par le langage M de Power Query
pour définir des critères de comparaison et ordonner des valeurs. Nous utiliserons les fonctions [Link]
et [Link] comme exemples pour montrer comment créer des règles personnalisées et contrôler
précisément l'ordonnancement des données.

Valeur numérique

Lors du tri de données avec [Link], vous pouvez indiquer une valeur numérique pour indiquer l'ordre
de tri souhaité. Les valeurs inférieures sont prioritaires sur les valeurs supérieures, les données étant
classées par ordre croissant. Cette méthode est simple et adaptée aux cas où l'ordre de tri peut être
directement lié aux valeurs numériques.

laisser

myTable = [Link]( { [Label=“Modéré”, Order=1], [Label=“Faible”,


Order=2],

[Label=“Élevé”, Order=0] }, type table[Label=texte, Order=[Link]] ), sortData =

[Link]( myTable, each [Order] ) dans

trier les données

Calcul d'une clé de tri

Pour les scénarios plus complexes, vous pouvez utiliser une fonction pour calculer une clé pour chaque
élément ; cette clé servira de base au tri. Cette méthode est particulièrement utile lorsque la clé
de tri souhaitée ne peut être directement dérivée des valeurs d'origine et nécessite un calcul.

[Link]( { « Avril », « Février », « Janvier », « Mars » }, chaque [Link]( _ &


« 2020 » ) )

Il peut également arriver que les valeurs ordinales ne puissent pas être calculées directement.
Dans ce cas, une recherche peut être nécessaire pour établir l'ordre. Par exemple, un
enregistrement personnalisé est utilisé pour spécifier l'ordre : [Élevé = 0, Modéré = 1, Faible = 2]. La
fonction [Link] permet d'associer chaque libellé à un nom de champ, obtenant ainsi la
valeur du champ, qui indique l'ordre de tri.
Machine Translated by Google

laissez

myTable = [Link]({ { « Modéré », « Faible », « Élevé » } }, type

table[Label=texte] ), sortData = [Link]( myTable, each [Link]( [Élevé=0,

Modéré=1, Faible=2], [Label] ) ) dans

trier les données

Liste avec clé et ordre


Pour sélectionner simultanément une clé spécifique pour le tri et contrôler l'ordre de tri, vous
pouvez utiliser une liste de listes comme critère de tri. Chaque liste imbriquée doit contenir
deux éléments : la clé de tri et le sens de tri souhaité, spécifié par [Link]
([Link] = 0 ou [Link] = 1). Cette méthode offre une certaine
flexibilité lorsqu'une logique de tri personnalisée est requise.

laisser

myTable = [Link]({ [Catégorie = « Catégorie


A », Sous­catégorie = « Sous­catégorie 11 »], [Catégorie = « Catégorie C », Sous­catégorie = « Sous­catégorie 20 »],
[Catégorie = « Catégorie A », Sous­catégorie = « Sous­catégorie 1 »], [Catégorie = « Catégorie B », Sous­catégorie =
« Sous­catégorie 2 »], [Catégorie = « Catégorie C », Sous­catégorie = « Sous­catégorie 9 »], [Catégorie = « Catégorie
B », Sous­catégorie = « Sous­catégorie 5 »], [Catégorie = « Catégorie A », Sous­catégorie = « Sous­catégorie 10 »] },
type table [Catégorie=texte, Sous­catégorie=texte]), sortedTable = [Link]( myTable, { {each
[Link]( [Link]([Catégorie], « « )), 1}, {chaque [Link]([Link]([Sous­catégorie], {« 0 ».. »9 »})),
0} }) dans

tableau trié

Comparateur personnalisé avec logique conditionnelle

Pour contrôler entièrement le processus de comparaison, vous pouvez créer une fonction de
comparaison personnalisée prenant deux arguments. Cette fonction doit renvoyer ­1, 0 ou 1 selon
la relation entre les entrées gauche et droite. Bien que l'exemple suivant soit simplifié, il illustre
l'utilisation de la logique conditionnelle pour gérer des scénarios de tri plus complexes.

laisser

tierComparer = (a, b) => si a[Ventes] > b[Ventes]


alors 1 sinon si a[Ventes] < b[Ventes] alors ­1 sinon si
a[MargeBénéfice] < b[MargeBénéfice] alors 1 sinon si a[MargeBénéfice] >
b[MargeBénéfice] alors ­1 sinon 0, salesData = [Link]({ [Product = “Produit A”, Ventes =
5000, MargeBénéfice = 0,08], [Product = “Produit B”, Ventes = 7000, MargeBénéfice = 0,10], [Product =
“Produit C”, Ventes
= 6000, MargeBénéfice = 0,16],
Machine Translated by Google

[Produit = « Produit D », Ventes = 5 000, Marge bénéficiaire = 0,14], [Produit = « Produit E », Ventes = 7 000, Marge
bénéficiaire = 0,12] }, type table [Produit=texte, Ventes=[Link], Marge bénéficiaire=[Link]]), sortedSalesData
= [Link](salesData,
tierComparer) dans

Données de vente triées

Comparateur personnalisé avec [Link]

Vous pouvez également créer une fonction de comparaison personnalisée à deux paramètres
pour contrôler entièrement le processus de comparaison. Utilisez la fonction [Link] pour
déléguer une logique de comparaison personnalisée et obtenir un résultat de ­1, 0 ou 1 selon les besoins.
Cette méthode est particulièrement utile lorsque des règles de comparaison complexes sont
requises.

laisser

weekdayComparer = (a, b) => let weekstartDate =


#date(2024, 1, 1), weekdayCulture = “en­US”, weekdayRecord =
[Link]( [Link]( [Link]( weekstartDate, 7,
[Link](1)), each [Link]( {[Link]( _,
[Link]( weekstartDate, 0 ))},
{[Link]( _, try weekdayCulture ?? “en­US” otherwise “en­US” )} ))) in
[Link]( [Link]( weekdayRecord, a[colName] ),
[Link]( weekdayRecord, b[colName] ) ), myData = [Link]({ {“Jeudi”, “Dimanche”, “Samedi”, “Lundi”, “Mardi”, “Vendredi”,
« Mercredi »} }, tapez table [colName=texte] ), sortedData = [Link](myData, weekdayComparer) dans

données triées

Dans cet exemple, weekdayComparer inclut une fonction imbriquée qui génère un
weekdayRecord, sensible à la culture et indiquant les jours de la semaine et leur numéro. La culture
par défaut est « en­US ». Pour une exploration plus approfondie, le code M de cette partie
de la fonction est séparé ici sous la forme fxCreateWeekdayRecord.

laissez fxCreateWeekdayRecord = (weekstartDate


comme date, weekdayCulture facultatif comme texte)
comme enregistrement =>

[Link]( [Link]( [Link]( weekstartDate, 7, [Link](1)), each


[Link]( { [Link]( _,
[Link]( weekstartDate, [Link] )) }, { [Link]( _, essayez weekdayCulture ?? « en­US » sinon « en­US » ) } ) )),
fxDocumentation = [ [Link] = « fxCreateWeekdayRecord », [Link] = « Renvoie un enregistrement où
Machine Translated by Google

Les noms de champ correspondent au nom du jour de la semaine, les valeurs de champ
correspondent au numéro du jour de la semaine. « weekstartDate » est considéré comme le
premier jour de la semaine. « weekdayCulture » est facultatif et sa valeur par défaut est « en­US ». « , [Link] =
« Melissa de Korte », [Link] = « 1.0 »

]
dans
[Link]( fxCreateWeekdayRecord, [Link]( [Link]( fxCreateWeekdayRecord ),
fxDocumentation

))

Comme le montre la figure 11.2, toute cette fonction fxCreateWeekdayRecord nécessite


une valeur de date unique qui marque le premier jour de la semaine et éventuellement
une culture.

Figure 11.2 la sortie de la fonction personnalisée, un weekdayRecord

Lorsqu'on utilise des critères de comparaison pour organiser des données, il est important
de comprendre leur adaptabilité à diverses situations. Les techniques explorées ici, comme la
simple utilisation de valeurs numériques pour le tri ou l'exploitation de fonctions plus
avancées pour calculer des clés de tri, mettent en évidence la diversité des outils à notre
disposition. La possibilité de créer des fonctions de comparaison personnalisées, permettant
de comparer des valeurs et de déterminer leur ordre relatif ou leur égalité, permet des
comparaisons complexes et ajoute une touche de sophistication au processus.

Critères d'équation
Les critères d'équation permettent de déterminer l'égalité et de faire correspondre les données
dans des tableaux ou des listes selon une logique spécifique. Dans cette section, nous
explorerons différentes manières de spécifier des critères d'équation en langage M.
La fonction [Link] illustre comment ces méthodes permettent de contrôler les
tests d'égalité.

Comparateurs par défaut


Machine Translated by Google

Dans ce chapitre, nous avons déjà abordé en détail le rôle des fonctions de comparaison : elles
fournissent une méthode pour comparer des valeurs et déterminer leur ordre relatif et leur égalité.
Par conséquent, vous pouvez simplement passer un comparateur par défaut comme
equationCriteria. Le comparateur sélectionné agit alors comme un livre de règles intégré que
[Link] suit lors de la comparaison des valeurs. En ignorant la casse, « New York » et « new
york » sont considérés comme égaux.

[Link]( {« New
York », « Londres », « Tokyo »}, « New York »,
[Link] )

//Résultat : VRAI

Comparateur personnalisé

Pour des scénarios plus complexes, vous pouvez créer un comparateur personnalisé à deux
paramètres. Cela permet de contrôler entièrement le processus de comparaison en
définissant vos propres règles d'égalité. Par exemple, cette fonction vérifie si un élément de liste (x)
contient une sous­chaîne spécifique (y).

[Link]( {« New
York », « Londres », « Tokyo »}, « yO », (x, y)=>
[Link]( x,
y, [Link]) )

//Résultat : VRAI

Sélecteurs de clés

Les sélecteurs de clé vous permettent de vous concentrer sur un champ spécifique ou une
sélection de champs, attirant ainsi l'attention de la fonction sur ces zones spécifiques. Par exemple,
si vous travaillez avec une liste d'enregistrements et que vous souhaitez uniquement faire correspondre
le champ « ID », un sélecteur de clé permettra de se concentrer uniquement sur ce champ, ignorant
toutes les autres valeurs.

[Link]( { [ID=1,

Nom=“John”, Rôle=“Manager”], [ID=2, Nom=“Jane”, Rôle=“Développeur”],


[ID=3, Nom=“Sam”, Rôle=“Concepteur”] }, [ID=1, Nom=“Anne”, Rôle=“Analyste”],
each [ID] )

//Résultat : VRAI

Combinaison de sélecteurs et de comparateurs clés

En combinant sélecteurs et comparateurs de clés, vous pouvez vous concentrer sur des champs
spécifiques (grâce au sélecteur de clés) et appliquer des règles de comparaison spécifiques
(grâce au comparateur). Ici, nous effectuons une correspondance insensible à la casse sur deux
champs d'enregistrement.
Machine Translated by Google

[Link]( { [ID=1,

Nom=“John”, Rôle=“Manager”], [ID=2, Nom=“Jane”, Rôle=“Développeur”],


[ID=3, Nom=“Sam”, Rôle=“Concepteur”] }, [ID=1, Nom=“Anne”, Rôle=“manager”],
{ each [Link](_, {“ID”, “Rôle”}), [Link] } )

//Résultat : VRAI

Les critères d'équation sont utiles pour comparer les données dans des tableaux ou des
listes. Nous avons présenté plusieurs techniques permettant de gérer les tests d'égalité dans les
fonctions M. À l'instar de comparisonCriteria, la possibilité de définir et de transmettre des
comparateurs personnalisés sous forme d'equationCriteria offre une grande flexibilité pour déterminer
l'égalité.

Remplaçants

Les fonctions de remplacement sont utilisées par d'autres fonctions du langage M de Power
Query. Il existe deux fonctions de remplacement par défaut : [Link] et
[Link], utilisées comme arguments de [Link] ou
[Link] pour remplacer une valeur. Cela permet aux utilisateurs de remplacer des sous­
chaînes ou des valeurs spécifiques par de nouvelles chaînes, de nouvelles valeurs ou des
expressions. Ces fonctions sont couramment utilisées dans les scénarios de transformation de
données, où il est nécessaire de modifier et de nettoyer des données incohérentes pour obtenir
une uniformité. Prenons par exemple cette table (Figure 11.3) où nous souhaitons remplacer
« RH » par « Ressources humaines » dans la colonne Service.

Figure 11.3 Exemple de données

Voici comment procéder à l’aide de l’interface utilisateur graphique (GUI) :

• Sélectionnez la colonne « Département » du tableau. •


Accédez à l'onglet « Transformer » sur le ruban et choisissez « Remplacer »
valeurs'.
Machine Translated by Google

• Une boîte de dialogue apparaîtra, saisissez « RH » dans le champ pour la valeur à rechercher.
• Saisissez « Ressources humaines » dans le champ pour la valeur à remplacer par • Sous
« Options avancées », définissez « Correspondre à l'intégralité du contenu de la cellule » et
confirmer.

Une étape « Valeur remplacée » est ajoutée à la requête, ce qui donne lieu à une table modifiée
(Figure 11.4) où « RH » a été remplacé par « Ressources humaines » dans la colonne Département.

Figure 11.4 Résultat de l'opération Valeur remplacée

En observant le code M dans la barre de formule, vous remarquerez l'appel de la fonction d'ordre
supérieur [Link]. Cette fonction fournit tous les arguments nécessaires à la fonction interne
[Link].

laisser

Exemple = [Link]( { {« John », « Lisa », « David »,


« Sarah »,
« Alex »}, {« Ventes », « Marketing », « Finances », « RH », « Opérations »} }, type table [Nom de
l'employé=texte, Service=texte] ), #« Valeur remplacée » = [Link](Exemple, « RH », « Ressources humaines »,
[Link] dans

#« Valeur remplacée »

Il est maintenant temps d'examiner plus en détail les fonctions de remplacement. Il existe deux fonctions
de remplacement par défaut dans le langage M.

[Link]

La fonction [Link] facilite la substitution d'un modèle de texte spécifique par un autre dans
une chaîne fournie. Elle possède trois paramètres de type texte : l'entrée (ou curText) où le remplacement
doit avoir lieu, l'ancien (oldText) modèle à identifier et à remplacer, et enfin le nouveau (newText) qui
le remplacera. La fonction recherche toutes les occurrences de l'ancien (oldText) dans le curText et les
remplace par le nouveau (newText). Voici un exemple de requête :

laisser

String1 = « Le soleil brille, brille intensément. »,


Machine Translated by Google

String2 = « Un bruit de cliquetis soudain a effrayé les oiseaux. », Example =


[Link]({ [ curText=String2, oldText=“t”,
newText=“f”, ReplaceText=[Link](curText, oldText, newText) ], [ curText=String2,
oldText=“tt”, newText=“ff”, ReplaceText=[Link](curText, oldText, newText) ], [ curText=String1, oldText=“brille”,
newText=“rayonne”, ReplaceText=[Link](curText, oldText, newText) ],
[ curText=String1, oldText=“brille,”, newText=“rayonne”, ReplaceText=[Link](curText, oldText, newText) ] }, let t = type
text in type table [curText=t, oldText=t, newText=t, ReplaceText=t] ), ReplaceValue = [Link]( Exemple,
«. », «! », [Link], {« curText », « ReplaceText »} ) dans

Remplacer la valeur

La fonction [Link] remplace chaque occurrence de oldText par newText


dans la chaîne de texte fournie ou curText. Elle prend en charge les remplacements
de texte partiels. La syntaxe est la suivante :
[Link](curText, oldText, newText). Ce processus est illustré dans l'étape
Exemple de la requête, comme illustré à la figure 11.5. Les trois premières colonnes
du tableau présentent les valeurs d'entrée, et la dernière colonne affiche la sortie après
l'exécution d'une fonction [Link] complète.

Figure 11.5 Exemples de texte de remplacement

Lorsque vous sélectionnez « Remplacer les valeurs » dans l'onglet


« Transformer » de l'interface utilisateur graphique (GUI), la transformation est appliquée
à toutes les colonnes sélectionnées. Les noms de ces colonnes sont listés dans
l'argument final de [Link], comme illustré dans la figure 11.6.

Figure 11.6 Appel implicite de [Link] dans


[Link]

Dans les colonnes « curText » et « ReplaceText » du tableau, un point a été remplacé


par un point d’exclamation.

[Link]
Machine Translated by Google

La fonction [Link], quant à elle, permet de remplacer des


valeurs spécifiques par d'autres valeurs ou expressions. Elle possède trois
paramètres de type any : l'entrée d'origine (ou curVal) où le
remplacement sera effectué ; oldVal, c'est­à­dire la valeur à identifier et à
remplacer ; et newVal, qui la remplacera. La fonction compare oldVal et curVal et, si
elles correspondent, remplace curVal par newVal. Voici un exemple de
requête pour une meilleure compréhension :

laissez Value1 = « Faites du bruit. », Exemple =


[Link]({ [ curVal=Value1, oldVal=“noise”,
newVal=“love”, ReplaceValue=[Link](curVal, oldVal, newVal)], [ curVal=Value1,
oldVal=Value1, newVal=“You rock!”, ReplaceValue=[Link](curVal, oldVal, newVal)], [ curVal=10.1, oldVal=10,
newVal=11, ReplaceValue=[Link](curVal, oldVal, newVal)], [ curVal=10, oldVal=10,
newVal=11, ReplaceValue=[Link](curVal, oldVal, newVal)], [ curVal={1..3}, oldVal={3..5}, newVal=[Link]({1..3}),
ReplaceValue=[Link](curVal, oldVal, newVal)], [ curVal={1..3},
oldVal={1..3}, newVal=[Link]({1..3}), ReplaceValue=[Link](curVal, oldVal, newVal)] }, let t = type texte dans type
table [curVal=t, oldVal=t, newVal=t, ReplaceValue=any]) dans

Exemple

La fonction [Link] remplace la valeur curVal par la nouvelle valeur,


lorsque celle­ci correspond à l'ancienne valeur. Ceci est illustré dans l'exemple
de la requête (figure 11.7). Les trois premières colonnes du tableau présentent les
valeurs d'entrée, et la dernière colonne affiche la sortie après l'appel complet de la
fonction [Link].

Figure 11.7 Exemples de valeurs de remplacement

Il est important de souligner que [Link] requiert une


correspondance exacte. Cette opération peut être effectuée sur n'importe quel type
de valeur, qu'il soit primitif ou structuré. Pour illustrer ce cas de figure, voici un
exemple de remplacement conditionnel. Prenons un scénario courant, mais
n'oublions pas qu'il existe plusieurs solutions à ce type de problème. Votre table de
dimension évolue lentement. Notre exemple (figure 11.8) présente les employés et
leurs services respectifs pendant des périodes d'emploi spécifiques.
Machine Translated by Google

Figure 11.8 Dimension changeant lentement

Copiez et collez ce code dans une nouvelle requête vide, pour suivre.

laisser

SCD = [Link]( { {« John », « Lisa »,


« David »,
« John », « Lisa »}, {#date(2020, 1, 1), #date(2015, 9, 15), #date(2019, 3, 1), #date(2023, 11,
6), #date( {#date(2023, 11, 5), #date(2023, 12, 10), null, null, null }, {« Opérations », « Ventes », « Finances », « Ventes », « Marketing » } }, type table [Emp=texte, StartDate=date,
EndDate=date, Dept=texte] ), MergedExample = [Link]( [Link]( { [Link]( {#date(2023, 11, 1),
#date(2023, 12, 1), #date(2024, 1, 1) }, 3 ), [Link]( {“John”}, 3 ) & [Link]( {“Lisa”}, 3 ) & [Link]( {“David”}, 3 },
type table [Date=date, Employee=texte]

), {« Employé »}, SCD, {« Emp »},


« Département »,
[Link] ) dans

Exemple fusionné

Cette dimension a été fusionnée avec une table de faits afin de générer une table
contenant tous les services où un employé était actif, car il n'y avait qu'une seule clé de
fusion : l'employé (figure 11.9). Pour l'enregistrement initial de John au 1er novembre 2023,
nous souhaitons renvoyer « Opérations », et pour les enregistrements suivants,
nous prévoyons de renvoyer « Ventes » à partir de cette table imbriquée.

Figure 11.9 La fusion a obtenu tout l'historique du département pour chaque employé
Machine Translated by Google

Pour générer le code, sélectionnez la colonne « Département », accédez à l'onglet


« Transformer » du ruban et sélectionnez « Remplacer les valeurs ». Dans la boîte de dialogue,
laissez les paramètres tels quels et confirmez. Le code créé est visible dans la barre de
formule.

[Link](Exemple fusionné,""","",[Link],{"Département"})

La fonction d'ordre supérieur, [Link], a appelé la fonction


[Link]. Il reste à spécifier l'ancienne valeur recherchée et la nouvelle
valeur par laquelle elle sera remplacée dans l'expression parente. Cela permettra de
transmettre ces valeurs à la fonction replacer, au lieu des chaînes de texte vides fournies. La
première partie est simple : nous sommes dans un tableau et, pour chaque ligne de ce
tableau, nous souhaitons remplacer la valeur actuellement présente dans la cellule. Nous
devons donc remplacer la première chaîne de texte vide, constituée de guillemets, par :
each [Department]. Le deuxième ensemble de guillemets correspond à la valeur de
remplacement. Ici, nous souhaitons utiliser [Link] pour sélectionner une seule
ligne du tableau imbriqué afin d'extraire le département.

chaque [Link]( [Département], (ligne) => ligne[DateDébut] <=


[Date] et (ligne[DateFin] >= [Date] ou ligne[DateFin] = null)

)[Département]?{0}?

À ce stade, si vous n'avez pas besoin de comprendre pleinement le code M, consultez le


chapitre 8, consacré à l'utilisation de structures imbriquées, qui abordera ces types de
scénarios plus en détail. Nous avons abordé les « remplaceurs » par défaut du langage M
de Power Query, particulièrement utiles pour la modification et le nettoyage des données.
Ces tâches peuvent inclure la suppression de caractères indésirables, la correction de
fautes d'orthographe ou la standardisation de valeurs. [Link] se concentre
sur la substitution de sous­chaînes dans le texte, tandis que [Link] permet
de remplacer le contenu d'une cellule. Tous deux sont utilisés par des fonctions d'ordre
supérieur telles que [Link] et [Link] pour manipuler et
transformer facilement les données afin de répondre à des exigences spécifiques.
L'opération « Remplacer des valeurs » en est un parfait exemple.

Remplacements personnalisés

Les fonctions de remplacement de [Link] ou [Link] jouent un rôle


crucial dans la transformation et la manipulation des données. Elles permettent aux
utilisateurs de remplacer des valeurs spécifiques d'une colonne de table ou d'une liste
par de nouvelles valeurs, selon des règles ou conditions définies. Il est fréquent de
rencontrer des incohérences ou des erreurs lors de l'utilisation de données. Les
fonctions de remplacement personnalisées offrent une solution flexible et performante
pour résoudre ces problèmes en permettant aux utilisateurs de définir leur propre
logique de remplacement. Pour gérer efficacement le processus de remplacement,
vous pouvez créer à la volée une fonction de remplacement anonyme en ligne, prenant trois paramètres, comme illustré

[Link]( Source, //
table pour transformer chaque true, // oldValue,
condition logique
Machine Translated by Google

null, // newValue (x, y, z) => si y alors z


sinon x, // logique de remplacement personnalisée colList // colonnes sous forme de liste)

La logique de remplacement personnalisée, comme les remplacements par défaut, nécessite


trois paramètres : currentValue (x), oldValue (y) et newValue (z). Elle peut également être définie
comme une fonction personnalisée. Vous pouvez bien sûr écrire cette fonction typée ou
non typée.

laisser

customReplacer = (currentValue, oldValue, newValue) => si oldValue alors newValue sinon currentValue

dans customReplacer

Dans cet exemple, la fonction customReplacer est définie sans type et prend comme paramètres
currentValue, oldValue et newValue. Elle évalue si oldValue renvoie true ; si oui, elle remplace
currentValue par newValue. Sinon, elle conserve currentValue inchangée. Les fonctions de
remplacement personnalisées peuvent être utilisées dans les fonctions [Link] et
[Link] d'ordre supérieur pour répondre à des besoins de remplacement spécifiques.

Il est important de noter que les fonctions de remplacement personnalisées offrent une grande
flexibilité. Prenons l'exemple du tableau de la figure 11.10 : il contient quatre colonnes de
date. Ces colonnes contiennent trois valeurs de date spécifiques nécessitant un remplacement
par une valeur nulle. Pour éviter de multiples transformations de valeurs de remplacement, nous
allons élaborer une stratégie permettant de les remplacer toutes en une seule étape.

Figure 11.10 Plusieurs valeurs de date doivent être remplacées

En fait, ce code M illustre trois méthodes légèrement différentes à explorer. La première est
« Anonymous », une fonction inline non typée. La seconde est « Typed », une fonction inline typée.
Enfin, nous avons « CF », une fonction personnalisée typée affectée à la variable
dateReplacer.

let
datesToReplace = {#date(1, 1, 1),#date(1900, 1, 1),#date(9999, 9, 9)}, dateReplacer = (x comme date nullable, y comme logique nullable, z
comme date nullable) comme nullabl if [Link]( datesToReplace, x) then z else x, colsList = [Link]( [Link](Source), each [Link](_, “Date”)), Source =
[Link]( { {“Entrée 1”, “Entrée 2”, “Entrée 3”, “Entrée 4”, “Entrée 5”}, {#date(2023, 11, 1),
#date(2023, 9, 9), #date(2024, 2, 2), #date(2021, 5, 25), #date( {#date(2023, 12, 9), #date(1900, 1, 1), #date(2023,
12, 11), #date(1, 1, 1), #date(20 {#date(2024, 1, 21), #date(1, 1,
1), #date(9999, 9, 9), #date(1900, 1, 1), #date(2023
{#date(1,
1, 1), #date(2024, 3, 9), #date(2023, 9, 3), #date(2024, 1, 11), #date(2024 }, type table[Label=text, Date Column1=date, Date
Column2=date, Date Column3=date, Date ), Anonymous = [Link]( Source, null, null, (x, y, z) =>
Machine Translated by Google

si [Link]( datesToReplace, x) alors z sinon x, colsList ), Typed = [Link]( Source, null, null, (x comme date
nullable, y comme logique nullable si [Link]( datesToReplace, x) alors z sinon x, colsList ), CF = [Link]( Source, null, null, dateReplacer, colsList ) dans

FC

Les fonctions de remplacement par défaut permettent de remplacer des valeurs


sur plusieurs colonnes, mais elles reposent sur des valeurs spécifiées et sont donc plus
limitées. Les fonctions de remplacement personnalisées offrent une solution plus
polyvalente. Elles vous permettent de définir vos propres conditions, supprimant ainsi toute
limitation et fournissant une méthode précise et adaptée à vos besoins spécifiques.
Nous avons introduit le concept de fonctions de remplacement personnalisées,
en présentant trois méthodes différentes : une fonction inline non typée, une fonction
inline typée et une fonction typée affectée à une variable. Ces méthodes permettent un
remplacement dynamique de valeurs selon des conditions spécifiées. Les fonctions de
remplacement personnalisées doivent être définies comme des fonctions à
trois paramètres représentant respectivement currentValue, oldValue et newValue.

Combineurs
Dans le langage Power Query M, les combinateurs fusionnent une liste de valeurs
textuelles en un seul texte. Ils sont utilisés par des fonctions de bibliothèque standard
d'ordre supérieur, telles que [Link] et [Link], qui utilisent une
fonction combinatrice pour traiter chaque ligne d'une table et produire une valeur unique
par ligne. Une opération courante réalisée via l'interface utilisateur graphique (GUI)
est la « Fusion de colonnes ». Située dans l'onglet Transformation du ruban, elle utilise
[Link] et [Link] et applique une inférence
de type pour garantir une opération sécurisée. Pour plus d'informations sur l'inférence
de type, consultez le chapitre xx. Lorsque des types autres que du texte sont
inférés, un [Link] imbriqué est incorporé à la transformation.
Cela garantit la production d'une valeur textuelle unique ou d'une erreur au niveau de la
cellule. Cette fonctionnalité permet aux utilisateurs de combiner en toute sécurité
diverses valeurs primitives, notamment du texte, des nombres, des dates, etc. Prenons
l'exemple de ce tableau.

laissez Source = [Link]({ {“1”, 1, 1, null, true,


#time(12, 0, 0), #date(2024, 1, 1)}, {“2”, “2”, 2, 2, false, #time(1, 0, 0), #date(2024, 2, 2) } }) dans

Source

Lorsque vous sélectionnez plusieurs colonnes, dans ce cas les deux (voir figure 11.11),
l'option « Fusionner les colonnes » (2) est activée dans l'onglet « Transformer » (1).
Cette action ouvre la boîte de dialogue correspondante (3).
Machine Translated by Google

Figure 11.11 Fusionner les colonnes via l'interface utilisateur graphique

Une tabulation est sélectionnée comme séparateur dans le menu déroulant.


Après confirmation de l'opération, une nouvelle colonne nommée « Fusionné » remplace
les colonnes d'entrée. Le code M suivant est généré, la culture variant selon votre
région.

laisser

Source = [Link]({ {« 1 », 1, 1, null, true,


#time(12, 0, 0), #date(2024, 1, 1)}, {« 2 », « 2 », 2, 2, false, #time(1, 0, 0), #date(2024, 2, 2) } }), MergedColumns =
[Link]( [Link]( Source, {{« Colonne1 », type texte}, {« Colonne2 », type
texte}},
« en­US »

), {« Colonne 1 », « Colonne 2 »},


[Link]( « #(tab) », [Link] », « Fusionné » ) dans

Colonnes fusionnées

Veuillez noter que si vous souhaitez conserver les colonnes d'entrée, sélectionnez
« Fusionner les colonnes » dans l'onglet « Ajouter une colonne » du ruban. Cependant, cela
générera du code M utilisant la fonction [Link] au lieu d'un combinateur pour
produire une valeur unique. Le langage M propose cinq fonctions de combinateur par
défaut permettant de combiner des valeurs de texte de différentes manières.

[Link]
Cette fonction a deux paramètres : un délimiteur et un quoteStyle facultatif.
Le délimiteur requiert une valeur de type texte définissant le ou les caractères
utilisés comme séparateurs entre les valeurs de texte combinées. Le style
quoteStyle est une énumération qui contrôle le traitement des guillemets dans une chaîne
de texte lors d'opérations telles que la combinaison de texte.
Machine Translated by Google

[Link](“­­­”)( {“a”, “b”, “c”} )

//Résultat : a­­­b­­­c

[Link] signifie que les guillemets d'une chaîne n'ont aucune signification
particulière. Ils sont traités comme n'importe quel autre caractère du texte.

[Link](“_”, [Link])( {“Ceci”, “est”,,”une ““chaîne entre


guillemets”““} )

//Résultat : Ceci _est_une « chaîne entre guillemets »

[Link] signifie que les guillemets doivent être traités comme des caractères spéciaux
pour indiquer le début et la fin d'une chaîne entre guillemets. Les guillemets imbriqués
dans une chaîne sont indiqués par deux guillemets successifs.

[Link](“_”, [Link])( {“Ceci”, “est”,,”une ““chaîne entre


guillemets”““} )

//Résultat : Ceci _est_”une “chaîne entre guillemets”“

[Link] renvoie une fonction applicable à une liste de valeurs


textuelles, les combinant en un seul texte à l'aide des arguments spécifiés. Si vous omettez
l'argument optionnel quoteStyle ou passez une valeur nulle, [Link] sera appliqué par
défaut.

[Link]

Cette fonction a deux paramètres : des délimiteurs sous forme de liste et un quoteStyle facultatif.
La séquence des délimiteurs est déterminée par leur nombre et leur ordre, fournis
comme premier argument. Si le nombre de valeurs textuelles à combiner dépasse le
nombre de délimiteurs, les valeurs textuelles restantes sont combinées sans séparateur.
Le comportement de quoteStyle est équivalent à celui de la fonction
[Link]. Pour éviter d'épuiser les délimiteurs disponibles, vous
pouvez calculer le nombre minimal de délimiteurs requis et le stocker dans une variable. En
adoptant une approche modulaire, créez une fermeture, une fonction qui conserve l'accès aux
variables de sa portée parente, même après la fin de son exécution. Cette capacité unique
à mémoriser son environnement initial distingue une fermeture des autres fonctions et l'invoque
sur la liste d'entrées.

laissez inputList = {“a”, “b”, “c”, “d”, “e”, “f”}, delimiterPattern = {“­­­”, “_”}, delimitersList =
[Link]( delimiterPattern, [Link]( ([Link](inputList)­1) /
[Link](delimiterPattern) ) ), closure = [Link](delimitersList),
Result = closure(inputList) dans

Résultat
Machine Translated by Google

La fonction [Link] renvoie une fonction qui fusionne une liste


de valeurs de texte en un seul texte, en utilisant un nombre et un ordre de délimiteurs spécifiés.

[Link]

Cette fonction possède deux paramètres : une liste de longueurs et un modèle optionnel de texte.
La liste « longueurs » indique le nombre de caractères à extraire de chaque valeur textuelle
correspondante. L'argument optionnel « modèle » définit les caractères initiaux de la sortie
combinée. S'il est omis ou défini à null, la fonction utilise une chaîne d'espaces dont le nombre
correspond à la somme des longueurs spécifiées. Si vous fournissez une chaîne
personnalisée, elle remplace ce modèle par défaut. Un modèle est écrasé par les textes
extraits lors de la combinaison. Si un modèle personnalisé ne contient pas le nombre de
caractères requis, il est complété par des espaces supplémentaires. Cependant, tout caractère
excédentaire d'un modèle apparaîtra dans la sortie finale du texte combiné.

[Link]( { 4, 4, 4, 4 }, "\\\
\^^^^////****")( {"98", "DELTA", "19990110", "NON", "¯\_( )_/¯"} )

//Résultat : 98\\DELT1999NO**

Les caractères excédentaires sont ignorés, tout comme les valeurs de texte supplémentaires pour
lesquelles aucune longueur correspondante n'est fournie. Cependant, si une longueur
dépasse le nombre de caractères, la valeur de texte complète est extraite et le modèle n'est pas
entièrement écrasé.

[Link]

Cette fonction possède deux paramètres : une liste de positions et un modèle optionnel de texte. La
liste « positions » représente le nombre cumulé de caractères à extraire de la valeur textuelle
correspondante. Chaque position suivante doit être égale ou supérieure à la précédente.

[Link]( { 0, 4, 6, 10, 12, 12 },


[Link]( “*”, 14))( {“98”, “DELTA”, “19990110”, “NON”, “¯\_( )_/¯”, “Attendre”, “Quoi”} )

//Résultat : 98**DE1999NOWait

La figure 11.12 illustre le fonctionnement de ce processus :

Figure 11.12 le processus [Link]


Machine Translated by Google

Le « modèle » facultatif est une chaîne définissant un modèle à écraser lors du processus
de combinaison. Lorsque le nombre de caractères à extraire dépasse la longueur de la
valeur de texte correspondante, une partie de ce modèle n'est pas écrasée et est intégrée
au résultat. Les caractères excédentaires sont ignorés. Cependant, si des textes
supplémentaires ne sont pas positionnés, seul le premier texte complet est inclus, les
valeurs de texte suivantes étant exclues.

[Link]

Cette fonction possède deux paramètres : des plages (liste) et un modèle optionnel (texte).
La liste « plage » contient une liste imbriquée de deux valeurs. Une position de
départ indique l'emplacement des caractères dans la chaîne de sortie.
Le nombre de caractères à extraire du texte correspondant ou une valeur nulle indiquant
la chaîne entière doit être inclus. Il est essentiel de noter que si la position d'une extraction
ultérieure chevauche une précédente, cette dernière écrasera la précédente.
Tout élément excédentaire de la liste d'entrée pour lequel aucune plage n'est spécifiée
est ignoré.

[Link]( {{2, 2 }, {6, 4}, {10,


4}, {0, null}}, [Link]( "*", 16))( {"98", "DELTA", "19990110", "NON", "¯\_( )_/¯"} )

//Résultat : NO98**DELT1999**

Le « modèle » facultatif fournit un modèle de chaîne initial qui est écrasé.


Lorsqu'une position de départ dépasse le nombre de caractères extraits à ce point
précis, ou que le nombre de caractères du « modèle » personnalisé dépasse le nombre
de caractères fournis, les caractères du modèle sont intégrés au résultat. Nous avons
abordé les « combineurs » du langage M de Power Query, essentiels pour joindre des
valeurs textuelles en une seule chaîne. Ces combinateurs sont utilisés par des fonctions
d'ordre supérieur telles que [Link] et [Link],
qui utilisent un combinateur pour traiter les lignes d'un tableau, générant une valeur
unique par ligne. L'opération « Fusionner les colonnes » proposée par l'interface
utilisateur graphique en est un parfait exemple. Nous avons également fourni des extraits
de code pratiques pour fusionner efficacement des valeurs textuelles pour chaque fonction
de combinateur par défaut du langage M. Ces exemples, à la fois informatifs et
exécutables, constituent une référence précieuse pour explorer leurs fonctionnalités.

Séparateurs

Dans le langage Power Query M, les séparateurs permettent de séparer une chaîne en une
liste de valeurs textuelles selon un délimiteur ou un modèle spécifique. Ils sont souvent
utilisés par des fonctions de bibliothèque standard d'ordre supérieur,
telles que [Link], conçue pour diviser une colonne en plusieurs
colonnes ou lignes. Il s'agit d'une opération courante, fréquemment utilisée lors du
traitement de chaînes nécessitant une analyse ou une transformation. Lorsque vous
sélectionnez une colonne contenant des valeurs textuelles, le bouton « Split Column » est
activé dans l'interface utilisateur graphique. Vous le trouverez sur les pages d'accueil et
Machine Translated by Google

Transformez les onglets du ruban. Cela appelle la fonction [Link], utilisant l'un des nombreux
séparateurs par défaut selon la sélection de l'utilisateur, ici « Par délimiteur ». Prenons par exemple ce
tableau (Figure 11.13) où nous souhaitons diviser « Colonne 1 » en colonnes.

Figure 11.13 Exemple de données

Voici comment procéder à l’aide de l’interface utilisateur graphique.

• Sélectionnez la colonne « Colonne 1 » du tableau. •


Accédez à l'onglet « Accueil » ou « Transformer » sur le ruban et choisissez « Fractionner la
colonne ». • Une
boîte de dialogue apparaîtra, sélectionnez Personnalisé, entrez une virgule suivie d'un
espace.
• Ouvrez les « Options avancées » divisées en « Colonnes » et « 2 » est correct.
Confirmer.

Une étape « Split Column by Delimiter » est ajoutée à la requête, ce qui donne lieu à une table
modifiée (Figure 11.14) où « Column1.2 » a été ajouté avec « World » dans la première cellule de
cette nouvelle colonne.

Figure 11.14 Résultat de cette opération de fractionnement de colonne

Lors de l'inspection du code M dans la barre de formule, vous pouvez voir que la fonction
[Link] d'ordre supérieur est invoquée et qu'elle a fourni tous les arguments de texte requis
à la fonction interne [Link](“, “, [Link]).

laissez Source = [Link]( {“Bonjour le monde”,


“Power Query”}, [Link]() ), #”Diviser la colonne par délimiteur”
= [Link](Source,
Machine Translated by Google

« Colonne 1 »,
[Link](“, “, [Link]), {“Colonne 1.1”, “Colonne 1.2”} ) dans

#« Diviser la colonne par délimiteur »

Les fonctions de séparation sont polyvalentes, ce qui en fait un outil puissant pour
la manipulation de texte. Chacune produit une valeur de fonction lorsqu'elle est invoquée.
Pour utiliser efficacement une fonction de séparation, il est préférable de la définir
d'abord en spécifiant les arguments, puis d'appeler la fonction renvoyée, également appelée
fermeture, en passant la chaîne de texte à séparer. La fonction renvoyée, ou fermeture,
effectue l'opération de séparation proprement dite. Ce processus en deux étapes offre
une plus grande flexibilité : vous pouvez définir la fonction une fois avec des
arguments spécifiques et la réutiliser plusieurs fois avec différentes chaînes de texte. Cela
la rend efficace pour le traitement de texte par lots. Explorons maintenant les caractéristiques
spécifiques de chaque fonction de séparation. Le langage M propose dix fonctions de
séparation par défaut. Quatre d'entre elles acceptent un
paramètre optionnel quoteStyle. Il s'agit de : [Link],
[Link], [Link] et [Link].
Ce paramètre est une énumération qui régit la gestion des guillemets dans une chaîne
lors d'une opération de fractionnement. [Link] indique que les
guillemets dans une chaîne n'ont aucune signification particulière et sont traités comme
n'importe quel autre caractère du texte. [Link] implique que les guillemets
doivent être considérés comme un caractère spécial pour indiquer le début et la fin
d'une chaîne entre guillemets. Les guillemets imbriqués dans la chaîne sont
représentés par deux guillemets consécutifs. Si vous omettez l'argument facultatif
quoteStyle ou passez une valeur nulle, [Link] sera utilisé par défaut.

Sé[Link]

Cette fonction n'a pas de paramètres. Lorsqu'elle est appelée, elle renvoie une
fonction spécialement conçue pour gérer le fractionnement dans les opérations Power
Query, tout en préservant la structure de données prévue. Pour ce faire, son
argument est encapsulé dans une liste, créant ainsi une liste à élément unique qui
empêche le fractionnement. Cela garantit que les données ne sont pas affectées
par le fractionnement des fonctions d'ordre supérieur. Par défaut, Power
Query utilise des virgules comme séparateurs. Par exemple, si nous avons deux
éléments dans une liste et que nous souhaitons la convertir en un tableau à une seule
colonne, nous pouvons utiliser la fonction [Link]. Cependant, l'exécution du code
de la figure 11.15 entraîne le fractionnement de chaque chaîne en colonnes, renvoyant
un tableau de deux colonnes.
Machine Translated by Google

Figure 11.15 : division par défaut par [Link]

Pour ajuster ce comportement de division, [Link] peut être appelé.


Cette fonction encapsule chaque valeur dans une liste, garantissant que chaque chaîne est traitée
comme un élément individuel, renvoyant un tableau à une seule colonne, comme illustré dans la
Figure 11.16.

Figure 11.16 remplaçant le comportement de fractionnement par défaut

Voici le code de ces exemples, ainsi qu'un autre qui démontre le processus d'encapsulation en
plaçant son argument dans une liste, créant ainsi une liste à élément unique empêchant toute
opération de fractionnement.

laissez defaultBehaviour = [Link]( {« Bonjour tout le monde »,


« Power Query »} ), modifiedBehaviour = [Link]( {« Bonjour tout le
monde »,
« Power Query »}, [Link]() ), encapsulatingElements=
[Link]( {« Bonjour tout le monde », « Power Query »},
[Link]() )

dans

encapsulationElements

[Link]
Machine Translated by Google

Cette fonction possède trois paramètres : des délimiteurs sous forme de liste, un
quoteStyle facultatif et un startAtEnd facultatif. Elle renvoie une fonction applicable à une
valeur texte, la divisant en une liste de valeurs texte selon les arguments spécifiés.
L'argument « Delimiters » est obligatoire et prend une liste de valeurs textuelles servant
chacune de délimiteur pour l'opération de fractionnement. Ces délimiteurs peuvent être
composés d'un ou de plusieurs caractères, et la fonction fractionne le texte à chaque
occurrence d'un délimiteur. L'argument « quoteStyle » est facultatif et spécifie la gestion
des guillemets dans le texte. Il accepte deux valeurs : [Link] et
[Link]. Le premier inclut les guillemets dans le résultat, tandis que le second les
ignore. L'argument « startAtEnd » est également facultatif et prend une valeur booléenne.
Lorsqu'il est défini sur « true », la fonction inverse le sens de fractionnement et démarre
l'opération à la fin de la chaîne de texte, ce qui peut produire un résultat différent dans
certains cas, comme illustré ici.

laisser

string = « pomme, » « orange, banane; raisin » « , mangue » « », splitFunction = [Link]( {“, ,”;”},
[Link], true ), result = splitFunction(string) in

résultat // startAtEnd

true: {“pomme,orange”, “banane”, “raisin,mangue”} // startAtEnd false: {“pomme”, “orange,banane,raisin, “mangue”}

Ici, l'argument startAtEnd est utile lorsqu'une chaîne de texte est asymétrique
ou contient des guillemets qui la rendent non uniforme. Dans ce cas, démarrer l'opération
de division depuis la fin peut produire un résultat différent, offrant ainsi un niveau de
contrôle supplémentaire sur le processus de manipulation du texte.

Sé[Link]

Cette fonction possède deux paramètres : un « avant » et un « après », qui peuvent être
soit une liste de caractères, soit une fonction évaluant un caractère et renvoyant vrai/
faux. Comme tous les autres séparateurs, elle génère une nouvelle fonction, conçue ici
pour segmenter du texte en une liste en fonction de la transition entre les
caractères. Cela permet de diviser du texte à chaque passage d'un caractère « avant »
à un caractère « après », ce qui implique que les deux conditions doivent être remplies.

laisser

string = « Abc1234Abc1234 », isEven = (char) => essayez


[Link]( [Link](char)) sinon
faux, splitFunction = [Link]( chaque vrai, isEven

), résultat =
splitFunction(chaîne) dans le résultat

//Sortie : {« Abc1 », « 23 », « 4Abc1 », « 23 », « 4 »}


Machine Translated by Google

Le paramètre « before » est défini pour toujours renvoyer « true » pour tout caractère. Le
paramètre « after » utilise la fonction « isEven » pour vérifier si un caractère représente un
nombre pair. Lorsque les deux conditions sont remplies, la chaîne est divisée, garantissant
que le texte d'entrée est séparé avant chaque caractère représentant un nombre pair. Bien
entendu, la fonction « isEven » peut être remplacée par une liste contenant uniquement
des nombres pairs, comme {« 0 », « 2 », « 4 », « 6 », « 8 »}, pour obtenir le même résultat.
Lorsque des fonctions sont utilisées comme arguments, il est important de gérer les
exceptions. Dans cet exemple, les mots­clés « try » et « otherwise » sont utilisés pour
empêcher l'échec de la fonction lorsqu'elle tente de convertir un caractère non numérique en
nombre. La possibilité d'utiliser des fonctions comme paramètres dans
[Link] étend
considérablement son utilité.
Permettant des scénarios de division de texte plus complexes adaptés pour répondre à des
exigences spécifiques.

Sé[Link]

Cette fonction a deux paramètres : un délimiteur sous forme de texte et un quoteStyle facultatif.
Le délimiteur requiert une valeur de type texte définissant le ou les caractères utilisés
comme séparateurs pour diviser la chaîne de texte. L'attribut quoteStyle est une énumération
qui détermine la gestion des guillemets lors du fractionnement. Contrairement à la fonction
[Link], cette fonction n'accepte pas de liste de délimiteurs et n'inclut
pas de paramètre startAtEnd, ce qui la rend moins flexible mais plus simple.

Comparé à la fonction [Link] étroitement liée, la caractéristique distinctive de


[Link] est sa capacité à gérer les styles de citation.
Cependant, si vous n'avez pas besoin de [Link], la simplicité et la convivialité de
[Link] en font un choix idéal pour toutes les tâches de fractionnement de texte de base.

laissez string = « pomme, » « orange, banane; raisin » « , mangue » « », splitFunction =


[Link]( « , », [Link] ), result = splitFunction(string) in

résultat
//Sortie : {« pomme », « orange », « banane ; raisin » « », « mangue » « }

Dans ce cas, le fractionnement utilise une virgule comme délimiteur. L'énumération


[Link] indique que les guillemets dans le texte ne doivent pas être considérés comme
des caractères spéciaux lors du fractionnement. Par conséquent, la chaîne d'entrée est divisée à
chaque virgule, ignorant les guillemets. Cependant, si vous remplacez quoteStyle par
[Link], tout texte entre guillemets est considéré comme une seule unité, même
s'il inclut le délimiteur choisi ; une telle chaîne ne sera pas affectée par le fractionnement.

Sé[Link]
Machine Translated by Google

Cette fonction possède trois paramètres : des délimiteurs (liste), un style de citation (optionnel)
et un paramètre startAtEnd (optionnel). La séquence et le nombre de délimiteurs fournis en
premier argument déterminent où et combien de fois une chaîne de texte est divisée. Le
comportement de quoteStyle et startAtEnd est équivalent à celui décrit précédemment.

laissez

la chaîne = « pomme », « orange, banane ; raisin », « mangue », splitFunction = [Link]( {« , »,


« ; »}, [Link], true

), résultat
= splitFunction(chaîne) dans le résultat

//Sortie : {« pomme », « orange, banane », « raisin », « mangue »}

Dans ce cas, startAtEnd est défini sur true, ce qui indique que la fonction lance le
fractionnement à partir de la fin de la chaîne de texte. Elle suit ensuite l'ordre précis et le
nombre de délimiteurs fournis pour diriger le processus de fractionnement.

Sé[Link]

Cette fonction a deux paramètres : les longueurs sous forme de liste et startAtEnd facultatif.
Longueurs est une liste contenant des nombres positifs représentant la longueur de chaque
segment à diviser dans un texte. Le paramètre startAtEnd est une valeur booléenne
facultative qui, si elle est définie sur « true », permet d'inverser le sens de division, de la fin
à la fin. La fonction renvoyée peut être appliquée à une valeur texte. Elle divise son entrée
selon la direction et les longueurs spécifiées pour produire une liste de valeurs texte.

laisser

chaîne = « pomme », « orange, banane ; raisin », « mangue », longueurs = {5, 1, 1, 6, 1, 6, 1, 5, 1},


splitFunction = [Link]( longueurs, false ), résultat =
splitFunction(chaîne) dans

résultat
//Sortie : {« pomme », « », « « », « orange », « », « banane », « ; », « raisin », « « }

Les caractères pour lesquels aucune longueur correspondante n'est fournie sont ignorés.
Cependant, si la longueur dépasse le nombre total de caractères, un élément de liste de
zéro caractère est ajouté pour chaque élément excédentaire, sans générer d'erreur. La
fonction [Link] est particulièrement utile pour gérer des chaînes de
caractères provenant de bases de données ou de fichiers plats avec une largeur fixe
prédéfinie pour chaque champ ou colonne. Cela garantit que chaque champ occupe un nombre
cohérent de caractères, simplifiant ainsi le processus d'analyse et de manipulation
des données. L'identification des données à largeur fixe est simple.
Accédez à l'onglet « Affichage » et activez « Monospace ». Ce paramètre modifie la police en
une police où chaque caractère occupe la même quantité de
Machine Translated by Google

Espace horizontal. Si un espace égal a été attribué aux champs ou aux colonnes, il
devrait désormais être clairement visible.

Sé[Link]

Cette fonction a deux paramètres : les positions sous forme de liste et startAtEnd facultatif.
La liste « positions » représente un nombre cumulé de caractères pour la division.
Chaque élément de la liste « positions » doit correspondre ou dépasser le précédent et
ne peut pas être négatif.

laisser

chaîne = « pomme », « orange, banane ; raisin », « mangue », positions = {0, 5, 5, 6, 7, 13}, splitFunction
= [Link]( positions, false

), résultat
= splitFunction(chaîne) dans

résultat
//Sortie : {« pomme », « », « », « », « « », « orange », « ,banane ; raisin » « ,mangue » « »}

Lorsque le dernier élément de la liste des positions comporte moins de caractères que le
nombre total de caractères, tous les caractères restants de la chaîne sont inclus.
Cependant, pour chaque élément de la liste des positions dépassant le nombre total de
caractères, un élément de zéro caractère est ajouté à la liste de résultats, sans générer d'erreur.

Sé[Link]

Cette fonction a deux paramètres : des plages sous forme de liste et startAtEnd facultatif.
La liste des plages, qui contient des listes imbriquées à deux valeurs, détermine l'ordre
de sortie. Ces valeurs représentent une position de départ et le nombre de caractères à
récupérer, ou une valeur nulle pour inclure tous les caractères restants de la chaîne. Si
les positions de fractionnement chevauchent une position précédente, la fonction récupère
à nouveau ce segment de texte.

laisser

chaîne = « pomme », « orange, banane ; raisin », « mangue », plages = {{14, null}, {0, 5}, {3, 2}, {7, 6}},
splitFunction = [Link](

plages, faux

), résultat
= splitFunction(chaîne) dans

résultat
//Sortie : {« banane ; raisin » « mangue » « », « pomme », « le », « orange »}

Pour chaque élément de la liste des plages où la position dépasse le nombre total
de caractères, un élément avec zéro caractère est ajouté à la liste de résultats, sans
générer d'erreur.

Sé[Link]
Machine Translated by Google

Cette fonction possède deux paramètres : length (un nombre) et startAtEnd


(facultatif). Length est un nombre positif représentant la longueur du segment à diviser. Le
paramètre startAtEnd est une valeur booléenne facultative qui, si elle est définie sur true, permet
d'inverser le sens de division. La fonction renvoyée peut être appliquée à une valeur de texte,
en la divisant selon le sens et la longueur spécifiés, afin de générer une liste de valeurs de
texte.
Contrairement à [Link], cette fonction ne prend pas de liste de
longueurs, ce qui la rend moins flexible mais plus conviviale pour diviser des tâches avec
une longueur cohérente.

laissez string = « pomme, » « orange, banane; raisin » « , mangue » « », splitFunction =


[Link]( 10, false ), result = splitFunction(string) in

résultat
//Sortie : {"pomme", "ora", "nge,banane", ";raisin"""",ma", "ong"""}

Il n'y a pas de capacité de remplissage, par conséquent l'élément final de la liste de résultats
peut être constitué de moins de caractères que la longueur spécifiée.

Sé[Link]

Cette fonction possède un paramètre : quoteStyle (facultatif). Elle renvoie une fonction qui
divise le texte en une liste à chaque espace. Dans le langage Power Query M, les
espaces englobent divers caractères, notamment les espaces et les caractères de contrôle
tels que les retours chariot, les sauts de ligne et les tabulations. Le paramètre quoteStyle
est facultatif et spécifie le traitement des guillemets dans le texte. [Link] inclut
les guillemets car il les traite comme n'importe quel autre caractère, tandis que [Link]
les ignore ; une section entre guillemets ne sera pas séparée.

laissez la chaîne = « A#(000D) B#(tab) C#(lf)D#(cr,lf)


E#(cr)F#(lf)1#(0000000D)”, splitFunction =
[Link](), result = splitFunction(string) dans le résultat //Sortie : {« A », « B », « C »,
« D », « E », « F », « 1 », « »}

Dans les valeurs textuelles, une séquence d'échappement est nécessaire pour insérer
des caractères de contrôle. Par exemple, pour insérer un retour chariot, vous pouvez utiliser
sa valeur courte à 4 chiffres hexadécimaux #(000D), sa valeur longue à 8 chiffres
hexadécimaux #(0000000D) ou le raccourci d'échappement compact #(cr). En général, le
raccourci d'échappement est privilégié. Ainsi, pour une tabulation, on utilise #(tab) et pour un saut de ligne, #(lf).
Plusieurs codes d'échappement peuvent être inclus dans une séquence d'échappement,
séparés par des virgules, comme dans #(cr,lf), équivalent à #(cr)#(lf). Les séparateurs sont
utiles pour diviser une chaîne en parties plus petites selon un modèle, un délimiteur,
une longueur ou des positions spécifiques. Ils sont couramment utilisés dans les
scénarios impliquant l'analyse de chaînes contenant des valeurs combinées, telles que
Machine Translated by Google

Dans un fichier CSV, un fichier texte délimité ou des chaînes contenant d'autres valeurs intéressantes,
comme des dates ou des nombres. Les extraits de code fournis sont destinés à servir de référence et
à explorer leurs fonctionnalités.

Exemples pratiques
Jusqu'à présent, vous avez acquis une compréhension des différents comparateurs,
remplaçants, combinateurs et séparateurs disponibles dans le langage M. Maintenant, avec ces
connaissances fondamentales, il est temps de consolider votre apprentissage grâce à des
exemples pratiques qui démontrent leur utilisation dans des scénarios réels.
Ces exemples vous permettront de mieux comprendre comment intégrer ces fonctions à vos propres
workflows. N'hésitez pas à élaborer votre propre stratégie pour ces scénarios avant de vous y plonger.
Si vous n'êtes pas encore à l'aise avec la traduction en code M, ce n'est pas un
problème. Vous pouvez néanmoins formuler un plan et envisager les obstacles potentiels à
surmonter. Cela vous permettra de comparer votre approche avec celle proposée ici.

Cependant, gardez à l’esprit qu’il existe de nombreuses solutions à un problème donné ; ce


livre ne présente qu’une seule méthode possible.

Scénario 1. La tâche.

Une tâche courante lors du nettoyage et de la transformation de chaînes de texte consiste à


supprimer les caractères de contrôle et les espaces superflus. Contrairement à la fonction de rognage
d'Excel, son équivalent dans Power Query, [Link], supprime uniquement les espaces de début et
de fin d'une valeur texte.

Scénario 1. Une solution.

Créons notre propre fonction, cleanTrim, capable de tout faire. Améliorez [Link] pour
supprimer les caractères de contrôle et les espaces superflus dans une chaîne. C'est le domaine de la
fonction [Link], qui divise un texte à chaque espace et renvoie une liste de
valeurs textuelles.

(chaîne sous forme de texte) sous forme de


texte =>

[Link]( [Link]( [Link]()( chaîne ), “ “ ) )

En M, les espaces blancs englobent à la fois les espaces et les caractères de contrôle. Lorsque le
séparateur est appelé, il renvoie une liste de valeurs textuelles, qui peuvent être combinées avec un
espace unique pour être reconverties en chaîne. Des fonctions comme
[Link] ou [Link], par exemple, donnent le même résultat.
Cependant, il est important de comprendre que si la liste contient une chaîne de texte vide comme
élément initial ou final, une opération de combinaison insérera un espace avant ou après. Ce
problème peut être résolu avec [Link]. Il est important de noter que, d'après des tests limités, une
opération de découpage sur l'entrée « chaîne » interne n'a pas d'impact significatif sur les performances.
Machine Translated by Google

par rapport à son application à la production combinée, comme démontré ici.

Scénario 2. La tâche.

Outre le nettoyage et la transformation des chaînes de texte, il est tout aussi important de
pouvoir extraire une partie spécifique d'une chaîne. Bien qu'il existe de nombreux types
de scénarios différents et qu'il n'existe pas de solution universelle, la
compréhension des séparateurs peut s'avérer stratégiquement utile. Notre prochaine
tâche consiste à extraire ce qui semble être des adresses e­mail valides à partir de cet échantillon de données.

laisser

Source = [Link]( { {« Wendy Darling,


Royaume­Uni,
[Link]@[Link] »}, {« [Link]@[Link], Royaume­Uni ; [Link]@[Link] »}, {« michael ;
[Link]@nevergrowup »}, {« Peter Pan [Link]@[Link] »}, {« tink@pixie@[Link] la Fée Clochette »}, {« Capitaine
Crochet : [Link]@[Link] »} }, tapez table [Contact info=text] ) dans

Source

Scénario 2. Une solution.

L'examen de cet exemple révèle que les lignes trois et cinq sont structurellement invalides, soit
en raison d'un domaine manquant, soit de la présence de plusieurs symboles « @ »
dans l'adresse. Il est également important de noter que plusieurs séparateurs sont
nécessaires pour segmenter efficacement chaque chaîne. Notre
objectif final est de créer une fonction getEmail personnalisée.
Cependant, nous devons d'abord développer une logique permettant d'exclure et d'extraire
les adresses e­mail de ces entrées. Cliquez sur l'icône du mini­tableau située à gauche
de l'en­tête de la colonne « Informations de contact » et sélectionnez « Ajouter une colonne
personnalisée ». Nous élaborerons progressivement une solution en examinant
les résultats intermédiaires.

• Dans la boîte de dialogue, vous pouvez éventuellement attribuer un autre nom à


cette colonne, comme il s'agit simplement d'une colonne temporaire, nous la
laisserons telle quelle. • Entrez [Link]() dans la section
de formule car plusieurs séparateurs sont
nécessaires. • Dans les parenthèses, incluez une liste avec tous les séparateurs
distinctifs : {“ “, “,”, “;”, “:”} • Pour
exécuter cette fonction, ajoutez un autre ensemble de parenthèses après la
parenthèse fermante et choisissez le champ Informations de contact dans la
section des colonnes disponibles.
• Formaté ici pour plus de lisibilité, mais dans la barre de formule, le généré
le code par ces actions ressemblera à ceci.

[Link](Source, « Personnalisé », chaque


[Link]( {“ “, “,”, “;”, “:”}

)([Coordonnées]) )
Machine Translated by Google

• Prévisualisez le contenu des listes de sortie en cliquant sur l'espace blanc à côté de ces
valeurs de liste imbriquées. Par exemple, les valeurs de la liste de la deuxième
ligne sont : { « [Link]@[Link] », « », « UK »,
« [Link]@[Link] »}. •
Ces listes nécessitent un filtrage. Pour ce faire, revenez à la boîte de dialogue Colonne
personnalisée en cliquant sur l'icône en forme d'engrenage située à droite du nom de
l'étape dans la section Étapes appliquées du volet Paramètres de la requête. • Devant
la formule, ajoutez : [Link]( Ensuite, continuez jusqu'à la fin, saisissez une virgule
suivie d'une parenthèse fermante ')'. Vous verrez un avertissement indiquant qu'une
virgule ne peut pas précéder une parenthèse fermante. Il est temps de
spécifier un argument « sélection en tant que fonction ». • Une adresse e­mail
structurellement valide doit inclure le symbole @, suivi d'un point (.), dans cet ordre. Nous
pouvons donc tenter de diviser à nouveau chaque élément de la liste en utilisant
[Link] avec cet argument {“@”, “.”}. Pour l'invoquer, ajoutez
une paire de parenthèses avec le trait de soulignement (_). • Bien que cela résolve
l'avertissement
d'erreur, notre expression n'est pas
complet. Ce séparateur produira une nouvelle liste, mais nous ne nous intéressons
qu'aux listes contenant trois éléments. Par conséquent, ajoutez [Link]( … ) = 3.
Le code dans la zone de formule devrait ressembler à ceci.

[Link]( [Link]( {“ “, “,”, “;”, “:”}

)([Coordonnées]), chaque

[Link]( [Link]( {“@”, “.”} )(_) ) =3 )

• Prévisualisez à nouveau le contenu en cliquant sur l'espace vide à côté des valeurs de la
liste imbriquée. Des critères supplémentaires sont nécessaires pour exclure les
adresses e­mail structurellement invalides. Par exemple, les cas qui incluent plusieurs
symboles « @ », ou les cas où le symbole « @ » est immédiatement suivi d'un point
(.), doivent encore être traités. • Pour ce faire, revenez à la boîte de dialogue
Colonne personnalisée en cliquant sur l'icône en forme de roue dentée. Développez la
sélection comme argument de fonction en saisissant le mot­clé « and » suivi de
cette expression : [Link]( [Link](_, « @ »)) = 1. Cela résout
un problème potentiel. Pour résoudre l'autre, saisissez un autre mot­clé « and »
suivi de : not [Link](_, « @. ») comme indiqué ici.

[Link]( [Link]( {“ “, “,”, “;”, “:”})


( [Coordonnées]), chaque

[Link]( [Link]( {“@”, “.”} )(_) ) = 3 et


[Link]( [Link](_, “@”)) = 1
et non
[Link](_,
“@.”)
Machine Translated by Google

• L'étape finale consiste à extraire et à combiner les éléments restants de la liste. Ouvrez la
boîte de dialogue et entourez­la de [Link]( …, “, “).
Une fois satisfait du résultat, vous pouvez copier le code M dans son intégralité. • Choisissez
« Nouvelle source », puis
« Requête vide ». Supprimez le « let » par défaut.
expression et remplacez­la par le code copié. Pour transformer ce code en requête de fonction
personnalisée, nous devons commencer cette expression par un initialiseur de fonction.
Positionnez votre curseur avant le code et ajoutez : (string as text) as text =>

Cette fonction prend une entrée de type texte et génère une valeur de type texte : (chaîne de
caractères) (texte). Le paramètre d'entrée est nommé « chaîne » et non « [Coordonnées] ».
Remplacez­le, fermez cette requête et attribuez­lui un nom approprié, par exemple : getEmail.

(chaîne comme texte) comme texte =>

[Link]( [Link]( [Link]( {“ “, “,”, “;”, “:”} )


(chaîne), chaque [Link]( [Link]( {“@”,
“.”} )(_) ) = 3 et
[Link]( [Link](_, “@”)) = 1 et non
[Link](_, “@.”) ), “, “ )

Vérifiez la fonctionnalité de cette fonction personnalisée en l’appliquant aux données d’exemple et en


comparant les résultats avec la sortie de la colonne personnalisée.
Sélectionnez simplement « Invoquer une fonction personnalisée » dans l’onglet « Ajouter une colonne »
du ruban et attribuez un argument à chaque entrée.

Scénario 3. La tâche.

Le fractionnement de valeurs de cellules combinées est une opération courante lorsqu'il s'agit de
traiter des données stockées dans une seule cellule. Ce processus est simple et s'effectue en
sélectionnant « Fractionner la colonne » dans le ruban de l'interface utilisateur graphique.
En ajustant les paramètres nécessaires dans la boîte de dialogue, vous pouvez facilement séparer
les valeurs de cellules combinées en plusieurs colonnes ou lignes (voir les options avancées).
Cependant, si vous rencontrez plusieurs colonnes contenant des valeurs de cellules combinées devant
être séparées en lignes, répéter cette procédure peut ne pas produire le résultat escompté.

Considérez ce scénario, illustré à la figure 11.17. Les colonnes « Priorité » et « Planification »


doivent être séparées en lignes.

laisser

Données = [ p =
[Link]( {“1”..”3”} ) & “4”, c = “W01”, s1 =

[Link]( [Link]( {“24x7 #(cr,lf)”}, 3) & {“““8x5 (9:00 ­ 17:00)”““} ),


Machine Translated by Google

s2 = [Link]( Liste.Répéter( {“““9x5 (9:00 ­ 18:00)”““} & {“#(lf,cr)”}, 3) & {“““9x5 (9:00 ­ 18:00)”““} ), s3 =
[Link]( Liste.Répéter( {“““ “““} & {“#(lf)”}, 2) & {“““9x5 (9:00 ­ 18:00)”““} & {“#(cr)”} & {“““9x5 (9:00 ­
18:00)”““}) ], Source = [Link]( { [ID = “A”, Code=Data[c], Priorité = Data[p], Planning = Data[s1]], [ID = “B”,
Code=Data[c], Priorité = Data[p], Horaire = Données[s2]], [ID = « C », Code = Données[c], Priorité = Données[p], Horaire = Données[s3]] }, tapez
table
[ID = texte, Code = texte, Priorité = texte, Horaire = texte] )
dans

Source

Figure 11.17 : exemples de données de valeurs de cellules combinées

Pour suivre les étapes décrites dans la section suivante, veuillez transférer le code fourni pour cet exemple
dans une nouvelle requête vide.

Scénario 3. Une solution.

Il s'agit clairement de caractères d'espacement, souvent invisibles (non graphiques). Il s'agit notamment de
l'espace (élément de la classe Unicode Zs), des tabulations horizontales et verticales, des sauts de
page et des séquences de caractères de nouvelle ligne.
Les séquences de nouvelle ligne comprennent le retour chariot, le saut de ligne, une combinaison de retour
chariot et de saut de ligne, la ligne suivante et les caractères de séparation de paragraphe.
Il peut s'agir d'artefacts provenant de l'extraction de données ou de la saisie utilisateur. Dans la section
précédente de ce chapitre, nous avons exploré comment les séparateurs génèrent une fonction permettant de
diviser une chaîne de texte en une liste de valeurs textuelles. La fonction [Link]
permet de séparer et ainsi d'éliminer les espaces d'une chaîne. Son style de citation optionnel spécifie le
traitement des guillemets dans le texte. Par défaut, [Link] est appliqué, ignorant les chaînes entre
guillemets afin qu'elles ne soient pas affectées par le processus de fractionnement. Dans l'onglet « Ajouter
une colonne » du ruban, sélectionnez « Colonne personnalisée ». Dans la boîte de dialogue, saisissez
« temp » comme nom de la nouvelle colonne. N'oubliez pas que l'expression d'invocation est un ensemble
de parenthèses pouvant inclure une liste d'arguments optionnels, ce qui déclenche l'appel de la fonction. Pour
la formule de colonne personnalisée, nous pouvons saisir [Link]() pour
lancer le séparateur et recevoir ses
Machine Translated by Google

Valeur de retour, qui est une nouvelle fonction. Nous pouvons ensuite ajouter une autre
expression d'invocation et sélectionner « schedule » dans la section « Colonnes disponibles » à
droite, comme illustré à la figure 11.18.

Figure 11.18 Boîte de dialogue Colonne personnalisée

La nouvelle colonne « Temp » contient une liste de valeurs textuelles. En cliquant sur l'espace
vide à côté d'une valeur de liste, un aperçu secondaire apparaît, offrant une vue limitée du contenu
de la liste. Ce processus peut également être répété pour la colonne « Priorité », mais la gestion
de plusieurs colonnes de liste peut s'avérer complexe, car le développement de chaque colonne
séparément peut entraîner une duplication indésirable de lignes dans une table. En
consolidant toutes les listes en une seule table, nous pouvons créer une structure unique qui
simplifie et contrôle le processus de développement. Dans la section « Étapes appliquées » des
paramètres de requête, cliquez sur l'icône en forme de roue dentée visible à l'étape « Personnalisé
ajouté » pour rouvrir la boîte de dialogue Colonne personnalisée. Nous allons modifier le
code pour créer une table incluant les valeurs des colonnes « Priorité » et « Planification ». Le
code M est illustré à la figure 11.19.
Machine Translated by Google

Figure 11.19 Mise à jour du code dans la boîte de dialogue Colonne personnalisée

Pour créer une table à partir de plusieurs listes, utilisez la fonction [Link].
Comme premier argument, spécifiez une liste de listes séparées par des virgules représentant
les valeurs des colonnes. Comme second argument, facultatif, indiquez une liste de noms de
colonnes. Suivre ces étapes créera une table. Terminé. Nous pouvons également attribuer des
types de colonnes à cette table imbriquée, évitant ainsi une étape de modification
ultérieure du type. Dans la barre de formule, entre les parenthèses fermantes des
fonctions [Link] et [Link], commencez par insérer une virgule,
suivie de « type table », puis un enregistrement de paramètre de type listant chaque colonne
par son nom et son type, comme ceci : type table [Priority = text, Schedule = text]. Avant
de développer la table imbriquée dans la colonne « temp », nettoyons les colonnes Priority
et Schedule d'origine.
Il existe plusieurs méthodes pour y parvenir, comme supprimer ou sélectionner des colonnes.
Cependant, comme nous ne nous intéressons qu'à trois colonnes, la projection est la
méthode la plus simple. Ce concept est abordé en détail au chapitre 6 de ce livre. Dans la
barre de formule, après la parenthèse fermante de la fonction [Link],
insérez des crochets. À l'intérieur de ces crochets, sélectionnez chaque colonne à
conserver en référençant son nom entre d'autres crochets. Par exemple : [[ID], [Code],
[temp]]. Enfin, extrayez les champs en développant la table imbriquée dans la colonne
« temp », à l'aide des flèches latérales disponibles dans l'en­tête. Voici les étapes traduites
en code M. Pour intégrer cela à l'exemple de code fourni, une virgule doit être placée
directement après la parenthèse fermante de la fonction [Link] à l'étape Source,
qui se trouve sur la première ligne. La clause in et la variable Source suivantes doivent
être omises lors de l'intégration de ce code.

# « Ajout personnalisé » = [Link]( Source, « temp », chaque

[Link]( { [Link]()([Priorité]),
Machine Translated by Google

[Link]()([Calendrier])
}, {« Priorité », « Planification »} ), type table [Priorité = texte,

Planification = texte] )[[ID], [Code], [temp]], # « Température étendue » = [Link](# « Personnalisé ajouté », « temp »,
{« Priorité », « Planification »}, {« Priorité », « Planification »} ) dans # « Température étendue »

Le résultat est une table transformée qui ressemble à ceci.

Figure 11.20 Valeurs de cellules combinées divisées en lignes

Scénario 4. La tâche.

Une question fréquemment posée sur de nombreux forums est la suivante : « Dans mon
projet en cours, je gère un ensemble de données nécessitant des remplacements de valeurs
importants sur de nombreuses colonnes. J'utilise des étapes de remplacement de valeurs
individuelles, ce qui rend la requête lente et complexe. Existe­t­il une méthode plus
efficace pour gérer les remplacements en masse ? » Voici notre exemple de jeu de
données. Vous pouvez transférer ce code dans l'éditeur avancé et renommer cette requête en
« rawData ».

laisser

rawData = [Link]( { {1..3}, {« Produit A, 5


pièces »,
« Produit B, Qté : 10 »,
« Produit C ; Quantité : 2 »}, {« Produit A, 5 pièces », « Produit B, Qté : 10 », « Produit C ; Quantité : 2 »}, {« Produit A, 5 pièces », « Produit
B, Qté : 10 », « Produit C ; Quantité : 2 »}, {« Produit A, 5 pièces », « Produit B, Qté : 10 », « Produit C ; Quantité : 2 »} }, type table
[ ID=[Link], Description=texte, Description2=texte, Description3=texte, Description4=texte, Description5=texte ] ), reSized =
[Link]( rawData, 100 ) dans

redimensionné
Machine Translated by Google

La requête suivante génère une table « Remplacements », qui permet de visualiser le


processus de remplacement. La colonne « Ancien » contient la valeur « oldValue »,
une sous­chaîne que nous souhaitons remplacer par la valeur « newValue » de la colonne
« Nouveau » adjacente.

laisser

Source = [Link]( {{“Prdct”, “Product”}, {“pcs”,


“pieces”}, {“Qty”, “Quantity”}}, type table [Old=text, New=text] ) dans

Source

Scénario 4. Une solution.

Bien que notre requête de solution n'exploite pas la table « Remplacements » présentée
précédemment, nous utiliserons deux listes représentant chacune des colonnes de cette table.
Cela signifie que les valeurs oldValue et newValue doivent être alignées et partager le même
index de position dans leurs listes respectives. Nous utiliserons la fonction plus avancée
[Link], qui sera abordée en détail au chapitre 14 de ce livre. Détaillons cette
solution.

laissez

Old = [Link]({“Prdct”, “pcs”, “Qty” }), New = [Link]({“Product”, “pieces”, “Quantity”}), Replacer =
[Link]( {0..[Link](Old)­1}, rawData, (s, a) => [Link](

s, Old{a}, New{a}, [Link],


[Link]([Link](rawData), each
[Link](_, “Description”) ) ) ) dans

Remplaçant

L'objectif de cette requête est de substituer des sous­chaînes spécifiques dans les
colonnes dont le nom commence par « Description ». Les éléments d'une ancienne liste sont
remplacés par les éléments correspondants d'une nouvelle liste dans les colonnes sélectionnées.
Voici le fonctionnement de la requête :

1. Old = [Link]({“Prdct”, “pcs”, “Qty” }) : L'ancienne liste contient les sous­chaînes


destinées au remplacement. L'utilisation de [Link] garantit que la liste est évaluée
une fois et conservée en mémoire pour de meilleures performances.
Cependant, la mise en mémoire tampon des valeurs ne garantit pas un gain de
performances et doit être testée.
2. New = [Link]({“Product”, “pieces”, “Quantity”}): La nouvelle liste
Contient des sous­chaînes définies pour remplacer les sous­chaînes correspondantes
dans l'ancienne liste. [Link] est intégré pour améliorer les performances, bien qu'il soit
Machine Translated by Google

non garanti.
3. Replacer = [Link](...) : Cette fonction parcourt la liste {0..
[Link](Old)­1}, fournissant essentiellement des indices pour les anciennes et
nouvelles listes. Il applique une transformation à la table rawData, qui fait
référence à la requête contenant l'échantillon de données. Si vous avez nommé
cette requête avec des données d'échantillon différemment, vous devrez
mettre à jour cette
référence en conséquence. 4. (s, a) => [Link](...): La graine, notée « s »,
est la valeur initiale, qui dans ce cas est la table rawData. L'accumulateur,
noté « a », assumera chaque valeur de la liste {0.. [Link](Old)­ 1}, représentant
essentiellement les indices pour passer tous les éléments des anciennes et
nouvelles listes.
5. [Link]( s, Old{a}, New{a}, [Link], ...) : Cette
fonction remplace toutes les instances de la sous­chaîne Old{a} par New{a}
dans les colonnes spécifiées de la table.
6. [Link]([Link](rawData), each [Link](_, “Description”)) :
Cette expression sélectionne les colonnes à remplacer. Elle sélectionne toutes
les colonnes dont le nom commence par “Description”.

Cette solution s'avère plus efficace et dynamique lors du remplacement de plusieurs


valeurs de texte dans des colonnes spécifiques d'une table. [Link] permet un
remplacement performant des valeurs ligne par ligne et colonne par colonne, sans codage
en dur, ce qui simplifie la maintenance de la requête. La mise en mémoire tampon des
anciennes et nouvelles listes est une étape d'optimisation qui garantit que ces listes ne
sont évaluées qu'une seule fois, améliorant ainsi les performances générales, même si
cela nécessite des tests.

Scénario 5. La tâche.

Voici une autre exigence courante : transformer ces « enregistrements » à plusieurs


lignes, issus ici d'un exemple de relevé bancaire (figure 11.21), en une seule ligne. Pour
ce faire, nous devons rassembler et combiner tous les « Détails » des lignes encadrées
et les transformer en enregistrements uniques, afin d'obtenir un tableau de cinq lignes.
Machine Translated by Google

Figure 11.21 : exemples de données de relevé bancaire

Voici des exemples de données que vous pouvez explorer et expérimenter.

laisser

Source = [Link]( { {#date(2024, 2, 5),


« CloudBliss
Shopping », ­30,99}, {#date(2024, 2, 5), « Grocery Store », ­15,5}, {null, « Nature's Pantry », null}, {null, « Numéro de carte
564 », null}, {#date(2024, 2, 5), « PowerPro Utilities », ­90,0}, {null, « Période : janvier 2024 », null}, {null,
« Compte : 123456789 », null}, {null, « Numéro de référence : PPU­7890 », null},
{#date(2024, 2, 6), « Gourmet Bistro », ­75,50}, {null, « Date : 6 février 2024 », null},
{null, « 123 Main Street, Anytown », null}, {null, « Numéro de carte 564 », null}, {#date(2024, 2, 6), « TrustWise Bank »,
­150}, {null, « Retrait d'espèces au distributeur automatique », null}, {null, « Emplacement : 456
Oak Street, Anytown », null}, {null, « Numéro de carte 843 », null}, {#date(2024, 2, 6),
« HappyTimes : PQE­789012 », 5} }, type table [Date=date, Details=text, Debit=[Link]] ) dans

Source

Scénario 5. Une solution.

Plusieurs stratégies peuvent être employées dans un tel scénario, la fonction polyvalente [Link]
s'avérant souvent la plus efficace, notamment lorsque tous les enregistrements liés partagent une
clé commune. Cependant, des difficultés apparaissent en l'absence de clés partagées et leur
génération est complexe. Dans ce cas, par exemple, si le nombre de lignes liées fluctue, il
n'existe pas de modèle fixe sur lequel s'appuyer. D'un autre point de vue, l'utilisation de la colonne
de date comme clé est insuffisante pour la ségrégation.
Machine Translated by Google

et combiner ces enregistrements. En effet, plusieurs transactions sont susceptibles d'avoir lieu
à une date donnée. Sans marqueur supplémentaire pour les distinguer, cette option n'est pas
viable. Cependant, [Link] propose un comparateur facultatif dont nous pouvons
tirer parti. Explorons cette possibilité. Tout d'abord, nous utilisons l'interface utilisateur
graphique pour générer la majeure partie du code M. Sélectionnez la colonne « Date »
et choisissez « Grouper par » dans l'onglet « Accueil » ou « Transformer » du ruban. Définissez
l'option « Avancé », saisissez un nouveau nom de colonne, « Description », et sélectionnez
une opération. L'opération spécifique importe peu pour le moment, car nous la mettrons à
jour ultérieurement. Choisissez la colonne « Détails ». Puisque nous avons sélectionné
« Avancé », nous pouvons maintenant ajouter une autre agrégation. Cette fois, pour le
montant « Débit », définissez l'opération sur Min ou Max (les deux conviennent), puis
sélectionnez la colonne « Débit » (voir Figure 11.22), puis confirmez.

Figure 11.22 Boîte de dialogue Grouper par

Nous pouvons maintenant modifier le code dans la barre de formule. Il est clair que les
valeurs textuelles ne peuvent pas être additionnées ; nous allons donc remplacer la fonction
[Link] par [Link] et utiliser un espace comme deuxième argument (séparateur).
Puisqu'il n'y a qu'un seul montant de débit par transaction, le choix entre [Link] et
[Link] n'a aucune importance ; les deux produiront le même résultat. [Link] prend un
quatrième argument facultatif, groupKind. Nous pouvons passer [Link] pour
indiquer que nos données sont triées par clé(s) et que cette séquence doit être respectée.
Concentrons­nous maintenant sur son cinquième argument, le comparateur facultatif. Il est
essentiel de comprendre que lorsqu'une fonction de comparaison personnalisée est
passée, elle a priorité sur la clé spécifiée et se charge de créer de nouveaux groupes. Cela
signifie qu'une ligne peut être placée dans un groupe dont les clés diffèrent de la sienne. Voici
notre fonction de comparaison personnalisée : (x, y)=> [Link](y[Date] <> null).
Elle est passée.
Machine Translated by Google

Deux valeurs à la fois : la valeur de la ligne courante (x) et la valeur de la ligne


suivante (y). Un nouveau groupe est créé si la date de la ligne suivante n'est pas
nulle. Autrement dit, si la valeur est fausse, [Link] renvoie 0 (zéro) et affecte
la ligne au groupe actuel. En revanche, si la valeur est vraie, [Link]
renvoie la valeur 1 et génère un nouveau groupe. Voici les données et la
solution complète que nous venons de créer.

laissez

Source = [Link]( { {#date(2024, 2, 5), « CloudBliss

Shopping »,

­30,99}, {#date(2024, 2, 5), « Épicerie », ­15,5}, {null, « Nature's Pantry », null}, {null, « Numéro de carte 564 », null}, {#date(2024, 2, 5),

« PowerPro Utilities », ­90,0}, {null, « Période : janvier 2024 », null}, {null, « Compte : 123456789 », null}, {null, « Numéro

de référence : PPU­7890 », null}, {#date(2024, 2, 6), « Gourmet Bistro », ­75,50}, {null, « Date :
6 février 2024 », null}, {null, « 123 Main Street, Anytown », null}, {null, « Numéro de carte

564 », null}, {#date(2024, 2, 6), « TrustWise Bank », ­150}, {null, « Retrait d'espèces au distributeur automatique », null}, {null,

« Emplacement : 456 Oak Street, Anytown », null}, {null, « Numéro de carte 843 », null}, {#date(2024, 2,
6), « HappyTimes : PQE­789012 », 5} }, type table [Date=date, Details=text, Debit=[Link]] ),

# « Grouped Rows » = [Link]( Source, {« Date »}, { {« Description », each [Link]([Details], « », type text},

{« Débit », each [Link]([Debit]), type number} }, [Link], (x, y)=> [Link](y[Date] <> null) ) dans

#« Lignes groupées »

Résumé
Ce chapitre a commencé par poser les bases des concepts clés du langage M,
essentiels à la compréhension de certaines subtilités abordées plus loin. Nous avons
exploré des techniques telles que la division, la combinaison, la comparaison et le
remplacement de valeurs, entre autres, à l'aide d'exemples illustratifs pour une
meilleure compréhension. Cependant, maîtriser le langage M nécessitera de la
persévérance et une application pratique régulière au quotidien.
Machine Translated by Google

16 Activation des extensions

Rejoignez notre communauté de livres sur Discord

[Link]

Power Query prend en charge un large éventail de connecteurs de sources de données


permettant d'accéder à des données provenant de diverses sources et de les récupérer.
Power BI Desktop prend en charge nativement près de 200 connecteurs de sources de
données différents. De plus, nombre de ces connecteurs sont génériques pour diverses
normes et protocoles de format de données, tels que OData (Open Data Protocol),
ODBC (Open Database Connectivity), JSON (JavaScript Object Notation), XML (Extensible
Markup Language) et Parquet.
La prise en charge de ces normes et protocoles communs élargit considérablement le
potentiel de sources de données pour Power Query, atteignant des milliers, voire des
dizaines de milliers. Malgré toutes les sources de données déjà prises en charge par
Power Query, il est nécessaire d'en prendre en charge d'autres. En particulier, divers
services web fournissent souvent une interface de programmation d'application (API)
nécessaire pour accéder à leurs données. Ce chapitre explique comment créer des
extensions personnalisées pour Power Query afin de gérer ce type de scénarios, notamment :

• Que sont les extensions Power Query ? •


Préparation de votre environnement •
Création d'un connecteur personnalisé
• Installation et utilisation d'un connecteur personnalisé

Exigences techniques

• Code Visual Studio • Kit de

développement logiciel Power Query

Que sont les extensions Power Query ?


Machine Translated by Google

En résumé, les extensions Power Query sont principalement du code M qui enrichit
l'environnement global. Consultez le chapitre 10 pour en savoir plus sur l'environnement
global. Ces extensions existent sous quatre types de fichiers différents (extensions de fichier) :

• m – Un fichier texte simple contenant du code M • pq – Un


fichier texte simple contenant du code M • mez – Un fichier zip
standard contenant des fichiers de connecteur personnalisés. Peut utiliser un fichier zip standard et le
renommer de [Link] à [Link]. • pqx – Un fichier zip Open Packaging Components
(OPC) contenant des fichiers de connecteur personnalisés. Généralement empaqueté à l'aide
de la bibliothèque [Link] .NET. Ce format d'empaquetage
permet la signature numérique du fichier et est le format des connecteurs certifiés Microsoft.

Comme indiqué précédemment, les fichiers .mez et .pqx sont des collections de fichiers
utilisés pour créer des connecteurs de sources de données personnalisés. Nous aborderons la
création d'un connecteur personnalisé plus loin dans ce chapitre. Ces collections de
fichiers incluent toujours un seul fichier .m ou .pq , qui constitue le fichier principal contenant le
code du connecteur personnalisé. Les extensions Power Query sont implémentées à
l'aide du mot­clé section , et les fonctions de la section sont exposées à l'environnement global
grâce au mot­clé shared . Les sections sont implémentées en code M standard avec des
règles de syntaxe spécifiques. Prenons l'exemple de code suivant :

section MyAwesomeExtension; partagé


[Link] = (firstNumber comme nombre, secondNumber comme nombre) comme [Link](firstNumber) +
[Link](secondNu [Link] = (paramNumber comme nombre) comme nombre => paramNumber * paramN

Notez l'utilisation spécifique des points­virgules ( ; ) dans la syntaxe de la section . Tout


comme plusieurs expressions d'une instruction let sont séparées par une virgule ( , ),
plusieurs expressions d'une section sont séparées par des points­virgules.
Cette section possède une fonction partagée,
[Link] , et une fonction interne accessible uniquement dans la
section, [Link].
La fonction [Link] appelle
[Link] pour élever les deux nombres au carré et les
additionner. Collez ce code dans un éditeur de texte et enregistrez le fichier sous le nom
[Link]. Placez ce fichier dans le dossier [Documents]\Microsoft Power
BI Desktop\Custom Connectors. Vous devrez peut­être créer ce dossier. Ouvrez
l'éditeur Power Query dans Power BI Desktop et créez la requête suivante :

laisser

Source = [Link](10, 5) dans

Source

Cette requête renvoie 125. Notez que seule la


fonction [Link] est exposée et utilisable dans la requête. La
fonction [Link] ne peut pas être référencée, car elle n'est
pas préfacée par le paramètre partagé.
Machine Translated by Google

À ce stade, vous devriez comprendre la structure de base et la nature des extensions


Power Query, mais vous vous demandez peut­être comment vous pourriez les utiliser.

Que pouvez­vous faire avec des extensions ?

Il existe deux utilisations principales des extensions dans Power Query, notamment :

• Bibliothèque de fonctions personnalisées


• Connecteurs de sources de données personnalisés

Comme vous l'avez déjà vu, vous pouvez utiliser des extensions pour fournir une
bibliothèque de fonctions personnalisées et réutilisables à utiliser dans vos requêtes. Au
lieu de copier­coller du code entre les projets, vous pouvez inclure vos fonctions
personnalisées dans une section avec le mot­clé shared. Bien que cette fonctionnalité existe,
elle n'est pas l'utilisation principale des extensions et elle est peu répandue. Les connecteurs
de sources de données personnalisés constituent l'autre utilisation principale des
extensions Power Query. Bien que Power BI Desktop propose près de 200 connecteurs,
de nombreuses autres sources de données, notamment celles utilisant des API
personnalisées, ne sont pas incluses dans le produit. Les extensions Power Query
permettent aux développeurs de créer des connecteurs personnalisés qui se
connectent à ces sources de données supplémentaires. Ces connecteurs permettent
de créer de nouvelles sources de données ou de personnaliser et d'étendre des sources
existantes. Une fois installés, ces connecteurs étendent l'environnement global de Power
Query, offrant de nouvelles fonctions d'accès aux données non présentes par défaut
dans le langage M. La suite de ce chapitre se concentre sur la création d'un connecteur de source de données perso

Préparez votre environnement


Pour préparer votre environnement, vous devez télécharger et installer deux composants
logiciels :

• Visual Studio •
Kit de développement logiciel (SDK) Power Query

De plus, l'exemple de connecteur personnalisé présenté dans ce chapitre se connecte à


Discord, une plateforme sociale populaire de messagerie vocale et instantanée. Nous
utiliserons l'API Discord pour nous connecter à un serveur Discord et récupérer des informations.
Pour utiliser Discord, nous devrons également installer et configurer deux composants
supplémentaires, à savoir :

• Services d'information sur Internet •


Discord

Voyons comment installer et configurer ces composants logiciels.

Obtenir Visual Studio


Machine Translated by Google

Il existe actuellement deux versions de Power Query : une version publiée en 2017, qui
fonctionne comme une extension pour Visual Studio 2017 et 2019, et une nouvelle version
(actuellement en préversion à la date de publication de ce livre) compatible avec Visual Studio
Code. Pour ce livre, nous utiliserons la nouvelle version du SDK Power BI pour Visual
Studio Code. Pour commencer, téléchargez et installez la dernière version de Visual
Studio Code ici : [Link] Si vous ne connaissez
que Visual Studio 2017, 2019 et/ou 2022, Visual Studio Code vous semblera
probablement peu familier et peut­être un peu complexe à utiliser. D'ailleurs, vous ne
seriez pas mis à l'écart si vous pensiez que l'acronyme GUI signifie « Gratually Unintuitive
Interface » pour Visual Studio Code.

Visual Studio Code présente de nombreuses différences et particularités qui peuvent


prêter à confusion. Bien qu'une analyse complète de l'utilisation de Visual Studio Code
dépasse le cadre de ce livre, des efforts importants ont été déployés pour expliquer où et
comment naviguer dans Visual Studio Code pour créer un connecteur personnalisé. De plus,
les étapes de la section « Créer un connecteur personnalisé » ont été spécialement
conçues pour minimiser le nombre d'erreurs ou de messages inhabituels. Par conséquent,
suivez attentivement les étapes de cette section. Cela dit, il suffit parfois d'enregistrer son
travail, de fermer le dossier, puis de le rouvrir.

Obtenir le SDK Power Query

Le SDK Power Query est téléchargeable depuis la Marketplace de Visual Studio :


SDK Power Query ­ Visual Studio Marketplace. Si vous utilisez Visual Studio 2017 ou 2019,
vous pouvez télécharger et installer l'ancienne version du SDK ici : SDK Power Query ­
Visual Studio Marketplace. Les instructions de ce livre supposent que vous
utilisez le nouveau SDK pour Visual Studio Code. Cliquer sur le bouton « Installer » sur la page
web du nouveau SDK Power Query pour Visual Studio Code lance Visual Studio Code et
affiche la page d'installation du SDK Power Query.

Cliquez simplement sur le bouton Installer ici pour télécharger et installer le SDK.

Configuration des services d'information Internet

Internet Information Services est un serveur web configurable sur n'importe quel PC Windows.
Pour configurer Internet Information Services sur votre ordinateur local, procédez comme
suit :

1. Tapez Activer et désactiver des fonctionnalités Windows dans la barre de


recherche Windows et lancez la boîte de dialogue Fonctionnalités Windows .

2. Cochez la case en regard de Internet Information Services (IIS) comme indiqué


dans la Figure 14.1 :
Machine Translated by Google

Figure 14.1 : Activer les services d'information Internet

3. Cliquez sur le bouton OK pour configurer les services Internet (IIS).


Par défaut, les outils de gestion Web et les services World Wide Web sont automatiquement
sélectionnés , mais pas le serveur FTP. Cela convient parfaitement à nos besoins.

Dans notre exemple de connecteur personnalisé, nous utiliserons


OAuth pour l'authentification. OAuth signifie Open Authentication (authentification
ouverte). Il s'agit d'une norme ouverte permettant aux utilisateurs d'accorder un
accès limité à un site web ou à un service à des applications tierces. Nous utiliserons
les services Internet locaux comme point de terminaison pour l'URI (Uniform
Resource Identifier) de redirection requis par le protocole OAuth. Notez que l'URI de
redirection fourni n'est pas particulièrement important et que l'URI en question
n'a même pas besoin d'exister dans certains cas, y compris dans cet exemple. Il suffit
qu'un serveur web soit disponible pour servir de point de terminaison de l'URI de
redirection. Au lieu d'utiliser un serveur web local comme point de terminaison, nous
pourrions, en théorie, utiliser presque n'importe quel URI de
redirection OAuth, par exemple : [Link]
Cependant, cela peut être risqué si le nom de domaine, et donc le service web,
échappent au contrôle du développeur. En effet, ce point final pourrait à un
moment donné ne plus être valide, ce qui pourrait entraîner une erreur lors du
processus d'authentification. Notez que ce type de « non valide » est différent d'une
simple page inexistante pour un serveur web. Par exemple, « [Link] »
n'est pas un nom de domaine valide et générera donc une erreur lors du processus d'authentification en ca
Machine Translated by Google

Utiliser [Link] comme URI de redirection. Ceci est différent de l'utilisation d'une
page invalide pour un nom de domaine existant et répondant aux requêtes en tant que
serveur web. Dans ce dernier cas, un message d'erreur 404 (page introuvable) est généré,
ce qui n'entraîne pas automatiquement l'échec du processus d'authentification. Pour notre
développement, nous utiliserons les services Internet (IIS) locaux et nous pouvons
désigner ce serveur web par « localhost ». Évidemment, cela ne serait pas suffisant pour un
connecteur personnalisé de production, car tout le monde n'a pas de serveur web
local installé et configuré par défaut.
Les scénarios de production nécessiteraient que le développeur mette en place un serveur web accessible
à tous et l'URI de redirection correspondante. Ce type de scénario de production dépasse le
cadre de ce livre, mais il pourrait être aussi simple que de créer un blog WordPress avec ou sans
domaine personnalisé. L'étape suivante consiste à installer et configurer Discord, c'est ce que
nous allons faire.

Configuration de Discord

Pour configurer Discord afin de l'utiliser avec l'API Discord, nous avons besoin des éléments suivants :

1. Client Discord 2.
Serveur Discord 3.
Application Discord (App)
4. Configuration OAuth

Voyons comment obtenir et configurer chacun de ces éléments.

Client Discord

Pour télécharger et installer le client Discord, utilisez un navigateur web pour accéder à https://
[Link]. Cliquez sur le bouton « Télécharger pour Windows » sur la page d'accueil,
puis lancez l'installation. Vous pouvez également utiliser le bouton « Ouvrir Discord dans
votre navigateur » .

Serveur Discord

Pour créer un serveur Discord, cliquez simplement sur l'icône + dans la navigation de gauche
du client Discord, comme indiqué dans la figure 14.2 :
Machine Translated by Google

Figure 14.2 : Ajouter un serveur Discord

Choisissez le type de serveur à créer et donnez un nom à votre serveur.


Cliquez sur le bouton « Créer » pour créer le serveur. Une fois créé, le serveur
apparaîtra dans le volet de navigation de gauche du client Discord. L'étape suivante
consiste à créer une application Discord.

Application Discord (App)

Pour utiliser l'API Discord, nous devons créer une application Discord. Pour ce faire,
procédez comme suit :

1. Utilisez un navigateur Web et accédez à la page Web suivante,


[Link]
2. Cliquez sur le bouton Nouvelle application .

3. Donnez un nom à l'application, puis cliquez sur le bouton Créer comme indiqué
dans la Figure 14.3 :
Machine Translated by Google

Figure 14.3 : Créer une application Discord

4. Cliquez sur le bouton Créer pour créer l'application

Après avoir cliqué sur le bouton « Créer », vous accédez à la page des paramètres de
l'application. C'est ici que nous pouvons passer à l'étape suivante : configurer OAuth. Cette
application peut être ajoutée à un serveur Discord, mais cela ne sera pas nécessaire pour
nos besoins.

Configuration OAuth de Discord

Pour utiliser l'API et envoyer des requêtes à l'API Discord au nom d'un utilisateur, celui­ci doit
d'abord autoriser l'application. La configuration s'effectue dans les paramètres de l'application et
nécessite les étapes suivantes :

1. Cliquez sur le lien OAuth2 dans la navigation de gauche des paramètres de l'application
page.
2. Notez l' ID CLIENT sous « Informations client ». Copiez et enregistrez cet ID client, car nous en
aurons besoin ultérieurement pour créer notre connecteur personnalisé.

3. Ensuite, cliquez sur le bouton Réinitialiser le secret illustré dans la Figure 14.4 :
Machine Translated by Google

Figure 14.4 : Ajouter une redirection d'application OAuth2

4. Assurez­vous d'utiliser le bouton Copier pour copier votre clé secrète client et l'enregistrer. Vous
en aurez besoin lors de la création du connecteur personnalisé.
5. Cliquez maintenant sur le bouton Ajouter une redirection et ajoutez la redirection
[Link] comme indiqué dans la figure 14. .
6. Enfin, cliquez sur le bouton Enregistrer les modifications pour enregistrer la redirection.

La page web [Link] n'existe pas réellement. En fait, n'importe quel URI utilisant
localhost pourrait être utilisé pour cette étape. L'important est que localhost désigne notre
ordinateur local sur lequel un serveur web local est exécuté, comme configuré dans la section
« Configuration des services Internet ». La préparation de l'environnement est maintenant
terminée. Passons maintenant à la création d'un connecteur ou d'une extension personnalisée.

Création d'un connecteur personnalisé

Avec Visual Studio Code, le SDK Power Query installé, notre environnement local configuré
avec IIS et les éléments Discord créés et configurés, nous pouvons maintenant créer un
connecteur personnalisé pour Power Query. Le code complet du connecteur personnalisé est disponible
dans le dépôt GitHub de ce livre. Vous pouvez télécharger le fichier TDGTPQM_Discord.zip du chapitre
14 dans le dépôt, extraire les fichiers, copier­coller le dossier du connecteur sur votre PC, puis l'ouvrir
dans Visual Studio Code ( Fichier | Ouvrir le dossier…) , ou suivre la suite de cette section où nous créons
le connecteur de A à Z. Dans tous les cas, la lecture des explications du code tout au long de cette
section vous sera utile. La suite de cette section suppose que vous créez le connecteur personnalisé de
A à Z. Les étapes de création du connecteur sont les suivantes :
Machine Translated by Google

1. Créer le projet d'extension 2. Configurer


l'authentification 3. Configurer la
navigation et le contenu

Examinons la première étape, la création d’un projet d’extension.

Création d'un projet d'extension

Comme indiqué précédemment, nous allons créer notre connecteur personnalisé dans Visual Studio
Code, l’approche actuellement privilégiée par Microsoft au moment de la publication de ce livre.
Pour créer le projet d’extension, procédez comme suit :

1. Lancez Visual Studio Code s’il n’est pas déjà en cours d’exécution.

2. Accédez à l' Explorateur, développez la section POWER QUERY SDK , puis créez un nouveau
projet d'extension en cliquant sur le bouton Créer un projet d'extension comme illustré dans la
Figure 14.5 :

Figure 14.5 : Créer un projet d’extension

3. Lorsque vous y êtes invité, entrez TDGTPQM_Discord comme nom du nouveau projet et appuyez
sur la touche Entrée .
4. Lorsque vous êtes invité à choisir un dossier pour l'espace de travail, créez un nouveau dossier
nommé TDGTPQM_Discord, sélectionnez ce dossier et appuyez sur le bouton Sélectionner
l'espace de travail .

La structure de fichiers et de dossiers suivante est créée :


Machine Translated by Google

• TDGTPQM_Discord
◦ .vscode ◦
[Link] ◦
bin ◦
AnyCPU ◦
Débogage
• TDGTPQM_Discord.mez
◦ [Link]
• TDGTPQM_Discord.pq •
TDGTPQM_Discord.proj •
TDGTPQM_Discord.[Link] •
TDGTPQM_Discord.png •
TDGTPQM_Discord.png •
TDGTPQM_Discord.png •
TDGTPQM_Discord.png •
TDGTPQM_Discord.png •
TDGTPQM_Discord.png •
TDGTPQM_Discord.png •
TDGTPQM_Discord.png

Examinons de plus près les fichiers créés :

• [Link] – Un fichier JavaScript Open Notation (JSON) qui contient les


paramètres de l'espace
de travail. • TDGTPQM_Discord.mez – Ce fichier est contenu dans le répertoire
bin\AnyCPU\Debug et est l'extension réelle construite par le SDK Power Query
que vous déployez et utilisez comme connecteur personnalisé. •
[Link] – Un fichier XML (eXtensible Markup Language) qui stocke
principalement les chaînes utilisées dans l'extension. •
TDGTPQM_Discord.pq – Il s'agit du fichier de code principal du connecteur personnalisé.
Un seul fichier .pq est autorisé et son format est celui d'une section M.

• TDGTPQM_Discord.proj – Un fichier XML qui contient le projet


paramètres.
• TDGTPQM_Discord.[Link] – Principalement utilisé pour créer des requêtes
de test. Ce fichier contient simplement le code suivant :

laisser

résultat = TDGTPQM_Discord.Contents() dans

résultat

Ce fichier fait simplement référence à une fonction (TDGTPQM_Discord.Contents) définie


dans le fichier TDGTPQM_Discord.pq , comme nous le verrons plus loin. Ce code est suffisant
pour nos besoins et restera inchangé.

• Fichiers .png – Icônes utilisées par le connecteur.

Pour écrire notre connecteur personnalisé, nous travaillerons avec le


fichier TDGTPQM_Discord.pq , explorons donc ce fichier plus en détail.
Machine Translated by Google

TDGTPQM_Discord.pq

Ce fichier contient la logique de code principale du connecteur personnalisé et c'est celui que
nous modifierons pour créer notre connecteur personnalisé. L'intégralité du connecteur
personnalisé est implémentée sous forme de section, comme indiqué dans le code ci­dessus :

// Ce fichier contient votre section logique de connecteur de données [Version


= « 1.0.0 »] TDGTPQM_Discord ;

Comme expliqué précédemment, les documents de section indiquent comment les


extensions sont implémentées dans M. Sous cette définition de section, nous trouvons le code suivant :

[[Link]=“TDGTPQM_Discord”, Publish=“TDGTPQM_Discord.Publish”] shared TDGTPQM_Discord.Contents = (message facultatif


sous forme de texte) => let

_message = if (message <> null) then message else « Bonjour tout le monde », a = « Bonjour de HelloWorld : » & _message in

un;

TDGTPQM_Discord.Contents est la fonction principale que nous utiliserons pour renvoyer le


contenu de notre connecteur. Notez le mot­clé shared précédant la définition de la fonction.
Cela signifie que cette fonction peut être référencée en dehors de la section. Notez
également les définitions de [Link] et de Publish. [Link] est défini
comme TDGTPQM_Discord. L'utilisation du mot­clé shared et de la définition de l'attribut littéral
[Link] pour la fonction associe celle­ci à une source de données spécifique,
TDGTPQM_Discord. Le bloc de code suivant est l'enregistrement de définition de la source
de données associée, TDGTPQM_Discord :

// Description du type de source de données


TDGTPQM_Discord = [
Authentification = [
// Clé = [],
// Nom d'utilisateur Mot de passe = [],
// Fenêtres = [],
Anonyme = [] ] ];

L'enregistrement de définition de source de données définit les types d'authentification


pris en charge par la source de données. Dans ce cas, seules les authentifications
anonyme et implicite sont prises en charge. Outre l'attribut littéral [Link],
un attribut littéral Publish est associé à la fonction TDGTPQM_Discord.Contents. Le bloc de
code sous l'enregistrement de définition de source de données correspond à la définition de
l'enregistrement Publish.

// Description de la publication de l'interface utilisateur de la source de


données TDGTPQM_Discord.Publish = [ Beta
= true, Category = « Autre »,
ButtonText =
{ [Link](« ButtonTitle »), [Link](« ButtonHelp ») LearnMoreUrl = « [Link] », SourceImage =
TDGTPQM_Discord.Icons,
Machine Translated by Google

SourceTypeImage = TDGTPQM_Discord.Icons ];

L'enregistrement de publication est utilisé par l'interface utilisateur Power Query (Power Query Editor par
exemple) pour afficher l'extension de la source de données via la boîte de dialogue Obtenir des données .
Ces paramètres peuvent être ajustés pour modifier le comportement de certains
éléments de l'interface utilisateur (UI) tels que la catégorie dans laquelle le
connecteur de source de données est affiché, si le connecteur est en version bêta et le
lien En savoir plus pour le connecteur. Cet enregistrement de publication fait référence
à un enregistrement supplémentaire, TDGTPQM_Discord.Icons qui contient des
références aux fichiers image .png.

TDGTPQM_Discord.Icons = [ Icône16 =
{ [Link](“TDGTPQM_Discord16.png”), [Link](“TDGTPQM_Dis Icône32 = { [Link](“TDGTPQM_Discord32.png”),
[Link](“TDGTPQM_Dis ];

Voici les icônes affichées dans l'interface utilisateur Power Query du


connecteur. Ceci conclut notre exploration détaillée du fichier
TDGTPQM_Discord.pq . La faible quantité de code nécessaire à la création d'un
connecteur personnalisé pourrait surprendre. Ne vous y trompez pas : le projet
d'extension par défaut créé par le SDK Power Query est déjà un connecteur personnalisé
fonctionnel. Cela dit, ce connecteur ne fait actuellement rien d'autre que renvoyer l'équivalent
de « Hello World ». Une fois notre projet d'extension créé, nous pouvons maintenant
passer à l'écriture de notre code d'authentification personnalisé.

Configuration de l'authentification

Notre projet d'extension de base étant créé et expliqué, il est temps de nous concentrer
sur sa personnalisation pour répondre à nos besoins de connexion à Discord. Notre
première tâche consiste à coder et configurer l'authentification du connecteur. Discord
utilise le protocole de sécurité OAuth pour l'authentification. D'autres types
d'authentification sont disponibles, notamment :

• Anonyme •
Aad •
Nom d'utilisateurMot de
passe •
Windows • Clé

Chacun de ces mécanismes d'authentification est unique. Plus d'informations sur ces
types d'authentification supplémentaires sont disponibles ici : https://
[Link]/en­us/power­query/handling­authentication.
L'authentification OAuth est de loin la méthode d'authentification la plus
complexe pour les extensions Power Query, ce qui explique son choix comme exemple
pour ce livre. Comme mentionné précédemment, OAuth signifie Open Authentication
(authentification ouverte). Il s'agit d'une norme ouverte permettant aux utilisateurs d'accorder
un accès limité à un site web ou à un service à des applications tierces. Dans notre
cas, l'utilisateur accorde à notre connecteur personnalisé tiers un accès limité à ses
informations Discord. Le protocole OAuth permet cet accès.
Machine Translated by Google

Sans que l'utilisateur ait à partager ses identifiants (noms d'utilisateur et mots de passe),
OAuth offre un moyen sécurisé et standardisé d'autoriser des applications externes à accéder à
leurs données ou à effectuer des actions en leur nom. Au lieu d'identifiants tels que les noms
d'utilisateur et les mots de passe, OAuth utilise l'échange de secrets client et de jetons d'accès entre
l'utilisateur, l'application demandant l'accès et le service fournissant les ressources. Grâce à OAuth, les
fournisseurs de services garantissent la protection des identifiants des utilisateurs et leur protection
contre les applications externes. OAuth permet aux utilisateurs de contrôler et de révoquer l'accès
à leurs ressources à tout moment, leur offrant ainsi une sécurité et un contrôle accrus sur leurs
données. Globalement, OAuth joue un rôle crucial pour sécuriser et contrôler l'accès aux ressources,
favoriser l'interopérabilité et renforcer la confidentialité des utilisateurs dans diverses applications
web et mobiles. Vous avez probablement déjà vu des invites d'autorisation OAuth, même si vous ne
les avez peut­être pas reconnues.

1. Ajouter les fichiers d'ID client et de secret client


2. Ajouter les paramètres de configuration
3. Créer des fonctions Oauth 4.
Modifier la définition de la source de données 5.
Ajouter des informations
d'identification 6. Tester la connexion

Ajout de fichiers d'ID client et de secret client

La première étape de la configuration de l'authentification pour notre connecteur personnalisé consiste


à ajouter des fichiers pour stocker l'ID client et le secret client de notre application. Pour ce faire,
procédez comme suit :

1. Avec le projet d'extension ouvert, sélectionnez Fichier | Nouveau fichier dans le


Menu de Visual Studio Code.
2. Lorsque vous y êtes invité, saisissez client_id comme nom de fichier, appuyez sur la touche
Entrée , puis sur le bouton Créer un fichier . 3. Le fichier
client_id s'ouvre automatiquement dans Visual Studio Code. À la ligne 1, collez simplement
l'identifiant client enregistré dans la configuration OAuth pour Discord.

4. Répétez ces étapes, mais cette fois, utilisez client_secret pour le nom de votre fichier et collez
votre secret client enregistré dans le cadre de la configuration OAuth pour
Discord.

Les fichiers que vous venez de créer seront utilisés dans le cadre des paramètres de configuration
OAuth pour notre connecteur personnalisé. Ajoutons donc ces paramètres de configuration.
maintenant.

Ajout de paramètres de configuration

Les paramètres de configuration sont simplement des variables définies dans notre connecteur
personnalisé. Ces variables peuvent être considérées comme des variables « globales » : toute
expression ou fonction définie dans notre connecteur personnalisé peut y accéder et les utiliser. Pour
ajouter les paramètres de configuration, procédez comme suit :
Machine Translated by Google

• En haut de votre fichier, immédiatement sous la ligne : •


Section TDGTPQM_Discord ; •
Collez le code suivant :

// Paramètres de configuration OAuth client_id =


[Link]([Link](“client_id”)); client_secret =
[Link]([Link](“client_secret”)); redirect_uri = “[Link] authorize_uri =
“[Link] token_uri = “[Link]
token”; // Variables satiques api_uri = “[Link] // Fenêtre du connecteur windowWidth
= 1200; windowHeight = 1000;

Pour mieux expliquer les variables créées, considérez ce qui suit :

• client_id – Lit le fichier client_id créé dans la section Ajout des fichiers ID client et
Secret client et stocke sa valeur. • client_secret – Lit le fichier
client_id créé dans la section Ajout des fichiers ID client et Secret client et stocke sa
valeur. • redirect_uri – Stocke l'URI de redirection utilisé lors de
la configuration de Discord OAuth dans la section Configuration de Discord OAuth .
Il doit s'agir du même URI de redirection utilisé dans cette configuration.

• authorize_uri – Contient la valeur de l'autorisation OAuth de Discord


URI.
• token_uri – Contient la valeur de l'URI d'octroi du jeton de Discord. • api_uri –
Stocke l'URI de base de l'API Discord. • WindowWidth
– Définit la largeur de la fenêtre pour l'authentification
dialogue.
• WindowHeight – Définit la hauteur de la fenêtre pour l'authentification
dialogue.

Une fois ces variables/paramètres de configuration en place, nous pouvons maintenant


passer à l'implémentation des fonctions requises définies par le type d'authentification
OAuth de Power Query. Faisons­le donc maintenant.

Création de fonctions OAuth

Le type d'authentification OAuth de Power Query nécessite l'implémentation de deux


champs : StartLogin et FinishLogin. Deux champs facultatifs peuvent également être
implémentés : Refresh et Logout. Chacun de ces champs doit spécifier une fonction définie
dans notre connecteur personnalisé. Nous implémenterons les champs/fonctions
obligatoires, mais pas les champs/fonctions facultatifs dans ce connecteur
personnalisé. Entre la définition de l'enregistrement de la source de données,
TDGTPQM_Discord, et la définition de l'enregistrement
TDGTPQM_Discord.Publish , insérez le code suivant :

//
// Définition du flux OAuth2 //
Machine Translated by Google

StartLogin = (resourceUrl, état, affichage) => laisser

AuthorizeUrl = authorize_uri & [Link]( [ client_id =


client_id, redirect_uri = redirect_uri, response_type = “code”, scope =
“identifier les connexions e­mail
guildes [Link]” ] ) dans

[
LoginUri = AuthorizeUrl,
CallbackUri = redirect_uri,
HauteurDeLaFenêtre = HauteurDeLaFenêtre,
LargeurDeLaFenêtre = largeurdelafenêtre,
Contexte = nul

FinishLogin = (contexte, callbackUri, état) =>
laisser
Parts = [Link](callbackUri)[Requête] dans

TokenMethod(Parties[code]);
TokenMethod = (code) => laisser

Réponse = [Link]( token_uri, [ Content =


[Link]( [Link]( [ client_id
= client_id, client_secret
= client_secret, grant_type = “authorization_code”, code = code, redirect_uri =
redirect_uri ] ) ), En­têtes = [#”Content­type” = “application/x­www­form­urlencoded”,
#”Accept” ] ), Parties = [Link](Response)
dans

Parties;

Il convient de noter que le fonctionnement interne du type d'authentification OAuth


de Power Query est quelque peu flou. Microsoft fournit peu d'explications
ou de documentation, en dehors d'exemples de code d'implémentation. Le code ci­
dessous est basé sur l'exemple de connecteur GitHub de Microsoft, disponible ici :
[Link]
DataConnectors/tree/master/samples/Github. Les définitions des fonctions StartLogin et
FinishLogin varient selon les spécifications de chaque API. Ces fonctions implémentent
les informations et les structures requises par l'API Discord. Commençons par
examiner de plus près la fonction StartLogin . Elle lance le processus
d'authentification OAuth en créant l'URI d'autorisation attendue par l'API Discord. Cette
valeur est stockée par l'expression AuthorizationUrl. En effet, cette expression crée
simplement un URI avec des paramètres de chaîne de requête
spécifiques. L'URI réellement créé est le
Machine Translated by Google

Suivant : [Link]
client_id=1128020929558098050&redirect_uri=http%3A%2F %2Flocalhost%2Fdiscord

%2Fredirect&response_type=code&scope=identify%20guilds
%[Link]%20email%20connections. Notez que l'URI d'autorisation de base
provient de notre variable authorize_uri définie dans la section « Ajout de paramètres de
configuration » . La chaîne de requête contient notre client_id (le vôtre sera différent), ainsi
que notre redirect_uri, un response_type « code » et un paramètre scope . Le type de
réponse « code » indique à l'API Discord le type de réponse d'autorisation que nous souhaitons
recevoir, et le scope définit les autorisations que nous souhaitons accorder à notre
connecteur personnalisé tiers. La fonction StartLogin renvoie un enregistrement contenant les
champs suivants :

• LoginUri – L'expression AuthorizeUrl qui est en fin de compte l'URI fournie précédemment :
[Link]
client_id=1128020929558098050&redirect_uri=http%3A%2F %2Flocalhost%2Fdiscord

%2Fredirect&response_type=code&scope=identify%20guilds
%[Link]%20email%20connections • CallbackUri –
Notre variable/paramètre de configuration redirect_uri • WindowHeight – Notre
variable/paramètre de configuration WindowHeight • WindowWidth – Notre variable/paramètre
de configuration WindowWidth • Contexte – null

Pour mieux comprendre le fonctionnement, collez simplement l'URI fournie précédemment


(AuthorizeUrl) dans un navigateur web. Une invite d'autorisation Discord s'affiche,
indiquant qu'une application tierce demande les autorisations suivantes :

• Accédez à votre nom d'utilisateur, votre avatar et votre


bannière • Accédez à votre adresse
e­mail • Accédez à vos connexions tierces •
Sachez sur quels serveurs vous vous
trouvez • Lisez vos informations de membre (pseudo, avatar, rôles, etc.) pour les serveurs
auxquels vous appartenez

Cette liste d'autorisations provient du paramètre scope de la chaîne de requête de l'URI. Cliquez sur
le bouton Authorize. Vous êtes alors redirigé vers l'URL de redirection spécifiée : [Link]
discord/redirect. Cette page n'existe pas réellement, votre serveur web local renvoie donc une
page 404 Not Found. Cependant, consultez [Link]
code=WV9s0kMY3Rg6AsPvCzj6CgbgnUvwz0. Notez le paramètre code dans la chaîne de requête. Puisque nous
avons demandé un response_type de « code », il s'agit du code renvoyé par le
serveur Discord. Nous utilisons ensuite ce code dans la fonction FinishLogin pour générer un jeton
d'accès et finaliser notre processus d'autorisation. Pour ce faire, nous introduisons le code
(Parts[code]) dans la fonction TokenMethod. En effet, la méthode FinishLogin récupère la réponse
de notre URL de redirection et alimente la fonction TokenMethod avec la valeur du
paramètre code . La fonction TokenMethod complète le processus de récupération de notre
jeton d'accès OAuth. Pour mieux comprendre ce processus, nous pouvons utiliser
Machine Translated by Google

Le facteur doit émuler le comportement comme indiqué dans la figure 14.6 :

Figure 14.6 : Récupération du jeton d'accès OAuth via Postman

Dans cette requête Postman, nous avons choisi une opération POST (plutôt que GET). Notre
connecteur personnalisé se comporte de la même manière, car nous avons inclus un élément
Headers dans notre appel de fonction [Link] , au sein de la fonction TokenMethod .
Dans la figure 14, nous avons spécifié une publication à l'URI [Link]
identique à l' URI token_uri utilisée dans notre connecteur personnalisé. Dans le corps de notre
requête Postman, nous avons spécifié x­www­form­urlencoded, identique à celui implémenté
dans nos en­têtes pour le type de contenu de la fonction TokenMethod . Dans ce
corps, nous encodons les informations suivantes :

• client_id – Il s'agit de notre ID client généré dans la section Configuration OAuth de


Discord. • client_secret – Le
secret client généré dans la section Configuration OAuth de Discord. • grant_type = Ceci
est défini sur
authorization_code comme requis par l'API OAuth de Discord • redirect_uri – Notre URI
de redirection défini dans
la section Configuration OAuth de Discord, [Link] • code – Il
s'agit du code renvoyé par l'API Discord initiale

Appel d'autorisation. Dans notre connecteur personnalisé, voici le code généré et inséré
dans la chaîne de requête de notre redirect_uri. Si vous avez collé l'exemple d'URI
(AuthorizationUrl), il s'agit du code suivant : [Link]
redirect?code=WV9s0kMY3Rg6AsPvCzj6CgbgnUvwz0
Machine Translated by Google

Chacune de ces informations est également encodée dans notre requête effectuée via la fonction
TokenMethod . La figure 14 illustre également la réponse fournie par Discord. L'URI du
jeton Discord renvoie les informations suivantes au format JSON.

• token_type – Le type de jeton renvoyé, dans ce cas Bearer. • access_token – Le jeton


d'accès Bearer • expires_in – Quand le jeton expire •
refresh_token – Un jeton pour actualiser notre jeton
• scope – La portée du jeton d'accès

Notez que dans notre fonction TokenMethod , nous attendons un [Link] comme réponse
(Response). Bien que les paramètres exacts transmis dans ces requêtes varient selon les
implémentations API OAuth, le code M fourni devrait fonctionner avec des
modifications minimales pour la plupart des scénarios d'authentification OAuth. Heureusement,
le type d'authentification OAuth de Power Query prend désormais en charge une grande
partie du travail. Par exemple, si nous continuions notre exemple dans Postman, pour chaque
requête API suivante (par exemple, pour obtenir la liste des serveurs de l'utilisateur),
nous devrions inclure le jeton d'accès dans un paramètre appelé Authorization avec la valeur
« Bearer <access_token> ».

Cependant, le type d'authentification OAuth de Power Query gère automatiquement l'inclusion


des en­têtes nécessaires pour nous lors de ces demandes d'API ultérieures. Maintenant que
nous avons implémenté les fonctions de type d'authentification OAuth requises, nous pouvons
désormais modifier notre définition d'enregistrement de source de données pour changer le
type d'authentification d'Anonyme à OAuth.

Modification de la définition de l'enregistrement de la source de données

Une fois les fonctions OAuth requises implémentées, nous pouvons modifier notre définition de
source de données pour passer de l'authentification anonyme à l'authentification OAuth. Pour
cela, procédez comme suit :

1. Recherchez l'enregistrement de définition de la source de données,


TDGTPQM_Discord 2. Remplacez la définition de l'enregistrement par le code suivant :

// Description du type de source de données


TDGTPQM_Discord =
[ TestConnection = (dataSourcePath) => {“TDGTPQM_Discord.Contents”}, Authentication = [ OAuth = [ StartLogin =
StartLogin, FinishLogin =
FinishLogin ] ] ];

Notez que nous spécifions maintenant le type d'authentification OAuth fourni sous forme
d'enregistrement, qui spécifie nos fonctions StartLogin et FinishLogin pour les champs
correspondants. Notre type d'authentification OAuth étant désormais défini, il est
temps de tester l'authentification OAuth pour notre connecteur personnalisé. Pour ce faire, nous
devons d'abord ajouter un identifiant.
Machine Translated by Google

Ajout d'un justificatif d'identité

L'ajout d'informations d'identification dans Visual Studio Code émule le comportement de l'interface utilisateur
Power Query (comme l'éditeur Power Query) lorsque vous vous connectez ou vous authentifiez afin
de vous connecter à une source de données. Pour ajouter des informations d'identification, procédez
comme suit :

1. Si vous ne l'avez pas déjà fait, choisissez Fichier | Enregistrer tout dans Visual Studio
Menu de codes.

2. Développez POWER QUERY SDK dans le volet Explorateur .


3. Cliquez sur « Exécuter la fonction TestConnection ». Notez que vous recevrez un
erreur:

4. Échec de l'exécution de la requête en raison de l'erreur : Échec de l'exécution de la requête en raison de


Erreur : Impossible de trouver les informations
d'identification pour « TDGTPQM_Discord/TDGTPQM_Discord ».
5. Cliquez sur « Évaluer le fichier actuel ». Notez que vous recevez à nouveau une erreur.
message:
6. Des informations d'identification sont requises pour se connecter à la source TDGTPQM_Discord.
(Source : TDGTPQM_Discord.)
7. Cliquez sur Définir les informations d’identification.

8. Lorsque vous êtes invité à « Choisir le type de source de données », choisissez


TDGTPQM_Discord de la liste.
9. Lorsque vous êtes invité à « Choisir un fichier de requête/test », choisissez
TDGTPQM_Discord.[Link] dans la liste.
10. Lorsque vous êtes invité à « Choisir une méthode d’authentification », choisissez OAuth dans la liste.

Notez que si vous ne voyez qu'Anonymous dans la liste, il s'agit d'une des nombreuses bizarreries de
Visual Studio Code. Essayez d'enregistrer votre travail et de réexécuter les étapes 3 et 4. Si cela ne fonctionne
pas, choisissez Fichier | Fermer le dossier dans le menu, enregistrez votre travail si vous y êtes invité, puis rouvrez
le dossier avec Fichier | Ouvrir le dossier… Une fois le dossier rouvert, développez la section POWER
QUERY SDK dans le volet Explorateur et revenez à l'étape 5.

1. Une boîte de dialogue semblable à la figure 14.7 devrait s'afficher :


Machine Translated by Google

Figure 14.7 : Boîte de dialogue d'autorisation Discord

2. Cliquez sur le bouton Autoriser

Vous devriez recevoir le message « Les nouvelles informations d’identification OAuth ont été générées avec
succès ». Avec nos informations d’identification en place, nous pouvons maintenant tester notre connexion.

Tester la connexion

Bien que notre connecteur personnalisé ne fasse pas grand­chose d'autre que de répondre
essentiellement avec le texte omniprésent « Hello World », tester la connexion à ce stade
confirme que nos informations d'identification OAuth sont présentes. Pour tester la
connexion, procédez comme suit :

1. Développez la section POWER QUERY SDK dans le volet Explorateur . 2. Cliquez sur
« Exécuter la fonction TestConnection ». Cette fois, aucune erreur ne s'affiche.
affiché.
3. Assurez­vous que le fichier [Link] est sélectionné dans l'Explorateur
Dans le volet « Évaluer le fichier actuel », cliquez sur « Évaluer le fichier actuel ». Cette fois, un
onglet de résultat PQTest apparaît, avec une valeur commençant par
« Bonjour de TDGTPQM_Discord : ».

Une fois notre connexion personnalisée testée avec succès, confirmant que nos informations
d’identification OAuth sont créées et présentes dans Visual Studio Code, nous pouvons maintenant
passer à la récupération des données de l’API Discord par notre connecteur personnalisé.
Machine Translated by Google

Configuration de la navigation et du contenu

Il est maintenant temps de configurer notre connecteur personnalisé pour récupérer et présenter les
données de Discord. Si l'on considère l'expérience utilisateur dans l'éditeur Power Query lors de la
connexion à une source de données, on obtient l'expérience suivante :

1. Choisissez Obtenir des données, puis sélectionnez un connecteur de source de données.


2. Connectez­vous ou authentifiez­vous selon les options d'authentification
présenté.
3. Souvent, une boîte de dialogue Navigateur s'affiche dans laquelle vous pouvez parcourir les dossiers
et des tables pour récupérer les données d'aperçu.
4. Vous choisissez des tableaux de données dans la boîte de dialogue Navigateur et appuyez sur le
bouton OK pour récupérer les données.

Nous avons déjà implémenté notre type d'authentification, OAuth. Pour implémenter le reste des étapes en
code M, nous devons essentiellement exécuter ce processus dans l'ordre inverse, en procédant
comme suit :

1. Ajoutez des fonctions de récupération de données d'appel API ­ Ces fonctions


Implémenter la récupération des données depuis l'API Discord. Voici comment les données seront
récupérées et affichées dans le panneau d'aperçu de la boîte de dialogue du navigateur, ainsi que
comment elles seront récupérées et chargées dans l'éditeur Power Query, puis dans le modèle
de données.
2. Ajouter des fonctions de navigation – Ces fonctions présenteront la boîte de dialogue
Navigateur (le panneau de navigation de gauche) et lieront cette navigation aux opérations
de récupération de données appropriées (fonctions d’appel d’API) implémentées à l’étape 1.

3. Modifier la fonction [Link] – Terminez l’implémentation de la boîte de


dialogue Navigation en modifiant la fonction [Link] pour initialiser la
navigation.

Voyons comment implémenter la première étape de ce processus, en créant le code M pour effectuer les
appels API.

Ajout de fonctions de récupération de données d'appel API

Pour notre connecteur Discord personnalisé, nous souhaitons implémenter trois opérations de récupération
de données différentes liées aux éléments suivants :

• Les informations associées à l'identité de l'utilisateur. • Les informations relatives


aux serveurs ou guildes auxquels appartient l'utilisateur. • Les informations associées à l'identité de
l'utilisateur au sein de chaque serveur/guilde.

Pour mettre en œuvre ces opérations de récupération de données, procédez comme suit.
Immédiatement au­dessus de la définition du type de source de données, TDGTPQM_Discord, insérez
les trois fonctions suivantes :

// ** Identité
TDGTPQM_Discord.GetIdentity = () as table =>
Machine Translated by Google

laisser
apiCall = [Link]( [Link]( api_uri, [ RelativePath
= « utilisateurs/@me »

] ) ), sortie =
[Link]({apiCall})
dans

sortie ; // ** Serveurs (Guildes)

TDGTPQM_Discord.GetGuilds = () comme table =>


laisser
apiCall = [Link]( [Link]( api_uri, [ RelativePath
= “users/@me/guilds” ] ) ), sortie =
[Link](apiCall, [Link](),
null, null, ExtraValues in

sortie ; // ** Membre
Utilisateur
TDGTPQM_Discord.GetGuildMember = (guildid as text) as table =>
laisser
apiCall = [Link]( [Link]( api_uri, [ RelativePath
= “users/@me/guilds/” & guildid & “/member” ] ) ),
sortie = [Link]({apiCall}) dans

sortir;

Ces fonctions sont très similaires. Commençons par la fonction


TDGTPQM_Discord.GetIdentity . Elle récupère les informations relatives à
l'identité de l'utilisateur. Comme le montre sa définition, elle renvoie un type table
(table) et ne possède aucun paramètre. En lisant l'expression apiCall à l'envers,
nous construisons un URI composé de notre api_uri de base, créé lors de
l'ajout des paramètres de configuration, et du chemin relatif « users/@me ».
Cet URI devient alors : [Link] . Nous utilisons
[Link] pour récupérer la réponse de cet appel d'URI et spécifions que ce
contenu est un [Link]. L'expression de sortie récupère ensuite les
informations de ce document JSON à l'aide de la fonction [Link] .
La fonction suivante, [Link], récupère les informations relatives aux
serveurs, ou guildes dans le jargon de l'API Discord, auxquels l'utilisateur
appartient. Cette fonction ne prend également aucun paramètre et renvoie une
table. L'appel d'API est effectué vers l'URI suivante : [Link]
@me/guilds. L'expression de sortie est légèrement différente. Au lieu de traiter
des enregistrements, nous traitons une liste à l'aide de la fonction [Link] .
On peut naturellement se demander comment traiter la réponse de l'appel d'API :
utiliser la fonction [Link] ou la fonction
Machine Translated by Google

Fonction [Link]. La réponse se trouve dans la documentation fournie par


l'API appelée. Une astuce consiste à utiliser Postman pour générer et afficher la réponse. Pour
ce faire, procédez comme suit :

1. Collez l'AuthorizationUrl dans un navigateur Web et appuyez sur la touche Entrée.


Pour référence, cet URI est : 2.
[Link]
client_id=1128020929558098050&redirect_uri=http%3A%2F
%2Flocalhost%2Fdiscord
%2Fredirect&response_type=code&scope=identify%20guilds
%[Link]%20email%20connections
3. Copiez la valeur du paramètre de chaîne de requête de code renvoyée dans le cadre de
redirection_uri.
4. Comme indiqué dans la Figure 14. , utilisez Postman pour demander un jeton d'accès en
utilisant le code comme l'un des paramètres codés 5.
Utilisez ce jeton d'accès dans une autre requête Postman à l'appel d'API comme indiqué
dans la Figure 14.8 :

Figure 14.8 : Appel d'API Discord à l'aide de Postman

Comme le montre la figure 14, nous avons lancé une requête Get vers le point de terminaison
de l'API Discord : [Link] Nous avons inclus un
paramètre d'autorisation dans nos en­têtes avec la valeur « Bearer <jeton d'accès> ». Dans le
panneau inférieur, nous pouvons consulter la réponse renvoyée par l'appel d'API.

1. Copiez la réponse renvoyée et collez ces données dans un fichier.


Machine Translated by Google

2. Utilisez l'interface utilisateur de l'éditeur Power Query pour récupérer et développer/traiter les
informations dans le fichier.
3. Affichez le code M généré dans l'éditeur avancé.
4. Copiez le code M pertinent depuis l'éditeur avancé et collez­le
code comme expression de sortie pour notre fonction.

Nous espérons que cela vous aidera à comprendre comment créer le code M pour vos fonctions de
récupération de données. Terminons cette section en examinant rapidement la dernière fonction de
récupération de données,
TDGTPQM_Discord.GetGuildMember . Cette fonction récupère les
informations associées à l'identité de l'utilisateur au sein de chaque serveur/guilde. Elle
renvoie également une table en sortie, mais n'accepte qu'un seul paramètre : guildid.
Ce paramètre est utilisé dans l'appel d'API pour spécifier le serveur/la guilde à partir duquel
récupérer les informations utilisateur. L'appel d'API est au format suivant : [Link]
users/@me/guilds/<guildid>/member. L'expression de sortie utilise [Link] pour
transformer la réponse en table. Ceci conclut
notre explication des fonctions de récupération de données des appels d'API.

Nous pouvons maintenant passer aux fonctions qui fourniront notre expérience de navigation
dans la boîte de dialogue Navigation de l'interface utilisateur de Power Query Editor.

Ajout de fonctions de navigation

Avec nos fonctions de récupération de données d'appel API codées, nous pouvons désormais
implémenter les fonctions qui présenteront l'expérience utilisateur dans la boîte de dialogue
Navigation de l'interface utilisateur de Power Query Editor. Pour implémenter les fonctions
de navigation, nous devons d'abord coder une fonction d'assistance.
[Link]. Le code de cette fonction est directement tiré de l'exemple Microsoft
disponible ici : [Link]
tree/master/samples/NavigationTable . Ajoutez la fonction suivante à la fin du code du connecteur personnalisé :

// Fonctions des tables de navigation [Link]


= ( table comme table, keyColumns comme liste,
nameColumn comme texte,
dataColumn comme texte, itemKindColumn
comme texte, itemNameColumn comme
texte, isLeafColumn comme texte

) comme table => soit

tableType = [Link](table), newTableType = [Link](tableType,


keyColumns, true) méta [ [Link] = nameColumn, [Link] = dataColumn, [Link]
= itemKindColumn, [Link] = itemNameColumn, [Link] =
isLeafColumn ], navigationTable = [Link](table, newTableType) dans

table de navigation;
Machine Translated by Google

En résumé, cette fonction transforme une table en ajoutant les métadonnées attendues
par l'interface utilisateur du navigateur dans Power Query. Les métadonnées ajoutées
incluent la liste suivante :

• [Link] •
[Link] •
[Link] •
[Link] •
[Link]

Actuellement, vous devez ajouter manuellement cette fonction à votre code. Cependant,
Microsoft a indiqué qu'elle pourrait éventuellement être intégrée à la bibliothèque standard
M. Cette fonction accepte les arguments suivants :

• table – La table que vous souhaitez convertir en table de navigation. •


keyColumns – Les colonnes de clé primaire (valeurs uniques) pour votre
tableau.
• nameColumn – La colonne utilisée pour le nom d'affichage dans la boîte de
dialogue Navigateur.
• dataColumn – La colonne contenant une table ou une fonction qui
Renvoie un tableau. Il s'agit des données réelles qui seront récupérées si elles sont
sélectionnées dans la boîte
de dialogue du navigateur. • itemKindColumn – La colonne qui spécifie le type
d'icône à afficher dans la boîte de dialogue du navigateur. Les valeurs de cette
colonne peuvent
être
l'une des suivantes :
◦ Cube ◦
CubeDatabase ◦
CubeView ◦
CubeViewFolder ◦
Database ◦
DatabaseServer

DefinedName
◦ Dimension
◦ Feed ◦
Folder ◦
Function
◦ Record ◦ Sheet ◦ Subcube ◦ Table ◦ View
• itemNameColumn – La colonne qui spécifie le mode de gestion de l'aperçu des
données dans la boîte de dialogue du Navigateur. La plupart du temps, la
valeur de itemKindColumn est identique à celle de itemNameColumn.

• isLeafColumn – La colonne qui indique si l'élément peut être développé ou


non. Cette colonne doit contenir une valeur logique ou booléenne.
Machine Translated by Google

Des informations supplémentaires sur cette fonction sont disponibles ici : https://
[Link]/en­us/power­query/handling­navigation­tablesEnsuite, immédiatement au­
dessus de la fonction TDGTPQM_Discord.GetIdentity , ajoutez les trois fonctions suivantes :

TDGTPQM_Discord.UsersNavigation = () as table => // Navigation //** Navigation des utilisateurs


let objects = #table( {“Nom”, “Clé”,
“Données”, “Type d’élément”, “Nom d’élément”,
“IsLeaf”},
{ {“Moi”, “moi”, TDGTPQM_Discord.GetIdentity(),
“Enregistrement”, “Enregistrement”, true} } ), Navigation = [Link](objects, {“Clé”}, “Nom”, “Données”, “Type d’élément”, in
Navigation;
TDGTPQM_Discord.GuildsNavigation = () as table => // Navigation //** Navigation des guildes (serveur) let objects = #table( {“Nom”, “Clé”, “Données”, “Type d’élément”,
“Nom d’élément”,
“IsLeaf”},
{ {“Serveurs”, “guildes”, TDGTPQM_Discord.GetGuilds(), “Table”, “Table”, true} } ),

Navigation = [Link](objets, {« Clé »}, « Nom », « Données », « Type d'élément », dans Navigation ; TDGTPQM_Discord.MemberNavigation = () as table => //
Navigation //

** Navigation d'adhésion let

servers = [Link](TDGTPQM_Discord.GetGuilds(), « Colonne1 », {« nom », addDataColumn = [Link](serveurs, « Données », each TDGTPQM_Discord.GetGuildMembe

addItemKindColumn = [Link](addDataColumn, « Type d'élément », each « Enregistrement »), addItemNameColumn = [Link](addItemKindColumn, « Nom d'élément », each « Fonction »)
addIsLeafColumn = [Link](addItemNameColumn, « IsLeaf », each true), Navigation = [Link](addIsLeafColumn, {« Clé »}, « Nom », « Données », « Élément dans la

navigation ;

Les deux premières fonctions, TDGTPQM_Discord.UsersNavigation et


TDGTPQM_Discord.GuildsNavigation , sont quasiment identiques. Dans les deux cas, une
expression d'objet définit une table contenant les colonnes suivantes :

• Nom •
Clé •
Données
• Type
d'élément • Nom
de l'élément • IsLeaf

Pour chaque nœud, un seul nœud de navigation est défini. La fonction


TDGTPQM_Discord.UsersNavigation définit les éléments suivants.
Machine Translated by Google

valeurs pour la ligne unique de ce tableau :

• Moi
• moi
• TDGTPQM_Discord.GetIdentity() • Enregistrement

Enregistrement
• vrai

Selon cette définition, le mot « Moi » apparaîtra dans la boîte de dialogue du navigateur
pour ce nœud. Le nom ou la clé unique du nœud est « moi ». Les données récupérées en
sélectionnant ce nœud sont celles récupérées par notre fonction de récupération de
données d'appel d'API TDGTPQM_Discord.GetIdentity. L'icône et l'aperçu sont
spécifiés comme étant des enregistrements, et la valeur finale « true » indique qu'il s'agit
d'un nœud feuille (point final) et non d'un dossier extensible, par exemple. La fonction
TDGTPQM_Discord.GuildsNavigation est presque identique, mais spécifie une
valeur de colonne « Données » pour notre fonction de récupération de données d'appel
d'API TDGTPQM_Discord.GetGuilds. De plus, nous spécifions que l'icône et l'aperçu
des données doivent être traités comme une table plutôt qu'un enregistrement. Dans les
deux cas, cette table est ensuite transmise à la fonction
[Link] avec les paramètres supplémentaires référençant les
colonnes appropriées de notre table d'objets . La fonction TDGTPQM_Discord.MemberNavigation
présente une navigation dynamique plus complexe. Cette fonction utilise notre fonction
de récupération de données d'appel d'API
TDGTPQM_Discord.GetGuilds pour récupérer la liste des serveurs auxquels
l'utilisateur appartient. Les enregistrements renvoyés sont étendus pour les colonnes name
et id renvoyées par l'appel d'API et renommés Name et Key. Nous ajoutons ensuite
les colonnes supplémentaires requises par la fonction [Link] , notamment
une colonne Data , où nous appelons notre fonction TDGTPQM_Discord.GetGuildMember ,
en passant la clé (identifiant du serveur/de la guilde) comme unique paramètre. Nous
spécifions également une colonne ItemKind avec la valeur « Record » et une
colonne IsLeaf contenant la valeur logique true. Pour la colonne ItemName , au lieu de
spécifier la même valeur que pour la colonne ItemKind (« Record »), nous spécifions
la valeur « Function ». Ceci est nécessaire car il s'agit d'une table de navigation
générée dynamiquement. Ceci termine notre explication des fonctions de la table de
navigation. Nous sommes maintenant prêts à terminer notre connecteur
personnalisé en modifiant la fonction TDGTPQM_Discord.Contents , alors faisons­le
ensuite.

Modification de la fonction Contenu

Il est temps de finaliser le code de notre connecteur personnalisé. La dernière


modification nécessaire consiste à modifier la fonction TDGTPQM_Discord.Contents
afin de présenter le niveau supérieur de notre navigation, qui apparaîtra dans la boîte
de dialogue Navigation de l'interface utilisateur de Power Query. Pour cela, suivez
ces étapes :

1. Localisez la fonction TDGTPQM_Discord.Contents dans votre code de connecteur


personnalisé.
Machine Translated by Google

2. Remplacez la fonction TDGTPQM_Discord.Contents par la fonction


suivant:

[[Link]=“TDGTPQM_Discord”, Publish=“TDGTPQM_Discord.Publish”] shared TDGTPQM_Discord.Contents = () => let objects =


#table( {“Nom”, “Clé”, “Données”, “Type d’élément”, “Nom d’élément”, “IsLeaf”},
{ {“Utilisateurs”,
“Dossier_utilisateurs”,
TDGTPQM_Discord.Navigation_utilisateurs(), “Dossier”, “utilisateur {“Serveurs”, “Dossier_guildes”, TDGTPQM_Discord.Navigation_guildes(),
“Dossier”, “ {“Adhésion”,
“Dossier_adhésion”, TDGTPQM_Discord.Navigation_membre(), “Fol } ), Navigation = [Link](objects, {“Clé”}, “Nom”, “Données”, “Type d’élément”, in Navigation;

Comme vous pouvez le constater, le code est très similaire à nos deux premières fonctions de
navigation, TDGTPQM_Discord.UserNavigation et
TDGTPQM_Discord.GuildsNavigation. Nous définissons à nouveau une expression d'objet qui
renvoie une table contenant les colonnes attendues par la fonction
[Link] . Chaque ligne de cette table contient un nom (Name) et une clé unique
(Key) , ainsi qu'une spécification de ItemKind ( Dossier), ItemName ( Dossier) et IsLeaf
( Faux).
Pour la colonne Données, nous spécifions les valeurs de nos fonctions de table de navigation
correspondantes, selon le cas, à savoir :

• TDGTPQM_Discord.UserNavigation •
TDGTPQM_Discord.GuildsNavigation •
TDGTPQM_Discord.MemberNavigation

Comme pour les fonctions de navigation, nous alimentons cette table d'objets vers notre
fonction [Link] en sortie de la fonction
TDGTPQM_Discord.Contents. Le codage de notre connecteur personnalisé est maintenant
terminé. Nous sommes enfin prêts à l'installer et à l'utiliser dans Power BI Desktop.

Installation et utilisation d'un connecteur personnalisé

Une fois le codage de notre connecteur personnalisé terminé, il est temps d'installer et d'utiliser le
connecteur personnalisé créé pour récupérer les données de Discord. Pour installer et utiliser votre
connecteur personnalisé, suivez ces étapes :

1. Avec votre projet ouvert dans Visual Studio Code, enregistrez votre travail en
en cliquant sur Fichier | Enregistrer tout dans le menu.
2. Développez la section POWER QUERY SDK dans le volet Explorateur .
3. Cliquez sur la fonction Exécuter TestConnection et assurez­vous qu'aucune erreur n'est
affiché.
4. Assurez­vous que le fichier [Link] est sélectionné dans l'Explorateur
Cliquez sur le panneau « Évaluer le fichier actuel », puis sur « Évaluer le fichier actuel ». Cette fois, l'onglet
« Résultats du test PQ » devrait afficher les informations suivantes, comme illustré à la figure 14.9 :
Machine Translated by Google

Figure 14.9 : Sortie d'évaluation de [Link]

Comme vous pouvez le voir, il s'agit du niveau supérieur de la façon dont notre navigation sera
affichée dans la boîte de dialogue Navigation de l'interface utilisateur Power Query et correspond
directement aux spécifications de notre expression d'objets de notre fonction
TDGTPQM_Discord.Contents .

1. Cliquez sur le lien du dossier bin\AnyCPU\Debug dans le volet Explorateur pour développer
ce dossier.
2. Cliquez avec le bouton droit sur le fichier TDGTPQM_Discord.mez et choisissez Révéler dans
Explorateur de fichiers.
3. Copiez le fichier TDGTPQM_Discord.mez .
4. Dans l’Explorateur de fichiers, accédez à votre répertoire Documents .
5. Créez un dossier appelé « Microsoft Power BI Desktop ».
6. Accédez au dossier « Microsoft Power BI Desktop » .
7. Créez un dossier appelé « Connecteurs personnalisés ».
8. Accédez au dossier Connecteurs personnalisés .
9. Collez le fichier TDGTPQM_Discord.mez .
10. Ouvrez Power BI Desktop.
11. Dans le ruban, accédez à Fichier | Options et paramètres | Options.
12. Dans la boîte de dialogue Options , choisissez Sécurité dans la navigation de gauche.
13. Sous Extensions de données, sélectionnez le bouton radio « (Non recommandé)
Autoriser le chargement de toute extension sans validation ni avertissement ».

14. Cliquez sur le bouton OK .


15. Redémarrez Power BI Desktop.
16. Dans l’ onglet Accueil du ruban, choisissez Transformer les données pour ouvrir l’éditeur Power
Query.
17. Dans l' onglet Accueil du ruban de l'éditeur Power Query, choisissez
Nouvelle source | Plus.
18. Dans la barre de recherche, saisissez « tdgtpqm ».

19. Choisissez le connecteur TDGTPQM_Discord (Bêta) , puis cliquez sur le bouton « Connecter » .
La boîte de dialogue suivante s'affiche, comme illustré à la figure 14.10 :
Machine Translated by Google

Figure 14.10 : Notification de connexion à un service tiers

20. Appuyez sur le bouton Continuer .


21. Cliquez sur le bouton Se connecter .
22. Autorisez l'application en cliquant sur le bouton Autoriser dans le
boîte de dialogue.
23. Cliquez sur le bouton Connecter .
24. La boîte de dialogue Navigateur s'affiche comme dans la Figure 14.11 :

Figure 14.9 : Boîte de dialogue Navigateur du connecteur personnalisé TDGTPQM._Discord dans


l'éditeur Power Query
Machine Translated by Google

Félicitations ! Vous avez créé avec succès un connecteur personnalisé pour Power
Query qui se connecte à l'API Discord et récupère les données depuis celle­ci. Vous pouvez
utiliser ce connecteur de la même manière que les connecteurs par défaut inclus
dans Power BI Desktop.

Résumé
Dans ce chapitre, nous avons exploré l'extension des fonctionnalités de Power
Query en ajoutant une bibliothèque de fonctions personnalisées et en créant un
connecteur personnalisé. Power Query est un puissant outil de transformation et d'intégration
de données, mais son véritable potentiel peut être exploité en développant vos
propres connecteurs pour accéder à des sources de données ou des API spécialisées.
Cela vous permet d'importer des données provenant de systèmes ou de services
uniques non pris en charge nativement par Power Query. Nous avons commencé
par préparer un environnement de développement, notamment en configurant Visual Studio
Code, le SDK Power Query et des éléments de Discord, notre source de données cible. Nous
avons ensuite créé et expliqué le modèle de base pour les extensions Power Query
personnalisées. Nous avons ensuite codé et configuré l'authentification OAuth pour notre connecteur personnalisé.
De plus, nous avons écrit le code M personnalisé pour récupérer les données de l'API
Discord et présenter une expérience de navigation pour la boîte de dialogue Navigateur
de l'interface utilisateur de Power Query. Enfin, nous avons montré comment installer et
utiliser le connecteur personnalisé dans Power BI Desktop. Tout au long de ce chapitre,
nous avons expliqué en détail le processus de développement et l'anatomie d'un
connecteur personnalisé, en décomposant ses composants et son code pour expliquer leur
fonction. Nous avons examiné comment définir les métadonnées du connecteur,
établir des connexions, gérer l'authentification et implémenter la logique de récupération
et de transformation des données.

Vous aimerez peut-être aussi