Anyone who has worked with dynamic color measures using Power BI knows the pain of creating 150 measures in Power BI, waiting for the model to validate after pasting in the copied DAX from the original measure, and updating filter variables.Â
First, we jumped to using the Tabular Editor, skipping around all of the waiting for those validation sequences. But oh no, now the measure logic needs to be changed, and I have to open each of those measures again, make updates, and then check 15 times to be sure that I updated everything correctly. Well, the time has come for User-Defined Functions!
In this blog, we will discuss User-Defined Functions in Power BI, how to enable them in Power BI Desktop, and walk through examples of how to start using them in both TMDL and DAX views.Â
What are User Defined Functions in Power BI?
User-Defined Functions (UDFs) are a preview feature released in the September 2025 update for Power BI, that allow you to package and reuse common DAX logic in a semantic model, including the passing type-specific parameters so that the logic can be reused with minimal change needed as updates to business logic change.Â
How to Enable UDFs in Power BI?
To enable UDF’s in Power BI Desktop, you need to go to Options and Settings > Preview Features and enable DAX user-defined functions.Â
Once this is applied, restart Power BI, and you will be able to create and update UDFs.
How Should You Leverage UDFs in Power BI?
The first step in using UDFs is identifying a use case for your function. It should be logical that it is parameter-dependent and will be reused across multiple measures, calculated columns, visual calculations, or other UDFs. An easy example would be the percent difference between two values.
We must first define the measure, using TMDL or DAX Query View. Let’s give an example of both!
Defining a UDF using DAX Query View
The format for creating a UDF in DAX Query is
DEFINE
/// Optional description above the function
FUNCTION = ( [ParameterName]: [ParameterType], ... ) =>
And the types for parameters areÂ
Type: (AnyVal, Scalar, Table, or AnyRef).
Subtype (only for scalar type): (Variant, Int64, Decimal, Double, String, DateTime, Boolean, or Numeric)
So if we define percent change as (x-y) ÷ x, where x represents the original value and y represents the new value, we know that we need to make numeric parameters to represent the values for x and y. So the UDF would look like this in DAX View
DEFINE
///UDF to Find Percentage Change between two values
FUNCTION PercentChange = (OriginalValue : numeric, NewValue :numeric) =>
DIVIDE((OriginalValue-NewValue),OriginalValue,0)
You will then see a notice in the code asking you to update the model. You can do this by selecting the note or by selecting Update model with changes.
Once this is in the model, you can evaluate the UDF in DAX Query View
EVALUATE
{PercentChange(100,50)}
Defining a UDF Using TMDL View
Similar to DAX Query View, you can use TMDL View to create UDFs, but with small changes in context. The format is as follows:
createOrReplace
/// Optional description above the function
FUNCTION = ( [ParameterName]: [ParameterType], ... ) =>
So, for our PercentChange UDF, we would writeÂ
createOrReplace
///UDF to Find Percentage Change between two values
function PercentChange = (OriginalValue : numeric, NewValue :numeric) => DIVIDE((OriginalValue-NewValue),OriginalValue,0)
TMDL can be particular about spacing and text formatting, but as you start typing, the format should populate for you with code tooltips to assist your development.Â
Once you are done writing your UDF, click Apply to save changes to the model.
If you want to evaluate this UDF, though, you will need to go back to DAX Query View or use it in a Measure, Calculated Column, or Visual Calculation. We’ll talk about how to do that next!
Calling a UDF
UDFs can be called from Measures, Calculated Columns, Visual Calculations, and other UDFs. Let’s look at some of the ways to do this!
Calling a UDF From a Measure
Using a UDF inside a measure is really easy, but you must understand what values you are passing to the UDF. If your parameter is intended to be a single value, your measure must ensure that the values being passed to the UDF are aggregated.Â
Let’s create a measure for using our UDF on the built-in sample financial data in Power BI Desktop:
UseThisUDF =
VAR Sales = SUM(financials[Sales])
VAR Profit = SUM(financials[Profit])
RETURN PercentChange(Sales,Profit)
By aggregating the Sales and Profit column before passing the values to the UDF, the measure is able to be evaluated in visuals without concern that the parameters will throw an error.Â
Calling a UDF from a Calculated Column
Because UDFs return a variant type by default, we must use a CONVERT function to ensure the data type is defined.Â
LineDiscountPercent = CONVERT(PercentChange(financials[Gross Sales],financials[Sales]),DECIMAL)
Calling a UDF from a Visual Calculation
While using a UDF in a Visual Calculation, you may see issues with the function suggestions, but the UDFs still work! You must keep in mind that visual calculations can only use the fields present in the visual, so nested calculations where the values aren’t present in the visual will cause issues with the UDF.
% Discount = PercentChange([Sum of Gross Sales],[Sum of Sales])
Calling a UDF from another UDF
Lastly, we are going to nest a UDF inside of another UDF. This will pass the first parameter provided to the AddShippingAndDiscount UDF to the AddShipping UDF that is nested inside. While nesting UDFs, take care to ensure that the parameters match types across all UDFs.Â
DEFINE
/// AddShipping Estimate takes in amount and returns estimated shipping
FUNCTION AddShipping =
( amount : NUMERIC ) =>
amount + 50
/// Uses Addshipping and a discount to give out the door price
FUNCTION AddShippingAndDiscount =
(
amount : NUMERIC ,
discount : NUMERIC
) =>
AddShipping ( amount - discount )
EVALUATE
{ AddShippingAndDiscount(1000,50)}
Best Practices
- While creating UDFs, ensure you use Pascal case (CapitalizingEveryWordInTheName), so that the UDF can be easily distinguished in DAX expressions from the built-in functions that use all capital letters.
- By using three forward slashes in your definition (///), you will automatically add the description to the UDF in the semantic model.
- Be sure to test these functions thoroughly while they’re in preview. Once these go to general availability, they will be a huge time-saving project!
Closing
User-Defined Functions are a game-changer for DEVs who utilize standardized formatting and functions across Power BI, and when these are combined with Scalable Vector Graphics (SVGs), they allow for consistent, customized visuals that can be easily reused across reports.
Transform your reporting with Power BI
If you’re looking to scale your Power BI reporting or streamline how your organization builds and maintains dashboards, phData’s experts can help. Our team specializes in optimizing data workflows and building scalable, impactful Power BI solutions.
FAQs
I don’t see User Defined Functions as available in Power BI Desktop. Where do I find them?
This preview feature came out in September 2025, and needs to be enabled under Options and Settings > Preview Features, and then Power BI must be restarted before you can create them. Be sure you are using the latest version of Power BI to test these functions!
Why do we use UDFs instead of calculating these values closer to the data source?
While calculating most things as close to the data source as possible is best practice, some values must be calculated with the context of the visual they’re in, and UDF’s allow for consistent coding across multiple measures and visualizations, but as with all analytics solutions, the quality you retrieve from UDFs will correlate to the effort put in to defining it. Be sure to define your parameters correctly, follow best practices for creating and using measures, and be especially careful when using calculated columns for anything.




