Unlocking Next-Level Productivity with Power BI's TMDL View and AI
- Jihwan Kim
- 2 days ago
- 8 min read
Introduction: A New Chapter in My Power BI Development Journey
In this writing, I'd like to share my journey with a feature that has fundamentally changed my approach to Power BI development: the TMDL View. I initially saw it as just another tab in Power BI Desktop, but my most recent learning point is that it's not a feature—it's a gateway to an entire professional development ecosystem.
For those new to the term, Tabular Model Definition Language (TMDL) is a human-readable scripting language that acts as the blueprint for a Power BI semantic model. Every table, relationship, and measure is represented in a clean, text-based format. The TMDL View, available as a preview feature in Power BI Desktop, is the built-in code editor that lets you see and interact with this blueprint directly.
My central discovery, and the focus of this post, is that the true power of TMDL View is realized not in isolation, but when combined with Power BI Projects (.pbip), external editors like Visual Studio (VS) Code, version control with Git, and the assistive power of Generative AI like GitHub Copilot. This synergy transforms Power BI development from a series of UI clicks into a structured, efficient, and collaborative process akin to modern software engineering. This evolution represents a strategic pivot by Microsoft, elevating the native development experience by incorporating capabilities that previously required a heavy reliance on third-party tools. This post will walk you through my learning curve, from initial efficiency gains to embracing a full-fledged development lifecycle that has unlocked a new level of productivity.
Beyond the UI: My First Steps and Foundational Learnings with TMDL View
Getting started is straightforward. You first need to enable the feature by navigating to File > Options and settings > Options > Preview features and checking the box next to "TMDL View". After a quick restart of Power BI Desktop, a new icon for the TMDL View appears on the left-hand pane.


My First Script
My first interaction was simple: I dragged a table from the Data pane onto the empty TMDL View canvas. Instantly, Power BI Desktop generated a createOrReplace script for that table, laying out its entire definition in clean text. The experience felt immediately familiar, much like scripting a database object in SQL Server Management Studio. This was the first "wow" moment—the sheer transparency of it. Instead of hunting through scattered properties panes and dialogs in the UI, the complete definition of the object was right there in one place.

createOrReplace
table fact_sales
lineageTag: 356586d9-fd5d-4218-b3c8-125b424fb56c
column date
dataType: dateTime
formatString: Long Date
lineageTag: 4180d495-9366-46f9-a0fe-7e7f7eae5ff8
summarizeBy: none
sourceColumn: date
annotation SummarizationSetBy = Automatic
annotation UnderlyingDateTimeDataType = Date
column product
dataType: string
lineageTag: 68f8713f-e4bd-4f7a-b6ef-06b710d470c2
summarizeBy: none
sourceColumn: product
annotation SummarizationSetBy = Automatic
column sales
dataType: int64
formatString: 0
lineageTag: 74624111-fb40-4669-81bc-53e7a39086a2
summarizeBy: sum
sourceColumn: sales
annotation SummarizationSetBy = Automatic
partition fact_sales = m
mode: import
source =
let
Source = Csv.Document(File.Contents("C:\Users\JI\Downloads\sales_product.csv"),[Delimiter=",", Columns=3, Encoding=65001, QuoteStyle=QuoteStyle.None]),
#"Promoted Headers" = Table.PromoteHeaders(Source, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"date", type date}, {"product", type text}, {"sales", Int64.Type}})
in
#"Changed Type"
annotation PBI_NavigationStepName = Navigation
annotation PBI_ResultType = Table
Viewing M Code Without the Editor
An unexpected productivity boost came from being able to view a table's Power Query transformations directly within the TMDL script. The M code resides within the table's partition definition, as seen above or below. This allows for a quick check of the logic without launching the resource-intensive Power Query Editor, which can be a time-saver during development. It is important to note, however, that the TMDL View currently lacks syntax highlighting or validation specifically for the embedded M code.
https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-tmdl-view?wt.mc_id=DP-MVP-5004989

