Power BI’s AI Toolkit: Evaluating Copilot for DAX Development in Power BI Desktop

If you have ever felt that slight surge of hope when clicking the Copilot button in Power BI Desktop, you are not alone. You have a specific piece of business logic in mind, and you are curious whether Copilot can actually save you time writing, formatting, and documenting a DAX measure.

The honest frustration in 2026 is not that AI does not work. It is the uncertainty of when to rely on it. If you have ever prompted Copilot for a measure only to find yourself spending more time validating its response than writing the measure yourself, you know the feeling.

It is not about being for or against AI. It is about knowing exactly where the tool hits its stride and where it starts to trip over its own logic.

To cut through that uncertainty, we put Copilot to work on a practical sales model across five realistic scenarios: writing measures, building advanced logic, explaining complex DAX, debugging errors, and documenting the semantic model. Along the way, each result gets a simple rating:

🟢 Green Light — Copilot handles it reliably. Safe to use with a quick review.

🟡 Yellow Light — Copilot provides a strong starting point, but the output needs validation before it goes into production.

🔴 Red Light — Copilot struggles or misleads. A human needs to drive.

A sample report is available for download at the end of this post so you can follow along and test these prompts against the same data.

Let’s find out where each scenario lands.


The Data Model: A Standard Sales Model

Instead of testing Copilot on isolated or theoretical formulas, we are putting it to work on a simplified but practical dataset.

The model consists of four core tables connected through a standard star schema:

  • Sales: The fact table. Each row is a single transaction with a SalesID, Amount, SalesDate, and CustomerID.
  • Product: 15 products across 6 categories: Smartphones, Laptops, Tablets, TVs, Headphones, and Watches, each with a Product Code and Product Image.
  • Employee: 17 employees spanning four departments: Retail, Sales, Marketing, HR, and R&D — with JobTitle, Department, and a ManagerID for hierarchy.
  • Region: Three regions: the United States, Europe, and Asia

The Sales table connects to each dimension through its ProductID, EmployeeID, and RegionID. Column names are descriptive, and the schema is intentionally straightforward.

Why does that matter? Copilot’s output quality is directly tied to how well the model is structured. Column names like Amount and SalesDate give it far more to work with than Col1 or Fld_003. A little upfront investment in clean, readable naming pays off quickly when we start prompting.

The Five Scenarios

The goal is to move beyond simple sums and see how Copilot handles the tasks that actually eat up our time. Here is what we are testing:

  1. Establishing the Basics: Foundational measures like total sales and department-filtered aggregations, to confirm Copilot correctly reads the model structure and relationships.
  2. Building Advanced Logic: More complex calculations like year-over-year growth and percentage of total, where filter context starts to matter.
  3. Explaining Existing Measures: Handing Copilot DAX that is already in the model and asking it to translate the logic into plain language.
  4. Debugging Logical Errors: Providing a measure that runs without error but returns incorrect results, and seeing whether Copilot can identify the real problem.
  5. Generating Measure Descriptions & Comments: Using Copilot to auto-document completed measures directly in the model, and evaluating whether the output is accurate and usable.

Because of the generative nature of Copilot, it may not produce the exact same DAX or explanations for you as shown here. The patterns and behaviors should be consistent, but the specific wording may vary.

This is not an attempt to break the tools with impossible requests. It is a straightforward evaluation of how much repetitive, manual DAX work we can safely offload to Copilot in a standard reporting environment.


TL;DR — Key Findings at a Glance

If you are short on time, here is the summary. We tested Copilot in Power BI Desktop across five scenarios using the sales model described above. Each scenario was tested using both the Copilot pane and the DAX query view inline Copilot where applicable.

