We released a new course for SQLBI+ subscribers: Understanding Visual Calculations in DAX. This is not an introduction to visual calculations for users. The goal is to explain the details of implementing visual calculations for experienced DAX developers, including new concepts such as visual shape and visual context.

The training is reference material for model and report developers who want to understand how visual calculations work internally, for troubleshooting, and to build better semantic models that delegate to visual calculations operations that do not belong in a centralized semantic model, such as most formatting-related operations specific to a report.

The course includes over 2.5 hours of videos and a white paper in PDF format that should be used as companion content. The first draft of the whitepaper was released in 2024; we have now finalized and updated the document to align with the latest updates to visual calculation functions. The video course has been produced very recently and includes more practical examples of the user interface, whereas the white paper has the same structure and content but does not provide user interface instructions. Combining both resources is usually the best idea!
Visual Calculations is a Power BI feature that is not available in other client tools, such as Excel. Other content we produced has an introductory description of visual calculations: the latest book (The Definitive Guide to DAX, 3rd edition) and the video course (Mastering DAX: the third edition will be available by the end of March 2026). This SQLBI+ content goes deeper and complements the DAX book and video course.
The course is organized into the following modules:
- Introducing visual calculations
- Visual calculations and window functions
- Understanding the visual shape
- Visual calculations are new columns in the virtual table
- Understanding densification
- Understanding the visual context
- Understanding EXPAND, COLLAPSE, EXPANDALL, and COLLAPSEALL
- Navigating the lattice of the virtual table
- Accessing the virtual table through ROWS and COLUMNS
- Understanding the unique behaviors of the visual context
- Understanding ROWS and COLUMNS used together
- Understanding reset and direction
- Using CALCULATE in visual calculations
- Understanding blank handling
- Understanding visual calculation functions
- Understanding PREVIOUS, NEXT, FIRST, LAST
- Understanding LOOKUP, LOOKUPWITHTOTALS, and auto-expand
- Understanding RUNNINGSUM
- Understanding ISATLEVEL
- Understanding MOVINGAVERAGE
- Understanding RANGE
- Visual calculations and calculation groups
- Visual calculation examples
- Computing the moving average over the last six months
- Computing growth over the same period last year
- Comparing sales over the average of the siblings
- Computing year-to-date
- Computing the Pareto / ABC Class
- Conclusions
Stay tuned for new SQLBI+ content coming later in 2026, and thank you to all SQLBI+ subscribers for their support!
Retrieves a context with added levels of detail compared to the current context. If an expression is provided, returns its value in the new context, allowing for navigation in hierarchies and calculation at a more detailed level.
EXPAND ( [<Expression>] [, <Axis>] [, <Column> [, <Column> [, … ] ] ] [, <N>] )
Retrieves a context with removed detail levels compared to the current context. With an expression, returns its value in the new context, allowing navigation up hierarchies and calculation at a coarser level of detail.
COLLAPSE ( [<Expression>] [, <Axis>] [, <Column> [, <Column> [, … ] ] ] [, <N>] )
Retrieves a context with added detail levels along an axis compared to the current context. With an expression, returns its value in the new context, enabling navigation to the lowest level on the axis, and is the inverse of COLLAPSEALL.
EXPANDALL ( [<Expression>], <Axis> )
Retrieves a context with removed detail levels along an axis. With an expression, returns its value in the new context, enabling navigation to the highest level on the axis and is the inverse of EXPANDALL.
COLLAPSEALL ( [<Expression>], <Axis> )
Evaluates an expression in a context modified by filters.
CALCULATE ( <Expression> [, <Filter> [, <Filter> [, … ] ] ] )
The Previous function retrieves a value in the previous row of an axis in the Visual Calculation data grid.
PREVIOUS ( <Column> [, <Steps>] [, <Axis>] [, <OrderBy>] [, <Blanks>] [, <Reset>] )
The Next function retrieves a value in the next row of an axis in the Visual Calculation data grid.
NEXT ( <Column> [, <Steps>] [, <Axis>] [, <OrderBy>] [, <Blanks>] [, <Reset>] )
The First function retrieves a value in the Visual Calculation data grid from the first row of an axis.
FIRST ( <Column> [, <Axis>] [, <OrderBy>] [, <Blanks>] [, <Reset>] )
The Last function retrieves a value in the Visual Calculation data grid from the last row of an axis.
LAST ( <Column> [, <Axis>] [, <OrderBy>] [, <Blanks>] [, <Reset>] )
Identifies cells where specified columns match evaluated expressions, and retrieves a column value (only when a single cell is identified) or calculates an expression’s value from those matching cells. Filter context from columns not specified will be applied implicitly.
LOOKUP ( <Result_ColumnOrExpression>, <Search_Column>, <Search_Value> [, <Search_Column>, <Search_Value> [, … ] ] )
Identifies cells where specified columns match evaluated expressions, and retrieves a column value (only when a single cell is identified) or calculates an expression’s value from those matching cells. LOOKUPWITHTOTALS defaults the non-specified columns to the total, whereas LOOKUP does not change the filter over non-specified columns.
LOOKUPWITHTOTALS ( <Result_ColumnOrExpression>, <Search_Column>, <Search_Value> [, <Search_Column>, <Search_Value> [, … ] ] )
Calculates a running sum along the specified axis of the Visual Calculation data grid.
RUNNINGSUM ( <Column> [, <Axis>] [, <OrderBy>] [, <Blanks>] [, <Reset>] )
Report whether the column is present at the current level.
ISATLEVEL ( <Column> )
Calculates a moving average along the specified axis of the Visual Calculation data grid.
MOVINGAVERAGE ( <Column>, <WindowSize> [, <IncludeCurrent>] [, <Axis>] [, <OrderBy>] [, <Blanks>] [, <Reset>] )
Retrieves a range of rows within the specified axis, relative to the current row.
RANGE ( <Step> [, <IncludeCurrent>] [, <Axis>] [, <OrderBy>] [, <Blanks>] [, <Reset>] )