Get a table from each Excel file in folder | speed up the process

%3CLINGO-SUB%20id%3D%22lingo-sub-2274082%22%20slang%3D%22en-US%22%3EGet%20a%20table%20from%20each%20Excel%20file%20in%20folder%20%7C%20speed%20up%20the%20process%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2274082%22%20slang%3D%22en-US%22%3E%3CP%3EHi%2C%3CBR%20%2F%3EI've%20setup%20a%20query%20to%20read%20the%20content%20of%20a%20Table%20inside%20several%20Excel%20files%20in%20a%20folder.%3CBR%20%2F%3EMy%20problem%20is%20that%20those%20files%20are%20quite%20big%20(3MB%2B%20each)%20and%20when%20the%20folder%20contains%20many%20files%20the%20process%20is%20getting%20really%20slow.%3CBR%20%2F%3EIs%20there%20a%20way%20to%20speed%20things%20up%20in%20M%20code%3F%3C%2FP%3E%3CP%3EThis%20my%20origin%20query%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-powerquery%22%3E%3CCODE%3Elet%0A%20%20%20%20Origine%20%3D%20Folder.Files(%22C%3A%5CUsers%5C...myPath....%5CmyFolder%22)%0Ain%0A%20%20%20%20Origine%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3Eand%20this%20is%20the%20query%20I%20use%20to%20extract%20the%20content%20of%20the%20tables%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-powerquery%22%3E%3CCODE%3Elet%0A%20%20%20%20Origine%20%3D%20ODPcartellatutti_i_file%2C%0A%20%20%20%20%23%22Filtrate%20righe1%22%20%3D%20Table.SelectRows(Origine%2C%20each%20Text.Contains(%5BExtension%5D%2C%20%22xls%22)%20or%20Text.Contains(%5BExtension%5D%2C%20%22XLS%22))%2C%0A%20%20%20%20%23%22Rimosse%20colonne%22%20%3D%20Table.RemoveColumns(%23%22Filtrate%20righe1%22%2C%7B%22Date%20accessed%22%2C%20%22Date%20modified%22%2C%20%22Date%20created%22%2C%20%22Folder%20Path%22%7D)%2C%0A%20%20%20%20%23%22Aggiunta%20colonna%20personalizzata%22%20%3D%20Table.AddColumn(%23%22Rimosse%20colonne%22%2C%20%22Tabella_Riepilogo%22%2C%20each%20try%20Excel.Workbook(%5BContent%5D%2Cnull%2C%20true)%20otherwise%20%22%22)%2C%0A%20%20%20%20%23%22Tabella%20Tabella_Riepilogo%20espansa%22%20%3D%20Table.ExpandTableColumn(%23%22Aggiunta%20colonna%20personalizzata%22%2C%20%22Tabella_Riepilogo%22%2C%20%7B%22Name%22%2C%20%22Data%22%2C%20%22Item%22%7D%2C%20%7B%22Tabella_Riepilogo.Name%22%2C%20%22Tabella_Riepilogo.Data%22%2C%20%22Tabella_Riepilogo.Item%22%7D)%2C%0A%20%20%20%20%23%22Filtrate%20righe%22%20%3D%20Table.SelectRows(%23%22Tabella%20Tabella_Riepilogo%20espansa%22%2C%20each%20try%20(%5BTabella_Riepilogo.Name%5D%20%3D%20%22TAB_ODP%22)%20otherwise%20%22%22)%2C%0A%20%20%20%20%23%22Tabella%20Tabella_Riepilogo.Data%20espansa%22%20%3D%20Table.ExpandTableColumn(%23%22Filtrate%20righe%22%2C%20%22Tabella_Riepilogo.Data%22%2C%20%7B%22Cliente%22%2C%20%22Oggetto%22%2C%20%22Materiale%22%2C%20%22Data%20ordine%22%2C%20%22Data%20consegna%22%2C%20%22Autore%22%2C%20%22Importo%22%2C%20%22Acconto%22%2C%20%22Saldo%22%2C%20%22TAGLIA-B.%22%2C%20%22DISCO-FILO%22%2C%20%22FILO-SAG%22%2C%20%22TELAIO%22%2C%20%22WATER%20JET%22%2C%20%22INTERMAC%22%2C%20%22OMAG%2FGMM%22%2C%20%22FRESE%22%2C%20%22VARIE%22%7D%2C%20%7B%22Tabella_Riepilogo.Data.Cliente%22%2C%20%22Tabella_Riepilogo.Data.Oggetto%22%2C%20%22Tabella_Riepilogo.Data.Materiale%22%2C%20%22Tabella_Riepilogo.Data.Data%20ordine%22%2C%20%22Tabella_Riepilogo.Data.Data%20consegna%22%2C%20%22Tabella_Riepilogo.Data.Autore%22%2C%20%22Tabella_Riepilogo.Data.Importo%22%2C%20%22Tabella_Riepilogo.Data.Acconto%22%2C%20%22Tabella_Riepilogo.Data.Saldo%22%2C%20%22Tabella_Riepilogo.Data.TAGLIA-B.%22%2C%20%22Tabella_Riepilogo.Data.DISCO-FILO%22%2C%20%22Tabella_Riepilogo.Data.FILO-SAG%22%2C%20%22Tabella_Riepilogo.Data.TELAIO%22%2C%20%22Tabella_Riepilogo.Data.WATER%20JET%22%2C%20%22Tabella_Riepilogo.Data.INTERMAC%22%2C%20%22Tabella_Riepilogo.Data.OMAG%2FGMM%22%2C%20%22Tabella_Riepilogo.Data.FRESE%22%2C%20%22Tabella_Riepilogo.Data.VARIE%22%7D)%2C%0A%20%20%20%20%23%22Rimosse%20colonne1%22%20%3D%20Table.RemoveColumns(%23%22Tabella%20Tabella_Riepilogo.Data%20espansa%22%2C%7B%22Extension%22%2C%20%22Attributes%22%2C%20%22Tabella_Riepilogo.Name%22%7D)%2C%0A%20%20%20%20%23%22Rinominate%20colonne%22%20%3D%20Table.RenameColumns(%23%22Rimosse%20colonne1%22%2C%7B%7B%22Tabella_Riepilogo.Data.Cliente%22%2C%20%22Nome%20cliente%22%7D%2C%20%7B%22Tabella_Riepilogo.Data.Materiale%22%2C%20%22Materiale%22%7D%2C%20%7B%22Tabella_Riepilogo.Data.Data%20ordine%22%2C%20%22Data%20ordine%22%7D%2C%20%7B%22Tabella_Riepilogo.Data.Data%20consegna%22%2C%20%22Data%20consegna%22%7D%2C%20%7B%22Tabella_Riepilogo.Data.Autore%22%2C%20%22Autore%22%7D%2C%20%7B%22Tabella_Riepilogo.Data.Importo%22%2C%20%22Importo%20netto%22%7D%2C%20%7B%22Tabella_Riepilogo.Data.Acconto%22%2C%20%22Acconto%20netto%22%7D%2C%20%7B%22Tabella_Riepilogo.Data.Saldo%22%2C%20%22Dalso%20netto%22%7D%2C%20%7B%22Tabella_Riepilogo.Data.Oggetto%22%2C%20%22Oggetto%22%7D%7D)%2C%0A%20%20%20%20%23%22Modificato%20tipo%22%20%3D%20Table.TransformColumnTypes(%23%22Rinominate%20colonne%22%2C%7B%7B%22Importo%20netto%22%2C%20Currency.Type%7D%2C%20%7B%22Dalso%20netto%22%2C%20Int64.Type%7D%2C%20%7B%22Acconto%20netto%22%2C%20Int64.Type%7D%7D)%2C%0A%20%20%20%20%23%22Rimosse%20colonne2%22%20%3D%20Table.RemoveColumns(%23%22Modificato%20tipo%22%2C%7B%22Tabella_Riepilogo.Item%22%2C%20%22Content%22%7D)%2C%0A%20%20%20%20%23%22Rinominate%20colonne1%22%20%3D%20Table.RenameColumns(%23%22Rimosse%20colonne2%22%2C%7B%7B%22Name%22%2C%20%22Name%20File%22%7D%2C%20%7B%22Dalso%20netto%22%2C%20%22Saldo%20netto%22%7D%7D)%0Ain%0A%20%20%20%20%23%22Rinominate%20colonne1%22%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3Ewhere%20I%20think%20this%20line%20of%20code%20is%20slowing%20things%20down%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-powerquery%22%3E%3CCODE%3E%23%22Aggiunta%20colonna%20personalizzata%22%20%3D%20Table.AddColumn(%23%22Rimosse%20colonne%22%2C%20%20%22Tabella_Riepilogo%22%2C%20each%20try%20Excel.Workbook(%5BContent%5D%2Cnull%2C%20true)%20%20otherwise%20%22%22)%2C%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3Ebecause%20is%20getting%20all%20Excel%20files%20content%20and%20then%20in%20the%20next%20steps%20I'm%20filtering%20the%20rows%20that%20contain%20the%20table%20name%20%22TAB_ODP%22%20which%20is%20what%20I'm%20looking%20for.%3CBR%20%2F%3EIs%20there%20a%20way%20to%20directly%20get%20the%20table%20(if%20exists%20in%20the%20file)%20instead%20of%20getting%20ALL%20the%20content%20and%20then%20filtering%3F%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EMany%20thanks%20in%20advanced!%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-2274082%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EBI%20%26amp%3B%20Data%20Analysis%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EExcel%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E
New Contributor