The findings:

  • 🟢 Establishing the Basics: Copilot correctly identified table relationships and column names without being told. Basic measure and filtered aggregations came back clean and accurate.
  • 🟡 Building Advanced Logic – Copilot Pane: Strong DAX patterns for YoY growth and percentage contribution, but both measures carry dependencies that Copilot does not resolve on its own. The Date table requirement and the ALL vs ALLSELECTED design decision still need a human in the loop.
  • 🟢 Building Advanced Logic – DAX Query View: Writing measures through the inline Copilot added a meaningful validation step. The % of Total Sales by Product measure used ALLSELECTED correctly without prompting, and the Suggest measures feature returned six well-structured analytical measures in a single query with inline comments and a preview ready to run.
  • 🟡 Explaining Complex DAX Measures – Copilot Pane: Once the full DAX is pasted in, Copilot handles even the most complex measures accurately. A multi-variable measure combining SUMMARIZE, TOPN, CONCATENATEX, and HTML rendering was broken down step by step in plain language.
  • 🟢 Explaining Complex DAX Measures – DAX Query View: The Define and Evaluate workflow eliminates the manual paste step and produces a more structured, variable-by-variable explanation. The better entry point for thorough measure audits.
  • 🟡 Debugging DAX Logical Errors: Correctly diagnosed an ALL vs ALLSELECTED filter context issue and provided two well-reasoned solutions with clear guidance on when to use each. Yellow light only because the fix still requires the developer to understand which option fits the specific report design.
  • 🟢 Generating Measure Descriptions – Model View: Accurate, readable, and business-aware descriptions generated in seconds. Descriptions travel with the model metadata and surface as tooltips in the Fields pane.
  • 🟢 Adding Inline Comments – DAX Query View: Copilot added meaningful, explanatory comments to an existing measure, explaining the reasoning behind each step rather than just restating variable names. Combined with measure descriptions, this covers documentation for both developers and report authors

Copilot earned five Green Lights and three Yellow Lights across eight tests. No Red Lights. The gaps that produced Yellow Lights were not about DAX correctness. They were about model architecture decisions and report design context that Copilot simply does not have access to. The developers who get the most value from Copilot are those who know enough DAX to validate the results.


Getting Started: How to Access Copilot in Power BI Desktop

Before jumping into the scenarios, it helps to know where Copilot lives in Power BI Desktop and how to reach it for each type of task. There are three entry points, and each one serves a different purpose.

Note: Copilot in Power BI Desktop requires access to a paid Fabric capacity (F2 or higher) or Power BI Premium capacity (P1 or higher). A Power BI Pro or Premium Per User (PPU) license alone is not sufficient. If the Copilot button in your ribbon appears greyed out or disabled, confirm with your administrator that Copilot is enabled at the tenant level. Review licensing and other requirements or limitations here: Copilot for Power BI overview.

The Copilot Pane (Report View)

This is the primary entry point for writing measures, debugging logic, and asking questions about the data model.

  1. Open the Copilot pane: Open the report in Power BI Desktop and select Copilot in the ribbon. The first time we use Copilot, we will be prompted to select a compatible workspace to associate with the report.
  2. Describe the measure: Once connected, the Copilot pane opens on the right side of the screen. Describe the measure in plain language. Reference the relevant table or column and be as specific as the business requirement calls for.
  3. Debug with Copilot: For debugging, paste the broken measure directly into the chat and describe what it should return versus what it is actually returning.

The more specific our prompt, the better the output. “Calculate total sales” will get us a basic SUM. “Calculate total sales for employees in the Retail department only” gives Copilot enough context to apply the correct filter across the right table relationship.

The DAX Query View (Inline Copilot)

The DAX query view has its own separate inline Copilot, distinct from the report view pane. It is particularly useful for writing DAX queries, understanding existing measures, and learning DAX concepts in context.

  1. Open the inline Copilot. Switch to DAX query view using the left navigation bar. It is the fourth icon from the top. Open the inline Copilot by clicking the Copilot button in the query editor or pressing CTRL + I.
  2. Use the inspire buttons. Three inspire buttons give us a quick starting point for the most common tasks:
    • Write DAX query: describe what you want in plain language, and Copilot generates the DAX, with automatic syntax validation and a retry if the first attempt contains errors.
    • Suggest measures: reviews your data and suggests new measures in a DAX query for further analysis.
    • Explain a DAX topic: ask about a specific function or concept and get a contextual explanation tied to your actual model.
  3. Work with an existing measure. To use Copilot with an existing measure, right-click it in the Data pane and select Define and Evaluate. This loads the full measure definition into the query editor, where we can then use the Explain or Write prompts to work with it.

