Note

Access to this page requires authorization. You can try signing in or .

Access to this page requires authorization. You can try .

DAX user-defined functions

Data Analysis Expressions (DAX) user-defined functions (UDFs) let you package reusable, parameterized DAX logic into your models making your DAX code easier to write, maintain, and share. Instead of repeating formulas across measures, calculated columns, and visuals, UDFs bring programming-style flexibility to your semantic models, letting you define functions once and use them everywhere DAX is supported.

DAX UDFs are generally available in Power BI Desktop and the Power BI Service starting with the June 2026 release. To learn more, see DAX user-defined functions.

Why use user-defined functions?

  • Reusability and consistency: Define a calculation once and reuse it everywhere.
  • Maintainability: Update logic in one place to fix or evolve rules.
  • Safer authoring: Optional type hints and type check helpers support predictable, error-resistant code.
  • First-class model objects: UDFs live in the model and can be viewed in Model Explorer.

Define a function

You can define a user-defined function in Power BI Desktop using DAX query view (DQV) or TMDL view.

General syntax

The general syntax for a UDF is:

/// Optional description above the function
/// @param {ParameterType} ParameterName - ParameterDescription
/// ...
/// @returns Return description
FUNCTION <FunctionName> = ( [<ParameterName> [: [<ParameterType>] [<ParameterSubtype>] [<ParameterPassingMode>]] [= <DefaultExpression>], ...] ) => <FunctionBody>

Example: Simple tax function

Here's a simple example in DQV that adds tax onto the given amount. You can also evaluate UDFs in DQV.

DEFINE
 /// AddTax takes in amount and returns amount including tax
 FUNCTION AddTax = (
 amount : NUMERIC
 ) =>
 amount * 1.1

EVALUATE
{ AddTax ( 10 ) }
// Returns 11

After a UDF is defined, you can update the model or use the code lens to add the function to your model.

👁 Screenshot of DAX query view in Power BI Desktop, highlighting two locations where you can save a user-defined function. The first is the Update model with changes button at the top of the view. The second is a status line in the code editor labeled Update model: Add new function.

The same example can be created in TMDL view.

createOrReplace
 /// AddTax takes in amount and returns amount including tax
 function AddTax = (amount : NUMERIC) => amount * 1.1

After a UDF is defined, you can apply changes to add the function to your model.

👁 Screenshot of TMDL view in Power BI Desktop, highlighting the Apply button at the top of the view. This button is the location where you can save a user-defined function.

Manage user-defined functions

Once defined and added to the model, you can view and manage all user-defined functions from Model explorer under the Functions node.

👁 Screenshot of a model explorer panel in Power BI Desktop showing the expanded Functions node. Three user-defined functions are listed: AddTax, AverageOrderValue, and CustomerLifetimeValue.

In DAX query view (DQV), you can use Quick queries through Model explorer to easily define and evaluate functions.

👁 Screenshot of a model explorer pane in Power BI Desktop displays the expanded Functions node. Two context menus are open: the first menu provides Quick queries, Rename, Delete from model, Hide in report view, Unhide all, Collapse all, and Expand all. Quick query is highlighted and selected. The second menu is highlighted and offers Quick queries options Evaluate, Define and evaluate, Define new function, and Define all functions in this model.

In TMDL view, you can drag and drop functions into the canvas or use Script TMDL to through Model explorer.

👁 Screenshot of a model explorer pane in Power BI Desktop displays the expanded Functions node. Two context menus are open: the first menu provides Script TMDL to, Rename, Delete from model, Hide in report view, Unhide all, Collapse all, and Expand all. Script to TMDL is highlighted and selected. The second menu is highlighted and offers Script to TMDL options Script tab and Clipboard.

If using a Power BI Project, functions are also stored in functions.tmdl within the definition folder.

👁 Visual Studio Code screenshot of a Power BI project. Explorer is open to the semantic model folder. 'functions.tmdl' is open in the code editor. Three functions are displayed: CustomerLifetimeValue, AverageOrderValue, and AddTax.

Use user-defined functions

After adding a UDF to the model, you can use it anywhere DAX is supported. Here we use AddTax as an example.

Use UDFs with full filter context with measures.

Total Sales with Tax = AddTax ( [Total Sales] )

Apply UDFs to every row in a table with calculated columns.

Sales Amount with Tax = CONVERT ( AddTax ( 'Sales'[Sales Amount] ), CURRENCY )

Use UDFs directly in visuals with visual calculations.

Sales Amount with Tax = AddTax ( [Sales Amount] )

Nest UDFs for advanced scenarios.

DEFINE
 /// AddTax takes in amount and returns amount including tax
 FUNCTION AddTax = (
 amount : NUMERIC
 ) =>
 amount * 1.1

	FUNCTION AddTaxAndDiscount = (
			amount : NUMERIC,
			discount : NUMERIC
		) =>
		AddTax ( amount - discount )

EVALUATE
{ AddTaxAndDiscount ( 10, 2 ) }
// Returns 8.8

Parameters

DAX UDFs support zero or more parameters. To make your functions safer and more predictable you can optionally specify parameter type hints:

  • Type: what type of value the parameter accepts (AnyVal, Scalar, Table, AnyRef, CalendarRef, ColumnRef, MeasureRef, or TableRef).
  • Subtype (only for scalar type): the specific scalar data type (Variant, Int64, Decimal, Double, String, DateTime, Boolean, or Numeric).
  • ParameterMode: when the argument is evaluated (val for eager or expr for lazy).

Type hints follow the form: [type] [subtype] [parameterMode]

Example: Type casting

DEFINE
 /// returns x cast to an Int64
 FUNCTION CastToInt = (
 x : SCALAR INT64 VAL
 ) =>
 x

EVALUATE
{ CastToInt ( 3.4 ), CastToInt ( 3.5 ), CastToInt ( "5" ) }
// returns 3, 4, 5

This example uses a Scalar type, Int64 subtype, and val parameterMode. You can also achieve the same effect by just including the Int64 subtype as seen in the example below. Non-numeric strings result in an error.

DEFINE
 /// returns x as an Int64
 FUNCTION CastToInt = (
 x : INT64
 ) =>
 x

EVALUATE
{ CastToInt ( 3.4 ), CastToInt ( 3.5 ), CastToInt ( "5" ) }
// returns 3, 4, 5

Type checking

Validate parameter types inside your function using built-in DAX type-checking functions such as:

For a complete list of available type-checking functions, see DAX user-defined functions.

Related content

For more information on using user-defined functions, see the following resources:


Feedback

Was this page helpful?

Additional resources