| name | Power BI DAX |
| description | Write, execute, and optimize DAX queries and measures for Power BI semantic models using pbi-cli. Invoke this skill whenever the user mentions DAX, queries data in Power BI, writes calculations, creates measures, asks about EVALUATE, SUMMARIZECOLUMNS, CALCULATE, time intelligence, or wants to analyze/aggregate data from a semantic model. Also invoke when the user asks to run a query, test a formula, or check row counts. This skill contains critical guidance on passing DAX expressions via CLI arguments -- multi-line DAX (VAR/RETURN) requires special handling. |
| tools | pbi-cli |
Power BI DAX Skill
Execute and validate DAX queries against connected Power BI models.
Prerequisites
pipx install pbi-cli-tool
pbi-cli skills install
pbi connect
Executing Queries
pbi dax execute "EVALUATE TOPN(10, Sales)"
pbi dax execute --file query.dax
cat query.dax | pbi dax execute -
echo "EVALUATE Sales" | pbi dax execute -
pbi dax execute "EVALUATE Sales" --max-rows 100
pbi dax execute "EVALUATE Sales" --timeout 300
pbi --json dax execute "EVALUATE Sales"
DAX Expression Limitations in CLI
When passing DAX as a -e argument, the shell collapses newlines into a single line. Simple expressions like SUM(Sales[Amount]) work fine, but multi-line DAX using VAR/RETURN breaks because the DAX parser needs line breaks between those keywords.
Why this matters: A measure like VAR x = [Total Sales] VAR y = [Sales PY] RETURN DIVIDE(x - y, y) will fail with a syntax error because the engine sees it as one continuous line without statement separators.
Workarounds (pick one):
echo 'VAR TotalSales = SUM(Sales[Amount])
VAR TotalCost = SUM(Sales[Cost])
RETURN TotalSales - TotalCost' | pbi measure create "Profit" -e - -t Sales
echo 'EVALUATE
ROW("Result",
VAR x = SUM(Sales[Amount])
RETURN x
)' > query.dax
pbi dax execute --file query.dax
Single-line alternatives (preferred when possible):
For simple ratio/growth measures, use inline patterns instead of VAR/RETURN:
pbi measure create "Margin %" \
-e "DIVIDE(SUM(Sales[Amount]) - SUM(Sales[Cost]), SUM(Sales[Amount]))" \
-t Sales --format-string "0.0%"
pbi measure create "YoY %" \
-e "DIVIDE([Total Sales] - [PY Sales], [PY Sales])" \
-t Sales --format-string "0.0%"
Validating Queries
pbi dax validate "EVALUATE Sales"
pbi dax validate --file query.dax
Cache Management
pbi dax clear-cache
Creating Measures with DAX
pbi measure create "Total Sales" -e "SUM(Sales[Amount])" -t Sales
pbi measure create "YTD Sales" -e "TOTALYTD(SUM(Sales[Amount]), Calendar[Date])" -t Sales
pbi measure create "PY Sales" -e "CALCULATE([Total Sales], SAMEPERIODLASTYEAR(Calendar[Date]))" -t Sales
pbi measure create "YoY %" -e "DIVIDE([Total Sales] - [PY Sales], [PY Sales])" -t Sales --format-string "0.0%"
Common DAX Patterns
Explore Model Data
pbi dax execute "EVALUATE INFO.TABLES()"
pbi dax execute "EVALUATE INFO.COLUMNS()"
pbi dax execute "EVALUATE TOPN(10, Sales)"
pbi dax execute "EVALUATE ROW(\"Count\", COUNTROWS(Sales))"
Aggregations
pbi dax execute "EVALUATE ROW(\"Total\", SUM(Sales[Amount]))"
pbi dax execute "EVALUATE SUMMARIZECOLUMNS(Products[Category], \"Total\", SUM(Sales[Amount]))"
pbi dax execute "
EVALUATE
SUMMARIZECOLUMNS(
Products[Category],
\"Total Sales\", SUM(Sales[Amount]),
\"Avg Price\", AVERAGE(Sales[UnitPrice]),
\"Count\", COUNTROWS(Sales)
)
"
Filtering
pbi dax execute "
EVALUATE
ROW(\"Online Sales\", CALCULATE(SUM(Sales[Amount]), Sales[Channel] = \"Online\"))
"
pbi dax execute "
EVALUATE
FILTER(
SUMMARIZECOLUMNS(Products[Name], \"Total\", SUM(Sales[Amount])),
[Total] > 1000
)
"
Time Intelligence
pbi dax execute "
EVALUATE
ROW(\"YTD\", TOTALYTD(SUM(Sales[Amount]), Calendar[Date]))
"
pbi dax execute "
EVALUATE
ROW(\"R12\", CALCULATE(
SUM(Sales[Amount]),
DATESINPERIOD(Calendar[Date], MAX(Calendar[Date]), -12, MONTH)
))
"
Ranking
pbi dax execute "
EVALUATE
TOPN(
10,
ADDCOLUMNS(
VALUES(Products[Name]),
\"Total\", CALCULATE(SUM(Sales[Amount]))
),
[Total], DESC
)
"
Performance Tips
- Use
--max-rows to limit result sets during development
- Run
pbi dax clear-cache before benchmarking
- Prefer
SUMMARIZECOLUMNS over SUMMARIZE for grouping
- Use
CALCULATE with simple filters instead of nested FILTER
- Avoid iterators (
SUMX, FILTER) on large tables when aggregations suffice