Power Query Récupérer les données des propriétés d'une liste de fichier Excel via Power Query

thibaut_excel

XLDnaute Nouveau
Bonjour.

j'ai un fichier de suivi Excel qui utilise l'obtention de données a partir d'un dossier(power query), j'arrive à récupérer toutes les données que je souhaite sauf le nom du dernière auteur( celui qui la enregistrer en dernier).
Avez-vous un idée pour réussir a obtenir ces données directement dans le fichier Excel, j'aimerais pouvoir associer le nom du dernière auteur au nom du fichier.
1672663977729.png


merci d'avance pour vos réponses.

Thibaut.
 
Solution
Bonjour Thibaut, Chris, le forum

Et bonne année !

Comme le dit Chris, selon les types de fichiers cette info n'est pas disponible.

D’après ton screenshot, tous tes fichiers sont des fichiers xlsm. Si tel est le cas, la fonction ci-dessous GetOpenXmlFileProps peut t’aider.

Elle dézippe le fichier Open XML et récupère les propriétés à partir des fichiers xml le composant et les renvoie sous forme de table.

Le code permettant de dézipper vient d’ici.

Code de la fonction (à intégrer dans une requête nommée GetOpenXmlFileProps) :
Code:
let
    
    fn = (openXmlFileBinary as binary) as table =>
        let
        
            // unzip function source...

chris

XLDnaute Barbatruc
Bonjour à tous

Do mon côté j'ai testé sur 500 fichiers Excel les 2 versions donnent le même résultat : pas de valeur null mais j'ai 1 fichier qui bloque sur la décomposition XML

1/500 c'est peanuts mais prévoir la suppression des erreurs sur la colonne avant de la développer
 

mromain

XLDnaute Barbatruc
Bonjour à tous,

