Unlimited Power BI Usage History — Snapshot the Built-In Usage Metrics Model to Lakehouse

Power BI’s built-in usage metrics report is great — until you need history beyond 30 days. The underlying dataset is a rolling window: yesterday’s view counts are there, last quarter’s are gone. If you want to track adoption trends, prove ROI, or spot reports that have quietly died, you need to capture that data yourself.

The fix is surprisingly simple: a single Fabric notebook that queries the hidden Report Usage Metrics Model semantic model over XMLA and appends each daily snapshot to Lakehouse Delta tables. Unlimited history, append-only, ~30 lines of Python.

Usage Metrics Snapshot architecture

Honest Disclaimer — Prefer FUAM

Before you build this: if you have any meaningful scale of Power BI / Fabric tenant, use FUAM (Fabric Unified Admin Monitoring) instead. FUAM is the Microsoft-published, open-source accelerator that snapshots not just usage metrics but capacity events, activity logs, refresh history, inventories — the whole tenant story — into a Lakehouse with a ready-made semantic model and report. It is far more complete than what’s in this post.

So when do I reach for the little notebook below instead?

  • A single workspace where you just need report-level view history and don’t want to deploy a full monitoring solution.
  • You need a quick fix today and FUAM rollout is weeks away.
  • You want to understand how the underlying mechanism works — the notebook is small enough to read end-to-end in five minutes.

For everything else: start with FUAM.

The Problem: 30 Days Is Not Enough

  • Rolling window. Each day, the oldest day falls off. Anything older than 30 days is permanently gone — you cannot recover it.
  • No YoY, no trends. Did adoption grow over the last year? Which reports are losing users? You literally cannot answer these questions with the built-in model.
  • No ownership. Microsoft controls the model. Schema changes happen without notice. You cannot extend it, share it, or join it to your own dimensions cleanly.

The Solution: Daily Snapshot to Lakehouse

The hidden Report Usage Metrics Model is a normal semantic model — it just happens to be auto-managed by Microsoft. That means you can hit it with XMLA queries like any other model. Using sempy.fabric.evaluate_dax, we pull each source table, stamp a SnapshotUtc column, and append to Delta tables in a Lakehouse:

import sempy.fabric as fabric
from datetime import datetime, timezone

WORKSPACE_ID = "<your-workspace-guid>"
DATASET_NAME = "Report Usage Metrics Model"
TABLES = ["Views", "Reports", "Users", "Dates", "DistributionMethods", "Platforms"]

snap_ts = datetime.now(timezone.utc)

for t in TABLES:
    df = fabric.evaluate_dax(
        dataset=DATASET_NAME,
        workspace=WORKSPACE_ID,
        dax_string=f"EVALUATE '{t}'",
    )
    df.columns = [c.split("[")[-1].rstrip("]") if "[" in c else c for c in df.columns]
    df["SnapshotUtc"] = snap_ts.isoformat()
    (spark.createDataFrame(df).write
        .mode("append")
        .option("mergeSchema", "true")
        .saveAsTable(f"usage_metrics_{t.lower()}"))

That’s the whole engine. Schedule it daily after 04:00 UTC (the source refreshes around 03:00 UTC) and you have a permanent historical record.

What Lands in the Lakehouse

One Delta table per source table, prefixed usage_metrics_*, with an extra SnapshotUtc column. Append-only — every run adds today’s full snapshot.

Source tableLakehouse tableRole
Viewsusage_metrics_viewsFact
Reportsusage_metrics_reportsDimension
Usersusage_metrics_usersDimension
Datesusage_metrics_datesDimension
DistributionMethodsusage_metrics_distributionmethodsDimension
Platformsusage_metrics_platformsDimension

Three Design Decisions Worth Calling Out

  • Append, not merge. Every snapshot is the full 30-day window. Yes, days overlap across snapshots — but storage is cheap and append is bulletproof. Deduplication happens at query time (see below), not at ingest time.
  • mergeSchema=true. Microsoft occasionally adds columns to the usage metrics model. With schema merging on, the next snapshot just absorbs the new columns instead of crashing.
  • Retention with DELETE. Default 400 days (≈13 months, enough for YoY) — but you can set RETENTION_DAYS = None to keep forever. The delete is a normal Delta operation, so time travel still works if you mess up.

Querying Without Double-Counting

Because every snapshot contains the last 30 days, the same activity row appears in up to 30 snapshots. To get clean numbers, take the latest snapshot per natural key:

WITH ranked AS (
    SELECT v.*,
           ROW_NUMBER() OVER (
               PARTITION BY Date, ReportGuid, UserGuid
               ORDER BY SnapshotUtc DESC
           ) AS rn
    FROM usage_metrics_views v
)
SELECT Date,
       ReportGuid,
       COUNT(*)                  AS views,
       COUNT(DISTINCT UserGuid)  AS distinct_users
FROM ranked
WHERE rn = 1
GROUP BY Date, ReportGuid
ORDER BY Date DESC, views DESC

For older history (where a date appears in only one snapshot), the deduplication is a no-op — the row simply passes through. For the most recent 30 days, you always pick the freshest version of each fact.

Prerequisites

  • Workspace on Premium / PPU / Fabric capacity (XMLA endpoint enabled — read is enough).
  • The Report Usage Metrics Model dataset exists in the workspace. It is auto-created the first time anyone clicks More options → View usage metrics report on any report in that workspace.
  • A Lakehouse attached to the notebook (any Lakehouse in the same workspace works).
  • Tenant setting “Usage metrics for content creators” enabled (admin portal).

Try It — Fabric Notebook Gallery

The notebook is also submitted to the Fabric Notebook Gallery. Grab the .ipynb directly from GitHub and import it into any Fabric workspace:

📓 Usage Metrics Snapshot.ipynb — one notebook, six Delta tables, daily schedule. Set WORKSPACE_ID, attach a Lakehouse, schedule after 04:00 UTC. Done.

Take It Further — A Power BI Report on Top

The Lakehouse tables are already the hard part. From here, building a proper Adoption & Usage Power BI report is a short hop:

  • Point a Direct Lake semantic model at the six usage_metrics_* Delta tables — no import, no refresh schedule, fresh on the next snapshot.
  • Wrap the "latest snapshot per natural key" dedup logic in a SQL view in the Lakehouse SQL endpoint so the model stays simple. One view per fact, deduped, ready to consume.
  • Build the obvious pages: Adoption over time (views & distinct users by month, YoY), Top & bottom reports, Dying reports (had >X views last year, <Y this quarter), Platform & distribution mix.
  • Join to your own Reports dim (owner, business domain, criticality) for actionable cuts — e.g. "critical reports with zero views in 30 days".

That’s the whole point of owning the history: once the data lives in your Lakehouse, you can model and visualise it however your stakeholders need — not however Microsoft’s built-in report happens to ship it.

Wrap-Up