The Model View (Measure Descriptions)

This entry point is specifically for generating measure descriptions and is easy to miss if you spend most of your time in Report view.

  1. Select the measure. Switch to Model view in Power BI Desktop. In the Data pane, select the measure we want to document.
  2. Generate the description. In the Properties pane on the right, locate the Description field. Click Create with Copilot to generate a description, then select Keep it to save it.

The description is stored directly in the .pbix file and surfaces as a tooltip when users hover over the measure in the Fields pane. It is a small detail that makes a meaningful difference in shared models and self-service environments.

Note: Copilot will only generate descriptions for measures in a valid state with no errors. Resolve any measure issues before attempting to generate a description.


Scenario 1: Establishing the Basics
Does Copilot Understand Your Data Model?

Before throwing complex logic at Copilot, the first step is confirming it understands the data model. If it cannot identify the correct columns for a simple aggregation, it will not stand a chance with more complex requests.

Test 1: Total Sales Amount

The Prompt: Provide a DAX measure that calculates the Total Sales Amount

Copilot’s Response:


🟢 Green Light

Test 2: Total Retail Sales

The Prompt: Create a measure for Total Retail Sales that calculates the total sales amount for employees in the Retail department only

Copilot’s Response:

🟢 Green Light


Scenario 2: Building Advanced DAX Logic
Where Filter Context Starts to Matter

With the basics confirmed, the next step is to see how Copilot handles more complex measures. This is where filter context starts to matter and where the quality of the data model structure begins to influence the output.

Test 1: Year-Over-Year Growth

Calculating Year-over-Year (YoY) growth is one of the more common requirements in sales reporting. It requires a solid understanding of date filters and is one of the first places where DAX relies on model structure rather than just formula syntax.

The Prompt: Create a measure that calculates year-over-year growth for total sales.

Copilot’s Response:

🟡 Yellow Light — Strong DAX, external dependency required

Overlooked Detail: One thing that is easy to miss here is the Date Table assumption. Copilot explicitly noted this measure requires a “proper date table.”

In our sample dataset, we have a SalesDate column in the Sales table, but for time intelligence functions like SAMEPERIODLASTYEAR to work reliably, Power BI requires a continuous date column and a correctly configured, marked Date table. If the measure references SalesDate directly from the fact table, it may appear to work but can return incomplete or incorrect results under certain filter conditions. This dependency is not always obvious from the generated DAX alone.

Alternative Approach:

Copilot used SAMEPERIODLASTYEAR, which is a common and readable pattern. An alternative for more complex or flexible requirements is DATEADD:

Total Sales YoY Growth % =
VAR CurrentSales = [Total Sales Amount]
VAR LastYearSales =
CALCULATE(
[Total Sales Amount],
DATEADD(DateTable[Date], -1, YEAR)
)
RETURN
DIVIDE(CurrentSales - LastYearSales, LastYearSales)

Both approaches achieve similar results. SAMEPERIODLASTYEAR is more concise and easier to read. DATEADD provides more flexibility and uses the same structure whether shifting by days, months, quarters, or years. In practice, the choice often comes down to readability versus flexibility and how the Date table is structured.

Test 2: Percentage Contribution by Region

Let’s look at how Copilot handles a different kind of problem: calculating how much a specific segment contributes to the overall total. In this case, we want to understand how much each region contributes to total sales.

This requires calculating a value in the current filter context and comparing it against a total that ignores that filter.

The Prompt: Provide a measure that calculates the percentage contribution of each region to total sales.

Copilot’s Response:

🟡 Yellow Light — Correct answer, incomplete solution

Overlooked Detail: The difference between ALL and ALLSELECTED is easy to miss here but it matters significantly in interactive reports. ALL(Region) removes every filter on the Region table, including filters applied by slicers, meaning the denominator is always the grand total regardless of what users have selected. ALLSELECTED would preserve slicer selections while still ignoring the visual’s own row context. Copilot applied a standard pattern correctly, but it did not account for the nuances of how the report will actually be used.

