Above(Sum(Sales))

Above, Below, Before and After in Power BI

Above() reads the value from the previous row of the chart. Power BI offers three replacements: the OFFSET window function, the PREVIOUS visual calculation, and calendar-aware time intelligence. Each behaves differently when periods are missing.

Partial / different approach DAX

Short answer: For "previous row" use CALCULATE([Sales], OFFSET(-1, ALLSELECTED('Date'[YearMonth]), ORDERBY('Date'[YearMonth]))), or the visual calculation PREVIOUS([Sales]). For "previous calendar month" use DATEADD.

What it does in Qlik

Above([TOTAL] expr [, offset [, count]]) evaluates the expression on the row above the current one in the chart's column segment. Below looks down. Before and After do the same across pivot-table columns. The result depends on the chart's sort order, and the first row returns NULL.

Qlik example

Qlik chart expressions
Above(Sum(Sales))                     // previous row
Sum(Sales) - Above(Sum(Sales))        // change vs previous row
Above(Sum(Sales), 12)                 // 12 rows up (same month last year, if no gaps)

Power BI equivalent

Window function (model measure)

This assumes 'Date'[YearMonth] is a sortable column such as 202401.

DAX
Sales previous row =
CALCULATE (
    [Sales],
    OFFSET ( -1, ALLSELECTED ( 'Date'[YearMonth] ), ORDERBY ( 'Date'[YearMonth], ASC ) )
)

Visual calculation

DAX (visual calculation)
Previous = PREVIOUS ( [Sales] )
Change = [Sales] - PREVIOUS ( [Sales] )

Calendar-aware (time intelligence)

DAX
Sales previous month = CALCULATE ( [Sales], DATEADD ( 'Date'[Date], -1, MONTH ) )
Sales last year = CALCULATE ( [Sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) )

Gotchas and behaviour differences

  • Above moves by displayed row. If a month has no data and is hidden, Qlik's "previous" is the month before the gap. DATEADD always uses the calendar. OFFSET over ALLSELECTED('Date'[YearMonth]) includes empty months, because it walks the date table.
  • 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 previous row comes back empty. 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.
  • Above(..., 12) for "same month last year" breaks as soon as a month is missing. SAMEPERIODLASTYEAR does not.
  • The sort order in a Qlik chart changes what Above returns. OFFSET uses its own ORDERBY, independent of the visual's sort.
  • 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)
  • The time intelligence functions need a proper date table with contiguous dates, marked as a date table. See master calendar.

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.