DAX Formatter for Power BI

Paste a Power BI or Analysis Services measure and get the readable layout DAX developers expect. Your model logic is formatted inside this browser tab and is not sent to any formatting service.

Input

Settings

History

Load from URL

The layout it produces

PasteKit formats DAX with a built-in DAX tokenizer and printer that follows the conventions popularised by SQLBI’s DAX Formatter, so the output will look familiar to anyone who has read their books or articles:

  • a function call that fits on one line is written as SUM ( Sales[Amount] ), with spaces inside the parentheses
  • a call that does not fit puts one argument per line, indented, with the closing parenthesis lined up under the function name
  • VAR and RETURN each start a new line, and the expression after RETURN is indented
  • long chains of && and || break before the operator, so each condition reads as a line
  • measure definitions keep their Name = header on the first line

Both measure and calculated-column definitions (Margin % = DIVIDE ( ... )) and full DAX queries starting with EVALUATE, DEFINE or containing ORDER BY are handled. Table references like 'Date'[Date] and column references like Sales[Amount] are kept exactly as written.

Function case and other settings

Function case has two choices. UPPER (the default) writes function names and keywords in capitals — CALCULATE, SAMEPERIODLASTYEAR, VAR, RETURN, EVALUATE — which is the near-universal convention in Power BI teams. As written leaves the casing you typed, for when you want only whitespace to change. Table, column and measure names are never re-cased in either mode, because they must match the model.

The toolbar indent sets how far arguments and RETURN bodies are indented, and the line width decides when a call is too long to stay on one line. Narrower widths produce the tall, one-argument-per-line style that many people find easiest to review in Tabular Editor or a pull request.

Shortcuts: Ctrl/Cmd+Enter to format, Ctrl/Cmd+Shift+C to copy back into Power BI Desktop, Ctrl/Cmd+K for the command palette. Ctrl/Cmd+Shift+M does not apply, since DAX has no minify mode here.

Forgiving by design

The parser is intentionally lenient. DAX has hundreds of functions and new ones arrive in Power BI updates, so anything the printer does not recognise is passed through token by token rather than rejected. Formatting therefore never drops, reorders or “corrects” your code. The only hard errors are the ones that make the expression impossible to read: an unclosed string, quoted table name or /* */ comment, or unbalanced parentheses and brackets. Each is reported with its line and column and a hint.

Comments in all three DAX styles (//, -- and /* */) are kept. This is not a semantic validator, so a misspelled column or a filter argument of the wrong type will format happily; Power BI will still tell you about those when you commit the measure.

Working with the rest of the Power BI stack? The Power Query formatter handles M code from the query editor.

Examples

Year-over-year measure with variables

Each VAR gets its own line, functions are upper-cased, and the RETURN expression is indented.

Input
Sales YoY % = var cur=sum(Sales[Amount]) var prev=calculate(sum(Sales[Amount]),sameperiodlastyear('Date'[Date])) return if(isblank(prev),blank(),divide(cur-prev,prev))
Output
Sales YoY % =
VAR cur = SUM ( Sales[Amount] )
VAR prev =
  CALCULATE ( SUM ( Sales[Amount] ), SAMEPERIODLASTYEAR ( 'Date'[Date] ) )
RETURN
  IF ( ISBLANK ( prev ), BLANK (), DIVIDE ( cur - prev, prev ) )
Open this example in the tool

SWITCH ( TRUE () ) banding

The SWITCH call is too long for one line, so every argument is placed on its own line.

Input
Margin Band = var m=divide([Profit],[Revenue]) return switch(true(),m>=0.3,"High",m>=0.1,"Medium",isblank(m),blank(),"Low")
Output
Margin Band =
VAR m = DIVIDE ( [Profit], [Revenue] )
RETURN
  SWITCH (
    TRUE (),
    m >= 0.3,
    "High",
    m >= 0.1,
    "Medium",
    ISBLANK ( m ),
    BLANK (),
    "Low"
  )
Open this example in the tool

DAX query, casing as written

With Function case set to As written, only whitespace changes; EVALUATE and ORDER BY each start a line.

Input
evaluate summarizecolumns('Date'[Year],'Product'[Category],"Revenue",[Total Revenue],"Orders",countrows(Sales)) order by 'Date'[Year] desc
Output
evaluate
  summarizecolumns (
    'Date'[Year],
    'Product'[Category],
    "Revenue",
    [Total Revenue],
    "Orders",
    countrows ( Sales )
  )
order by 'Date'[Year] desc
Open this example in the tool

FILTER with a chain of conditions

Nested calls indent under CALCULATE; the && chain stays on one line because it fits the width.

Input
Big Paid Orders = calculate(countrows(Orders),filter(Orders,Orders[Status]="Paid"&&Orders[Total]>1000&&Orders[Country]<>"SG"))
Output
Big Paid Orders =
CALCULATE (
  COUNTROWS ( Orders ),
  FILTER (
    Orders,
    Orders[Status] = "Paid" && Orders[Total] > 1000 && Orders[Country] <> "SG"
  )
)
Open this example in the tool

Common errors and how to fix them

ErrorCauseFix
This '(' is never closedA function call is missing its closing parenthesis, often at the very end of a long measure.Add the matching ‘)’. Formatting the part that does parse with a narrower width makes the nesting easier to count.
Unexpected ')' — there is no matching '(' before itThere is one closing parenthesis too many.Remove the extra parenthesis at the reported column.
This string is never closedA text literal is missing its closing double quote.Add the closing “. To put a quote inside a DAX string, double it (”").
This quoted table name is never closedA table name in single quotes, such as ‘Date’, is missing its closing apostrophe.Close the quote. An apostrophe inside a table name is written twice (‘’).

Frequently asked questions

Is this the same as daxformatter.com?

It follows the same layout conventions but is an independent formatter that runs in your browser. Results are very close for typical measures.

Can I format a whole DAX query, not just a measure?

Yes. EVALUATE, DEFINE, MEASURE and ORDER BY are recognised, so queries from DAX Studio or Performance Analyzer format too.

Will it change my column or measure names?

No. Function case only affects functions and keywords; table, column and measure references are left exactly as written.

Does it check that my DAX is valid?

Only for unbalanced brackets and unclosed quotes. It has no access to your model, so references and types are not checked.

Related tools