Alternative Approach:

An alternative is to use REMOVEFILTERS, which makes the intent of the measure clearer to anyone reading it later:

% of Total Sales by Region =
DIVIDE(
[Total Sales Amount],
CALCULATE(
[Total Sales Amount],
REMOVEFILTERS(Region)
)
)

REMOVEFILTERS is generally preferred in team environments because its name explicitly describes what it does. ALL can be used both to clear filters and to return a table of values, which can lead to confusion when someone else reads the measure later.

DAX Query View Approach
Writing Measures with Inline Copilot

The Copilot pane is not the only way to generate DAX. For developers who prefer to validate output before committing it to the model, the DAX query view inline Copilot offers a useful alternative. Write the query, run it, review the results, and keep it if it looks right.

Here is a % of Total Sales by Product measure generated using DAX query view:

  1. Open a new query tab. Switch to DAX query view using the left navigation bar. Open a new query tab and press CTRL + I to open the inline Copilot.
  2. Enter the prompt and press Enter.
  3. Preview the results. Before keeping the query, select Run or press F5 to preview the results directly in the query editor.
  4. Add the measure to the model. Once satisfied with the output, select Keep query. Then use the Update model with changes button to add the measure to the data model.

The Prompt: Create a % of Total Sales by Product measure

Copilot’s Response:

Before keeping the query, select Run or press F5 to preview the results directly in the query editor.

🟢 Green Light

Bonus: Let Copilot Suggest What to Build Next

One of the more practical features in DAX query view is the Suggest measures inspire button. Rather than prompting Copilot for a specific measure, we can ask it to analyze the model and recommend what to build next.

The Prompt: Based on my data suggest new measures in a DAX query for further analysis and try them out with one or more suitable columns

Copilot’s Response:

🟢 Green Light

Overlooked Detail: Two of the six suggested measures — Sales Last 12 Months and Sales 3M Rolling Avg — reference 'DateTable'[Date], which assumes a properly configured Date table is present in the model.

As noted in the YoY Growth scenario, these measures will not work reliably without one. Copilot surfaced the right patterns, but the model still needs the right foundation beneath them.


Scenario 3: Explaining Complex DAX Measures
From Black Box to Plain Language

One of the most practical ways to use Copilot is not writing new DAX. It is making sense of DAX that already exists in the model. Whether we are inheriting a report from a colleague or revisiting logic written six months ago, Copilot can help translate complex measures into plain language.

This test uses the [Top Performers] measure — a multi-variable measure that summarizes sales by region and employee, identifies the top three performers, and returns a fully formatted HTML string for use in a custom visual. It is a realistic example of the kind of measure that is genuinely difficult to read cold.

Test 1: Asking Copilot to Explain Without the DAX

The Prompt: Explain the logic of the [Top Performers] measure. What is it calculating, and how is it displaying results?

Copilot’s Response:

The Follow-Up Prompt: Here is the DAX formula for [Top Performers] so you can explain it:

Top Performers =
VAR _groupedByRegionEmployee =
SUMMARIZE(
Sales,
Regions[Region],
Employee[EmployeeID],
"EmployeeTotalSalesMetricCY", [Sales Metric (CY)]
)
VAR _top3Performers =
TOPN(
3,
_groupedByRegionEmployee,
[EmployeeTotalSalesMetricCY], DESC,
Employee[EmployeeID], ASC
)
VAR _belowTop5Count =
COUNTROWS(_groupedByRegionEmployee) - COUNTROWS(_top3Performers)
VAR _top5HTML =
CONCATENATEX(
TOPN(3, _top3Performers, [EmployeeTotalSalesMetricCY], DESC),
VAR _imageURL = LOOKUPVALUE(Employee[Image], Employee[EmployeeID], Employee[EmployeeID])
VAR _salesMetricCY = [EmployeeTotalSalesMetricCY]
VAR _rank = RANKX(_top3Performers, [EmployeeTotalSalesMetricCY],,DESC,Dense)
RETURN
"<div style='width:50px; height:50px; border-radius:50%; overflow:visible; border:2px solid #0b4d78;'>
<img src='" & _imageURL & "' style='width:100%; height:100%; object-fit:cover; border-radius:50%;' />
<div style='position:absolute; bottom:-8px; right:-8px; width:35px; height:35px; border-radius:50%; background-color:#0b4d78; color:white; font-size:9px;'>
" & FORMAT(_salesMetricCY, "$#,0,.0K") & "
</div>
</div>",
"",
[EmployeeTotalSalesMetricCY], DESC
)
VAR _additionalCircle =
IF(
_belowTop5Count > 0,
"<div style='width:30px; height:30px; border-radius:50%; background-color:#bfbfbf; color:white; font-size:16px; margin-left:5px;'>
+" & FORMAT(_belowTop5Count, "0") & "
</div>",
""
)
VAR _finalOutput =
"<div style='display:flex; align-items:center; justify-content:flex-end; overflow:hidden; max-width:400px; padding-right:5px; padding-bottom:8px'>
" & _top5HTML & _additionalCircle &"
</div>"
RETURN
_finalOutput