Hi,
I've setup a query to read the content of a Table inside several Excel files in a folder.
My problem is that those files are quite big (3MB+ each) and when the folder contains many files the process is getting really slow.
Is there a way to speed things up in M code?

This my origin query:

 

 

let
    Origine = Folder.Files("C:\Users\...myPath....\myFolder")
in
    Origine

 

 

and this is the query I use to extract the content of the tables:

 

 

let
    Origine = ODPcartellatutti_i_file,
    #"Filtrate righe1" = Table.SelectRows(Origine, each Text.Contains([Extension], "xls") or Text.Contains([Extension], "XLS")),
    #"Rimosse colonne" = Table.RemoveColumns(#"Filtrate righe1",{"Date accessed", "Date modified", "Date created", "Folder Path"}),
    #"Aggiunta colonna personalizzata" = Table.AddColumn(#"Rimosse colonne", "Tabella_Riepilogo", each try Excel.Workbook([Content],null, true) otherwise ""),
    #"Tabella Tabella_Riepilogo espansa" = Table.ExpandTableColumn(#"Aggiunta colonna personalizzata", "Tabella_Riepilogo", {"Name", "Data", "Item"}, {"Tabella_Riepilogo.Name", "Tabella_Riepilogo.Data", "Tabella_Riepilogo.Item"}),
    #"Filtrate righe" = Table.SelectRows(#"Tabella Tabella_Riepilogo espansa", each try ([Tabella_Riepilogo.Name] = "TAB_ODP") otherwise ""),
    #"Tabella Tabella_Riepilogo.Data espansa" = Table.ExpandTableColumn(#"Filtrate righe", "Tabella_Riepilogo.Data", {"Cliente", "Oggetto", "Materiale", "Data ordine", "Data consegna", "Autore", "Importo", "Acconto", "Saldo", "TAGLIA-B.", "DISCO-FILO", "FILO-SAG", "TELAIO", "WATER JET", "INTERMAC", "OMAG/GMM", "FRESE", "VARIE"}, {"Tabella_Riepilogo.Data.Cliente", "Tabella_Riepilogo.Data.Oggetto", "Tabella_Riepilogo.Data.Materiale", "Tabella_Riepilogo.Data.Data ordine", "Tabella_Riepilogo.Data.Data consegna", "Tabella_Riepilogo.Data.Autore", "Tabella_Riepilogo.Data.Importo", "Tabella_Riepilogo.Data.Acconto", "Tabella_Riepilogo.Data.Saldo", "Tabella_Riepilogo.Data.TAGLIA-B.", "Tabella_Riepilogo.Data.DISCO-FILO", "Tabella_Riepilogo.Data.FILO-SAG", "Tabella_Riepilogo.Data.TELAIO", "Tabella_Riepilogo.Data.WATER JET", "Tabella_Riepilogo.Data.INTERMAC", "Tabella_Riepilogo.Data.OMAG/GMM", "Tabella_Riepilogo.Data.FRESE", "Tabella_Riepilogo.Data.VARIE"}),
    #"Rimosse colonne1" = Table.RemoveColumns(#"Tabella Tabella_Riepilogo.Data espansa",{"Extension", "Attributes", "Tabella_Riepilogo.Name"}),
    #"Rinominate colonne" = Table.RenameColumns(#"Rimosse colonne1",{{"Tabella_Riepilogo.Data.Cliente", "Nome cliente"}, {"Tabella_Riepilogo.Data.Materiale", "Materiale"}, {"Tabella_Riepilogo.Data.Data ordine", "Data ordine"}, {"Tabella_Riepilogo.Data.Data consegna", "Data consegna"}, {"Tabella_Riepilogo.Data.Autore", "Autore"}, {"Tabella_Riepilogo.Data.Importo", "Importo netto"}, {"Tabella_Riepilogo.Data.Acconto", "Acconto netto"}, {"Tabella_Riepilogo.Data.Saldo", "Dalso netto"}, {"Tabella_Riepilogo.Data.Oggetto", "Oggetto"}}),
    #"Modificato tipo" = Table.TransformColumnTypes(#"Rinominate colonne",{{"Importo netto", Currency.Type}, {"Dalso netto", Int64.Type}, {"Acconto netto", Int64.Type}}),
    #"Rimosse colonne2" = Table.RemoveColumns(#"Modificato tipo",{"Tabella_Riepilogo.Item", "Content"}),
    #"Rinominate colonne1" = Table.RenameColumns(#"Rimosse colonne2",{{"Name", "Name File"}, {"Dalso netto", "Saldo netto"}})
