CAP 2791C Final Project · Power Query and data modeling

Florida Licensed Drivers, 2006–2026

21 annual PDFs in three layouts, turned into one Power BI model: a handover to the colleague who maintains it next

Power BI: Data Preparation · Miami Dade College · Fall 2026

Part 1 · The business problem

One PDF a year for 21 years, and no table to download

21
Annual reports, 2006–2026
Published by FLHSMV, the state motor vehicle department: licensed drivers by county, age bracket and sex
3
Table layouts
The layout changes twice over the 21 years, so one set of query steps cannot read every file
43,080
Rows in one table
Year, county, age bracket, sex and drivers; a full refresh takes about a minute
Insurerspricing young drivers by county
Countiesplanning where to open a service office
Driving schoolssizing their local market

Part 1 · The data

The same table, printed in three layouts

2006–2011, 2018
Wide
Ages across the columns; the county is printed on the F row only
CountySex1516…
AlachuaF583959…
nullM572933…
2012–2017
Stacked
F and M rows sit under each county's total row
County1516…
Alachua………
F………
M………
2019–2026
Long
One row per county and age, Female and Male side by side
CountyAgeFemaleMale
Alachua CountyAge 15612565
Alachua CountyAge 16922855
2Sourceparameters and SourceFiles
3–4Parseone parser per layout
4CheckQA Reconciliation
5Modelstar schema and measures
Part 2 · Data source

One parameter, one source

Part 2 · Parameters

Change one value to move the project or switch the source

Parameters - Source Path
SourcePath the start of the path to the PDFs
...\final-project\data\→ local copies, offline https://www.flhsmv.gov/pdf/driver-vehiclereports/→ the original source
Parameters - File Names
File_2006countysexage2006.pdf
File_2007countysexage2007.pdf
⋮
File_20262026annuallicenseddriverreport.pdf
21 parameters, one per year; the names are the same in both places
Manage Parameters dialog with SourcePath selected: type Text, required, with a description naming the local folder and the FLHSMV web folder.

Part 2 · Staging

SourceFiles turns 22 parameters into one table

SourceFiles with SourcePath set to the FLHSMV web folder: 21 rows with year, file name, layout, binary content and source URL.
Here SourcePath points at the FLHSMV web folder; Source Location shows where each year was read from.
21
rows, one per report year
1
data source: Web.Contents for http, Folder.Files otherwise; no firewall errors
Public
privacy level for flhsmv.gov, asked once on the first web refresh
Layout
column that picks the parser for each year
Part 3 · Parsers

The long and wide layouts

Part 3 · Long layout, 2019–2026

The long parser is the class ADA query, made general

Sample Long 2026 at the Renamed Columns step: County, AgeBracket, Female, Male and Total columns; Applied Steps on the right.
Sample Long 2026 in the Walkthrough group: the same steps as fnParseLong, on one PDF.
Two filters replace one year's list of title and total labels, so the steps work for every year: Column3 = "Female" and AgeBracket does not contain "to".
14
steps, all ribbon commands except the year column
2019–2025 read the accessible _ada files. In the wide 2020 and 2021 files, the PDF connector merges the page header into the first row of each page, and that row's numbers are lost.

Part 3 · Wide layout, 2006–2011 and 2018

Fill Down and Unpivot turn fifteen age columns into one

1 / 4 · Expanded Data

The PDF table as Power Query reads it: the county is printed on the F row, with null on the M row.

Expanded Data step of Sample Wide 2006.
2 / 4 · Promoted Headers

Remove Empty drops the title; Use First Row as Headers turns the age brackets into column names.

Promoted Headers step: columns County, Sex, 15, 16 and so on.
3 / 4 · Filled Down

Fill Down copies each county onto its M row.

Filled Down step: every row carries its county; the formula bar shows Table.FillDown.
4 / 4 · Changed Type with Locale

Unpivot Other Columns, Replace Values (the dash printed for zero, F and M spelled out) and the type change: one row per county, sex and age bracket.

Final step of Sample Wide 2006: columns County, Sex, AgeBracket, Drivers and Year.
Part 4 · Parsers and checks

Stacked layout, hand edits, reconciliation

Part 4 · Stacked layout, 2012–2017

