Budget vs Actuals Power Bi

Budget vs Actuals Power Bi

Admin
June 8, 2026
Budget vs Actuals in Power BI: The Complete Guide (2026) | Flexa Intel

Power BI Guide  ·  Updated June 2026  ·  12 min read  ·  Flexa Intel Team

Budget vs Actuals in Power BI: The Complete Guide (2026)

Quick Answer To build a budget vs actuals report in Power BI: store Actuals and Budget in the same fact table with a Scenario column, create DAX measures for each scenario and their variance using CALCULATE with scenario filters, then display them in a Matrix visual. For Finance teams who need variance columns without writing DAX, Flexa Tables adds Actual vs Budget comparison directly in the published report.
80%of Finance teams use Excel for budget vs actuals instead of Power BI
3–5×more DAX measures needed for multi-scenario variance than a standard report
0DAX required with Flexa Tables for period-over-period variance

1. Why Budget vs Actuals Is Harder Than It Looks in Power BI

A budget vs actuals report sounds simple: show Actuals, show Budget, show the difference. In Excel, you add a column. In Power BI, you quickly realize the Matrix visual doesn't have a built-in way to compare two scenarios side by side — you need to engineer that comparison yourself through DAX and data modeling.

The three specific challenges that trip most developers up:

  • Data model design: Actuals and Budget usually live in different source systems (ERP vs planning tool). Combining them into a coherent Power BI model requires a deliberate design decision upfront.
  • DAX complexity: For a P&L with 10 line items, you can end up with 40+ measures (Actuals, Budget, Variance, Variance % × 10 line items). Any schema change breaks everything.
  • P&L structure: Revenue and expense lines have opposite sign conventions for variance. A positive variance on revenue is favorable; a positive variance on an expense line is unfavorable. Standard DAX patterns don't handle this automatically.

2. The Right Data Model: Scenario Column vs Separate Tables

Budget vs Actuals recommended data modelSingle fact table with Scenario column connected to DimDate and DimGLAccount dimension tables, feeding DAX measuresFactFinancialsDateFK → DimDateGLAccountFK → DimGLCostCenterFK → DimCCScenario"Actual"|"Budget"|"Forecast"AmountDecimalCurrencyTextDimDateDate (PK)MonthYearDimGLAccountGLCode (PK)GLNameCategoryFavorableDirectionDAX measuresActualsBudgetForecastVarianceVariance %Variance FavorableKey design decisionOne table, not separate Actuals/Budget tablesFact tableDimensionsDAX measuresDesign note
Recommended data model: single fact table with Scenario column

The single most important decision in a budget vs actuals Power BI model is how you store your data. There are two common approaches:

Option A — Single Fact Table with Scenario Column (Recommended)

Store all financial data in one fact table with a Scenario column containing values like Actual, Budget, Forecast.

FactFinancials
| Date       | GLAccount | CostCenter | Scenario  | Amount    |
|------------|-----------|------------|-----------|-----------|
| 2026-01-01 | 4001      | CC-Sales   | Actual    | 125,000   |
| 2026-01-01 | 4001      | CC-Sales   | Budget    | 118,000   |
| 2026-01-01 | 4001      | CC-Sales   | Forecast  | 121,000   |
Why this works better: All scenarios share the same Date dimension, GL Account dimension, and Cost Center dimension. DAX measures filter by Scenario cleanly with CALCULATE([Total Amount], FactFinancials[Scenario] = "Actual"). Adding Forecast later requires zero model changes.

Option B — Separate Tables (Common but Problematic)

Some setups store Actuals and Budget in separate tables (FactActuals and FactBudget) with a bridge relationship via Date and GL Account. This works but creates cross-filter complexity and makes it harder to add a third scenario without restructuring the model.

Avoid this pattern: Storing Actuals and Budget as separate columns in the same row (e.g., ActualAmount and BudgetAmount side by side). It looks simple but breaks when you add Forecast, when granularity differs between Actuals and Budget, or when you have sparse budget data (not every GL Account is budgeted).

3. DAX Patterns for Actuals, Budget, Variance, and Variance %

With the Scenario column data model in place, these four base measures cover the core budget vs actuals reporting needs:

Base measures

Actuals =
CALCULATE(
    SUM(FactFinancials[Amount]),
    FactFinancials[Scenario] = "Actual"
)

Budget =
CALCULATE(
    SUM(FactFinancials[Amount]),
    FactFinancials[Scenario] = "Budget"
)