in
    #"Rinominate colonne1"

 

 

where I think this line of code is slowing things down

 

 

#"Aggiunta colonna personalizzata" = Table.AddColumn(#"Rimosse colonne",  "Tabella_Riepilogo", each try Excel.Workbook([Content],null, true)  otherwise ""),

 

 

because is getting all Excel files content and then in the next steps I'm filtering the rows that contain the table name "TAB_ODP" which is what I'm looking for.
Is there a way to directly get the table (if exists in the file) instead of getting ALL the content and then filtering?

 

Many thanks in advanced!

4 Replies
Have you tried linking without the use of macro or VBA? Just link directly via a formula? I have a master sheet for tracking investments that links to multiple "source files" solely by using the FILTER function and pointing to the various source files. The source files, in my experience, do need to be open in order for the refreshed data to appear....but (also in my experience) the use of VBA or a macro often slows down the process. So whenever possible, I use Excel's built-in functions instead.

@mathetesThere's no VBa here, just pure M Language in PwerQuery. I do need to be able to pull data from closed excel files, so FILTER function is not right for this.

@marcob8986 

Perhaps something like this, at least for the part in question

let
    Origine = ODPcartellatutti_i_file,
    #"Filtrate righe1" = Table.SelectRows(
        Origine,
        each
            Text.Contains([Extension], "xls") or
            Text.Contains([Extension], "XLS")
    ),
    #"Rimosse colonne" = Table.RemoveColumns(
        #"Filtrate righe1",
        {"Date accessed", "Date modified", "Date created", "Folder Path"}
    ),
    #"Aggiunta colonna personalizzata" = Table.AddColumn(
        #"Rimosse colonne",
        "Tabella_Riepilogo",
        Excel.Workbook([Content],null, true)
    ),
    #"Removed Other Columns" = Table.SelectColumns(
        #"Aggiunta colonna personalizzata",
        {"Tabella_Riepilogo"}
    ),
    #"Removed Errors" = Table.RemoveRowsWithErrors(
        #"Removed Other Columns",
        {"Tabella_Riepilogo"}
    ),
    #"Tabella Tabella_Riepilogo espansa" = Table.ExpandTableColumn(
        #"Removed Errors",
        "Tabella_Riepilogo",
        {"Name", "Data", "Item", "Kind"},
        {"Tabella_Riepilogo.Name", "Tabella_Riepilogo.Data", "Tabella_Riepilogo.Item"}
    ),
    #"Filtrate righe" = Table.SelectRows(
        #"Tabella Tabella_Riepilogo espansa",
        each ([Kind] = "Table") and ([Name] = "TAB_ODP")
    ),
    #"Removed Other Columns1" = Table.SelectColumns(
        #"Filtrate righe",
        {"Data"}
    ),
    #"Tabella Tabella_Riepilogo.Data espansa" = Table.ExpandTableColumn(
        #"Removed Other Columns1",
        "Tabella_Riepilogo.Data",
        {"Cliente", "Oggetto", "Materiale", "Data ordine", "Data consegna",
         "Autore", "Importo", "Acconto", "Saldo", "TAGLIA-B.", "DISCO-FILO",
         "FILO-SAG", "TELAIO", "WATER JET", "INTERMAC", "OMAG/GMM",
         "FRESE", "VARIE"},
        {
            "Nome cliente",
            "Oggetto",
            "Materiale",
            "Data ordine",
            "Data consegna",
            "Autore",
            "Importo netto",
            "Acconto netto",
            "Dalso netto",
            "Tabella_Riepilogo.Data.TAGLIA-B.",
            "Tabella_Riepilogo.Data.DISCO-FILO",
            "Tabella_Riepilogo.Data.FILO-SAG",
            "Tabella_Riepilogo.Data.TELAIO",
            "Tabella_Riepilogo.Data.WATER JET",
            "Tabella_Riepilogo.Data.INTERMAC",
            "Tabella_Riepilogo.Data.OMAG/GMM",
            "Tabella_Riepilogo.Data.FRESE",
            "Tabella_Riepilogo.Data.VARIE"
        }
    ),
    #"Modificato tipo" = Table.TransformColumnTypes(
        #"Tabella Tabella_Riepilogo.Data espansa",
        {
            {"Importo netto", Currency.Type},
            {"Dalso netto", Int64.Type},
            {"Acconto netto", Int64.Type}
        }
    ),
    #"Rimosse colonne2" = Table.RemoveColumns(
        #"Modificato tipo",
        {"Tabella_Riepilogo.Item", "Content"}
    ),
    #"Rinominate colonne1" = Table.RenameColumns(
        #"Rimosse colonne2",
        {
            {"Name", "Name File"},
            {"Dalso netto", "Saldo netto"}
        }
    )
in
    #"Rinominate colonne1"
There is no vba code involved here....