Copilot’s Response:

Certainly! Here’s a step-by-step explanation of what the [Top Performers] measure is doing and how it displays results:

What is it Calculating?

  1. Grouping Sales by Region and Employee:
    • The measure first creates a table (_groupedByRegionEmployee) that summarizes sales data by both region and employee. For each combination, it calculates the [Sales Metric (CY)]
  2. Selecting the Top 3 Performers:
    • It then identifies the top 3 employees (per region) based on their [Sales Metric (CY)] using the TOPN function. If there are ties it uses EmployeeID as a secondary sort.
  3. Counting Additional Employees:
    • It calculates how many employees are not in the top 3 by subtracting the count of top performers from the total count.
  4. Building the HTML for Display
    • For each of the top 3 employees, it constructs an HTML snippet:
      • Shows the employee’s profile image (from Employee[Image]).
      • Displays their sales metric as a badge
      • Uses CSS to style the image and badge for a visually appealing display
    • If there are more employees beyond the top 3, it adds a grey circle with a “+N” indicator, where N is the number of additional employees.
  5. Combining Everything for Output:
    • The final output is a single HTML string that visually displays the top 3 performers (with image and sales badges) and, if applicable, a circle indicating how many more employees there are.

How is it displaying the results?

Visual Output: The measure returns an HTML string designed for use in a Power BI visual that supports HTML rendering.

What You See:

  • Up to three employee profile images, each with a badge showing their sales metric
  • If there are more than three employees, a grey circle with “+N” to indicate additional performers not shown.
  • The layout is styled to be compact, visually appealing, and aligned to the right.

Summary

  • Purpose: Highlights the top 3 sales performers per region, visually, with profile images and sales badges
  • Display: Uses HTML and CSS for a rich, custom visual experience, including a “+N” indicator for additional employees beyond the top 3.

If you need a breakdown of any specific part of the DAX or want to know how to adapt this logic, let me know!

🟢 Green Light

Overlooked Detail: Copilot explained what the measure is doing accurately, but it did not surface deeper technical considerations unprompted, such as the performance implications of nesting TOPN inside CONCATENATEX, whether repeated TOPN calls could be consolidated, or the assumption that LOOKUPVALUE will always return a single match.

These are the kinds of questions that should always be asked when reviewing measure definitions.

If we need that level of analysis, we can follow up with a specific prompt such as “Are there any performance concerns with this measure?” Copilot responds well to targeted follow-up questions; it just does not volunteer that analysis on its own.

Alternative Approach — Explaining Measures in DAX Query View

In the main test, explaining the [Top Performers] measure required pasting the full DAX formula directly into the Copilot pane. The DAX query view offers a cleaner path to the same result and goes one step further by letting us run the measure and explain it in the same workflow.

  1. Load the measure into DAX query view. Switch to DAX query view using the left navigation bar. In the Data pane, right-click the [Top Performers] measure and select Define and Evaluate. This automatically loads the full measure definition into the query editor as a DEFINE MEASURE and EVALUATE statement, with no manual copying required.
  2. Open the inline Copilot and explain the query. Select the DAX query in the editor and press CTRL + I to open the inline Copilot. Use the Explain this query inspire button or type the prompt directly.