A conditional column rebuilds Sex and County

Sample Stacked 2012 at Added Conditional Column1: county total rows followed by F and M rows.
Each county's total row, then its F and M rows. The formula bar shows the conditional column that keeps the county name on total rows; Fill Down then spreads it.
21
steps in fnParseStacked
2
conditional columns: Sex from F and M, County from the total rows
Remove Errors
drops the header that repeats on every page of the 2017 report

Part 4 · Hand edits

At most three steps per parser are typed by hand

ParserYearsStepsTyped by hand ("M edit")
fnParseLong2019–202614the year column
fnParseWide2006–2011, 201819rename by position; label the statewide row; the year column
fnParseStacked2012–201721rename by position; 2012 "21-30" to "22-30"; the year column
Each hand edit is marked "M edit" in the step's description (the info icon in Applied Steps). Change a step in the sample and in the function.
Replaced Value2 in Sample Stacked 2012: the formula bar wraps Table.ReplaceValue in if ReportYear = 2012 then ... else.
The 2012 column printed as 21-30 holds ages 22 to 30, so this one-line edit relabels it in 2012 only.

Part 4 · Quality check

All 21 years reconcile to zero

QA Reconciliation in Table view: for each year 2006-2026, the sum of county detail equals the published statewide total; difference 0, status Reconciled.
QA Reconciliation in Table view. Check it after every refresh.
21 of 21
years where the county rows add up to the statewide total printed in the PDF
69 → 68
counties: the Unknown line ends after 2013; any other count means a split or blank name
Part 5 · Data model

The model, and adding a year

Part 5 · Star schema

One fact table, three dimensions

Model view: Licenses related many-to-one to Year, County and Age Bracket; QA Reconciliation has no relationships.
TableRoleRows
Licensesfact: year, county, age bracket, sex, drivers43,080
Yeardimension, with source file and bracket scheme21
County67 counties, Out of State, Unknown69
Age Bracketevery bracket as published28
QA Reconciliationstandalone check21
The dimensions are built from the fact table in Power Query, so a new county spelling or bracket appears as a new row.

Part 5 · Age brackets

Three bracket schemes; Age Group compares all 21 years

YearsBrackets above age 20
2006–2012single years to 21, then 22–30
201321–30
2014–202621–29

Above 20 the schemes cannot be mapped onto each other. Every bracket stays as published, and Age Group holds the only groups identical in all years:

15–17
18–20
21+
Age Bracket table: 28 brackets with minimum and maximum age, age group, and first and last year used.

Part 5 · Measures

Each report is a snapshot: Licensed Drivers takes the latest year

Licensed Drivers =
VAR LatestYear = MAX ( 'Year'[Year] )
RETURN
    CALCULATE ( SUM ( Licenses[Drivers] ), 'Year'[Year] = LatestYear )

Florida County Drivers =
CALCULATE ( [Licensed Drivers], 'County'[Is Florida County] = TRUE () )

Seven measures in two display folders: Drivers (Licensed, Female, Male, Florida County) and Change (Prior Year, YoY Change, YoY Change %).

849,151 → 73,144
Out of State, 2022 to 2023: the reports changed how that line is counted
14.6 → 18.7 M
licensed drivers in Florida counties, 2006 to 2026

Part 5 · Maintenance

Adding 2027 takes four steps

  1. Save the 2027 PDF into data\under the file name FLHSMV publishes
  2. Add File_2027 to Parameters - File NamesManage Parameters, New, type Text
  3. Add one row to SourceFiles{2027, File_2027, "Long"}, or "Wide" or "Stacked" if the layout changes again
  4. Refresh and open QA Reconciliation2027 should read Reconciled with 68 counties; new county spellings go into CountyAliases

Conclusion

What you are taking over

  • 1One value to change. SourcePath switches between the local copies and the FLHSMV website.
  • 2Three parsers from ribbon steps. Each has a Walkthrough sample to click through, with at most three hand edits.
  • 3A check after every refresh. All 21 years reconcile to the statewide total printed in each PDF.
  • 4A star schema. Snapshot measures, and an Age Group that compares across all years.
  • 5A new year in four steps. One PDF, one parameter, one row, one check.

Thank you. Questions?