Merci Chris pour ton retour. Comme tu l’as suggéré, j’ai rajouté une étape pour supprimer les erreurs potentielles.
Voici le nouveau code de la fonction :
Code:
let
    
    fn = (openXmlFileBinary as binary) as table =>
        let
        
            // unzip function source: https://github.com/ibarrau/PowerBi-code/blob/master/PowerQuery/ExtractZIP.pq
            UnzipFile = (ZIPFile as binary) =>
                let
                    Header = BinaryFormat.Record([      Signature            = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32,ByteOrder.LittleEndian),
                                                        Version         = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16,ByteOrder.LittleEndian),
                                                        Flags             = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16,ByteOrder.LittleEndian),
                                                        Compression         = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16,ByteOrder.LittleEndian),
                                                        ModTime         = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16,ByteOrder.LittleEndian),
                                                        ModDate         = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16,ByteOrder.LittleEndian),
                                                        CRC32             = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32,ByteOrder.LittleEndian),
                                                        CompressedSize         = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32,ByteOrder.LittleEndian),
                                                        UncompressedSize     = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32,ByteOrder.LittleEndian),
                                                        FileNameLen         = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16,ByteOrder.LittleEndian),
                                                        ExtraFieldLen         = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16,ByteOrder.LittleEndian)
                                                    ]),
                
                    FileEntry = BinaryFormat.Choice(Header, each if _[Signature] <> 0x4034B50 then BinaryFormat.Null else
                                                             BinaryFormat.Record([
                                                                            Header           = _,
                                                                            FileName         = BinaryFormat.Text(_[FileNameLen]),
                                                                            ExtraField       = BinaryFormat.Text(_[ExtraFieldLen]),
                                                                            UncompressedData = BinaryFormat.Transform(BinaryFormat.Binary(_[CompressedSize]),(x) => try Binary.Buffer(Binary.Decompress(x, Compression.Deflate)) otherwise null)
                                                                            ]), type binary),
                    ZipFormat = BinaryFormat.List(FileEntry, each _<> null),    
                
                    Entries = List.Transform(
                            List.RemoveLastN( ZipFormat(ZIPFile), 1),
                        (e) => [FileName = e[FileName], Content = e[UncompressedData] ]
                    )
                in
                   Table.FromRecords(Entries),
        
            UnzipedFileTable = try UnzipFile(openXmlFileBinary) otherwise error "Source file is not an OpenXml file.",
            FilterProperties = let tblProps = Table.SelectRows(UnzipedFileTable, each Text.StartsWith([FileName], "docProps/") and Text.EndsWith([FileName], ".xml")) in if Table.RowCount(tblProps)=0 then error "Source file is not an OpenXml file." else tblProps,
            TransformXmlBinary = Table.TransformColumns(FilterProperties,{{"Content", each Xml.Document(_), type table}}),
            RemoveXmlErrors = Table.RemoveRowsWithErrors(TransformXmlBinary, {"Content"}),
            RecoverXmlData = Table.ExpandTableColumn(RemoveXmlErrors, "Content", {"Value"}, {"Value"}),
            RecoverProperties = Table.ExpandTableColumn(RecoverXmlData, "Value", {"Name", "Value"}, {"Name", "Value"}),
            RemoveEmptyProperties = Table.SelectRows(RecoverProperties, each (try Table.RowCount([Value]) otherwise 1)>0),
            AddColumnKind = Table.AddColumn(RemoveEmptyProperties, "Kind", each Text.BetweenDelimiters([FileName], "/", "."), type text),
            SelectColumns = Table.SelectColumns(AddColumnKind,{"Kind", "Name", "Value"})
        in
            SelectColumns,
    
    DocumentationMetadata = 
        [
            Documentation.Name = "GetOpenXmlFileProps",
            Documentation.Description = "This function extract properties of an OpenXml file (docx, xlsm, ppts, ...).", 
            Documentation.Examples = 
                {
                    [
                        Description = "Extract properties of a .docx file:",
                        Code = "GetOpenXmlFileProps(File.Contents(""c:\folder\document.docx""))",
                        Result = "Table with properties kind, name and values."
                    ],
                    [
                        Description = "Extract 'last modified by' property of a .xlsm file:",
                        Code = "GetOpenXmlFileProps(File.Contents(""c:\folder\workbook.xlsm"")){[Kind=""core"", Name=""lastModifiedBy""]}[Value]",
                        Result = "Text with 'last modified by' property."
                    ]
                }
        ]

in
    Value.ReplaceType(fn, Value.ReplaceMetadata(Value.Type(fn), DocumentationMetadata))

Je vais également mettre à jour le code dans mon post initial.

A+
 

chris

XLDnaute Barbatruc
Bonjour
Cela ne résout pas ce cas.
J'ai regardé ses propriétés : c'est un xlsx fabriqué par LibreOffice

Si je le réenregistre sous Excel, il passe sans souci...

Comme quoi l'extension ne suffit pas à être sûr de la nature du fichier...
 

chris

XLDnaute Barbatruc
RE
H10 c'est une cellule pas une colonne
il suffit de se baser sur le nom de la colonne et on peut en récupérer une ligne mais c'est une approche très tableur et il est toujours préférable de garder une logique base de données...

Pas sûr de l'intérêt de passer par PowerQuery plutôt que VBA si une seule cellule par fichier est utile...
 

thibaut_excel

XLDnaute Nouveau
RE
H10 c'est une cellule pas une colonne
il suffit de se baser sur le nom de la colonne et on peut en récupérer une ligne mais c'est une approche très tableur et il est toujours préférable de garder une logique base de données...

Pas sûr de l'intérêt de passer par PowerQuery plutôt que VBA si une seule cellule par fichier est utile...
Oui la cellule H10 désolé j'ai tapé trop vite le message. Pour les macros ok j'en est vu quelques une ce matin sur des forums, mais je voulais voir avec vous si il y avait une procédure autre que VBA.

un peu comme sur cette discution:

merci.
 

Discussions similaires

Statistiques des forums

Discussions
312 201
Messages
2 086 170
Membres
103 151
dernier inscrit
nassim