One notebook, one daily schedule, six Delta tables — and the 30-day blind spot is gone. You own the history, you can join it to your own data, and you can build proper adoption dashboards on top.

The full notebook (with retention, health-check, and example query cells) is on GitHub: KornAlexander/PBI-Tools → Notebook Gallery / Usage Metrics Snapshot.ipynb.

Power BI Report Prototyping with AI: From 35 Pages to 18 in 10 Minutes

Power BI Report Prototyping with Excalidraw and Copilot Agent Mode

How I used GitHub Copilot Agent Mode, Playwright MCP, and Excalidraw to prototype a Power BI report redesign — automatically.

1. The Problem

You have a Power BI report with 35 pages and 5 levels of drill-through navigation. Users get lost. Pages are hard to maintain. You want to redesign the navigation — but how do you plan it visually before touching a single Power BI file?

Traditional approaches involve:

  • Opening the report and clicking through pages manually
  • Sketching boxes on a whiteboard
  • Creating mockups in PowerPoint

None of these give you a connected view of what exists (screenshots of every page) alongside what should change (proposed page hierarchy).

2. The Solution: AI-Powered PBI Prototyping

I built a workflow that combines three tools:

  1. Playwright MCP — automatically screenshots every page of a Power BI report
  2. Excalidraw — organizes screenshots with labels, levels, and before/after comparison diagrams
  3. PBIR files — extracts the actual page navigation graph from the report definition

All orchestrated by GitHub Copilot in Agent mode inside VS Code.

Power BI Report Prototyping Process — automated workflow using Copilot Agent Mode

The complete prototyping workflow — from opening the report to the final Excalidraw file.

3. Screenshot Every Page with Playwright

Power BI renders visuals on <canvas> elements — there’s no way to extract the visual content as DOM elements. Screenshots are the only viable approach.

Using the Playwright MCP server in VS Code, Copilot navigates to the report, opens the page dropdown at the bottom, and loops through every page — clicking each one, waiting for visuals to render, and taking a screenshot. The entire process is hands-free.

Key learnings:

  • Open the report in full-screen mode before running the script — avoids capturing sidebars and filter panes
  • Wait 4 seconds per page for visuals to render (8 seconds for complex pages)
  • For non-default tenants, launch Edge with --remote-debugging-port=9222 and connect Playwright via CDP

Result: 35 clean, full-screen screenshots in under 3 minutes.

4. Extract Page Navigation from PBIR Files

Instead of manually mapping which pages link to which, I export the report’s PBIR definition via the Fabric REST API.

Every Power BI project (PBIP) consists of two parts: the PBIR (report definition) and the TMDL (semantic model definition). The PBIR contains a JSON file for every page and every visual — including the exact drill-through targets, button navigation actions, and page references. This means the complete navigation graph of the report is encoded in these files.

# Authenticate and export the report definition via Fabric REST API
Login-PowerBIServiceAccount
$uri = "https://api.fabric.microsoft.com/v1/workspaces/$workspaceId/reports/$reportId/getDefinition"
$response = Invoke-WebRequest -Uri $uri -Method Post -Headers $headers

# The API returns a long-running operation — poll until complete,
# then save all files locally (pages, visuals, assets, themes, ...)

By searching for cross-page references in the visual.json files, I can extract the complete navigation graph:

From: Page 1 (Overview) → To: Page 2a, Page 2b, Page 2c, ...
From: Page 2a → To: Page 3a, Page 3b, ...
From: Page 3a → To: Page 4a
From: Page 4a → To: Page 5a

This gives me the actual drill-through depth for every page — no guessing required.

Result: A complete navigation graph with hundreds of cross-page links, automatically determining that some sections have 5 levels of drill-through.

5. Build the Excalidraw Prototype

Excalidraw files are pure JSON — no special tools needed. I generate the entire prototype programmatically with Python. Screenshots are embedded as base64-encoded images directly into the Excalidraw JSON file, so the result is a single portable file with everything included.

Color-Coded Level Indicators

Each page gets a label with color coding based on its drill-through depth:

  • L1 (Teal) — Landing page
  • L2 (Blue) — First entry from overview
  • L3 (Purple) — Analysis pages
  • L4 (Orange) — History pages
  • L5 (Red) — Detail drill-through
  • TT (Gray) — Tooltip pages

Layout: Categories Horizontal, Pages Vertical

Categories are arranged as columns. Within each column, pages are stacked vertically in drill-through order. This gives an instant visual sense of which areas are deep and which are flat.

Before/After Comparison Diagrams

Below each category’s screenshots, I add box diagrams showing the current vs. proposed hierarchy:

BEFORE (12 pages, 5 levels)

[L1] Page 1
  └─ [L2] Page 2a
       ├─ [L3] Page 3a
       │    └─ [L4] Page 4a
       │         └─ [L5] Page 5a
       └─ [L3] Page 3b
            ├─ [L4] Page 4b
            └─ [L4] Page 4c

AFTER (5 pages, 3 levels)

[L1] Page 1
  └─ [L2] Page 2a
       ├─ [L3] Page 3a
       │    + Page 4a content (merged as table)
       │    + Page 5a content (merged as drill-through)
       └─ [L3] Page 3b
            + Page 4b content (merged as table)
            + Page 4c content (merged as chart)

Result: 35 pages → 18 pages. 5 levels → 3 levels. Clear visual comparison.

6. A Note on Figma

I also tried the Figma MCP server for this workflow. Figma’s capture can convert HTML pages into editable design layers — great for web UIs. I successfully captured the before/after box diagrams as editable Figma frames.

However, for Power BI prototyping specifically, Figma has limitations: Power BI renders visuals on <canvas> elements which are invisible to the capture script, the MCP is write-only (no editing existing layers), and each capture ID is single-use. If you need to share prototypes with designers already in Figma, it works as an additional output — but Excalidraw is the better primary tool because:

  • Full programmatic control — the JSON file format allows unlimited manipulation
  • No API limits or authentication required
  • Works offline in VS Code with the Excalidraw extension
  • Images, text, shapes, and arrows in a single portable file

7. The Complete Workflow

  1. Open PBI report in browser (Playwright MCP)
  2. Screenshot all pages (loop through page dropdown)
  3. Export PBIR definition (Fabric REST API)
  4. Parse navigation graph from visual.json files
  5. Build Excalidraw file with Python: embed screenshots, add labels, generate comparison diagrams
  6. Review in VS Code with Excalidraw extension
  7. Optionally capture to Figma for sharing

Total time: ~10 minutes for a 35-page report, fully automated.

8. Try It Yourself

Prerequisites

  • VS Code with GitHub Copilot (Agent mode)
  • Playwright MCP server (npx @playwright/mcp@latest)
  • Excalidraw VS Code extension (pomdtr.excalidraw-editor)
  • MicrosoftPowerBIMgmt.Profile PowerShell module

