Excel Course
Sales Dashboard Project
A Sales Dashboard is the most requested deliverable in business Excel work. Managers want to see revenue totals, regional breakdowns, top products, and month-on-month trends — all interactive, all from one screen. This project brings together Power Query for data preparation, Power Pivot with a star schema for the data model, DAX measures for KPIs, and a polished dashboard layer with PivotTables, charts, and slicers. By the end you have a fully interactive, filterable Sales Performance Dashboard that updates automatically when new data is loaded.
Project Overview — The Four Layers
The Source Data — Three Tables
The project uses three related tables loaded from CSV files. Together they form the complete picture of sales: individual transactions, the products sold, and the regions each sale belongs to.
| SaleID | PK |
| Date | Date |
| ProductID | FK |
| RegionID | FK |
| Qty | Int |
| Revenue | £ |
| ProductID | PK |
| Product Name | Text |
| Category | Text |
| Cost Price | £ |
| List Price | £ |
| RegionID | PK |
| Region | Text |
| Country | Text |
| Area Manager | Text |
Layer 1 — Power Query: Load and Shape
Load each of the three CSV files into Power Query:
Data → Get Data → From File → From Text/CSV
Do this three times — one query per file
For the Sales query:
Rename the query: Sales
Verify column types:
Date → Date
ProductID → Text (keep as text — it's a key, not a number to sum)
RegionID → Text
Qty → Whole Number
Revenue → Decimal Number
Add a Month-Year column (for monthly trend):
Add Column → Custom Column
Name: MonthYear
Formula: = Date.ToText([Date], "MMM-yyyy")
Change type to Text
Add a Year column:
Add Column → Custom Column
Formula: = Date.Year([Date])
Change type to Whole Number
For the Products query:
Rename: Products
Verify: ProductID = Text, all price columns = Decimal Number
No other changes needed
For the Regions query:
Rename: Regions
Verify: RegionID = Text, all columns = Text
No other changes needed
Load all three to Data Model (not worksheet):
Home → Close & Load To... → Only Create Connection
Tick: Add this data to the Data Model
Repeat for all three queries
Layer 2 — Power Pivot: Star Schema and DAX
Open Power Pivot: Power Pivot tab → Manage
Create relationships (Diagram View):
Sales[ProductID] → Products[ProductID] (many-to-one)
Sales[RegionID] → Regions[RegionID] (many-to-one)
This is a classic star schema:
- Sales is the fact table (centre)
- Products and Regions are dimension tables (points of the star)
ProductID
RegionID
Date · Qty
Revenue
Name
Category
Cost / List
Region
Country
Manager
DAX Measures — create these in a dedicated Measures table in Power Pivot:
Total Revenue:
=SUM(Sales[Revenue])
Total Units:
=SUM(Sales[Qty])
Transaction Count:
=COUNTROWS(Sales)
Average Order Value:
=DIVIDE([Total Revenue], [Transaction Count], 0)
Total Cost:
=SUMX(Sales, Sales[Qty] * RELATED(Products[Cost Price]))
Gross Profit:
=[Total Revenue] - [Total Cost]
Gross Margin %:
=DIVIDE([Gross Profit], [Total Revenue], 0)
Revenue vs Prior Year:
=CALCULATE(
[Total Revenue],
SAMEPERIODLASTYEAR(Sales[Date])
)
YoY Growth %:
=DIVIDE(
[Total Revenue] - [Revenue vs Prior Year],
[Revenue vs Prior Year],
0
)
Layer 3 — PivotTables: Five Helper Tables
Create five PivotTables on a hidden sheet named "Helper". Each feeds a specific section of the dashboard. The dashboard itself uses GETPIVOTDATA to pull individual values from these PivotTables into the KPI card cells and chart labels.
PivotTable 1 — Monthly Revenue Trend (feeds line chart)
Insert → PivotTable → From Data Model
Rows: Sales[MonthYear] (sorted by date, not alphabetically)
Values: [Total Revenue], [Revenue vs Prior Year]
Name: PT_Monthly
PivotTable 2 — Revenue by Region (feeds bar chart)
Rows: Regions[Region]
Values: [Total Revenue], [Gross Margin %]
Name: PT_Region
PivotTable 3 — Top 10 Products (feeds bar chart)
Rows: Products[Product Name]
Values: [Total Revenue]
Sort: Total Revenue descending
Top 10 filter: Value filters → Top 10
Name: PT_TopProducts
PivotTable 4 — Revenue by Category (feeds donut chart)
Rows: Products[Category]
Values: [Total Revenue]
Name: PT_Category
PivotTable 5 — KPI Summary (feeds KPI cards)
No rows — Grand Total row only
Values: [Total Revenue], [Total Units], [Transaction Count],
[Average Order Value], [Gross Margin %], [YoY Growth %]
Name: PT_KPI
After creating all five:
Right-click the sheet tab → Hide
The Helper sheet remains but is not visible to end users
Layer 4 — The Dashboard
The dashboard lives on a sheet named "Dashboard". Gridlines are hidden, rows and columns are resized to create a clean canvas, and all content is positioned using merged cells and linked values from the Helper PivotTables.
Building the Dashboard Step by Step
Step 1: Prepare the canvas
Insert a new sheet → rename "Dashboard"
View → uncheck Gridlines, Headings
Select all cells (Ctrl+A) → set row height 20, column width 3
This creates a blank grid you can freely arrange content on
Step 2: KPI Cards — one per metric
Select a range like B3:F8 → Merge & Centre → fill with dark colour
In the merged cell, link to PT_KPI using GETPIVOTDATA:
=GETPIVOTDATA("Total Revenue", Helper!$A$3)
Format: £#,##0,,"M" to display as £2.85M
Add a smaller merged cell below for the YoY label:
=TEXT(GETPIVOTDATA("YoY Growth %",Helper!$A$3),"+0.0%;-0.0%") & " vs PY"
Repeat for all four KPI cards across the top row
Step 3: Monthly Trend Chart (Line)
Click anywhere in PT_Monthly (on Helper sheet)
Insert → PivotChart → Line → OK
Move chart to Dashboard sheet
Format: remove gridlines, set line colour to #3b82f6
Remove chart title (it's replaced by a text label above the chart area)
Add a second line for Revenue vs Prior Year (dashed, lighter colour)
Set chart background to match the dashboard dark theme (#1e293b)
Step 4: Revenue by Region Chart (Horizontal Bar)
Click anywhere in PT_Region
Insert → PivotChart → Bar → Clustered Bar → OK
Move to Dashboard, position to the right of the trend chart
Sort bars by descending revenue: right-click bars → Sort → Largest to Smallest
Apply tonal colour scale: most revenue = darkest blue, least = lightest
Step 5: Top Products Chart (Horizontal Bar)
Click anywhere in PT_TopProducts
Insert → PivotChart → Bar → Clustered Bar → OK
Move to Dashboard, position across the bottom row
Show only Top 10: already filtered in PT_TopProducts
Step 6: Slicers — connect to all PivotTables
Click any chart or PivotTable → PivotChart Analyze → Insert Slicer
Insert slicers for: Regions[Region], Products[Category], Sales[Year]
For each slicer → Report Connections → tick all 5 Helper PivotTables
This makes all charts and KPI cards filter together when a slicer is clicked
Format slicers: no header border, 1-column layout, match dark theme colours
Step 7: Final polish
Lock the dashboard: Review → Protect Sheet
Untick "Select locked cells" → users can only interact with slicers
File → Save As → .xlsx (not .xlsm — no macros needed)
Test: click each slicer, verify all 4 KPI cards and all 3 charts update
GETPIVOTDATA — Linking KPI Cards
GETPIVOTDATA syntax:
=GETPIVOTDATA(data_field, pivot_table, [field1, item1], ...)
Total Revenue KPI card (no filter — pulls grand total):
=GETPIVOTDATA("Total Revenue", Helper!$A$3)
Gross Margin % card (formatted as percentage):
=GETPIVOTDATA("Gross Margin %", Helper!$A$3)
YoY Growth label (positive = green, negative = red via conditional formatting):
=GETPIVOTDATA("YoY Growth %", Helper!$A$3)
Apply: Home → Conditional Formatting → Icon Sets → 3 Triangles
Or: custom number format: [Green]+0.0%;[Red]-0.0%;0.0%
Why GETPIVOTDATA instead of a direct cell reference?
A direct reference like =Helper!B2 breaks if the PivotTable layout changes
GETPIVOTDATA always retrieves by field name regardless of where the value moves
It also respects the current slicer filter — so as the user clicks a region,
all KPI cards update to show that region's numbers automatically
🠐 Practice
Q1. You have built the dashboard and the Region slicer is working, but the Top Products bar chart is not filtering when you click a region. What is the most likely cause?
Q2. The KPI card for Total Revenue is showing a hard-coded cell reference =Helper!B2 instead of GETPIVOTDATA. Why is this a problem and how do you fix it?
Q3. Write the DAX measure for Gross Margin % using the Total Revenue and Total Cost measures already defined.
🟣 Quiz
Q1. Why are the three source tables loaded to the Data Model (Only Create Connection) rather than loading them as worksheet tables?
Q2. The SAMEPERIODLASTYEAR function in the Revenue vs Prior Year measure requires the Sales[Date] column to work correctly. What additional setup is needed in Power Pivot for this time intelligence function to work?
Q3. A colleague opens your dashboard file and edits PT_Monthly directly, accidentally adding a field that shifts the GETPIVOTDATA references. How should the dashboard be protected against this?
Next up — HR Dashboard Project, where we build an interactive HR analytics dashboard covering headcount, turnover rate, department breakdown, and hire trend — using the same four-layer approach applied to a workforce dataset.