RangeSum(Above(Sum(Sales), 0, RowNo()))

Running totals with RangeSum(Above(...)) in Power BI

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 DAX

Short answer: The classic pattern is CALCULATE([Sales], FILTER(ALLSELECTED('Date'[Date]), 'Date'[Date] <= MAX('Date'[Date]))). In a visual, RUNNINGSUM([Sales]) is the closest match to Qlik's row-based logic.

What it does in Qlik

RangeSum adds its arguments and treats non-numeric values (including NULL) as 0. Combined with Above(expr, 0, RowNo()), it adds the current row and all rows above it in the column segment, which gives a running total in chart order. Qlik Sense also has an "Accumulation" modifier on measures that does the same.

Qlik example

Qlik chart expressions
RangeSum(Above(Sum(Sales), 0, RowNo()))          // running total, restarts per segment
RangeSum(Above(TOTAL Sum(Sales), 0, RowNo(TOTAL))) // across the whole chart

Power BI equivalent

Cumulative by date (model measure)

DAX
Sales running total =
CALCULATE (
    [Sales],
    FILTER ( ALLSELECTED ( 'Date'[Date] ), 'Date'[Date] <= MAX ( 'Date'[Date] ) )
)

WINDOW function (any sortable column)

DAX
Sales running total (window) =
CALCULATE (
    [Sales],
    WINDOW ( 1, ABS, 0, REL, ALLSELECTED ( 'Date'[YearMonth] ), ORDERBY ( 'Date'[YearMonth], ASC ) )
)

Visual calculation

DAX (visual calculation)
Running total = RUNNINGSUM ( [Sales] )

Running total that resets each year

DAX
Sales YTD = TOTALYTD ( [Sales], 'Date'[Date] )

Gotchas and behaviour differences

  • Accumulating by a non-date column (for example products sorted by sales, for a Pareto chart) needs the WINDOW form with an ORDERBY on the measure, or a visual calculation. The date pattern does not apply.
  • Qlik's RowNo() version restarts in each column segment, for example per year in a Year > Month table. WINDOW restarts only if you add PARTITIONBY('Date'[Year]).
  • Put the column used in ORDERBY on the visual's axis. If the axis shows another column from the same table instead, such as a month name sorted by YearMonth or a text key sorted by an index column, that column's filter stays on every row and the window shrinks to the current row. Fix both parts. Use SUMMARIZE(ALLSELECTED('Date'), 'Date'[YearMonth]) as the relation, and remove the label column's filter with REMOVEFILTERS('Date'[MonthName]) in the surrounding CALCULATE. Also don't call ALLSELECTED inside an iterator such as SUMX, where it returns only the rows being iterated. Compute it in a variable before the iterator.
  • The FILTER(ALLSELECTED('Date'[Date]), ...) pattern relies on 'Date' being marked as a date table. Filtering its date column then also removes filters on other Date columns, such as a YearMonth on the axis. Without that, use ALLSELECTED('Date') in the FILTER.
  • RangeSum treats nulls as 0. DAX addition also treats BLANK as 0, but a cumulative measure returns BLANK on rows with no dates in context.
  • Visual calculations have limits that matter when you migrate: you can't filter or sort a visual by them, change their aggregation, or reuse them in another visual. Data exports leave them out. They don't support dynamic format strings or Show items with no data. Slicers, custom visuals and paginated reports don't support them, and you can't pin a visual that uses them to a dashboard or publish it to the web. If any of these matter, use the model measure instead. (Microsoft's list)

Official documentation

Related pages

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.