Quick start

  1. Open VS Code with GitHub Copilot (Agent mode)
  2. Install the Playwright MCP server (npx @playwright/mcp@latest)
  3. Open your Power BI report in the browser and copy the URL
  4. Ask Copilot: “Screenshot all pages of this Power BI report, download the PBIR definition, analyze the page navigation hierarchy, and create an Excalidraw file organized by category with level indicators and before/after comparison diagrams”

The AI handles the automation. You focus on the design decisions.

9. Beyond Prototyping: Visual Report Documentation

This workflow isn’t just for redesigning reports. It’s equally valuable as a documentation tool for important production reports:

  • Onboarding new team members — Instead of clicking through a 30-page report live, hand them an Excalidraw file with every page screenshot, labeled with descriptions and navigation hierarchy. They see the full picture in one canvas.
  • Change tracking — Run the screenshot workflow periodically and compare versions side by side. Visual diffs catch layout changes that text-based diffs miss.
  • Stakeholder communication — Share the Excalidraw file (or a Figma capture) with business stakeholders to discuss which pages they actually use, which are redundant, and where gaps exist.
  • Audit and compliance — For regulated environments, having a visual snapshot of every report page with timestamps serves as documentation of what was deployed and when.
  • Cross-team alignment — When multiple teams build reports in the same workspace, the navigation graph reveals overlaps, orphaned pages, and opportunities to consolidate.

The same 10-minute automated process that enables prototyping also produces comprehensive visual documentation — with zero manual effort.

What’s Next

  • Automated PBIR modification — Once the prototype is approved, programmatically update the report’s page structure to match the proposed design
  • Semantic model analysis — Apply the same prototyping approach to data model optimization
  • Template generation — Create reusable prototyping templates for common report patterns

Tools used: GitHub Copilot (Claude), Playwright MCP, Figma MCP, Excalidraw, Microsoft Fabric REST API, PowerShell, Python

Power BI Without Fabric Is Like Owning a Sports Car but Leaving It in Eco Mode

Preamble: This article is not meant to be a fully comprehensive guidance why adopting Microsoft Fabric makes sense for every organization. Instead, it highlights a collection of practical examples showing the benefits Fabric can deliver — even if your primary interest is Power BI. The views expressed here are my own and do not represent official Microsoft guidance.

Power BI is well established in many organizations. Reports run reliably, dashboards are widely used, and insights drive daily decision‑making. But as these environments grow, familiar pain points continue to appear beneath the surface:

  • Deployments become more fragile as complexity increases.
  • Troubleshooting takes longer and often depends on deep expert knowledge.
  • Semantic models, although functional, become harder to maintain and optimize.

These challenges may sometimes be present from the start, but they often become noticeable only as Power BI evolves into a business-critical tool.

This is where Microsoft Fabric steps in. You professionalize your environment.

Even for Power BI only environments not focused on other workloads like data engineering, data science, or real-time analytics, Microsoft Fabric brings crucial value. It streamlines management, enhances reliability, and simplifies troubleshooting—addressing issues that often surface as complexity grows. This article highlights why Fabric strengthens Power BI itself, regardless of your interest in other workloads.

1. Model Diagnostics with Fabric: BPA & Memory Analyzer in Just “Two Clicks”

Before Fabric, deep model analysis required juggling multiple tools such as Tabular Editor, DAX Studio, XMLA endpoints…

While powerful, the process was manual and dependent on expert users.

Fabric radically simplifies this workflow by integrating these powerful diagnostics directly into the platform. With only a few clicks, teams can run the Best Practice Analyzer (BPA) and Memory Analyzer without leaving the environment.

This integrated, frictionless workflow enables teams to:

  • Quickly assess rule violations and semantic model details such as model size per table/column
  • Identify performance bottlenecks
  • Apply best practices as part of a repeatable, team‑wide process

Fabric doesn’t change what needs to be analyzed or how to fix it — it changes how accessible and reliable that analysis becomes. And don‘t get me wrong: I‘m a huge fan of these tools and they are still very valid choices.

External Tools: The complex – expert way: Install Tabular Editor & DAX Studio + XMLA Endpoint

With the traditional approach you need to use DAX Studio and Tabular Editor. As shown in the screenshot below you need to add the BPA with a script into Tabular Editor. Btw. the installation script is part of my toolbox. My Power BI Toolbox: 80+ Tabular Editor Macros to Automate Data Model Development – Blog about Actionable Reporting – Alexander Korn Toolbox Installation Script: PBI-Tools/Data Model Toolbox/Installer HICODataModelToolbox.csx at main · KornAlexander/PBI-Tools · GitHub

Or alternatively just install the BPA directly with this script.

Analysis-Services/BestPracticeRules at master · microsoft/Analysis-Services · GitHub

Afterwards you can connect to your model (XLMA endpoint or local PBI Desktop instance) and run the BPA.

With the memory analyzer (vertipaq analyzer) the process is slightly less complicated but also requires a third party tool like DAX studio.

In Fabric: VertiPaq Analyzer & BPA the easy way – with “two clicks”

With Fabric this process is now super simple and no need for third party tool.

  1. Open semantic model
  2. Click on BPA / Memory Analyzer
  3. Run All Notebook

That’s it – now the same process follows like you would do in the external tools. For example checking for columns and data types with high impact or assess and fix the BPA violations.


2. Monitoring and Troubleshooting: Full Visibility Instead of Guesswork

In many Power BI environments, teams struggle not because things fail, but because things become slow, unpredictable, or resource‑intensive without a clear explanation. In the capacity metrics app (installation guidance here: Install the Microsoft Fabric capacity metrics app – Microsoft Fabric | Microsoft Learn) Performance bottlenecks often appear as capacity spikes, unexplained slowdowns, or inconsistent report behavior — and without proper insight, diagnosing these issues requires stitching together logs from multiple sources.

Fabric dramatically improves observability across the entire analytical environment by providing:

  • Detailed, structured logs that reveal exactly what happened and when
  • User‑friendly monitoring dashboards that visualize performance patterns
  • Clear classification of issues by gateway, dataset, service, or model
  • Faster diagnosis due to consolidated, contextualized monitoring data

Instead of reacting to unclear symptoms, teams can now proactively understand how workloads behave and where performance pressure originates.


Stuck with Operation IDs? Fabric Monitoring Unlocks Them

Anyone who has investigated a capacity spike or sudden performance drop has encountered cryptic Operation IDs or Root Activity IDs. Historically, these identifiers were extremely difficult to interpret — they didn’t map to a specific query, user action, or event.

Fabric Monitoring fundamentally changes this. Once enabled, it allows teams to:

  • Trace an Operation ID back to the exact DAX query executed
  • See the actual message or condition associated with the operation
  • Understand the filter context, duration, and triggering report
  • Inspect historical performance patterns to identify recurring bottlenecks

This transforms diagnostics from guesswork into precision.

What used to look like “Operation xyz123 consumed high resources” can now be understood as:

