Peek(field_name [, row_no [, table_name]])
Peek (running balances in the script) in Power BI
Peek reads a field from a row already loaded into the output table. It is used for running balances and for reading values into variables. Power Query has no row-by-row state, so use grouped list logic, a SQL window function upstream, or a DAX measure.
What it does in Qlik
Peek('Field', row, 'Table') reads from the output table. Row -1 (default) is the last loaded row, and 0 is the first. In a sorted LOAD ... RESIDENT ... ORDER BY, you can refer to the value just calculated for the previous row, for example the running balance. Peek is also how scripts move a value into a variable after loading.
Qlik example
Balances:
LOAD Account, TxDate, Amount,
If(Account = Peek('Account'), Peek('Balance') + Amount, Amount) AS Balance
RESIDENT Transactions
ORDER BY Account, TxDate;
LET vMaxDate = Peek('MaxDate', 0, 'Dates');Power BI equivalent
Power Query, per group
let
Grouped = Table.Group(Transactions, {"Account"}, {{"Rows", each
let
t = Table.Sort(_, {{"TxDate", Order.Ascending}}),
amounts = List.Buffer(t[Amount]),
running = List.Generate(
() => [i = 0, s = amounts{0}],
each [i] < List.Count(amounts),
each [i = [i] + 1, s = [s] + amounts{[i] + 1}],
each [s])
in
Table.FromColumns(Table.ToColumns(t) & {running}, Table.ColumnNames(t) & {"Balance"}),
type table}}),
Expanded = Table.ExpandTableColumn(Grouped, "Rows", {"TxDate", "Amount", "Balance"})
in
ExpandedSQL upstream (usually best)
SELECT Account, TxDate, Amount,
SUM(Amount) OVER (PARTITION BY Account ORDER BY TxDate, TxID
ROWS UNBOUNDED PRECEDING) AS Balance
FROM Transactions;DAX calculated column
Balance =
VAR d = Transactions[TxDate]
RETURN
CALCULATE ( SUM ( Transactions[Amount] ), ALLEXCEPT ( Transactions, Transactions[Account] ), Transactions[TxDate] <= d )Gotchas and behaviour differences
- Qlik's order is the row order of the load. The DAX and window versions need a unique sort key: with ties on
TxDate, the DAX column adds all of that date's rows at once. - Running balances as stored columns are rarely needed in Power BI. A measure respects filters, and a stored column does not.
PeekvsPrevious: Peek reads the output (afterWHERE), and Previous reads the input. See Previous.
Official documentation
- Peek - script function (Qlik Help)
- List.Generate (Power Query M) (Microsoft Learn)
- Table.Group (Power Query M) (Microsoft Learn)
- ALLEXCEPT function (DAX) (Microsoft Learn)
Related pages
Previous(expr)
Previous (compare with the previous input row)
Previous returns an expression's value from the previous input record. Power BI has no LAG in Power Query, so use the index-shift self-merge pattern, a SQL LAG upstream, or a DAX calculated column that finds the previous value.
Partial / different approach
RangeSum(Above(Sum(Sales), 0, RowNo()))
Running totals with RangeSum(Above(...))
The Qlik running-total idiom RangeSum(Above(Sum(Sales), 0, RowNo())) maps to a cumulative DAX measure, a WINDOW function, or the RUNNINGSUM visual calculation.
Partial / different approach
RecNo(), RowNo()
RecNo and RowNo
RecNo numbers input records and RowNo numbers output rows. In Power Query, add an index column before the filter step (RecNo) or after it (RowNo). The model has no row order, so keep the index as a column.
Partial / different approach
LOAD ... AUTOGENERATE ... WHILE ... IterNo()
Master calendar (date table)
The Qlik master calendar script maps to a date table built in Power Query (List.Dates) or DAX (CALENDAR), marked as a date table and related to the fact date. It is essential for every time-intelligence function.
Direct equivalent
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.