3 | Accès aux données et combinaison
En bref
- Objectifs : reconnaître les fonctions d'accès aux sources dans une étape Source ; régler les options de Csv.Document et Excel.Workbook ; lire du contenu web ; combiner des tables en M avec Table.Combine, Table.NestedJoin et Table.Join.
- Prérequis : chapitre « 2 | Lire et modifier le code généré ».
- Niveau : avancé.
Pourquoi ?
L'étape Source d'une requête appelle toujours une fonction d'accès : Excel.Workbook, Csv.Document, Sql.Database... Comprendre leurs arguments permet de corriger une connexion (encodage, en-têtes, délimiteur), de changer de source sans tout refaire, ou d'accéder à une source que l'interface gère mal. Les fonctions de combinaison, elles, sont le code des commandes Ajouter des requêtes et Fusionner des requêtes.
Notions clés
Fonctions d'accès aux fichiers et dossiers
| Source | Fonctions |
| Fichier (binaire) | File.Contents |
| Texte / CSV | Csv.Document |
| Excel | Excel.Workbook, Excel.CurrentWorkbook (dans Excel uniquement) |
| Dossier | Folder.Files, Folder.Contents |
| JSON | Json.Document |
| XML | Xml.Tables, Xml.Document |
Pdf.Tables | |
| Stockage Azure | AzureStorage.Blobs, AzureStorage.BlobContents, AzureStorage.DataLake, AzureStorage.Tables |
Les fichiers SharePoint et OneDrive professionnels, les bases de données et les services en ligne sont présentés dans la partie 1.
File.Contents
File.Contents(chemin) renvoie le contenu binaire d'un fichier. Il est passé à une fonction qui sait l'interpréter : Csv.Document, Excel.Workbook, Json.Document, Xml.Tables.
Astuce : une fonction saisie sans argument ni parenthèses (= File.Contents dans une requête vide) affiche sa documentation et une boîte de saisie de ses paramètres.

Csv.Document
Syntaxe : Csv.Document(source, columns, delimiter, extraValues, encoding), tous les arguments sauf le premier étant facultatifs. En pratique, l'interface génère un enregistrement d'options en deuxième argument :
| Option | Rôle | Valeur par défaut |
Delimiter | Séparateur de colonnes (",", ";", "#(tab)") | "," |
Columns | Nombre de colonnes, liste de noms ou type de table ; les colonnes en trop sont ignorées | Déduit du fichier |
Encoding | Page de codes : 65001 (UTF-8), 1252 (Windows), 1200 (UTF-16) | 65001 |
CsvStyle | CsvStyle.QuoteAfterDelimiter (guillemets significatifs seulement après un délimiteur) ou CsvStyle.QuoteAlways | CsvStyle.QuoteAfterDelimiter |
QuoteStyle | QuoteStyle.Csv (un saut de ligne entre guillemets fait partie de la valeur) ou QuoteStyle.None (tout saut de ligne termine la ligne) | QuoteStyle.Csv |
L'argument extraValues règle le sort des valeurs en trop : ExtraValues.List, ExtraValues.Error ou ExtraValues.Ignore. Source
Excel.Workbook
Syntaxe : Excel.Workbook(classeur, useHeaders, delayTypes).
useHeaders(true,falseounull) : utilise la première ligne comme en-têtes ; vous pouvez aussi laissernullet ajouter une étape Utiliser la première ligne pour les en-têtes.delayTypes: laisse les colonnes sans type pour que vous les typiez vous-même.- Le deuxième argument peut aussi être un enregistrement d'options :
UseHeaders,DelayTypesetInferSheetDimensions. AvecInferSheetDimensions = true, la zone utilisée de chaque feuille est recalculée en lisant la feuille, au lieu de se fier aux dimensions enregistrées dans le fichier (format .xlsx uniquement). Source
Le résultat est une table de navigation (colonnes Name, Data, Item, Kind, Hidden), dans laquelle l'étape Navigation sélectionne une feuille ou un tableau : Source{[Item = "Ventes", Kind = "Sheet"]}[Data].
Contenu web
Le connecteur Web propose, avec l'option Exemples, le Code HTML ou le Texte affiché d'une page :

