In this series, we provide tips for how to effectively build a semantic model (formerly a dataset) in Power BI or Analysis Services. In the previous article, we described basics about DAX, and why it’s important when you make a semantic model. Once you’ve created and validated your relationships, you should now have the foundation of your model ready so that you can proceed with the next step.
In this article, we describe how you write DAX in a semantic model by using Power BI Desktop, Tabular Editor or Microsoft Fabric. The purpose of this article is to provide some tips about how you can write better DAX in each of these tools. In the next article, we’ll provide tips to specifically improve your productivity.
This series presents one approach to building a semantic model, sharing tips and good practices from our experience. The other published articles in this series:
When you start to write DAX, you can benefit your future self and other developers with whom you collaborate if you follow some good practices. Following these practices ensures that you spend less time on understanding and maintaining code, and more time on productive, value-based tasks.
'My table'[My column]) and don’t qualify measure names. If you create columns in temporary tables, prefix their names with @ to avoid ambiguity issues.Once defined, a variable becomes a fixed value and can’t have its filter context modified by CALCULATE. Ensure that you understand how to use variables and various considerations for how they are evaluated.
For items like this, you can use Tabular Editor to automatically check or perform tasks to ensure the quality of DAX in your model. For example, you can automatically format your DAX code, or use the Best Practice Analyzer to check your model for issues like duplicate objects or unsorted measures.
To improve your DAX, you can also use DAX Optimizer, which is a third-party add-on for Tabular Editor.
You can create DAX measures, columns, and tables in different ways with different tools. Each method has its own advantages and benefits. The following image depicts an overview of how you create DAX objects in your model or reports.
To front-load the most important information, here's how you should write DAX in different scenarios:
In Power BI Desktop you have several options to write DAX. However, not all of these options support all objects.
In Power BI, you can create quick measures when you want to write more complex DAX measures for common patterns. With quick measures, you select the fields you want to use and parameters for how you want to use them. The quick measure pane will then create the DAX measure for you in the model, and you can view and modify the resulting DAX.
Quick measures are very beneficial for business users and self-service users. When used in combination with implicit measures, quick measures can already cover a wide breadth of scenarios. However, even more experienced developers can benefit from quick measures to learn from the patterns and modify them themselves. In addition to the out-of-the-box quick measures, you can also request quick measure suggestions from Copilot. These suggestions use Q&A as well as generative AI (GPT3.5 LLM) to return suggested DAX code based on a natural language prompt that you provide. Quick measure suggestions can be a beneficial way to leverage generative AI, particularly if your model is well-organized with good naming conventions. However, the standard risks of using generative AI apply, such as ensuring that you vet and understand the code before you use it, to avoid incorrect or unexpected results.
Figure 3: You can insert quick measures, which are ready-made patterns for DAX expressions you can use.
Quick measures can be beneficial in scenarios like the following:
Quick measures can have some general caveats to consider:
Visual calculations were introduced in the February 2024 release of Power BI to define DAX within a specific visual. With visual calculations, you create neither measures, calculated columns, nor tables. Instead, you create a fourth type of DAX that is limited to the visual, itself. As such, you create visual calculations in reports, and not in semantic models.
Visual calculations are unique in that they have special functions that only work in that context, and they also only have access to the data in the visual (i.e. they cannot access the model).
To create a visual calculation, you can right-click a supported visual (like a line chart) and then define the calculation. Visual calculations can be useful for specific use cases, and in some scenarios might even be faster than a standard model measure, since they operate on a dataset provided to the visual (and not the full semantic model).
Figure 4: You can create visual calculations by right-clicking a visual and selecting “new calculation”.
One benefit of the user interface for visual calculations is that you can hide fields that you use in the visual (for example, for sorting). These fields are still evaluated as part of the DAX query, though.
Visual calculations can be beneficial in scenarios like the following:
Visual calculations can have some general caveats and considerations to keep in mind:
The formula bar is the default experience when you write DAX in Power BI. You use it for writing any expressions for measures or calculated columns and tables. You can view the formula bar and write DAX from the canvas, data, and model views.
Figure 5: You can write DAX expressions in the Power BI formula bar.
The formula bar also has some additional helpful features.
Power BI also added the DAX query view in 2023, providing similar capabilities to the existing DAX query views in third-party tools like Tabular Editor or DAX Studio. From this DAX query view, you can write DAX queries, where you can define query-scoped measures and later write them to the model. You can’t create calculated tables or columns from this view, although you can test calculated tables or columns here before you create them by using table expressions.
DAX queries in either Power BI Desktop or Tabular Editor are a good way to validate DAX as you write it by testing it for certain important dimensions, and comparing to a baseline. You can also reuse the query in other tools like DAX Studio for optimizing performance, or to automate testing in Azure Pipelines (which is a service in Azure DevOps) or semantic link (which is a library in Fabric notebooks).
Generally, DAX queries are useful for more advanced DAX authoring scenarios, and more efficient than writing measures and testing them in canvas visuals.
You can write your own queries from scratch, or right-click objects in the data pane to define “quick queries”. Additionally, you can copy queries from visuals by using the Performance Analyzer, which allows you to validate queries from reports. Any queries that contain measures will let you update the model by clicking a grey text above the defined measure. This lets you author DAX measures and queries to validate them, simultaneously.
In the DAX query view you can also format the query automatically. Formatting DAX is important to ensure that your code is readable and can be managed by other people. You can also use Copilot to help you author DAX queries, however, you can only do this if you connect to a workspace that uses an F64 Fabric capacity SKU or higher.
Ensure that you validate any results from Copilot and other LLMs before you use them. A good way to do this is to request in your prompt that the LLM explains each line of the DAX code with comments. You can then go through and check these comments with the code to make sure that these comments align with your understanding of how the code works. If not, it’s good to investigate learning materials so that you understand the code before you use it.
Tabular Editor 3 is a tool designed to help you write better DAX more productively. This means that in Tabular Editor you have features to make writing DAX faster and easier. Furthermore, you can use the scripting in Tabular Editor to scale and automate a lot of your simpler DAX, letting you focus on the more complex calculations.
The simplest way to write DAX in Tabular Editor is by creating objects in the model, then defining the expression and properties in their respective windows. In the TOM explorer of Tabular Editor, you create objects either by right-clicking or using keyboard shortcuts. Since you work in disconnected mode, you don’t need to wait for any user interface updates before you start to write DAX.
Figure 7: The expression editor window in Tabular Editor (highlighted in the red box), including some examples of associated windows and features that make it easier to write good DAX.
You get the following benefits when you write DAX in Tabular Editor this way:
Ctrl + Z to undo any model or code change across any object.F12 to see its documentation.Ctrl + R) and text (custom shortcut: Editor.MultipleSelectAddEach) all at once.You can write not only DAX but also Power Query (M code) in Tabular Editor, from the same window. You can view Power Query (M code) in the Tabular Editor Expression Editor when you select a partition of a table using import storage mode, or a shared expression (such as a custom function or table with load disabled).
Tabular Editor lets you author DAX queries, with similar capabilities to what were described above with Power BI Desktop. The following image gives an overview of what DAX queries in Tabular Editor look like.
Figure 8: With the DAX query window, you write DAX queries, and can also write measures to your model.
There are several key differences with the DAX query window in Tabular Editor and Power BI Desktop:
Otherwise, the guidance to use the DAX query window is identical to the query window in Power BI Desktop—use this view when you write advanced DAX and are testing (or exploring) your model.
We recommend that you save your DAX queries after you’ve used them. This is particularly beneficial for queries you obtain from the performance analyzer of Power BI reports, or queries you wrote yourself to test your model. When you save queries, it’s easier to use them later or access them in other tools.
DAX scripts are a feature unique to Tabular Editor that let you write multiple DAX objects to your model at once. These scripts are a convenient way to replicate DAX patterns, such as common code that you reuse across different models. DAX scripts also let you edit multiple properties in your model at once, and require no additional programming languages (like C#) to use or modify, making them a convenient choice for people who want to reuse DAX but who don’t know programming languages to do this, themselves.
Figure 9: DAX scripts let you edit multiple objects and their properties at once, including applying formatting, find/replace, renaming, and so on.
DAX scripts aren’t DAX queries, and they aren’t C# scripts. DAX scripts are a template for any DAX object (like measures, calculated columns, or calculated tables) that you can create (or modify) in your model, at the push of a button. These scripts use the YAML-like format, so they’re easy to read. However, note that DAX scripts aren’t context-sensitive like C# scripts. A C# script can modify the DAX pattern based on what’s in your model, or what you’ve currently selected in the TOM Explorer. DAX scripts are self-contained to what’s in the template. C# scripts are available broadly in Tabular Editor, whereas DAX scripts only exist in Tabular Editor 3.
Creating a DAX script in Tabular Editor is easy. You simply right-click the parent object (like a table, or even the model) and select “Script DAX”. This generates the template for you, which you can immediately modify and write those changes to the model, or save to reuse in other models, later.
Use DAX scripts when you:
Ctrl + F to do a find/replace.We recommend that you curate a library of DAX scripts for your teams to easily reuse simple DAX patterns that are common among your teams or organization.
In Tabular Editor, you can programmatically modify your model (and write or evaluate DAX) by using C# scripts. These scripts use the C# language and various APIs so that you can write code that will automate or simplify DAX.
Figure 10: An example of a commonly-used C# script to create base measures for your model, which aggregate columns.
There are many use cases for C# scripts. In relation to model DAX, you use them for two purposes:
Examples of C# scripting use cases for writing or modifying DAX include:
Examples of C# scripting use cases for evaluating DAX include:
For brevity, we list only a few examples of how to use C# scripts. There are numerous use cases for C# scripting. You can find both community and official C# script libraries to use yourself without writing C# code.
C# scripts have access to the full .NET ecosystem, and as such, they can be used for communication with services and APIs outside of Tabular Editor, like OpenAI or the online Power Query formatter. When you write or execute C# scripts in Tabular Editor, you’re responsible for the integrity/security of your own scripting solution.
You can author DAX for semantic models by using Fabric either from a user interface by authoring your model in the web, or programmatically creating objects in Python with semantic link in notebooks.
In Fabric, it’s possible to modify semantic models from the workspace. This is beneficial for users who don’t need the full capabilities of Power BI Desktop or Tabular Editor, or who can’t use these tools because they don’t have a Windows machine. You can perform all of the basic DAX authoring tasks in the web as you would in Power BI Desktop; however, these changes are saved automatically to the model.
Figure 11: An example of the web authoring user interface for semantic models in Fabric.
There are some other key differences when you use web authoring:
Ctrl + Z.Generally, you should avoid web authoring unless you really need to use it, or because it’s really the most convenient option for you. The main reason for this is in Power BI Desktop or Tabular Editor, you can better track and manage changes, both for version control and better collaboration, and you have more complete access to the model and its features or properties.
Web authoring can use Fabric CUs, which is an important resource to manage if you’re on Fabric capacity.
To reiterate, changes are saved automatically when someone modifies a model on the web. It’s not possible to revert changes or identify who made the change, unless you have access to the Power BI activity log. Be careful about who has write permissions and how you manage your models if you enable web authoring in your workspaces.
If you have Fabric capacity, semantic link in notebooks allows you to programmatically engage with semantic models by using Python. There are many possible use cases for semantic link, including writing DAX and evaluating DAX queries. We gave an example of this in a previous article, where we explained how to use semantic link to validate relationships by evaluating DAX queries.
A recent library created and managed by Michael Kovalsky from the Microsoft Fabric Customer Advisory Team (CAT) called fabric_cat_tools extends this and makes it easier for you to programmatically read and write semantic models from a notebook.
Figure 12: An example of programmatically creating a DAX measure for a semantic model by using the fabric_cat_tools library within Fabric notebooks.
Using fabric_cat_tools this way can be a significant boon for repeating commonly used DAX objects and patterns, so that you aren’t recreating them in new models, each time. With semantic link and fabric_cat_tools, developers who are familiar with Python will have a great and equally powerful alternative to Tabular Editor’s C# scripting.
Some possible caveats to using semantic link this way include:
Running notebooks uses Fabric CUs, which is an important resource to manage if you’re on Fabric capacity.
Writing DAX is an essential part of creating your semantic model. Ensure that you follow some good practices as you write to help you save time and ensure that your code (and model) will be easy to maintain. Depending on your scenario and available resources, you write DAX with different tools. Choose your tool based on your preferences and needs. However, generally, you should use DAX queries for more advanced scenarios and use programmatic approaches for when you want to reuse code snippets and patterns.
Take your semantic models further with Tabular Editor.
Give Tabular Editor a spin