Forum Discussion
ETL Options with files loop (powerquery or free?)
- 2 months ago
Hi icassiem,
You can do the looping in Power Query regardless of timestamps.
The query below will:
- Connect to a SharePoint site
- Find all CSV files
- Keep only files where the file name contains one of the keywords
- Combine all matching files into one table
- Add the source file name and source folder for audit purposes
Example
let SiteUrl = "https://yourtenant.sharepoint.com/sites/yoursite", Keywords = {"mature", "efficiency", "interna"}, Source = SharePoint.Files( SiteUrl, [ApiVersion = 15] ), FilterCsv = Table.SelectRows( Source, each Text.Lower([Extension]) = ".csv" ), FilterKeywords = Table.SelectRows( FilterCsv, each List.AnyTrue( List.Transform( Keywords, (k) => Text.Contains(Text.Lower([Name]), Text.Lower(k)) ) ) ), RemoveHiddenFiles = Table.SelectRows( FilterKeywords, each [Attributes]?[Hidden]? <> true ), TransformCsv = (FileContent as binary, FileName as text, FolderPath as text) as table => let Csv = Csv.Document( FileContent, [ Delimiter = ",", Encoding = 65001, QuoteStyle = QuoteStyle.Csv ] ), PromotedHeaders = Table.PromoteHeaders( Csv, [PromoteAllScalars = true] ), AddSourceFile = Table.AddColumn( PromotedHeaders, "SourceFile", each FileName, type text ), AddSourceFolder = Table.AddColumn( AddSourceFile, "SourceFolder", each FolderPath, type text ) in AddSourceFolder, AddData = Table.AddColumn( RemoveHiddenFiles, "Data", each TransformCsv([Content], [Name], [Folder Path]) ), Combined = if Table.RowCount(AddData) = 0 then #table({}, {}) else Table.Combine(AddData[Data]) in CombinedThe important part is this:
Keywords = {"mature", "efficiency", "interna"}This means the query will include files where the file name contains any of those words.
Examples that would be picked up:
202607_clientA_mature_export.csv clientB_efficiency_202607.csv timestamp_clientC_interna.csv
If you want separate outputs, for example one table for Mature and another for Efficiency, then create one query per keyword. But if all files should be appended into one table, the query above works.
Important: all files combined in the same query should have the same structure/columns.
And yes, you can definitly do this with powershell or Python, if you are want to do it that way, just ask we will figure out something.
And sorry if i misunderstand the problem above with PowerQuery looping.
Hi icassiem,
You can do the looping in Power Query regardless of timestamps.
The query below will:
- Connect to a SharePoint site
- Find all CSV files
- Keep only files where the file name contains one of the keywords
- Combine all matching files into one table
- Add the source file name and source folder for audit purposes
Example
let
SiteUrl = "https://yourtenant.sharepoint.com/sites/yoursite",
Keywords = {"mature", "efficiency", "interna"},
Source =
SharePoint.Files(
SiteUrl,
[ApiVersion = 15]
),
FilterCsv =
Table.SelectRows(
Source,
each Text.Lower([Extension]) = ".csv"
),
FilterKeywords =
Table.SelectRows(
FilterCsv,
each
List.AnyTrue(
List.Transform(
Keywords,
(k) => Text.Contains(Text.Lower([Name]), Text.Lower(k))
)
)
),
RemoveHiddenFiles =
Table.SelectRows(
FilterKeywords,
each [Attributes]?[Hidden]? <> true
),
TransformCsv =
(FileContent as binary, FileName as text, FolderPath as text) as table =>
let
Csv =
Csv.Document(
FileContent,
[
Delimiter = ",",
Encoding = 65001,
QuoteStyle = QuoteStyle.Csv
]
),
PromotedHeaders =
Table.PromoteHeaders(
Csv,
[PromoteAllScalars = true]
),
AddSourceFile =
Table.AddColumn(
PromotedHeaders,
"SourceFile",
each FileName,
type text
),
AddSourceFolder =
Table.AddColumn(
AddSourceFile,
"SourceFolder",
each FolderPath,
type text
)
in
AddSourceFolder,
AddData =
Table.AddColumn(
RemoveHiddenFiles,
"Data",
each TransformCsv([Content], [Name], [Folder Path])
),
Combined =
if Table.RowCount(AddData) = 0
then #table({}, {})
else Table.Combine(AddData[Data])
in
CombinedThe important part is this:
Keywords = {"mature", "efficiency", "interna"}This means the query will include files where the file name contains any of those words.
Examples that would be picked up:
202607_clientA_mature_export.csv clientB_efficiency_202607.csv timestamp_clientC_interna.csv
If you want separate outputs, for example one table for Mature and another for Efficiency, then create one query per keyword. But if all files should be appended into one table, the query above works.
Important: all files combined in the same query should have the same structure/columns.
And yes, you can definitly do this with powershell or Python, if you are want to do it that way, just ask we will figure out something.
And sorry if i misunderstand the problem above with PowerQuery looping.
- icassiem2 months ago
Post Prodigy
Parchitect Wow, jeez i feel stupid. Thank You ๐
Let me give this a try tomorow, it will be amazing if i can get this working in powerbi powerquery
- icassiem2 months ago
Post Prodigy
Parchitect Hi, Is there a way to grab the meta property of file date modified/updated where the client name was mispelled in the filename or date prefixed leaving me with duplicated client file and how i filter on the latest modified/updated date per client in powerquery?
Thanks
- Parchitect2 months ago
Solution Sage
Hi icassiem,
Good news on both parts. I have researched now for while on this problem.1. The metadata is already there. SharePoint.Files returns a Date modified column for every file โ nothing extra needed, we just haven't used it yet.
2. Latest file per client. The reliable pattern is Group By + Table.Max, which picks the newest row per client regardless of row order (the popular "sort then remove duplicates" trick is not guaranteed in Power Query). Insert this between RemoveHiddenFiles and AddData in the query I posted earlier:
AddClientKey = Table.AddColumn( RemoveHiddenFiles, "ClientKey", each Text.Lower( Text.Remove( Text.BeforeDelimiter([Name], "."), {"0".."9", "_", "-", " "} ) ), type text ), LatestPerClient = Table.FromRecords( Table.Group( AddClientKey, {"ClientKey"}, {{"Latest", each Table.Max(_, "Date modified"), type record}} )[Latest] ),Then change AddData to reference LatestPerClient instead of RemoveHiddenFiles.
How it works: the key strips all digits and separators, so 202607_clientA_mature.csv and 20260708_clientA_mature.csv get the same key, and Table.Max keeps the row with the newest Date modified. Since the type word (mature/efficiency) stays in the key, you get the latest file per client per source type โ matching your 5 sources.
3. Misspelled client names โ honest limitation. No formula can safely know that "Contosso" is "Contoso". The robust fix is a small mapping table (Excel or SharePoint list) with two columns, Alias โ Client, merged on the ClientKey. Misspellings land as unmatched rows you review once and add to the table โ execs never see a duplicate.
One caution: Date modified is the upload time, so re-uploading an old file makes it "latest". Acceptable for the interim MVP, just worth knowing.
๐Parchitect
Solutions Architect ยท Microsoft Fabric Specialist
๐กHelpful? Kudos are appreciated.
โ๏ธSolved? Mark as Solution so others can find it faster.