createOrReplace
createOrReplace
table dim_calendar
lineageTag: 287cecaa-890f-4d55-bc5c-fe8168a36f3c
dataCategory: Time
column date
dataType: dateTime
isKey
formatString: Short Date
lineageTag: 8e35a2e7-e13d-4f94-a198-f979063cdb0f
summarizeBy: none
sourceColumn: date
annotation SummarizationSetBy = Automatic
annotation UnderlyingDateTimeDataType = Date
column Year
dataType: int64
formatString: 0
lineageTag: 8883a462-b09c-41c9-8d6c-15a23b7f8da4
summarizeBy: none
sourceColumn: Year
annotation SummarizationSetBy = Automatic
column Month
dataType: int64
formatString: 0
lineageTag: b62e5d1e-b03b-4cf3-a797-8e999f249edf
summarizeBy: none
sourceColumn: Month
annotation SummarizationSetBy = Automatic
column 'Month Name'
dataType: string
lineageTag: f9eb476b-2980-4022-812e-9b25ee86aebd
summarizeBy: none
sourceColumn: Month Name
sortByColumn: Month
changedProperty = SortByColumn
annotation SummarizationSetBy = Automatic
column 'Start of Month'
dataType: dateTime
formatString: Short Date
lineageTag: f4446e5e-c3c9-4a75-afa8-a7339de8844c
summarizeBy: none
sourceColumn: Start of Month
annotation SummarizationSetBy = Automatic
annotation UnderlyingDateTimeDataType = Date
column 'End of Month'
dataType: dateTime
formatString: Short Date
lineageTag: 02b7585a-4df5-4c3c-ac58-b23e13209943
summarizeBy: none
sourceColumn: End of Month
annotation SummarizationSetBy = Automatic
annotation UnderlyingDateTimeDataType = Date
column Year-Month
dataType: string
lineageTag: 793670ce-a42c-46a8-bb73-48c0ae4660c2
summarizeBy: none
sourceColumn: Year-Month
sortByColumn: 'End of Month'
changedProperty = SortByColumn
annotation SummarizationSetBy = Automatic
partition dim_calendar = m
mode: import
source =
let
Source = Excel.Workbook(File.Contents("C:\Users\JI\Downloads\calendar.xlsx"), null, true),
Sheet1_Sheet = Source{[Item="Sheet1",Kind="Sheet"]}[Data],
#"Promoted Headers" = Table.PromoteHeaders(Sheet1_Sheet, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"date", type date}}),
#"Inserted Year" = Table.AddColumn(#"Changed Type", "Year", each Date.Year([date]), Int64.Type),
#"Inserted Month" = Table.AddColumn(#"Inserted Year", "Month", each Date.Month([date]), Int64.Type),
#"Inserted Month Name" = Table.AddColumn(#"Inserted Month", "Month Name", each Date.MonthName([date]), type text),
#"Inserted Start of Month" = Table.AddColumn(#"Inserted Month Name", "Start of Month", each Date.StartOfMonth([date]), type date),
#"Inserted End of Month" = Table.AddColumn(#"Inserted Start of Month", "End of Month", each Date.EndOfMonth([date]), type date),
#"Added Custom Column" = Table.AddColumn(#"Inserted End of Month", "Year-Month", each Text.Combine({Text.From([Year], "en-US"), "-", Text.Start([Month Name], 3)}), type text)
in
#"Added Custom Column"
annotation PBI_NavigationStepName = Navigation
annotation PBI_ResultType = Table
The Productivity Breakthrough: Mastering Bulk Operations and Hidden Properties
After getting comfortable with viewing scripts, the next step was to leverage the editor for modifications. This is where the productivity gains become truly tangible, especially for repetitive tasks.
Conquering Repetitive Tasks
The built-in code editor facilitates bulk changes with an efficiency that the graphical UI cannot match. For instance, if you need to remove a standard prefix like "dim_" or "fact_" from all your table names, you can script the entire Semantic model, use the find-and-replace feature (Ctrl+F) with a regular expression like dim_, and replace all occurrences with an empty string in a single action.


Another real-world example is updating a property across dozens of measures. In one project, I needed to update the formatStringDefinition for approximately 40 different measures. Doing this through the UI would have involved clicking on each measure individually, navigating to the properties, making the change, and waiting for it to apply—a tedious and error-prone process. With TMDL View, I scripted the table containing the measures, used find-and-replace to update all instances at once, and applied the changes in seconds. This saved a significant amount of time and eliminated the risk of manual errors. For more complex, non-uniform edits, advanced features like multi-cursor editing (Ctrl+Shift+L or Crtl+D) allow for making simultaneous changes in multiple places without repeated find-and-replace operations.