“This specific DAX query with this filter context consumed excessive memory and caused a capacity spike.”

Workspace Monitoring: The Missing Link for Real Diagnostics

Workspace Monitoring provides the level of visibility Power BI admins have been missing for years — the kind of transparency that turns isolated signals into actionable intelligence. Instead of relying on high‑level capacity charts or disconnected logs, Workspace Monitoring brings together all query activity, performance characteristics, and error context in a single, cohesive diagnostic layer.

At its core, the built‑in template report offers:

  • Query history with timing, duration, and type, allowing admins to see precisely when workloads peak
  • Full drill‑through into query details, exposing expensive DAX statements, filter context, and execution patterns
  • Performance trends over time, helping teams identify recurring bottlenecks rather than treating symptoms in isolation
  • Error details surfaced directly in context, eliminating the guesswork that typically accompanies operational troubleshooting

But the real value emerges when you begin using these views together. With Workspace Monitoring, it becomes possible to correlate user behavior, query characteristics, report performance, and capacity load — all without leaving the Fabric environment.

This unified lens transforms Workspace Monitoring into a genuine forensic toolkit. Instead of trying to decode red bars in a metric app or pulling logs from multiple systems, admins can reconstruct what happened, why it happened, and who or what triggered it.

For example:

  • A sudden spike in capacity can be tied directly to the DAX query that caused it.
  • Slow report interactions can be traced back to specific visuals or filters.
  • Intermittent issues can be investigated by reviewing long‑term patterns rather than relying on anecdotal observations.

When combined with Fabric User Activity Monitoring (FUAM), this visibility becomes even more powerful. FUAM shows how users are interacting with reports — which pages they open, how frequently they query the model, and where user-driven pressure might be occurring.

Together, Workspace Monitoring and FUAM give organizations a complete operational picture that spans both system behavior and user behavior. This combination is essential for performance tuning, governance, right‑sizing capacity, and making evidence‑based platform decisions.

Instead of reactive troubleshooting, teams gain a proactive, data‑driven approach to managing their analytical environment — finally closing the long‑standing visibility gap that has challenged Power BI admins for years.

3. Access to Power BI Premium features without Premium cost — and why starting small with Fabric works

One of the most overlooked advantages of introducing Microsoft Fabric into an existing Power BI setup is the ability to unlock many Power BI Premium capabilities without purchasing a dedicated Premium capacity or Premium Per User licenses. With Fabric SKUs starting as low as F2, organizations can access features that previously required a full P1 (F64) or PPU. This fundamentally changes the adoption discussion for smaller teams that want to professionalize their Power BI lifecycle without enterprise‑level spend.

Key Premium‑class capabilities enabled by Fabric include:
• Deployment Pipelines for proper Dev/Test/Prod lifecycle management
• Advanced dataset and workspace governance
• Operational and scalability controls traditionally tied to Premium
• Copilot for Power BI — now available starting from F2 (previously required F64)

Example of Deployment Pipeline

This directly challenges the long‑held assumption that Premium is only realistic for large enterprises with large capacities. That used to be true, but Fabric has significantly lowered the entry point. In many cases, an F‑series capacity can even be cheaper per user than adding PPU licenses once you have more than a small group of users. As a result, Fabric becomes a cost‑effective way to unlock Premium functionality while also opening the door to broader data‑platform capabilities.

At the same time, Fabric scales down extremely well. Even small SKUs like F2, F4, or F8 already deliver:
• Centralized monitoring
• Pipeline‑based deployments
• Workspace isolation
• Robust governance controls
• Model‑ and capacity‑level diagnostics
• Integration with Lakehouse, Data Engineering, and other Fabric experiences

This makes it easy to follow a pragmatic, low‑risk adoption strategy:

  1. Start with a high‑value, well‑contained use case — something small, measurable, and easy to control.
  2. Measure improvements—model performance, stability, observability, developer workflow, governance.
  3. Scale intentionally—expand workspaces or capacities only when evidence shows clear value.

This approach avoids over‑investment, accelerates time‑to‑value, and establishes a strong, future‑proof architecture—while benefiting from Premium‑level features at a fraction of the historical cost.

Conclusion

Fabric does not replace Power BI — it elevates and operationalizes it.

  • Developers gain cleaner diagnostics, deeper insight into model behavior, and repeatable pipelines.
  • Admins gain stable operations, proactive monitoring, and the tooling to troubleshoot efficiently.
  • Organizations gain governance, reliability, and a scalable analytics foundation for the future.

Fabric is not dogma — it is a strategic evolution that emerges naturally as Power BI environments mature and grow in complexity.

My Power BI Toolbox: 80+ Tabular Editor Macros to Automate Data Model Development

When it comes to streamlining your Power BI data modeling, the value of automation cannot be overstated. One of the most powerful tools available to achieve this automation is Tabular Editor, where you can write C# scripts to optimize and automate repetitive tasks. In this blog post, I’ll introduce you to my Power BI Toolbox — an extension of my original Pimp script — and share how it helps bring efficiency and best practices to Power BI data modeling.

Tabular Editor Scripts: The Key to Automation

Tabular Editor Scripts, also referred to as macros, C# scripts, or custom actions, are essential tools for automating actions within Tabular Editor. Tabular Editor, an invaluable tool for Power BI professionals, offers the ability to write custom scripts to save time and ensure consistency in data models. With C# scripting capabilities, you can automate a huge collection of tasks like creating measures, setting properties, and sooo much more.

Over the years, I’ve developed and wide range of these scripts. My Power BI Toolbox is after my PIMP script the next evolution in this journey, containing a suite of over 80 Tabular Editor scripts, each designed to simplify various aspects of Power BI data modeling. If you want to know more about why this stuff is important for Tabular models check out the following video with Reid Havens. https://www.youtube.com/watch?v=-9YaxArn3TM

What’s in the Toolbox?

My Power BI Toolbox is a collection that includes:

  • Many of the Official Tabular Editor repository macros (excluding those exclusive to TE3)
  • Bernat’s macros, You will definitely find hidden gems there.
  • My own macros, which build upon the lessons learned from my earlier PIMP script

More Details on My Favorite Macros