Forecast =
CALCULATE(
    SUM(FactFinancials[Amount]),
    FactFinancials[Scenario] = "Forecast"
)

Variance measures

Variance (Actuals vs Budget) =
[Actuals] - [Budget]

Variance % (Actuals vs Budget) =
DIVIDE(
    [Actuals] - [Budget],
    ABS([Budget]),
    BLANK()
)
Critical: Always use ABS([Budget]) in the denominator, not [Budget]. When Budget is negative (common for expense lines in a P&L), using [Budget] without ABS causes the variance percentage to flip sign unexpectedly — showing a positive percentage when actuals exceeded budget on an expense line.

Handling the P&L sign convention

Revenue lines: favorable variance = Actuals > Budget (positive variance is good). Expense lines: favorable variance = Actuals < Budget (positive variance is bad). To handle this automatically, add a FavorableDirection column to your GL Account dimension (+1 for revenue, -1 for expense), then adjust:

Variance Favorable =
VAR _var = [Actuals] - [Budget]
VAR _direction = SELECTEDVALUE(DimGLAccount[FavorableDirection], 1)
RETURN _var * _direction

This single measure returns a positive value for all favorable variances and a negative value for all unfavorable variances — regardless of whether the line is revenue or expense. Conditional formatting then works consistently across the entire P&L.

4. Building the Matrix Layout: P&L Structure with Subtotals

The Matrix visual is the right choice for a P&L-style budget vs actuals report. The setup:

  • Rows: GL Account hierarchy (Category → Subcategory → Account). Use a SortOrder column in the GL Account dimension to control row order — the Matrix sorts alphabetically by default.
  • Columns: Month (as a Year-Month column, not the built-in date hierarchy). Format as MMM YYYY (e.g., Jan 2026).
  • Values: Actuals, Budget, Variance, Variance % — in that order.

For subtotals: the Matrix handles subtotals automatically at each hierarchy level. However, subtotals for P&L reports often need custom logic (Gross Profit = Revenue - COGS, Operating Income = Gross Profit - OpEx). These should be separate rows in the GL Account dimension with their own DAX measures, not the Matrix's built-in subtotals.

Tip: Turn off the Matrix's built-in subtotals (Format → Row subtotals → Off) and control every subtotal row explicitly through your GL Account dimension and measures. This gives you full control over labels, row ordering, and sign conventions.

5. Conditional Formatting: Red for Unfavorable, Green for Favorable