| Fonction | Résultat |
Web.BrowserContents(url) | Le code HTML de la page, tel qu'un navigateur l'affiche |
Html.Table(html, sélecteurs) | Une table extraite du HTML à l'aide de sélecteurs CSS |
Web.Page(html) | Une table de navigation dans la structure (DOM) de la page |
Web.Contents(url, options) | Le contenu binaire de la réponse, comme File.Contents pour un fichier |
Exemples (adaptez l'URL) :
let
Source = Web.BrowserContents("https://www.example.com/"),
Texte = Html.Table(Source, {{"Contenu", "BODY"}}),
Resultat = Texte[Contenu]{0}
in
Resultatlet
Source = Web.Contents(
"https://api.example.com",
[
RelativePath = "search",
Query = [query = "power bi", type = "book"],
Timeout = #duration(0, 0, 0, 30)
]
)
in
SourceAvec Web.Contents, gardez une URL de base fixe et placez la partie variable de l'adresse dans les options RelativePath et Query, plutôt que de concaténer l'URL. Source Une URL entièrement construite par concaténation est une source dynamique, que le service Power BI ne sait pas toujours actualiser. Source (actualisation)
Fonctions binaires : le cas d'Entrer des données
Accueil > Entrer des données stocke la table saisie dans le code, compressée et encodée en Base64. Pour une table de trois lignes (One 1, Two 2, Three 3), le code généré est :
let
Source = Table.FromRows(
Json.Document(
Binary.Decompress(
Binary.FromText("i45W8s9LVdJRMlSK1YlWCinPB7KNIOyMolSQjLFSbCwA", BinaryEncoding.Base64),
Compression.Deflate
)
),
let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t, Column2 = _t]
),
#"Type modifié" = Table.TransformColumnTypes(Source, {{"Column2", Int64.Type}})
in
#"Type modifié"Ne modifiez pas cette chaîne à la main : utilisez l'engrenage de l'étape Source pour rouvrir la grille de saisie.
Bases de données et cubes
Chaque base a sa fonction d'accès, qui reçoit le serveur et la base : Sql.Database (SQL Server, Azure SQL), Oracle.Database, MySQL.Database, PostgreSQL.Database, DB2.Database, Teradata.Database, SapHana.Database, Access.Database, AnalysisServices.Database (modèles Analysis Services). Ces sources prennent en charge le query folding (page « Query folding »). Source
Combiner des tables
Table.Combine({Table1, Table2})empile les lignes (Ajouter des requêtes). SourceTable.NestedJoin(Table1, {"ID"}, Table2, {"ID"}, "NouvelleColonne", JoinKind.LeftOuter)ajoute une colonne de tables à développer (Fusionner des requêtes). SourceTable.Joinréalise la jointure et renvoie directement les colonnes des deux tables, sans étape de développement. SourceTable.FuzzyNestedJoinetTable.FuzzyJoinsont les équivalents avec correspondance approximative. Source

Exemple
Code testable dans une requête vide : jointure interne entre des clients et leurs commandes avec Table.Join.
Table.Join(
Table.FromRecords({
[CustomerID = 1, Name = "Bob", Phone = "123-4567"],
[CustomerID = 2, Name = "Jim", Phone = "987-6543"],
[CustomerID = 3, Name = "Paul", Phone = "543-7890"],
[CustomerID = 4, Name = "Ringo", Phone = "232-1550"]
}),
"CustomerID",
Table.FromRecords({
[OrderID = 1, CustomerID = 1, Item = "Fishing rod", Price = 100.0],
[OrderID = 2, CustomerID = 1, Item = "1 lb. worms", Price = 5.0],
[OrderID = 3, CustomerID = 2, Item = "Fishing net", Price = 25.0],
[OrderID = 4, CustomerID = 3, Item = "Fish tazer", Price = 200.0],
[OrderID = 5, CustomerID = 3, Item = "Bandaids", Price = 2.0],
[OrderID = 6, CustomerID = 1, Item = "Tackle box", Price = 20.0],
[OrderID = 7, CustomerID = 5, Item = "Bait", Price = 3.25]
}),
"CustomerID"
)Le résultat compte 6 lignes : Ringo (client 4, sans commande) et la commande 7 (client 5 inconnu) disparaissent, car la jointure par défaut de Table.Join est interne.
[Capture : résultat de l'exemple Table.Join, 6 lignes avec les colonnes des deux tables]
Pièges et bonnes pratiques
- Un chemin de fichier écrit en dur dans
File.Contentscasse la requête si le fichier est déplacé : utilisez un paramètre. Table.Joinéchoue si les deux tables ont des colonnes de même nom autres que la clé ;Table.NestedJoinn'a pas ce problème, car les colonnes restent dans la colonne imbriquée.- Vérifiez l'encodage d'un CSV (accents mal affichés) avant toute autre transformation.
À retenir
- L'étape Source appelle une fonction d'accès ;
File.Contentsfournit le binaire aux fonctions de lecture. - Les options de
Csv.DocumentetExcel.Workbookrèglent délimiteur, encodage, en-têtes et types. - Avec
Web.Contents, gardez une URL de base fixe et passez la partie variable dansRelativePathetQuery. Table.Combineempile,Table.NestedJoinetTable.Joinrapprochent par une clé.