Power Query Simplifier/Universaliser l'import multiple de fichiers CSV

Staple1600

XLDnaute Barbatruc
Bonsoir le forum

Je cherche à simplifier l'import de CSV à partir d'un dossier donné.

Quand on utilise l'assistant de PowerQuery, il y a de nombreuses étapes (voir ci-dessous)
PQ_CSV_Capture.PNG


PowerQuery:
let
    Source = Folder.Files("C:\Users\STAPLE\Documents\PQ_CSV"),
    #"Fichiers masqués filtrés1" = Table.SelectRows(Source, each [Attributes]?[Hidden]? <> true),
    #"Appeler une fonction personnalisée1" = Table.AddColumn(#"Fichiers masqués filtrés1", "Transformer le fichier", each #"Transformer le fichier"([Content])),
    #"Colonnes renommées1" = Table.RenameColumns(#"Appeler une fonction personnalisée1", {"Name", "Source.Name"}),
    #"Autres colonnes supprimées1" = Table.SelectColumns(#"Colonnes renommées1", {"Source.Name", "Transformer le fichier"}),
    #"Colonne de tables développée1" = Table.ExpandTableColumn(#"Autres colonnes supprimées1", "Transformer le fichier", Table.ColumnNames(#"Transformer le fichier"(#"Exemple de fichier"))),
    #"Type modifié" = Table.TransformColumnTypes(#"Colonne de tables développée1",{{"Source.Name", type text}, {"ITEM_1", Int64.Type}, {"ITEM_2", Int64.Type}, {"ITEM_3", Int64.Type}, {"ITEM_4", Int64.Type}, {"ITEM_5", Int64.Type}, {"ITEM_6", Int64.Type}, {"ITEM_7", Int64.Type}, {"ITEM_8", Int64.Type}})
in
    #"Type modifié"
On peut faire plus simple et générique que Microsoft, non ?

Quelqu'un aurait-il un code M plus synthétique et universel(*) pour faire cette opération ?
(*) notamment ici #"Type modifié" : ne pas avoir à lister tous les noms des colonnes

