FOR EACH vFile IN FileList('lib://Data/*.csv') ... NEXT
FOR ... NEXT and FOR EACH loops in Power BI
Power Query has no loop statement. It's a functional language. Loop over a list instead. List.Transform covers "do this for each item". List.Generate covers while-style loops. A custom function invoked per row of a table covers "load each file/table/month". Looping over files is built in as the Folder connector with Combine files.
Short answer: Make the loop body a function (x) => ..., build a table of the values you'd loop over, add a column that invokes the function, then expand it. That's the Power Query version of FOR EACH plus CONCATENATE.
What it does in Qlik
FOR i = 1 TO n ... NEXTandFOR EACH v IN list ... NEXTrepeat script blocks, often to load many files, months or tables, each auto-concatenated.DO WHILEandLOOPrepeat until a condition is met, for example API paging.
Qlik example
FOR EACH vYear IN 2023, 2024, 2025
Sales: LOAD * FROM [lib://Data/sales_$(vYear).qvd] (qvd);
NEXT vYear
// API paging
LET vPage = 1;
DO WHILE vPage <= 10
Data: LOAD * FROM [lib://API/items?page=$(vPage)] (json);
LET vPage = vPage + 1;
LOOPPower BI equivalent
FOR EACH over values
let
LoadYear = (y as number) as table =>
Csv.Document(File.Contents("C:\Data\sales_" & Text.From(y) & ".csv"), [Delimiter = ","]),
Years = {2023, 2024, 2025},
Tables = List.Transform(Years, LoadYear),
Sales = Table.Combine(Tables)
in
SalesDO WHILE (API paging)
let
GetPage = (p) => Json.Document(Web.Contents("https://api.example.com",
[RelativePath = "items", Query = [page = Text.From(p)]])),
Pages = List.Generate(
() => [p = 1, data = GetPage(1)],
each [p] <= 10 and List.Count([data][items]) > 0,
each [p = [p] + 1, data = GetPage([p] + 1)],
each [data][items]),
Items = List.Combine(Pages)
in
Table.FromRecords(Items)Gotchas and behaviour differences
- In the Power BI service, dynamic URLs only refresh if the base URL is static. Put the variable parts in
RelativePathandQuery, as above, not in string concatenation. - For files in a folder, prefer the Folder or SharePoint folder connector. It generates the function and a sample file for you, and new files are picked up automatically. See loading from a folder.
Official documentation
- For..next - script control statement (Qlik Help)
- For each..next - script control statement (Qlik Help)
- List.Generate (Power Query M) (Microsoft Learn)
- List.Transform (Power Query M) (Microsoft Learn)
- Using custom functions (Microsoft Learn)
- Web.Contents (Power Query M) (Microsoft Learn)
Related pages
LOAD *, FileName() AS Source FROM [lib://Data/sales_*.csv] (txt);
Loading many files (wildcards and FileName)
Qlik loads every matching file with a wildcard in the FROM path, auto-concatenates them, and FileName() tells you which file each row came from. Power Query's Folder or SharePoint folder connector with Combine files does the same. It adds a Source.Name column, which is the FileName() equivalent. Filter on the file name to get the sales_*.csv pattern.
Direct equivalent
SUB LoadDim(vName) ... END SUB; CALL LoadDim('Customer');
SUB, CALL and $(Include)
A SUB in Qlik maps to a custom function in Power Query, (param) => ..., invoked like any function. $(Include=...), which shares script files across apps, has no direct equivalent in Power BI Desktop. The closest options are shared dataflows, which centralise the transformation itself, Power Query templates (.pqt), or copy-pasting functions, which is honest but manual.
Partial / different approach
Concatenate [(table)] LOAD ...
Concatenate (append tables)
Concatenate appends rows to an existing table. Qlik also does this automatically when field sets match. Power Query's Append queries (Table.Combine) matches columns by name and fills missing ones with null.
Direct equivalent
SET vSales = Sum(Sales); LET vToday = Today();
Variables (SET, LET and $-expansion)
Qlik variables hold expressions, values and settings, and are expanded as text. Power BI splits these roles: measures for reusable logic, Power Query parameters for load settings, what-if and field parameters for user input, calculation groups for logic applied to many measures, and VAR inside DAX.
Partial / different approach
Spotted an error or a better pattern? QlikToDax is maintained by a working BI consultant; corrections are welcome via the About page. Last reviewed 2026-10-25.