Apply conditional formatting to the Variance and Variance % columns to make favorable/unfavorable performance immediately visible:

  1. Select the Matrix visual → Format pane → Cell elements → Apply to: Variance column → Font color → ON
  2. Set rules: If value < 0 → Red (#C00000); If value ≥ 0 → Green (#375623)
  3. Repeat for Variance % column

If you implemented the Variance Favorable measure (which flips sign for expense lines), apply conditional formatting to that measure instead — then green always means favorable and red always means unfavorable across the entire P&L.

For the Variance % column, also consider adding data bars to show magnitude alongside direction:

  • Format → Cell elements → Apply to: Variance % → Data bars → ON
  • Set positive bar color = green, negative bar color = red

6. No-DAX Alternative: Flexa Tables for Finance Teams

Budget vs Actuals matrix with variance columns and conditional formattingSample Power BI matrix table showing Actuals, Budget, Variance and Variance % columns. Favorable variances shown in green, unfavorable in red.P&L lineActualsBudgetVarianceVariance %Total Revenue1,240,0001,180,000+60,000+5.1%Product Revenue890,000850,000+40,000+4.7%Service Revenue350,000330,000+20,000+6.1%Total Operating Expenses820,000790,000+30,000+3.8%Salaries510,000490,000+20,000+4.1%Marketing310,000300,000+10,000+3.3%Operating Income (EBIT)420,000390,000+30,000+7.7%FavorableUnfavorable
Matrix visual with Actuals, Budget, Variance, and Variance % — conditional formatting applied by favorable direction

The DAX approach above works well for BI developers building a fixed report. But Finance teams frequently need to:

  • Compare Actuals vs Budget for one month, then Actuals vs Forecast for the next
  • Switch between monthly and quarterly views
  • Add a new variance column without going back to Power BI Desktop
  • Explore different GL Account groupings without requesting a report change

None of these are possible with the native Matrix visual after publishing. Every change requires a developer, a Desktop session, and a republish.

Flexa Tables (Microsoft-certified, available on AppSource) solves this. Finance users add Actual vs Budget variance columns directly in the published Power BI report — no DAX, no Desktop access, no waiting. They select the two scenarios to compare and the variance column (absolute and %) appears instantly.

CapabilityNative Matrix + DAXFlexa Tables
Actuals vs Budget variance column✓ With DAX measures✓ One click, no DAX
Switch to Actuals vs Forecast✗ Requires new measures + republish✓ User selects in published report
MoM / YoY variance in same table✗ Requires additional DAX + layout change✓ Built-in, no DAX
End-user restructures layout✗ Not after publishing✓ Drag-and-drop in Service
Microsoft certified✓ Native✓ AppSource certified
Works with existing data model✓ Yes✓ Yes — no model changes needed

For teams already using Flexa Tables for pivot table reporting, the same visual handles budget vs actuals comparison — no additional setup required.

7. Three Common Mistakes and How to Fix Them

Mistake 1 — Using [Budget] instead of ABS([Budget]) in the variance % denominator

Symptom: Variance % shows incorrect sign on expense lines (e.g., +15% when actuals exceeded budget on an expense).
Fix: Always use DIVIDE([Actuals] - [Budget], ABS([Budget])).

Mistake 2 — Budget data at different granularity than Actuals

Symptom: Budget shows at month level but Actuals show at transaction level — variance is blank or incorrect when filtered to specific GL Accounts or Cost Centers that weren't budgeted at that level.
Fix: Always define the lowest granularity of Budget upfront and ensure the data model joins on exactly those columns. Use BLANK() guards in DAX where budget rows may be missing.

Budget (with blank guard) =
VAR _budget = CALCULATE(SUM(FactFinancials[Amount]), FactFinancials[Scenario] = "Budget")
RETURN IF(ISBLANK(_budget), 0, _budget)

Mistake 3 — Applying the Matrix's built-in subtotals to a P&L layout

Symptom: Subtotals show sum of all rows including expense lines, making Gross Profit and Operating Income incorrect (they should be Revenue − Expense, not Revenue + Expense).
Fix: Turn off Matrix subtotals and model every subtotal row explicitly in your GL Account dimension with dedicated DAX measures.

Skip the DAX complexity — try Flexa Tables

Finance teams using Flexa Tables add Actual vs Budget variance columns in the published report — no DAX, no developer, no waiting. Free trial on Microsoft AppSource.

Get Free Trial on AppSource →

FAQ

How do I create a budget vs actuals report in Power BI?

Store Actuals and Budget in the same fact table with a Scenario column. Create DAX measures for each scenario and their variance using CALCULATE with scenario filters. Display in a Matrix visual with rows as P&L line items and columns as months. For a no-DAX option, Flexa Tables adds variance columns directly in the published report.

What is the best data model for budget vs actuals in Power BI?

A single fact table with a Scenario column (Actual, Budget, Forecast) joined to shared dimension tables (Date, GL Account, Cost Center). This approach scales cleanly when you add Forecast or additional scenarios later.

Can I do budget vs actuals in Power BI without DAX?

Yes. Flexa Tables (Microsoft AppSource) lets end users add Actual vs Budget variance columns directly in the published report. Users select the two scenarios to compare and the variance column appears instantly — no DAX, no developer required.

How do I show negative variances in red in Power BI?

Use conditional formatting on the variance column: Format → Cell elements → Font color → Rules: if value < 0, color = red (#C00000); if value ≥ 0, color = green (#375623). For P&L reports with mixed revenue/expense sign conventions, implement a Variance Favorable measure that adjusts sign by line type before applying conditional formatting.

What is the difference between variance and variance % in budget vs actuals?

Variance (absolute) = Actuals − Budget, expressed in the same unit as the data (dollars, units, etc.). Variance % = DIVIDE(Actuals − Budget, ABS(Budget)) × 100, expressed as a percentage of budget. Always use ABS(Budget) in the denominator to handle expense lines correctly.

How do I handle missing budget rows in Power BI?

Add a BLANK() guard or default to 0 in your Budget measure: VAR _budget = CALCULATE(...) RETURN IF(ISBLANK(_budget), 0, _budget). This prevents blank variance columns when certain GL Accounts or Cost Centers have actuals but no budget defined.

FI
Flexa Intel Team Power BI custom visuals for tables, charts, design & analytics. Makers of Flexa Tables — the pivot and variance visual for Power BI.
flexaintel.com
facebooklinkedintwittermail