PS: j'ai regardé sur le forum les discussions avec le préfixe PowerQuery, j'ai regardé quelques vidéos sur YT (mais c'est pas pratique) et enfin je n'ai pas solliciter ChatGPT, préférant mes frères humains (notamment ceux d'XLD) et aussi un peu en souvenir de Sarah Connor. ;)

NB: Il me semble que les étapes de Microsoft sont peu ou prou ce que montrent cette vidéo, non ?
https://www.youtube.com/watch?app=desktop&v=IsLB3XR9eno
 
Solution
Re,

@alexga78
j'utilise aussi Office 365

Les fichiers de test CSV sont issus d'Excel (Enregistrer sous -> CSV, séparateur point virgule)

Tu as essayé avec les fichiers contenu dans le zip du message#2 ?

Tu peux mettre ton code M complet, stp avec le let .... in
merci

Sinon tu vois comment simplifier le code "anglophone" ?

Re,
les fichiers testés sont ceux du zip.

un autre essai pour le nom des fichiers

PowerQuery:
let
    Source = Folder.Files("C:\Users\STAPLE\Documents\PQ_CSV"),
    Result = let x =  Table.SelectColumns(Table.AddColumn(Source, "Custom", each Table.PromoteHeaders(Csv.Document([Content],[Delimiter=";", Encoding=TextEncoding.Windows, QuoteStyle=QuoteStyle.None]))),{"Name","Custom"}) in Table.ExpandTableColumn(x,"Custom", List.Union(Table.TransformColumns(x, {"Custom", each...

Amilo

XLDnaute Accro
Bonjour à tous,
Un autre code PQ plus ou moins identique à ceux déjà proposés
Si besoin, ajoutez une étape : Table.SelectRows

VB:
let
    Source = Folder.Files("C:\Users\STAPLE\Documents\PQ_CSV"),
    Personnalisé1 = Source[[Folder Path],[Name]],
    #"Personnalisée ajoutée" = Table.AddColumn(Personnalisé1, "Personnalisé", each  Table.PromoteHeaders(Csv.Document(File.Contents([Folder Path] & [Name]), null, ";", 1 , 1252))),
    Personnalisé2 = Table.Combine(#"Personnalisée ajoutée"[Personnalisé])
in
    Personnalisé2
Cordialement
 

Staple1600

XLDnaute Barbatruc
Bonjour @Amilo

Certaines étapes de ton code M sont manuelles et d'autres faite avec l'assistant PQ, non ?
Personnalisé1=manuelle
#"Personnalisée ajoutée"= assistant
Personnalisé2=manuelle

On ne peut à partir d'une requête vide, faire toutes les étapes à la souris avec l'assistant PQ ?

1) Je créé une requête vide, j'affiche l'éditeur avancé
et je remplace Source="" par Source= Folder.Files("C:\Users\STAPLE\Documents\PQ_CSV"),
et je continue tout le reste à la souris

Sauf que par exemple à l'étape Personnalisée ajoutée, il faut ajouter la formule à la main, non ?
= Table.AddColumn(Personnalisé1, "Personnalisé", each Table.PromoteHeaders(Csv.Document(File.Contents([Folder Path] & [Name]), null, ";", 1 , 1252)))
Car si on ne connait pas la syntaxe, et quon se contente de manipuler PQ à la souris, l'assistant produit ceci
= Table.AddColumn(Personnalisé1, " Personnalisé", each [Folder Path][Name])
et donne une erreur

Dans ton code M, il manque la partie permettant d'avoir le nom des fichiers en colonne 1
 

Amilo

XLDnaute Accro
Bonjour @Staple1600 ,
Les 3 étapes que vous citez sont en manuel
Code:
Personnalisé1=manuelle
#"Personnalisée ajoutée"= manuelle
Personnalisé2=manuelle

Concernant le nom de la feuille dans la table, vous pouvez ajouter une nouvelle étape comme ci-dessous :
Code:
#"Personnalisée ajoutée1" = Table.AddColumn(#"Personnalisée ajoutée", "Personnalisé.1", each Table.AddColumn([Personnalisé], "Personnalisé.1", (x)=> [Name])),

Ce qui donnerait :
Code:
let
    Source = Folder.Files("C:\Users\STAPLE\Documents\PQ_CSV"),
    Personnalisé1 = Source[[Folder Path],[Name]],
    #"Personnalisée ajoutée" = Table.AddColumn(Source, "Personnalisé", each  Table.PromoteHeaders(Csv.Document(File.Contents([Folder Path] & [Name]), null, ";", 1 , 1252))),
    #"Personnalisée ajoutée1" = Table.AddColumn(#"Personnalisée ajoutée", "Personnalisé.1", each Table.AddColumn([Personnalisé], "Personnalisé.1", (x)=> [Name])),
    Personnalisé2 = Table.Combine(#"Personnalisée ajoutée1"[Personnalisé.1])
in
    Personnalisé2

Je reviens vers vous avec une autre solution uniquement par l'assistante PQ sans passer par celle indiquée dans votre 1er message #1
Cordialement
 
Dernière édition:

Staple1600

XLDnaute Barbatruc
Bonjour @Amilo

Merci pour cet ajout

J'ai ajouté une dernière étape pour avoir la colonne Nom au début
= Table.ReorderColumns(Personnalisé2,{"Personnalisé.1", "ITEM_1", "ITEM_2", "ITEM_3", "ITEM_4", "ITEM_5", "ITEM_6", "ITEM_7", "ITEM_8"})

Je n'ai pas réussi à modifier votre syntaxe pour que cela se fasse directement à l'étape
#"Personnalisée ajoutée1"
 

Amilo

XLDnaute Accro
Re,
Je regarde également cette partie, mais sinon une autre proposition rapide mail manuelle avec une étape "Table.ExpandTableColumns" au lieu de Table.Combine

VB:
     #"Personnalisée ajoutée1" = Table.AddColumn(#"Personnalisée ajoutée", "Nom fichier", each Table.AddColumn([Personnalisé], "Nom fichier", (x)=> [Name])),
    #"Autres colonnes supprimées" = Table.SelectColumns(#"Personnalisée ajoutée1",{"Nom fichier"}),
    #"Nom fichier développé" = Table.ExpandTableColumn(#"Autres colonnes supprimées", "Nom fichier", {"Nom fichier", "ITEM_1", "ITEM_2", "ITEM_3", "ITEM_4", "ITEM_5", "ITEM_6", "ITEM_7", "ITEM_8"})
in
    #"Nom fichier développé"

Cordialement
 

Pièces jointes

  • Nom fichier.jpg
    Nom fichier.jpg
    203.1 KB · Affichages: 7

Amilo

XLDnaute Accro
Re,
J'ai essayé avec les fonctions "Binary" mais sans y parvenir.
Du coup je ne vois pas comment éviter la saisie manuelle de Csv.Document sauf peut-être à bricoler des cellules dans Excel en paramétrant un texte "Csv.Document" et un chemin Path

Le plus simple que j'ai, sans trop avoir de codes en manuel est :
VB:
let
    Source = Folder.Files("C:\Users\STAPLE\Documents\PQ_CSV"),
    Personnalisé1 = Source[[Folder Path],[Name]],
    #"Personnalisée ajoutée" = Table.AddColumn(Personnalisé1, "Personnalisé", each  Table.PromoteHeaders(Csv.Document(File.Contents([Folder Path] & [Name]), null, ";", 1 , 1252))),
    #"Colonnes supprimées" = Table.RemoveColumns(#"Personnalisée ajoutée",{"Folder Path"}),
    #"Personnalisé développé" = Table.ExpandTableColumn(#"Colonnes supprimées", "Personnalisé", {"ITEM_1", "ITEM_2", "ITEM_3", "ITEM_4", "ITEM_5", "ITEM_6", "ITEM_7", "ITEM_8"}, {"ITEM_1", "ITEM_2", "ITEM_3", "ITEM_4", "ITEM_5", "ITEM_6", "ITEM_7", "ITEM_8"})
in
    #"Personnalisé développé"

Cordialement
 

Staple1600

XLDnaute Barbatruc
Re

Merci @Amilo pour vos essais

J'ai essayé en utilisant l'Assistant
(Cela revient à utiliser ce qu'on voit dans mon 1er message, puis de revenir sur certaines étapes et de les éditer manuellement)
Ce qui donne un truc du genre
(mais c'est justement ce que je voulais éviter ;))
PowerQuery:
let
    Source = Folder.Files("C:\Users\STAPLE\Documents\PQ_CSV"),
    #"Fichiers masqués filtrés1" = Table.SelectRows(Source, each [Attributes]?[Hidden]? <> true),
    #"Appeler une fonction personnalisée1" = Table.AddColumn(#"Fichiers masqués filtrés1", "Transformer le fichier (2)", each #"Transformer le fichier (2)"([Content])),
    #"Colonnes renommées1" = Table.RenameColumns(#"Appeler une fonction personnalisée1", {"Name", "Source.Name"}),
    #"Autres colonnes supprimées1" = Table.SelectColumns(#"Colonnes renommées1", {"Source.Name", "Transformer le fichier (2)"}),
    #"Colonne de tables développée1" = Table.ExpandTableColumn(#"Autres colonnes supprimées1", "Transformer le fichier (2)", Table.ColumnNames(#"Transformer le fichier (2)"(#"Exemple de fichier (2)"))),
    #"Type modifié" = Table.TransformColumnTypes(#"Colonne de tables développée1",{{"Source.Name", type text}, {"ITEM_1", Int64.Type}, {"ITEM_2", Int64.Type}, {"ITEM_3", Int64.Type}, {"ITEM_4", Int64.Type}, {"ITEM_5", Int64.Type}, {"ITEM_6", Int64.Type}, {"ITEM_7", Int64.Type}, {"ITEM_8", Int64.Type}})
in
    #"Type modifié"
Donc pour éviter l'assistant de PQ, pas d'autres choix que de copier un code M prêt à l'emploi dans une requête vide, non ?

le code M doit être générique
Donc dans ton dernier code, à cette étape: #"Personnalisé développé" , il faudrait ne pas s'occuper des noms des colonnes
(voir par exemple le code dans le message#36)
 

Amilo

XLDnaute Accro
@Staple1600 ,
La puissance de PQ vient surtout de la saisie manuelle.
Mais c'est bien d'avoir essayé en retravaillant le code de l'assistant du message #1, c'est un bon moyen d'apprendre.
Concernant l'étape des noms de colonnes en dur, ce problème peut être effectivement réglé avec le code du message #36 au cas où des noms de colonnes seraient modifiés.
Pour une fusion de fichiers .csv ou autres (.xlsx....etc), à ma connaissance, il faudrait passer par au moins une ligne de code en manuel.

Cordialement
 

Staple1600

XLDnaute Barbatruc
Re

@Amilo
C'est plus par curiosité que je continue à faire des essais dans PQ.

Ce qui m'étonne (comme je l'ai dit plus bas) c'est que l'assistant passe tout ce qu'on voit sur ma copie d'écran d'un message#1

Alors qu'un simple code M comme ceux proposés par les membres du forum dans ce fil suffisent.

Par curiosité, justement, j'ai trahi Sarah Connor ;)
Voilà ce que m'a pondu CoPilot dans Bing
PowerQuery:
let
    // Spécifiez le chemin du dossier contenant les fichiers CSV
    Source = Folder.Files("C:\Users\STAPLE\Documents\PQ_CSV"),
    // Filtrez pour ne sélectionner que les fichiers CSV
    FilteredRows = Table.SelectRows(Source, each Text.EndsWith([Name], ".csv")),
    // Combinez les fichiers en utilisant la fonction Csv.Document
    Combine = Table.AddColumn(FilteredRows, "Combined", each Csv.Document([Content])),
    // Promouvez les en-têtes de la première ligne
    PromoteHeaders = Table.TransformColumns(Combine, {"Combined", each Table.PromoteHeaders(_)}),
    // Combinez les tables en une seule
    CombinedTables = Table.Combine(PromoteHeaders[Combined])
in
    CombinedTables
Il a pas tout compris ou je me suis mal exprimé ;)
Mais je le remercie d'avoir ajouter tout seul des commentaires
 

Staple1600

XLDnaute Barbatruc
@Cousinhub
Décidemment on ne fait que se collisionner
(sans doute un hommage inconscient à M. HIGGS)
;)

Voilà ce que je viens de sortir du four
PowerQuery:
let
    // Spécifiez le chemin du dossier contenant les fichiers CSV
    Source = Folder.Files("C:\Users\STAPLE\Documents\PQ_CSV"),
    // Filtrez pour ne sélectionner que les fichiers CSV
    FilteredRows = Table.SelectRows(Source, each Text.EndsWith([Name], ".csv")),
    // Combinez les fichiers en utilisant la fonction Csv.Document
    Combine = Table.AddColumn(FilteredRows, "Combined", each Table.PromoteHeaders(Csv.Document([Content], [Delimiter=";"]))),
    // Promouvez les en-têtes de la première ligne
     PromoteHeaders = Table.TransformColumns(Combine, {"Combined", each Table.PromoteHeaders(_)}),
    // Combinez les tables en une seule
    CombinedTables = Table.Combine(Combine[Combined])
in
    CombinedTables
Alors maintenant lui faire comprendre que j'ai besoin du nom des fichiers en colonne 1, ca va être coton ;)
 

Staple1600

XLDnaute Barbatruc
Bon Sarah Connor peut dormir tranquille

L'IA pédale dans la semoule.
Certes, il est poli, mais il n'y arrive pas
Parfois, il me propose deux fois le même code
Mais il échoue toujours à ce que j'obtienne mes noms de fichiers en colonne 1
Et plus ca va, plus il rajoute des lignes de code M
PowerQuery:
let
    Source = Folder.Files("C:\Users\STAPLE\Documents\PQ_CSV"),
    // Filtrez pour ne sélectionner que les fichiers CSV
    FichiersCSV = Table.SelectRows(Source, each Text.EndsWith([Name], ".csv")),
    // Extraire les données des fichiers CSV avec le délimiteur spécifié
    ImporterCSV = Table.TransformColumns(FichiersCSV, {"Content", each Csv.Document(_, [Delimiter=";", Encoding=1252, QuoteStyle=QuoteStyle.None])}),
    // Ajoutez une colonne avec les noms des fichiers
    AjoutNomFichier = Table.AddColumn(ImporterCSV, "Nom de fichier", each [Name]),
    // Déplacez la colonne "Nom de fichier" au début
    ReorderColumns = Table.ReorderColumns(AjoutNomFichier, {"Nom de fichier", "Content"}),
    // Promouvoir les en-têtes de colonne
    PromouvoirEnTêtes = Table.TransformColumns(ReorderColumns, {"Content", each Table.PromoteHeaders(_)}),
    // Combinez les tables en une seule
    TablesCombinées = Table.Combine(PromouvoirEnTêtes[Content])
in
    TablesCombinées
Donc définitivement, je préfère échanger avec mes congénères XLDiens. ;)
 

Amilo

XLDnaute Accro
@Staple1600 ,

Désolé, je m'étais absenté,
Voici une étape supplémentaire pour compléter le code de mon message #48 avec l'ordre des colonnes

VB:
let
    Source = Folder.Files("C:\Users\STAPLE\Documents\PQ_CSV"),
    Personnalisé1 = Source[[Folder Path],[Name]],
    #"Personnalisée ajoutée" = Table.AddColumn(Source, "Personnalisé", each  Table.PromoteHeaders(Csv.Document(File.Contents([Folder Path] & [Name]), null, ";", 1 , 1252))),
    #"Personnalisée ajoutée1" = Table.AddColumn(#"Personnalisée ajoutée", "Nom fichier", each Table.AddColumn([Personnalisé], "Nom fichier", (x)=> [Name])),
    #"Personnalisée ajoutée2" = Table.AddColumn(#"Personnalisée ajoutée1", "Personnalisé.1", each Table.ReorderColumns([Nom fichier],{"Nom fichier", "ITEM_1"})),
    Personnalisé2 = Table.Combine(#"Personnalisée ajoutée2"[Personnalisé.1])
in
    Personnalisé2


Cordialement
 

Staple1600

XLDnaute Barbatruc
Re,

Bonsoir @Amilo

Voici ma 19ième du jour
PowerQuery:
let
Source=Folder.Files("C:\Users\STAPLE\Documents\PQ_CSV"),
// uniquement les CSV
Filtrer = Table.SelectRows(Source, each ([Extension] = ".csv")),
Ajout = Table.AddColumn(#"Filtrer", "CSV", each Table.PromoteHeaders(Csv.Document([Content],[Delimiter=";"]))),
List = List.Union(List.Transform(Ajout[CSV], each Table.ColumnNames(_))),
Expansion = Table.ExpandTableColumn(Ajout, "CSV", List),
// autre méthode pour avoir les noms de fichiers en colonne 1 et les données ensuite
Suppression = Table.RemoveColumns(Expansion,{"Content", "Extension", "Date accessed", "Date modified", "Date created", "Attributes", "Folder Path"})
in
Suppression
Je teste ton dernier code dans la 20ième ;)

Il me reste ensuite le problème du type de données
(car actuellement c'est considéré comme du Texte dans Excel)
Et il faudra aussi du générique (sans passer sur les colonnes une à une)
Je parle de cette étape faite par l'assistant
#"Type modifié" = Table.TransformColumnTypes(#"Colonne de tables développée1",{{"Source.Name", type text}, {"ITEM_1", Int64.Type}, {"ITEM_2", Int64.Type}

J'essaie d'adapter avec les exemples de syntaxe fournis dans le fil, pour faire un Table.TransformColumnTypes sans succès pour le moment.
 
Dernière édition:

Staple1600

XLDnaute Barbatruc
Re

Alors avec l'aide du net
(ceci est bon avec les fichiers CSV exemple du fil)
PowerQuery:
Suppression = Table.RemoveColumns(Expansion,{"Content", "Extension", "Date accessed", "Date modified", "Date created", "Attributes", "Folder Path"}),
// Format =Table.TransformColumnTypes(Suppression, List.Transform(Table.ColumnNames(Suppression), each {_, type number}),"fr-FR")
Format=Table.TransformColumnTypes(Suppression,List.Transform(List.RemoveFirstN(Table.ColumnNames(Suppression),1),each {_, type number}),"fr-FR")
in
Format
Là, la 1ere colonne est du texte et les autres des nombres (dans le tableau structuré affiché à la fin dans Excel)

==> Quelle serait la piste la plus simple à suivre pour cette étape ?
(avec les fichiers réels, il y a des colonnes avec des date, des heures, des nombres et du texte
 

Statistiques des forums

Discussions
315 109
Messages
2 116 306
Membres
112 716
dernier inscrit
jean1234