Here are some of my favorite macros that I’ve developed to improve efficiency and automation in Power BI data modeling:

  • Calendar Table as Calculation Group: This macro helps you create a calendar table as a calculation group and mark it as the calendar table in your data model. It’s a quick way to ensure that your time intelligence functions are referencing the correct table.
  • Time Intelligence Calculation Group: This script automatically detects the calendar table and creates a calculation group for common time intelligence measures like Year-to-Date, Quarter-to-Date, Month-to-Date, Previous Year, and more. This reduces manual work and helps ensure consistency in your model.If you have not marked your calendar table as calendar table it will ask you for it.
  • Units Calculation Group: Creates a calculation group for units without splitting text or ratio measures, making it easier to maintain a clean, efficient model structure.
  • Empty Measure Table Creation: This macro allows you to create an empty measure table, which is useful for organizing measures and maintaining a clean data model structure. The script needs to be run in two steps, first creation, than save, than hiding the column.
  • Explicit Measure Creation for Selected Columns: This macro lets you create explicit measures for selected columns and move them into a designated display folder. Additionally, it prompts you with the option to move these measures into a different table, such as an empty measure table, ensuring your data model is organized.
  • Previous Year, Delta PY, and Delta PY % Measure Creation: Automatically generates explicit measures for all selected measures with the variation previous year, delta previous year, and delta previous year percentage. The script is smart enough to recognize the marked calendar table and link these measures appropriately, saving you a lot of repetitive work.
  • Macros Containing Metadata Documentation This macro inspired by Martyn Booth is design to automatically document the model. The macro adds four new calculated tables need to be added, saved, and then hidden as part of the standard workflow. These tables can then be used to effectively document the data model, providing valuable metadata insights. The four calculated tables are: info.view.Tables, info.view.Columns, info.view.Measures, and info.view.Relationships. This approach essentially replaces the need for additional tools like VertiPaq Analyzer or Bravo for Power BI, to a considerable extent. One limitation is the absence of column size information, which would be a useful enhancement, but the benefit of automatic updates makes this a powerful feature for keeping documentation current without extra manual work. More info here: https://www.notjustaprettydashboard.com/auto-documentation-report-using-info-view-dax-functions/
  • Combine Time Intelligence with Value Parameter: This macro, inspired by Mark Endicott, extends my time intelligence template by adding a dynamic value parameter. The number of years is now made dynamic, allowing for more flexibility in time-based analysis. The next step is to make the period selection fully dynamic, enabling switching between different time frames such as year, quarter, month, and day.

These scripts are targeted at best practices in Power BI data modeling, enabling you to standardize and streamline your workflows in a consistent, efficient manner.

No Admin Rights? No Problem

No admin rights? No problem. Just make sure you’re running the latest version of Tabular Editor Portable. This version allows you to use all the powerful features of Tabular Editor without needing to install anything, making it perfect for environments where you lack administrative privileges.

How to Install the Power BI Toolbox for Tabular Editor

Installing the Power BI Toolbox is straightforward. You can use the Installation Script available here: Installation Script. Or as an alternative you can also just copy paste the MacroActions.json file into your AppData\Local\TabularEditor directories. Just paste into your file explorere “%AppData%” and you are already almost there. 

Here is a video of how to install it, if manual is not what you prefer: https://www.linkedin.com/posts/alexanderkorn_hicocando-actionablereporting-tabulareditor-activity-7250519843966181377-sfdd?utm_source=share&utm_medium=member_desktop

The installation script takes care of the following steps:

  1. Backup the MacroActions.json file if it exists in your AppData\Local\TabularEditor or TabularEditor3 directories.
  2. Add a fresh MacroActions.json file from my GitHub repository if one does not already exist.
  3. Append my DataModelToolbox.txt file to the current MacroActions.json file if one exists. Please note, if you already have some of my macros, this script does duplicate all of them.

The MacroActions.json file is where all the magic happens, containing the macros that Tabular Editor will use to automate your Power BI tasks. You can check it out here: MacroActions.json File.

How to Execute C# Scripts in Tabular Editor 2

To execute C# scripts in Tabular Editor 2, follow these simple steps:

  • Connect to Open Power BI Desktop: Start by connecting Tabular Editor to your open Power BI Desktop instance to gain access to the data model.
  • Right-Click Options: You can execute scripts by right-clicking on a table, column, data model, or measure within the model. Depending on the certain Macro it will be visible within the context menu where you can select and run the script.
  • Navigate to the C# Section: Alternatively, you can directly navigate to the C# scripting section within Tabular Editor, where you can write and execute your scripts.

Shortcuts for Macros

In Tabular Editor 3, you can even assign shortcuts to these actions, giving you more flexibility and making repetitive tasks even faster. This is especially useful when working with large and complex data models where efficiency matters most. 

Here is a video of this in action: https://www.linkedin.com/posts/alexanderkorn_do-you-also-have-a-button-to-implement-power-activity-7252416004079677443-0HHC?utm_source=share&utm_medium=member_desktop

You can either set the shortcuts for the macros under Tools > Preferences > Keyboard or alternatively copy and paste my UiPreferences.json file into your directory AppData\Local\TabularEditor3. You can find the UiPreferences.json file here: UiPreferences.json.

I am using the following shortcuts for my macros:

Macro ID Range Shortcut Combination
1 to 9 CTRL + SHIFT + Number (1 to 9)
10 to 19 CTRL + ALT + Number (1 to 9)
20 to 29 CTRL + ALT + SHIFT + Number (1 to 9)

I need to give for the keyboard shortcut and Stream Deck idea full credit to Bernat Agullo Rosello. He gave me the whole idea. I wasn’t aware of Stream Deck till he pointed me that way. While he had the idea, I went ahead and made it real. I am now using a Stream Deck with custom icons for these shortcuts, which allows me to apply data model changes with just the press of a button. This setup significantly enhances my productivity by making these powerful macros available at my fingertips. With the Stream Deck, I can visually organize the most frequently used macros, assign dedicated buttons to each, and execute them instantly. This workflow improvement not only saves time but also makes navigating complex models more intuitive, as I can easily trigger common actions without needing to remember numerous key combinations or navigate through menus.

Sorting the IDs

All Macros have an ID, those can be consequential but don’t need to be. The sorting in Tabular Editor 3 is by default exactly like the MacroActions.json file is sorted. That being said, if you move macros around in the json file, than the IDs do not get automatically adjusted. At the time of writing you will see that actually my file skips a few IDs and is not perfectly sorted. Andreas Nordgaard provided for us a free Python script which does the job.

Save the python script in the same location as the Macro file install python, potentially modify the python script to use the correct parent path and you are good to go.

