Business Professionals
Power BI | Power Pivot | Power Query | DAX
Cloud Flows | RPA | AI Builder | Copilot
60+ Formulas | Data Stories | Advanced Reporting & Modeling
VB Programming | Report Automation |
MS-Office Automation
Techno-Business Professionals
Power BI | Power Query | Advanced DAX | SQL - Query &
Programming
Microsoft Fabric | Power BI | Power Query | Advanced DAX |
SQL - Query & Programming
Power BI | Power Apps | Power Automate | Copilot Studio | Power Pages | Dataverse
Microsoft Power Apps | Microsoft Power Automate
Power BI | Adv. DAX | SQL (Query & Programming) |
VBA | Python | Web Scrapping | API Integration
Power BI | Power Apps | Power Automate |
SQL (Query & Programming)
Power BI | Adv. DAX | Power Apps | Power Automate |
SQL (Query & Programming) | VBA | Python | Web Scrapping | API Integration
Power Apps | Power Automate | SQL | VBA | Python |
Web Scraping | RPA | API Integration
Technology Professionals
Power BI | DAX | SQL | ETL with SSIS | SSAS | VBA | Python
Power BI | SQL | Azure Data Lake | Synapse Analytics |
Data Factory | Databricks | Power Apps | Power Automate |
Azure Analysis Services
Microsoft Fabric | Power BI | SQL | Lakehouse |
Data Factory (Pipelines) | Dataflows Gen2 | KQL | Delta Tables | Power Apps | Power Automate
Power BI | Power Apps | Power Automate | SQL | VBA | Python | API Integration
Power BI | Advanced DAX | Databricks | SQL | Lakehouse Architecture
Business Professionals
Power BI | Power Pivot | Power Query | DAX
Cloud Flows | RPA | AI Builder | Copilot
60+ Formulas | Data Stories | Advanced Reporting & Modeling
VB Programming | Report Automation |
MS-Office Automation
Techno-Business Professionals
Power BI | Power Query | Advanced DAX | SQL - Query &
Programming
Microsoft Fabric | Power BI | Power Query | Advanced DAX |
SQL - Query & Programming
Power BI | Power Apps | Power Automate | Copilot Studio | Power Pages | Dataverse
Microsoft Power Apps | Microsoft Power Automate
Power BI | Adv. DAX | SQL (Query & Programming) |
VBA | Web Scrapping | API Integration
Power BI | Power Apps | Power Automate |
SQL (Query & Programming)
Power BI | Adv. DAX | Power Apps | Power Automate |
SQL (Query & Programming) | VBA | Web Scrapping | API Integration
Power Apps | Power Automate | SQL | VBA |
Web Scraping | RPA | API Integration
Technology Professionals
Power BI | DAX | SQL | ETL with SSIS | SSAS | VBA
Power BI | SQL | Azure Data Lake | Synapse Analytics |
Data Factory | Azure Analysis Services
Microsoft Fabric | Power BI | SQL | Lakehouse |
Data Factory (Pipelines) | Dataflows Gen2 | KQL | Delta Tables
Power BI | Power Apps | Power Automate | SQL | VBA | API Integration
Power BI | Advanced DAX | Databricks | SQL | Lakehouse Architecture
Operations teams in Chicago plants rarely complain about "not enough data". They complain about staring at a Power BI report that doesn’t match the floor, is slow on Monday mornings, and doesn’t answer the question they were asked in the 6:00 AM stand‑up.
This walkthrough shows how to design a Power BI supply chain & manufacturing dashboard that ops teams actually use: wired to the right data, tuned for refresh and performance, and laid out for the reality of multi‑site plants around Chicago.
You’re supporting an operations group with:
They already have a Power BI workspace called “Supply Chain & Manufacturing”. The problem:
We’ll design one core dashboard/report that solves these issues, focusing on:
Power BI will let you drag visuals immediately, but for supply chain and manufacturing, the model is where most future pain comes from.
For this scenario:
Key points (current behavior as of late 2026):
A practical pattern:
For the Chicago scenario, a clean star schema might look like:
Fact tables:
FactOrders – order lines with requested and confirmed datesFactShipments – shipment lines with shipped quantities and datesFactInventoryMovements – receipts, issues, adjustmentsFactProduction – production quantities by line, shift, and timeFactDowntime – downtime events with duration and reason codesDimension tables:
DimDateDimPlantDimCustomerDimProductDimProductionLineDimShiftDimDowntimeReasonCore practices that matter here:
DimDate with a continuous date range and mark it as a Date table in Power BI.A simple DimDate generation in Power Query (Import mode):
let
StartDate = #date(Date.Year(DateTime.LocalNow()) - 2, 1, 1),
EndDate = #date(Date.Year(DateTime.LocalNow()) + 1, 12, 31),
Source = List.Dates(StartDate, Duration.Days(EndDate - StartDate) + 1, #duration(1,0,0,0)),
ToTable = Table.FromList(Source, Splitter.SplitByNothing(), {"Date"}, null, ExtraValues.Error),
AddYear = Table.AddColumn(ToTable, "Year", each Date.Year([Date]), Int64.Type),
AddMonth = Table.AddColumn(AddYear, "Month", each Date.Month([Date]), Int64.Type),
AddDay = Table.AddColumn(AddMonth, "Day", each Date.Day([Date]), Int64.Type),
AddYM = Table.AddColumn(AddDay, "YearMonth", each Date.ToText([Date], "yyyy-MM"), type text)
in
AddYM
This gives you a stable calendar that can support OTIF and trend analysis without relying on auto‑date/time.
Chicago plants typically run overnight ERP batches and near‑continuous MES feeds. Your Power BI refresh needs to respect both.
With Import mode, you can schedule dataset refreshes in the Power BI service (frequency depends on license/capacity):
Best practices that matter:
FactOrders and FactShipments.OrderDate or ShipmentDate).Example incremental refresh policy for FactShipments (configured in Power BI Desktop using parameters):
RangeStart and RangeEnd parameters defined as DateTime.FactShipments[ShipmentDate] using these parameters.This keeps historical data stable while only reprocessing recent partitions.
For MES data, DirectQuery can give near‑real‑time views of downtime and production events, but with trade‑offs:
To keep the ops dashboard usable:
FactDowntime and FactProduction) via views that:
PlantId, ProductionLineId, EventStartTime)If the floor team only needs near‑real‑time for open downtime events and last few hours of production, consider:
That hybrid pattern keeps the main dashboard fast while still supporting live views when needed.
The Chicago ops team wants one page they can use in the daily stand‑up, not six tabs of charts.
Build a single “Ops Overview” page with sections:
Keep visuals:
Ops users often need to go from summary to detail for a specific line or customer.
Set up drill‑through pages:
This keeps the main page clean while still supporting deep dives.
Once the model and layout are set, the measures drive whether the numbers match what the team sees in MES and ERP.
You need to align with how your ops team defines OTIF. A common pattern:
ShipmentDate ≤ RequestedDate.ShippedQty ≥ OrderedQty.Assuming FactShipments has one row per order line shipment, and FactOrders has one row per order line, a simple measure:
OTIF Orders =
VAR OnTimeInFullOrders =
CALCULATE(
DISTINCTCOUNT(FactOrders[OrderLineId]),
FILTER(
FactOrders,
FactOrders[ShippedQty] >= FactOrders[OrderedQty]
&& FactOrders[ShipmentDate] <= FactOrders[RequestedDate]
)
)
VAR TotalOrders = DISTINCTCOUNT(FactOrders[OrderLineId])
RETURN
DIVIDE(OnTimeInFullOrders, TotalOrders)
Notes:
FactOrders contains ShippedQty and ShipmentDate via ETL or relationships; if not, you’d need a measure that aggregates from FactShipments and compares to ordered quantities.DISTINCTCOUNT on a stable key (OrderLineId) to avoid double‑counting.For FactDowntime, assume:
DurationMinutes columnEventStartTime and EventEndTimeDimProductionLine and DimShiftTotal downtime minutes:
Downtime Minutes = SUM(FactDowntime[DurationMinutes])
Total scheduled minutes per line and shift can be a separate table or calculated measure. For a simple model where scheduled minutes are stored in DimShift:
Scheduled Minutes = SUM(DimShift[ScheduledMinutes])
Downtime percentage:
Downtime % =
DIVIDE(
[Downtime Minutes],
[Scheduled Minutes]
)
This works cleanly when filters are applied by plant, line, and date, because both measures respond to the same filter context.
For FactProduction with ProducedQty, and a plan table FactProductionPlan with PlannedQty:
Produced Qty = SUM(FactProduction[ProducedQty])
Planned Qty = SUM(FactProductionPlan[PlannedQty])
Production vs Plan % =
DIVIDE(
[Produced Qty],
[Planned Qty]
)
Avoid mixing row‑level logic into these measures unless you have a specific requirement. For ops dashboards, simple aggregate comparisons tend to be more reliable and understandable.
Ops teams notice when the main page takes 10+ seconds to load or slicers feel sluggish. They won’t care about your model elegance if it’s slow.
On the main ops page:
Use Power BI performance tools:
FILTER over large tables where possible.VAR) to avoid repeated calculations.Large manufacturing and supply chain datasets can grow quickly.
Key actions:
These steps reduce memory footprint and can improve Import model performance, especially in shared or constrained capacities.
For DirectQuery tables:
Ops pattern:
Chicago operations have some practical constraints:
To make the dashboard more useful locally:
DimPlant (city vs suburbs) so you can slice performance by site.These additions don’t change the core model but make the dashboard more relevant to regional discussions.
Before you roll the dashboard out to every supervisor and planner in Chicago, freeze two things:
Once those are stable and validated against ERP and MES, you can safely iterate on extra pages and analyses without breaking the daily stand‑up view that ops teams actually rely on.
This article reflects the shift from ad‑hoc manufacturing reports to a stable, model‑driven Power BI ops dashboard pattern that matters most for multi‑plant supply chain teams running mixed ERP and MES data in regional environments like Chicago.
Professionals who want to apply these patterns to their own data can explore Excelgoodies' Power BI Training in Chicago, Illinois programme - taught live by instructors, with certification awarded once a real project is running at work.
Insights compiled through ongoing industry research and discussions within the Excelgoodies Analytics Community.
Power BI
New
Next Batches Now Live
Power BI
SQL
Power Apps
Power Automate
Microsoft Fabrics
Azure Data Engineering