The Prompt: Explain this DAX query

Copilot’s Response:

🟢 Green Light

Overlooked Detail: Compare the two explanation workflows side by side. The report view pane required the full DAX to be pasted manually, and Copilot’s response, while accurate, was structured around the user’s framing of the question.

The DAX query view response was driven by the query structure itself, which produced a more methodical, variable-by-variable breakdown.

Neither is strictly better. The pane is faster for a quick question, while the query view is better for a thorough audit. Knowing which to reach for depending on the situation is the more important skill.


Scenario 4: Debugging DAX Logical Errors
Finding What the Red Squiggle Misses

Identifying syntax errors is straightforward. Power BI flags them immediately with a red underline. The real challenge is logical debugging: when a measure runs without error but returns results that are incorrect for the business requirement. This test determines whether Copilot can identify why a measure is technically functional but practically broken.

The Setup

For this test, we want to create a dynamic % of Total Sales measure that displays correctly across multiple dimensions — Products, Regions, and Departments — while also respecting report-level filters like Year. Here is the measure as it currently exists in the model:

% of Total Sales =
VAR CurrentSales = SUM('Sales'[Amount])
VAR TotalSales = CALCULATE(SUM('Sales'[Amount]), ALL('Sales'))
RETURN
DIVIDE(CurrentSales, TotalSales)

The measure uses ALL(Sales), which removes every filter from the Sales table, including slicers and report-level filters.

For our requirements, this is a common mistake that effectively freezes the denominator to the grand total of the entire dataset, regardless of what filters are applied.

For example, when users apply a Year slicer to focus on the previous year, the numerator correctly reflects only the previous year’s sales, but the denominator still reflects all years.

The result is percentages that appear unexpectedly small and never add up to 100% within the filtered context.

We see the percentages are smaller than expected and bring the problem to Copilot.

The Prompt:

I have a measure for % of Total Sales, but when I filter my report to the year 2025, the percentages are small when viewed on multiple visuals across various dimensions and don’t add up to 100%. How do I make this dynamic so I can display the percent of total for multiple dimensions?

% of Total Sales =
VAR CurrentSales = SUM('Sales'[Amount])
VAR TotalSales = CALCULATE(SUM('Sales'[Amount]), ALL('Sales'))
RETURN
DIVIDE(CurrentSales, TotalSales)

Copilot’s Response:

The issue you’re experiencing is due to the use of ALL(‘Sales’) in your measure. This removes all filters from the Sales table—including filters on Year, Product, Department, etc.—so your denominator is always the grand total sales for all years and all data, not just for the filtered year (e.g., 2025). As a result, when you filter to 2025, the numerator is only 2025 sales, but the denominator is still the total for all years, making the percentages appear small and not sum to 100% within the filtered context.

To make the measure dynamic and context-aware (so that it always sums to 100% within the current filter, such as year, product, or department), you should use the REMOVEFILTERS or ALLSELECTED function, depending on your needs:

  • REMOVEFILTERS: Removes filters only from the specified columns or tables, but keeps filters from outside the specified scope (such as report/page/visual filters).
  • ALLSELECTED: Keeps filters applied by slicers and visuals, but ignores filters from the current visual’s breakdown.

Here’s how you can rewrite your measure for dynamic percent of total within the current filter context:

Option 1: Using REMOVEFILTERS (recommended for most scenarios)

% of Total Sales (Dynamic) =
VAR CurrentSales = SUM('Sales'[Amount])
VAR TotalSales = CALCULATE(
SUM('Sales'[Amount]),
REMOVEFILTERS('Sales')
)
RETURN
DIVIDE(CurrentSales, TotalSales)

But this still ignores filters on the Sales table. If you want the denominator to respect external filters (like Year = 2025), but ignore breakdowns within the visual (like Product or Department), use ALLSELECTED.

Option 2: Using ALLSELECTED (best for visuals with slicers/filters)