Unlocking the Model's Secrets
Perhaps one of the most powerful aspects of TMDL View is that it exposes object properties that are not available in the Power BI Desktop user interface. Previously, accessing these required third-party tools like Tabular Editor. Now, they can be managed natively.
DetailRowsDefinition: This property allows you to customize the drill-through behavior for users who "Show Details" on a pivot table in Excel. By setting this in TMDL, you can control exactly which columns are returned, providing a curated and performant experience that was previously only possible with external tools.
IsPrivate and IsAvailableInMDX: You can set the IsPrivate property on a table to true to hide it from client tools, which is useful for intermediate tables that shouldn't be exposed to end-users. Similarly, setting IsAvailableInMDX to false on a column can reduce memory usage, though it makes the column inaccessible to MDX-based queries like Analyze in Excel.
Perspectives and Cultures: Features like perspectives, which are essential for the "Personalize Visuals" feature, and cultures (translations) for creating multilingual reports, lack a graphical interface in Power BI Desktop. TMDL View provides a direct, code-based way to create and manage them. 1
Connecting Power BI to Developer Tools
The real breakthrough for me was connecting the TMDL view to the broader world of developer tools like VS Code and GitHub Copilot. The key is to save my work as a Power BI Project file (.pbip).
Doing this changes how your data model is saved. Instead of being a single, complex file, it becomes a folder containing simple, text-based .tmdl files. This file structure is the secret to using professional developer workflows.
While my first attempt to use AI to write TMDL code didn't work out, the process itself was a huge learning experience. (Separately, I had great success using AI with M-code, but that’s a story for another day!)
My AI Experiment: A Learning Experience
I was excited to see if AI could revolutionize my workflow. My first try wasn't a success, but there's a lot to learn from the attempt. Here’s a walkthrough of what happened.
Save as PBIP: I saved my Power BI report as a .pbip file.
Open in VS Code: I opened the entire project folder in VS Code, where I had already installed the TMDL Language extension from Microsoft for syntax highlighting.
Locate the Script: Inside the \TMDLScripts or \definition folder, I found the calendar_dimension.tmdl file.
Prompt Copilot: After installing the extension in VS Code,

I right-clicked in the editor, started an inline chat with GitHub Copilot, and gave it a precise prompt: "Add calculated column "Quarter Number", and use QUARTER() DAX function.".


Review and Accept: Copilot immediately suggested the exact lines of code to add to the TMDL script. I reviewed its suggestion, saw it was NOT correct, but clicked "Accept", and saved it to see what would happen.


Apply in Power BI: I saved the file in VS Code, then reopened the .pbip file in Power BI Desktop. The TMDL View showed the modified script. I clicked the "Apply" button.

An error was displayed.
In my previous blog post, https://jihwankimcscp.wixsite.com/supplychainflow/post/leveraging-the-tmdl-view-feature-in-vscode-with-github-copilot-my-experience , the calendar table is created by writing DAX (calculated table), and I think this made easy for AI modifying or adding new columns.
The correct version is shown below; hopefully, AI will soon be able to provide accurate assistance.

Making Power BI Fun with AI
While my attempt in here was a learning curve, it opened my eyes to what's coming next, and it is incredibly exciting. Forget the sci-fi stuff; let's talk about having an AI coding partner right inside my Power BI workflow. This isn't about replacing developers; it's about giving me superpowers to ditch the boring tasks and focus on being creative architects.
Imagine having a tool like GitHub Copilot as my new junior dev—one that never gets tired and loves doing the tedious jobs. Here’s what that actually looks like:
My Personal Performance Coach: Instead of hunting for bottlenecks, I could just ask my AI partner to scan my model. It might come back with friendly tips like, "Hey, I noticed this DAX is working way too hard. Here’s a slicker version that will run much faster," or "You could shrink your model size by 15% just by changing this one data type!"
A Super-Smart Spellchecker for Your Model: Perhaps, I am the only one on my team who remembers the proper naming conventions? Let the AI be the friendly nudge. It can automatically flag things like, "It looks like this table isn't connected to my main date calendar," or "This is a great measure, but how about we add a quick comment so everyone knows how it works?"
The Ultimate Shortcut: The Model-Building Genie: This is where it feels like real magic. I could simply write a prompt like, "Create a basic sales model with tables for products, stores, and daily sales, and add standard MTD/QTD/YTD measures." Copilot could then generate the entire TMDL folder structure, building the foundation for me. I just get to handle the fun, creative parts.
This kind of AI assistance frees us up from the copy-paste grind and endless troubleshooting. It lets me jump straight to what really matters: designing and building robust, scalable, and genuinely impactful data solutions.
Now, you might be wondering what makes this AI-powered future possible. The secret ingredient is TMDL. It’s the key that unlocks the Power BI "black box." By saving my work as a Power BI Project (.pbip), I transform that one giant, mysterious .pbix file into a clean folder of human-readable text files. It's like finally being able to pop the hood of my car to see how everything works.
This is what allows me (and my AI partner) to get in there and work magic. It opens the door to using professional tools like Git, which means my whole team can collaborate on a single model without the classic "who has the latest version?!" panic. It paves the way for automating tests and deployments. In short, it helps Power BI development grow up. The journey is just beginning, and this transformation makes building things with data more creative and efficient than ever before.
I hope this helps having more fun in your journey with modern Power BI development.
API Connects is a leading IT firm in New Zealand, specializing in IoT development, IoT solutions, and data engineering services. We provide cutting-edge IoT solutions to enhance business operations and data engineering services for seamless data migration and optimization. Our expert DevOps team ensures secure core banking data migration for financial institutions. Visit- https://apiconnects.co.nz/iot-development-testing-consulting/ , https://apiconnects.co.nz/data-engineering-services/