Just be careful if you change your IDs those will than potentially not match your Tabular Editor 3 shortcuts anymore.

    https://github.com/aols0228/Semantic-Models/blob/main/Macros/MacroActions.json/Update%20Id’s%20in%20MacroActionsJSON.py

    Stream Deck Profile

    In case you also have Stream Deck and want to overcome the hustle to set it up here is my Stream Deck profile, which should have all the icons. Just make sure your shortcuts in TE3 align with the profile. https://github.com/KornAlexander/PBI-Tools/blob/main/Data%20Model%20Toolbox/Tabular%20Editor.streamDeckProfile

    Why Automate?

    The Power BI Toolbox is more than just a collection of scripts; it’s about bringing best practices to every model you create. It’s about removing friction, increasing productivity, and reducing the chance of human error when performing repetitive tasks. Automation lets you focus on what matters most: making data-driven decisions that impact your business.

    Get Started Today

    Ready to give your Power BI data modeling a productivity boost? Install the Power BI Toolbox and start automating today! You can access the installation script here and transform how you model your data or alternativly just add it manually.

    Let me know if you have any questions or if you need help getting started. Maybe do you have a killer script I need to add. Let me know. Would be very happy to receive it. Happy modeling! 🙂


    Video Demo

    Spot Poor Power BI Reports: No4. No “EMPTY MEASURE TABLE” 

    When building Power BI reports, deciding where to place your measures—whether in a dedicated measure table or directly in the fact table—can impact both usability and maintainability. Here’s a look at why creating a separate measure table often works best and why it’s becoming a popular approach for Power BI developers and report consumers alike. I call the approach of a dedicated measure table as “EMPTY MEASURE TABLE” because it is just a container, no actual data is in there, except maybe the relationships but that’s a minor detail.

    Advantages of a Dedicated Measure Table

    1. Clear Structure for Reports Under Development: Fact tables are often “work in progress” —especially in development or test environments — where new measures or transformations may still be in the pipeline. A measure table provides a consistent location for measures even if the fact table is incomplete.
    2. Ease of Development: From a developer’s perspective, having all measures in a single, separate table makes it easy to find and work with them. It avoids digging through the fact table, especially when it’s not fully denormalized.
    3. Attributes in Fact Table are unavoidable: Normally attributes in fact tables like an invoice number should be ideally avoided. But as we all know business request are a priority and this can’t be always avoided. As a result the fact table will not move to the top with the calculator icon. And if that is the case Measure Table for sure it is. A separate invoice number dimension table is also not optimal.
    4. Easier Tracking of Incomplete Work: Developers can quickly see if a fact table still needs further adjustments without having to go through measure definitions, as all measures are in their own place.
    5. Non-Disruptive Maintenance: When tables are deleted, measures in a separate measure table remain untouched, avoiding accidental data model breakages due to table deletions.
    6. Improved User Experience: Users may not always understand the difference between fact and dimension tables, and a dedicated measure table avoids confusing them with technical table names. This is especially helpful when users need quick access to measures such as variance or trend measures across multiple tables. Users don’t have to dig through multiple tables to find what they need.
    7. Consistent Naming Conventions: A measure table supports streamlined naming conventions. While dimensions and facts are often tagged in table names, this isn’t necessary with a measure table, which can be kept hidden or labeled more intuitively, contributing to a cleaner, more navigable model.

    Encounter the disadvantage of Excel functionality:

    Is the data model used in excel a lot the empty measure table approach should very carefully considered and maybe thrown over board.

    1. Drillthrough Flexibility: Yes the big disadvantage of missing the drillthrough needs to be addressed with additional work with detailrowexpression. Maybe we could set it on the table level instead of on the measure level. For more details on this: https://www.sqlbi.com/articles/controlling-drillthrough-in-excel-pivottables-connected-to-power-bi-or-analysis-services/
    2. Missing Relationships: In Excel normally the relationships are automatically visible. That means no wrong relationship can be used. With “Empty measure tables” manually setting up fake relationships is needed. Obviously this can’t be done as exact, since different measures might have different relationships.

    Naming Convention

    Did you know that you can’t use “Measures” as name for your empty measure table? The best next alternative is “Measure” – Easy fix.

    Organization in Display folders

    Obviously organizing the measures in folders and subfolders is needed, but this is unrelated to the fact which approach should be chosen. Organizing that way can be done in both worlds.

    But how do I implement it?

    Here is a super easy two step process in Tabular Editor 2. Just paste it into C# Script and Execute the two scripts separately.

    // ATTENTION FOR TE2 Users: Script needs modification AND needs to be run in 3 steps
    // First Step: Add Table
    var table = Model.AddCalculatedTable("Measure", "{0}");
    // Second Step: JUST FOR TE2 Save Data Model Changes
    // Third Step: Hides the column, uncomment the next two lines and execute it separately to the previous creation
    var table = Model.Tables["Measure"];
    table.Columns[0].IsHidden = true;

    Final Thoughts

    Using a separate measure table provides a cleaner, more efficient Power BI model that’s easier for both developers and end-users to navigate. This approach aligns with best practices in data model design, creating a well-organized, scalable, and maintainable report structure.

    And once again if Excel usage is a priority, the approach should be carefully considered and maybe revert back to the fact table approach. But than push hard to have it fully denormalized / all columns hidden.

    Spot Poor Power BI Reports: No3. No Units Calculation Group

    When working with large datasets in Power BI, displaying big numbers—especially those over a million—can become a challenge. Lengthy figures not only clutter your visuals but can also confuse your audience. To enhance readability and comprehension, it’s essential to format these numbers into thousands, millions, or even billions. While Power BI offers several methods to achieve this, not all are optimal.

    In this article, we’ll explore the various approaches to handling large numbers and show why implementing a “Units Calculation Group” is often the best solution.

    Common Approaches to Displaying Large Numbers

    There are several strategies you might consider when formatting big numbers in Power BI:

    1. Automatic Formatting by Visuals
    2. Fixing the Visual to a Specific Unit
    3. Using a Helper Table in Measures
    4. Implementing a Units Calculation Group

    1. Automatic Formatting by Visuals

    Letting the visual handle the formatting automatically seems convenient. However, Power BI’s automatic unit selection can sometimes be suboptimal. You might find your visuals displaying “0” or “1 million,” which lacks the necessary detail, especially without decimal places.

    2. Fixing the Visual to a Specific Unit

    Manually setting the unit (e.g., thousands, millions) in the visual’s format settings can work, but it locks you into one unit. This rigidity doesn’t accommodate data that spans multiple scales, limiting the flexibility of your report.

    3. Using a Helper Table in Measures

    Adding a helper table and integrating it into your measures offers more control but increases complexity. This method can clutter your model and make maintenance more challenging, especially as your data evolves.

    Why Implement a Units Calculation Group?

    Given the limitations of the previous methods, implementing a Units Calculation Group is often the most effective solution. This approach provides flexibility and precision, allowing you to display numbers in the appropriate units with the desired level of detail.

    Benefits of Using a Units Calculation Group in Combination with Dynamic Format String

    • Dynamic Unit Selection: Users can switch between units (e.g., thousands, millions) as needed.
    • Enhanced Readability: Proper formatting with decimal places improves data comprehension.
    • Consistency: All relevant measures are automatically included.

    Tips for Implementing a Units Calculation Group

    To ensure your Units Calculation Group works effectively, consider the following tips:

    1. Default Measure Display: The option for the actual measure without any selection (SELECTEDMEASURE()) isn’t necessarily needed. If no unit is selected, the actual measure will display by default.
    2. Exclude Text Values: Use ISNUMBER(SELECTEDMEASURE()) to exclude text measures from the calculation group, preventing errors.
    3. Exclude Percentage or Ratio Measures: Apply a condition like NOT(CONTAINSSTRING(SELECTEDMEASURENAME(), “%”)) to exclude percentage or ratio measures that shouldn’t be scaled.
    4. Use Dynamic Formatting Strings: Implement dynamic formatting to add decimal places for millions but not for thousands or when no unit is selected. This enhances precision where needed without cluttering smaller numbers. See below for DAX code.
    5. Display Selected Unit in Titles: Incorporate the selected unit into your visual titles or within the dynamic formatting string. This provides context to users about the scale of the numbers they’re viewing.

    Below is the full definition of the calculation item for “Thousand.” You can adapt this for the “Million” calculation item by adjusting the divisor.

    IF(
    ISNUMBER(SELECTEDMEASURE()),
    IF(
    NOT(
    CONTAINSSTRING(SELECTEDMEASURENAME(), "%") ||
    CONTAINSSTRING(SELECTEDMEASURENAME(), "ratio")
    ),
    DIVIDE(SELECTEDMEASURE(), 1000),
    SELECTEDMEASURE()
    ),
    SELECTEDMEASURE()
    )

    Explanation of the Code

    • ISNUMBER(SELECTEDMEASURE()): Checks if the measure is a number to exclude text values.
    • NOT(CONTAINSSTRING(…)): Excludes measures that contain “%” or “ratio” in their names.
    • DIVIDE(SELECTEDMEASURE(), 1000): Scales the measure down to thousands.
    • SELECTEDMEASURE(): Returns the original measure if conditions are not met.

    SWITCH(
    SELECTEDVALUE( UnitCalcGroup[Unit] ),
    "NameOfCalcItemThousand", "0,#",
    "NameOfCalcItemMillion", "#,0.#",
    "#,#"
    )

    To dynamically display the selected unit in your visual titles, use the following DAX expression and combine it with static text

    SELECTEDVALUE(UnitCalcGroupName[Unit])

    This expression retrieves the currently selected unit from your Units table, allowing you to inform users about the scale directly within the visual.

    Conclusion

    Optimizing the display of large numbers in Power BI reports is crucial for clarity and professionalism. While multiple approaches exist, implementing a Units Calculation Group offers the most flexibility and control. By following the tips outlined above, you can enhance your reports, making them more informative and user-friendly.

    Remember, the goal is to present data in a way that is both accurate and easily digestible. With the right formatting techniques, your Power BI reports will not only look better but also provide greater value to your audience.

    Spot Poor Power BI Reports: No2. The Lonely Fighter

    Okay this is not exactly a poor Power BI report or mistake per se, but might be just one contributing factor for your “poor Power BI report”.

    Have you learned your Power BI skills mostly by yourself via YouTube, reading through the endless Microsoft documentation, or some “secret blog article” like mine? 😉

    Here is a tip for you. Why don’t you just “call” support? I urge you to do so. Have you ever done so? And yes, with the millions of Power BI users, honestly, 99% of the questions have already been asked and answered, and yes we all have our AI helper, but still till today, I believe “calling” support is still a very valid and underestimated option.

    Probably lots of my former colleagues are going to hate me for this tip since they are maybe already flooded with support requests. But it’s their job to help you, not just when your Power BI report crashed and you are super desperate, when it is already too late. Instead, there is also something called “advisory cases.” In short there is no need to be the lonely fighter.

    Did you know that everyone, even with just a Pro license, is entitled to create support tickets as they wish? Honestly, depending on your support entitlement, you might not always receive the exact help you were looking for, but if that’s the case, then voice your concern. I guarantee you! After the case is closed, you have the possibility to enter feedback, and I am sure your feedback is highly valued. Even more important is positive feedback. 😉

    But if you are lucky, you might also talk to some of the most knowledgeable Power BI experts in their domain. I dare to say no Power BI consultant or Power BI developer, not even MVPs, will match their expertise, because only a few people can see that many different environments and can niche down on certain areas as they can.

    Support people at Microsoft are all super nice. Maybe they will give you additional things to collect, but isn’t it okay for them to ask for information from you when you request their help? So please don’t be rude if you think the “information” they asked for is useless or installing the newest Power BI Desktop version is not helping at all. It might indeed just be what they need to proceed with your case.

    And in case all of this is still not helping, obviously you could also ping me via LinkedIn or mail. 😉

    Everything you need to know about Power BI Support:

    Spot Poor Power BI Reports! No1: The Slicer Mess

    This article is part of a series on how to spot a poor Power BI report. There are many pitfalls, which are obvious like 3D Pie Charts, but then there are others which are less obvious. We all have done those mistakes, we actually all of us make some of those still every day, aware or unaware. I want to highlight a few of them in this upcoming series.

    I wrote already about one misconception in the past, so check it out: https://actionablereporting.com/2023/12/21/myths-about-red-green-deficiency-in-visualizations/

    I would like to start with one “Power BI Failure” which is definitely less obvious, heck maybe even up for discussion: Slicer Vs Filterpane

    If you’re familiar with Power BI, you know there are three primary ways to “filter” a report (page):

    1. Filter pane
    2. Visuals
    3. Slicers

    One sign of a poorly designed Power BI report is the excessive use of slicers. Here’s why using option 1 or 2 is in most cases better than option 3.

    1. Increase Information Density Without Losing Clarity

    • Visual Importance: If an element is significant enough to be on the report page as slicer, than it should be a visual like a bar chart. Visuals provide almost the identical functionality as slicers, with the added advantage that visuals convey information while slicers just don’t. The use of space can be the same or at least similar. In case you don’t know multi-select is possible with CTRL.
    • Filter Pane Utilization: In case you want to permanently apply the selection than you still can revert back to the filter pane. This approach not only streamlines the report but also reduces visual clutter.
    • Collapse and Expand Issues: Slicers cannot collapse or expand. Unless you design a slicer pane in your report. That’s definitely something I try to avoid at all costs, because that’s a set up for failure through a bookmark nightmare.

    2. Performance: Faster Reports

    • Impact on Loading Times: Each element on the page needs to be rendered, and visuals must wait for slicers to load as well. This can significantly slow down the report.
    • Optimization Tip: Set slicers to “All.” If nothing is selected. Supposedly that’s faster.

    3. Structure and Simplification

    • Consistency is key for user familiarity: Everyone who has used Power BI in the past at least once, can answer the following question: Where is the filter pane in Power BI? Easy: on the right side of the report. Does the same apply for slicers? Nope, sometimes those are top, left, right or maybe even scattered. No matter which report or company you are going to work with the filter pane is going to be on the right side of the report. Rarely if ever is the filter pane disabled. Did you know you can do that as well?
    • Single Source of Filtering: Totally ommiting is by the way often not an option, because you want to give the users often the possibility to filter more than just one or two attributes, therefore you absolutely need the filter pane. And if you are already using the filter pane than make the single source of filtering. Have you tried to put 20 filters as slicers on your page? Good luck with that. Not saying you should do it with the filter pane. But at least space usage is minimal and structure is super neat.
    • Three Levels of Granularity: The filter pane is super clear on the possibility to filter. There are three levels:
      • Visual
      • Page
      • report –> I try to reside just to this one. Skipping page and visual if possible

    In contrast have you tried to sync slicers across many pages? That can be a nightmare to maintain, which is visible on which page and which is syncing on which page?

    • Order and Size Consistency of filter: The order of filters in the filter pane is super consistent. I tend to number those filters in the filter pane. Each element is uniformly sized and has similar possibilities to filter. I tend to number the filters through with modification of their text. Note that numbering the filters in the filterpane shouldn’t be done if translations are in the game.
    • Search Functionality: Searching values in the filter pane is enabled by default. With slicers this also possible, you need to enable it through the three dots before.

    Exceptions: Where slicers have some small advantage:

    If you haven’t noticed I am not a big fan of slicers, but I want to acknowledge some arguments in favor of slicers.

    1. Hierarchies: When dealing with hierarchical data. Hierarchies in filter pane not possible, but in slicers it is. Edit 17. July 2024 But potential even a bigger performance impact.
    2. Logos: If you use your slicers with small pictures on your page such as logos, I am okay for that. Picture in the filter pane. Not possible.
    3. Unspottable Slicers: When a slicer with a field parameter overlays invisibly the new card visual, it can be the bomb. (e.g. you cards become clickable for different measures how cool is that)
    4. Title Integration: Once again if slicers are not noticeable I am okay too, such as part of a title or other text element you would have on your page either way.
    5. Publish to Web: okay this is definitely an argument for slicers. Filterpane is not available for reports published to the web (To be clear: I mean web not Power BI Service)

    In conclusion, while slicers can be a useful tool in Power BI, for me it is clear: The less slicers –> the better your Power BI. Yes I am also sometimes resorting back to slicers and yes sometimes the combination of all three options is the magic path.

    Increasing information density, having faster reports, and a better structure in my filters is key for me and I hope you take my advice and will think about the (over-)use of slicers in the future twice. 😉

    Edit: 17. July 2024

    Sharing this blog article I got great input from various people. My opinion still stands “it depends” or “both” is the right answer. With me clearly trying to lean towards the filter pane as much as possible. As long as you make an explicit for one or the other than you are good to go.

    Overall the majority was rather opposing my standpoint and the survey also supports this:

    Result of Survey

    Supporting / Supplemental arguments

    However some also supported my point of view such as Armand van Amersfoort performance argument.

    Or also Kerry Kolosko posted a great rule of thumb, which I support 100%

    Opposing Viewpoint

    If you are interested to read a completely opposite viewpoint than check out this great article from Johnny Winter:

    Power BI – Pimp – Script

    Do you would like to apply data model best practices with a click of a button to your existing Power BI reports? Than the “PBI-Pimp-Script” is the right place for you!

    Edit: This script had a major revamp, published on 31. January 2024 and includes now a lot more: Explicit Measure Creation, Units calc group, Further Calendar Tables, Adding BPA and more.

    This script is designed to streamline and enhance your Power BI modeling experience. Whether you are a Power BI data model expert or just getting started, this script helps you supercharge your modeling efforts.

    Overview and Customization

    At the beginning the PBI-Pimp-Script offers through various prompts a range of enhancements that can be customized to fit your specific needs. Let’s dig into key aspects of this script and how you can tailor it to your requirements.

    Calculation Group for Time Intelligence Measures

    One of the essential features of this script is the ability to add a Calculation Group for “Time Intelligence”. Calculation Groups is a great way to organize or even reduce your measures, making it easier to navigate and manage your Power BI model. With this script, you can define a custom name for your Calculation Group, define the name of the date table and date column to be used. This makes sure your Time Intelligence Calculation Group works even if you are using non-standard names. Do you have a fiscal year and need fiscal year calculation items than the script offers the flexibility to adjust the cutoff day. In contrast you don’t need YTD, than decide against it.

    Date Dimension Table

    A robust Date Dimension Table is crucial for time-based analyses in Power BI. The PBI-Pimp-Script allows you to generate a Date Dimension Table and specify its name and the date column name to match your dataset’s structure. This script follows the approach to push the date dimension as far as possible into the backend. For the script this means this is not a calculated table and instead a power query date dimension. You need to make sure the current time selection 2018 till 2025 fits your needs.

    Empty Measure Table

    The script includes an option to generate an Empty Measure Table. Not sure this is the correct name, but that’s how I call this table. The table basically consists of nothing but two columns which are optional to be filled in. Both columns are by default hidden, that means you won’t immediately find this table. The purpose of this table is to work as container for all of your measures. In case the description of the measures is not sufficient, potentially you could also use this table to document your measures in the columns with editing the table directly in Tabular Editor. In case you need additional measure containers, make sure to rerun the script and stating Yes just for the empty measure table question. If you follow tabular modeling best practices than all of your fact tables contain zero visible columns. Therefore Empty Measure Tables is the way to go.

    Last Refresh Table

    Monitoring data refresh times is essential for data-driven decision-making. The script offers the option to create a Last Refresh Table, which keeps track of the last time your data was refreshed. This information can be invaluable for troubleshooting and ensuring that your data is up-to-date. You can use than this table to add a visualization to your report displaying also the last refresh time to your end-user.

    DAX Formatting

    Consistency is key when it comes to DAX (Data Analysis Expressions) formatting. The script allows you to format all calculation items and if you want also all measures in your model, ensuring that your DAX expressions are easy to read and maintain. This feature enhances collaboration and ensures that your entire team follows the same formatting conventions.

    And much more

    Now that you’re familiar with the powerful features of the PBI-Pimp-Script, let’s walk through the manual process of applying it to your Power BI model.

    Manual to Apply the Script

    1. Connect Tabular Editor (TE2) to PBI Report: Start by connecting with Tabular Editor (TE2) to your local Power BI instance, your Power BI report opened in PBI Desktop
    2. Save and Reopen .bim Locally with TE2: To ensure that you have the necessary access to the Power BI model, save and reopen the .bim file locally with TE2.
    3. Apply “Pimp-Script”: Copy+paste the “Pimp-Script” to enhance your Power BI model. Save it as Macro for reuse. The script will prompt you with various options for customization.
    4. Save PBIP: Save your Power BI project (PBIP) to preserve your changes.
    5. Ingest Model.bim into the PBIP File: Copy and replace the updated “Model.bim” into the respective “ReportName.dataset” folder of your Power BI project.
    6. Reopen PBIP File: Reopen your Power BI project file to see the improvements and enhanced modeling capabilities in action. You might need to apply minor fixes, like the relationship between fact tables and new date dimension.

    I sincerely hope the PBI-Pimp-Script, will help you to apply Power BI data modeling best practices even easier with just a few clicks.

    You need more Power BI data modeling best practices or have ideas to take the script further? –> Ping me via LinkedIn

    Here is the “Power BI-Pimp-Script”


    Video Walkthrough

    Video Walkthrough (German)

    Live Session