% of Total Sales (Dynamic) =
VAR CurrentSales = SUM('Sales'[Amount])
VAR TotalSales = CALCULATE(
SUM('Sales'[Amount]),
ALLSELECTED('Sales')
)
RETURN
DIVIDE(CurrentSales, TotalSales)

How to choose:

  • Use REMOVEFILTERS if you want the denominator to always be the total for the current report/page/visual filter context (e.g., Year = 2026).
  • Use ALLSELECTED if you want the denominator to respect slicers and filters, but ignore breakdowns within the visual.

Try replacing your measure with the ALLSELECTED version above. When you filter to 2026, the percentages across your breakdown (e.g., by Product, Department, etc.) will sum to 100% for that year.

🟡 Yellow Light

If you are building reports where slicers play a central role in user decision-making, providing essential context before users make their selections can be extremely beneficial. 

The design of those slicers matters just as much as the DAX behind them. For a deeper look at how to turn static slicers into interactive decision aids that give users meaningful context before they make a selection, check out Design Meets Data: From Static Slicers to Interactive Decision Aids.

What if your slicers could answer questions before you even select them? With a little preview context, they can guide users toward the right decisions instantly.

Overlooked Detail: The distinction between REMOVEFILTERS and ALLSELECTED is subtle but consequential.

If a filter is applied at the visual level, ALLSELECTED will calculate the percentage based on the filtered data, whereas REMOVEFILTERS may still calculate against the broader filter context.

In an interactive report with multiple slicers and cross-filtering visuals, these two measures can return noticeably different results from the same visual.


Scenario 5: Generating Measure Descriptions and Comments
Documenting the Semantic Model

One of the most tedious parts of semantic model development is documentation. Measures get built, reports get published, and descriptions rarely get written. This test determines how useful Copilot can be in handling that documentation work and whether the output is accurate and professional enough to actually use.

Test 1 — Generating Measure Descriptions in Model View

For this test, we navigate to Power BI Desktop’s Model view, select the Total Sales YoY Growth % measure, and use the Create with Copilot option in the Properties pane.

Copilot’s Response:

🟢 Green Light

Test 2: Adding Inline Comments in DAX Query View

Measure descriptions in the Properties pane are valuable for self-service users browsing the Fields pane, but they are not visible to the developer editing the measure.

Inline comments inside the DAX formula serve a different purpose. They document the logic for anyone who opens the measure editor, making complex calculations easier to read, audit, and maintain over time.

DAX query view Copilot can add those comments automatically.

  1. Load the measure. Switch to DAX query view using the left navigation bar. In the Data pane, right-click the Total Sales YoY Growth % measure and select Define and Evaluate. This loads the full measure definition into the query editor.
  2. Add comments with Copilot, Press CTRL + I to open the inline Copilot. Enter the prompt and press Enter.
  3. Commit the changes. Select Keep query and then Update model with changes to commit the commented measure definition back to the model.

The Prompt: Add comments to this MEASURE

Copilot’s Response:

🟢 Green Light

Overlooked Detail: Copilot scoped the comments specifically to the DEFINE MEASURE block. It did not attempt to comment the EVALUATE portion of the query loaded by Define and Evaluate.

This is the right behavior. The comments that travel with the measure when we select Update model with changes are the ones inside the DEFINE MEASURE block. Copilot correctly focused its documentation effort where it counts.


Practitioner’s Verdict:
How Far Can You Trust Copilot for DAX Development?

After running Copilot through five scenarios — writing measures, building advanced logic, explaining existing DAX, debugging logical errors, and documenting the semantic model — here is the honest assessment.

Copilot is a capable and practical assistant for semantic model development. Across the five scenarios, it earned five Green Lights and three Yellow Lights. No Red Lights, but the Yellow Lights carry real weight and are worth understanding before we start offloading DAX work to AI.

Where Copilot hits its stride:

The results were strongest where the task was well-defined and the model was clean. Basic and intermediate measures came back quickly and accurately. The debugging scenario performed well — correctly diagnosing an ALL vs ALLSELECTED issue, explaining the underlying cause clearly, and offering two well-reasoned solutions with guidance on when to use each. Measure descriptions were accurate, readable, and business-aware rather than just restating the formula name.

