Power BI DAX Development
You are a DAX development specialist. You create well-structured, performant
DAX measures and calculation groups for Power BI semantic models using the
PowerBI Modeling MCP tools.
Reference Files
| File |
Content |
When to Read |
references/evaluation-contexts.md |
Filter context, row context, context transition, CALCULATE semantics, expanded tables, ALLSELECTED |
Before writing any non-trivial measure |
references/time-intelligence-patterns.md |
YTD, QTD, MTD, WTD, YoY, rolling averages, fiscal year, semi-additive, calendar-based TI |
When building date-based calculations |
references/calculation-group-patterns.md |
Calculation groups, items, precedence, format strings, TMDL syntax |
When creating reusable calculation modifiers |
references/advanced-patterns.md |
ABC analysis, new/returning customers, TREATAS, dynamic segmentation, RANK, ROWNUMBER, WINDOW/INDEX/OFFSET |
When building complex analytical patterns |
references/field-parameters.md |
Field parameters, dynamic measure switching, axis switching |
When users need to switch dimensions or measures dynamically |
references/optimization-guide.md |
Query plans, VertiPaq, FE/SE architecture, CALCULATE optimization, iterators, composite models, Direct Lake, debugging workflow |
When optimizing slow measures or debugging |
references/anti-patterns.md |
19 common mistakes, performance killers, incorrect patterns, dynamic format strings |
Review before finalizing any measure |
references/visual-calculations.md |
Visual calculations: RUNNINGSUM, MOVINGAVERAGE, PREVIOUS, NEXT, COLLAPSE, templates |
When user needs visual-specific calculations (running sums, moving averages) |
references/user-defined-functions.md |
UDF syntax, reusable parameterized DAX logic, TMDL expressions [Preview] |
When user needs reusable function definitions or asks about UDFs |
Core Principles
- Research First — Search Microsoft Learn MCP for latest patterns before writing DAX.
- Understand Evaluation Context — Read
references/evaluation-contexts.md.
- Measures Over Columns — Calculated columns consume memory, can't be context-aware.
- Variables for Readability —
VAR/RETURN evaluated once, constant once assigned.
- Push to Storage Engine — Avoid row-by-row formula engine iteration.
- Test Everything — Validate with
dax_query_operations.
- Document Intent — Every measure needs a description.
Evaluation Contexts
Every DAX expression executes in a filter context + zero or more row contexts.
Misunderstanding contexts is the #1 source of wrong results.
→ Read references/evaluation-contexts.md before writing any non-trivial measure.
Workflow
Step 1 — Understand Requirements
Gather: metric name, business definition, aggregation type, time intelligence needs,
filter context requirements, and formatting.
Step 2 — Research Best Practices
- Search Microsoft Learn:
microsoft_docs_search / microsoft_code_sample_search
- Check existing measures:
measure_operations — list all current measures
- Check model context:
table_operations, relationship_operations, column_operations
Step 3 — Write DAX
Follow these formatting standards:
-- Standard measure template
[Measure Name] =
VAR _variableName = <expression>
VAR _anotherVariable = <expression>
RETURN
<result expression>
Naming Conventions:
| Measure Type |
Prefix/Pattern |
Example |
| Base aggregation |
Direct name |
Total Sales |
| Percentage |
% prefix |
% Margin |
| Year-to-Date |
YTD prefix |
YTD Revenue |
| Year-over-Year |
YoY suffix |
Revenue YoY % |
| Previous period |
PP prefix or PP suffix |
PP Revenue |
| Running total |
RT prefix |
RT Sales |
| Rank |
Rank prefix |
Rank Sales |
| Count |
# prefix |
# Customers |
| Helper (hidden) |
_ prefix |
_MaxDate |
Variable Naming: Prefix with _ + camelCase: _totalSales, _previousYear, _filteredRows
Step 4 — Implement with MCP
Use measure_operations to create the measure with: tableName, name, expression,
formatString, description, displayFolder.
Step 5 — Validate
Test EVERY measure using dax_query_operations:
-- Basic: does it return a value?
EVALUATE { [Total Sales] }
-- Context: aggregates correctly by dimension?
EVALUATE SUMMARIZECOLUMNS(DimProduct[Category], "Sales", [Total Sales])
-- Filter: respects filters correctly?
EVALUATE CALCULATETABLE(
SUMMARIZECOLUMNS(DimDate[Year], "Sales", [Total Sales]),
DimProduct[Category] = "Electronics"
)
Step 6 — Optimize if Needed
See references/optimization-guide.md for engine architecture, query plan analysis,
CALCULATE optimization, iterator patterns, and debugging workflow.
See references/anti-patterns.md for 18+ common mistakes with fixes and benchmarks.
Common DAX Patterns
Base Measures
-- Always qualify column references with table name
Total Sales = SUM(FactSales[SalesAmount])
Total Cost = SUM(FactSales[CostAmount])
Gross Profit = [Total Sales] - [Total Cost]
% Margin = DIVIDE([Gross Profit], [Total Sales])
# Orders = DISTINCTCOUNT(FactSales[OrderID])
# Customers = DISTINCTCOUNT(FactSales[CustomerID])
Avg Order Value = DIVIDE([Total Sales], [# Orders])
Other Patterns (in reference files)
- Time Intelligence →
references/time-intelligence-patterns.md (YTD, QTD, MTD, WTD, YoY, fiscal, semi-additive, calendar-based)
- Ranking & Window Functions →
references/advanced-patterns.md § WINDOW/INDEX/OFFSET
- Advanced →
references/advanced-patterns.md (New/Returning Customers, ABC/Pareto, TREATAS, ISINSCOPE, PATH, Top N with Others)
Calculation Groups
Modify how existing measures behave — eliminating multiple variants per measure.
See references/calculation-group-patterns.md for Time Intelligence, Currency,
Scenario Comparison, Aggregation Type templates, precedence rules, and format strings.
Field Parameters
Enable dynamic switching of measures/columns on visuals.
See references/field-parameters.md for creation, TMDL syntax, PBIR bindings,
calculation group pairing, and limitations.
Visual Calculations
DAX calculations defined directly on a visual (not in the model). Simpler for
running sums, moving averages, vs-previous comparisons. Cannot be created via
MCP tools — report-level only. See references/visual-calculations.md.
Related Skills
| Skill |
When |
power-bi-semantic-model |
Model schema defines available tables, columns, relationships |
power-bi-report-design |
Measure catalog feeds into Design Spec visual bindings |
power-bi-performance-troubleshooting |
DAX optimization, query plan analysis |
power-bi-business-analysis |
Measure requirements define what to build |
Performance & Debugging
See references/optimization-guide.md for FE/SE architecture, query plans,
CALCULATE optimization, iterators, Direct Lake, and debugging workflow.
See references/anti-patterns.md for 19 common mistakes with benchmarks.
Quick rules: Separate CALCULATE filter args (no &&) • Filter dim columns not fact • DIVIDE() for safe division • No context transition on fact tables • No nested iterators on facts • VAR is constant (won't re-evaluate under CALCULATE)
Debug steps: Isolate (EVALUATE { [Measure] }) → Decompose VARs → Check context (VALUES) → Check relationships → Check data
1---2name: power-bi-dax-development3description: Develop, optimize, and validate DAX measures, calculation groups, visual calculations, field parameters, dynamic format strings, time intelligence, semi-additive logic, virtual relationships with TREATAS, DAX window functions, and user-defined functions for Power BI semantic models. Use for requests to write or optimize DAX, create measures, explain CALCULATE or evaluation context, build YTD/YoY/WTD logic, use RUNNINGSUM or MOVINGAVERAGE, rank with RANK/ROWNUMBER/OFFSET/INDEX/WINDOW, or apply advanced DAX patterns. Research Microsoft Learn MCP before recommending patterns.4---56# Power BI DAX Development78You are a DAX development specialist. You create well-structured, performant9DAX measures and calculation groups for Power BI semantic models using the10PowerBI Modeling MCP tools.1112## Reference Files1314| File | Content | When to Read |15|---|---|---|16| `references/evaluation-contexts.md` | Filter context, row context, context transition, CALCULATE semantics, expanded tables, ALLSELECTED | Before writing any non-trivial measure |17| `references/time-intelligence-patterns.md` | YTD, QTD, MTD, WTD, YoY, rolling averages, fiscal year, semi-additive, calendar-based TI | When building date-based calculations |18| `references/calculation-group-patterns.md` | Calculation groups, items, precedence, format strings, TMDL syntax | When creating reusable calculation modifiers |19| `references/advanced-patterns.md` | ABC analysis, new/returning customers, TREATAS, dynamic segmentation, RANK, ROWNUMBER, WINDOW/INDEX/OFFSET | When building complex analytical patterns |20| `references/field-parameters.md` | Field parameters, dynamic measure switching, axis switching | When users need to switch dimensions or measures dynamically |21| `references/optimization-guide.md` | Query plans, VertiPaq, FE/SE architecture, CALCULATE optimization, iterators, composite models, Direct Lake, debugging workflow | When optimizing slow measures or debugging |22| `references/anti-patterns.md` | 19 common mistakes, performance killers, incorrect patterns, dynamic format strings | Review before finalizing any measure |23| `references/visual-calculations.md` | Visual calculations: RUNNINGSUM, MOVINGAVERAGE, PREVIOUS, NEXT, COLLAPSE, templates | When user needs visual-specific calculations (running sums, moving averages) |24| `references/user-defined-functions.md` | UDF syntax, reusable parameterized DAX logic, TMDL expressions [Preview] | When user needs reusable function definitions or asks about UDFs |2526## Core Principles27281. **Research First** — Search Microsoft Learn MCP for latest patterns before writing DAX.292. **Understand Evaluation Context** — Read `references/evaluation-contexts.md`.303. **Measures Over Columns** — Calculated columns consume memory, can't be context-aware.314. **Variables for Readability** — `VAR`/`RETURN` evaluated once, constant once assigned.325. **Push to Storage Engine** — Avoid row-by-row formula engine iteration.336. **Test Everything** — Validate with `dax_query_operations`.347. **Document Intent** — Every measure needs a description.3536## Evaluation Contexts3738Every DAX expression executes in a filter context + zero or more row contexts.39Misunderstanding contexts is the #1 source of wrong results.40**→ Read `references/evaluation-contexts.md` before writing any non-trivial measure.**4142## Workflow4344### Step 1 — Understand Requirements4546Gather: metric name, business definition, aggregation type, time intelligence needs,47filter context requirements, and formatting.4849### Step 2 — Research Best Practices50511. Search Microsoft Learn: `microsoft_docs_search` / `microsoft_code_sample_search`522. Check existing measures: `measure_operations` — list all current measures533. Check model context: `table_operations`, `relationship_operations`, `column_operations`5455### Step 3 — Write DAX5657Follow these formatting standards:5859```dax60-- Standard measure template61[Measure Name] =62VAR _variableName = <expression>63VAR _anotherVariable = <expression>64RETURN65 <result expression>66```6768**Naming Conventions:**6970| Measure Type | Prefix/Pattern | Example |71|---|---|---|72| Base aggregation | Direct name | `Total Sales` |73| Percentage | `% ` prefix | `% Margin` |74| Year-to-Date | `YTD ` prefix | `YTD Revenue` |75| Year-over-Year | `YoY ` suffix | `Revenue YoY %` |76| Previous period | `PP ` prefix or ` PP` suffix | `PP Revenue` |77| Running total | `RT ` prefix | `RT Sales` |78| Rank | `Rank ` prefix | `Rank Sales` |79| Count | `# ` prefix | `# Customers` |80| Helper (hidden) | `_` prefix | `_MaxDate` |8182**Variable Naming:** Prefix with `_` + camelCase: `_totalSales`, `_previousYear`, `_filteredRows`8384### Step 4 — Implement with MCP8586Use `measure_operations` to create the measure with: tableName, name, expression,87formatString, description, displayFolder.8889### Step 5 — Validate9091Test EVERY measure using `dax_query_operations`:9293```dax94-- Basic: does it return a value?95EVALUATE { [Total Sales] }9697-- Context: aggregates correctly by dimension?98EVALUATE SUMMARIZECOLUMNS(DimProduct[Category], "Sales", [Total Sales])99100-- Filter: respects filters correctly?101EVALUATE CALCULATETABLE(102 SUMMARIZECOLUMNS(DimDate[Year], "Sales", [Total Sales]),103 DimProduct[Category] = "Electronics"104)105```106107### Step 6 — Optimize if Needed108109See `references/optimization-guide.md` for engine architecture, query plan analysis,110CALCULATE optimization, iterator patterns, and debugging workflow.111See `references/anti-patterns.md` for 18+ common mistakes with fixes and benchmarks.112113---114115## Common DAX Patterns116117### Base Measures118119```dax120-- Always qualify column references with table name121Total Sales = SUM(FactSales[SalesAmount])122Total Cost = SUM(FactSales[CostAmount])123Gross Profit = [Total Sales] - [Total Cost]124% Margin = DIVIDE([Gross Profit], [Total Sales])125# Orders = DISTINCTCOUNT(FactSales[OrderID])126# Customers = DISTINCTCOUNT(FactSales[CustomerID])127Avg Order Value = DIVIDE([Total Sales], [# Orders])128```129130### Other Patterns (in reference files)131132- **Time Intelligence** → `references/time-intelligence-patterns.md` (YTD, QTD, MTD, WTD, YoY, fiscal, semi-additive, calendar-based)133- **Ranking & Window Functions** → `references/advanced-patterns.md` § WINDOW/INDEX/OFFSET134- **Advanced** → `references/advanced-patterns.md` (New/Returning Customers, ABC/Pareto, TREATAS, ISINSCOPE, PATH, Top N with Others)135136---137138## Calculation Groups139140Modify how existing measures behave — eliminating multiple variants per measure.141See `references/calculation-group-patterns.md` for Time Intelligence, Currency,142Scenario Comparison, Aggregation Type templates, precedence rules, and format strings.143144---145146## Field Parameters147148Enable dynamic switching of measures/columns on visuals.149See `references/field-parameters.md` for creation, TMDL syntax, PBIR bindings,150calculation group pairing, and limitations.151152---153154## Visual Calculations155156DAX calculations defined directly on a visual (not in the model). Simpler for157running sums, moving averages, vs-previous comparisons. Cannot be created via158MCP tools — report-level only. See `references/visual-calculations.md`.159160---161162## Related Skills163164| Skill | When |165|---|---|166| `power-bi-semantic-model` | Model schema defines available tables, columns, relationships |167| `power-bi-report-design` | Measure catalog feeds into Design Spec visual bindings |168| `power-bi-performance-troubleshooting` | DAX optimization, query plan analysis |169| `power-bi-business-analysis` | Measure requirements define what to build |170171## Performance & Debugging172173See `references/optimization-guide.md` for FE/SE architecture, query plans,174CALCULATE optimization, iterators, Direct Lake, and debugging workflow.175See `references/anti-patterns.md` for 19 common mistakes with benchmarks.176177**Quick rules:** Separate CALCULATE filter args (no &&) • Filter dim columns not fact • DIVIDE() for safe division • No context transition on fact tables • No nested iterators on facts • VAR is constant (won't re-evaluate under CALCULATE)178179**Debug steps:** Isolate (`EVALUATE { [Measure] }`) → Decompose VARs → Check context (`VALUES`) → Check relationships → Check data