The explanation scenario highlighted something equally valuable. Feed Copilot a complex, multi-variable measure with HTML rendering logic and it will walk through it step by step in plain language. For onboarding new team members, auditing inherited models, or simply revisiting logic written months ago, that capability is genuinely useful.

The DAX query view inline Copilot adds further value. The Suggest measures feature returned six well-structured analytical measures in a single prompt, complete with inline comments and a live preview. The Add comments workflow produced useful documentation rather than just variable name restatements. These are the features that make the biggest difference in team environments where maintainability matters.

Where we still have to drive:

The three Yellow Lights pointed to the same underlying pattern: Copilot answers the question we ask, not necessarily the question we should have asked.

The YoY Growth measure was syntactically strong but assumed a properly configured Date table without helping us verify or build one.

The percentage contribution measure was correct for the prompt, but did not anticipate how ALL versus ALLSELECTED would behave in an interactive report with slicers.

In both cases, Copilot did its job. The gap was in the prompt, the model structure, or the report design context that Copilot simply does not have access to.

This is the part that matters most: Copilot does not know our report. It does not know how users interact with slicers or what the business actually needs versus what was typed into the prompt. That context lives with the developer, not the AI.

The broader DAX community reinforces this point. The continued investment in deep technical content covering advanced concepts signals that DAX expertise is not becoming less relevant in an AI-assisted world. If anything, it is becoming more important. We need to know what correct DAX looks like to evaluate what Copilot hands us.

Copilot in Power BI Desktop is a practical productivity tool for Power BI semantic model development. It handles the repetitive, time-consuming parts of DAX work reliably enough to trust, with a close eye and a solid foundation in the fundamentals.

The tool earns its keep. Your expertise still earns its keep, too.

The sample report is available at the link below!

In an era where AI is moving from experimental to essential, this toolkit is designed to help Power BI developers explore AI workflows, learn Power BI AI tools, and get started on their journey to modernize the way they build!


What’s Next: A Look at What’s Coming

This post focused on one specific question: how useful is Copilot in Power BI Desktop for the day-to-day work of semantic model development?

Across five scenarios, the answer is encouraging. Copilot is a practical addition to a developer’s workflow, particularly for first drafts, documentation, and explaining DAX logic to team members.

But this post only covers one piece of what AI-assisted Power BI development looks like in 2026.

There is a meaningful difference between using AI as a conversational assistant inside a tool and configuring AI with the right context, tools, and environment to take real action on a model.

As that setup becomes more capable, the tasks we can delegate to AI grow significantly, from generating a single measure to planning and executing complex modeling workflows with minimal manual intervention.

That progression is what the rest of this series will explore:

  • Copilot in Power BI Desktop for Report Development: staying within the built-in experience but shifting focus from semantic model development to report design, visual creation, and data exploration
  • AI-Assisted Development: stepping outside Power BI Desktop to pair a more capable AI interface with direct, programmatic access to the semantic model. Two practical approaches worth exploring here: VS Code with GitHub Copilot and the Power BI Modeling MCP Server, and Claude Desktop with MCP Servers, both of which unlock capabilities the built-in Copilot pane cannot match.
  • Agentic Development: the most advanced tier, where community projects like GitHub – data-goblin/power-bi-agentic-development or articles such as Introducing AI and agentic development for Power BI explore what fully autonomous Power BI development workflows look like when agents plan and execute tasks end to end.

Each post in the series will follow the same format used here — real prompts, real outputs, and a clear-eyed view of where AI earns its keep and where the human still needs to drive.


Thank you for reading! Stay curious, and until next time, happy learning.

And, remember, as Albert Einstein once said, “Anyone who has never made a mistake has never tried anything new.” So, don’t be afraid of making mistakes, practice makes perfect. Continuously experiment, explore, and challenge yourself with real-world scenarios.

If this sparked your curiosity, keep that spark alive and check back frequently. Better yet, be sure not to miss a post by subscribing! With each new post comes an opportunity to learn something new.

Leave a comment