HR Utilities
← All tools

Training Compliance Matrix

Everybody against every required course, with renewals applied, and the number an auditor actually asks for: how many people are fully compliant.

Reads your roster and your LMS export, as .xlsx or .csv, inside your browser. Nothing is uploaded.

The roster

Drop a spreadsheet here

Everybody who should be trained, from the HRIS. IDs, and ideally department, hire date and end date.

The completions

Drop a spreadsheet here

The LMS export: one row per completion, with the person's ID, the course, and the date.

95% complete, and a third of your people out of compliance

The completion rate on an LMS dashboard is counted per assignment: every person, every course, one tick each. Compliance is counted per person. Give everybody eight required courses and a 95% completion rate can still leave a third of the workforce missing at least one, because a small gap in each course lands on a different person each time.

Both numbers are true. Only one of them answers the question somebody asks when it matters, so the tool shows both, side by side.

A completions export counts “completed” forever

Somebody who did the annual course fourteen months ago shows as complete on a plain completions report, which is what most LMS exports are. The completion happened; it just stopped counting two months ago. So a third number sits between the other two: what is still current once each requirement’s renewal period is applied. Courses lapsing in the next month are flagged separately, because they are the ones worth a reminder now.

Two files that disagree about who somebody is

The roster comes from the HRIS and the completions from the LMS, and they rarely store an ID the same way. Employee 00123 in one is 123 in the other, because somebody opened the file in a spreadsheet. Leading zeros, case and spacing are ignored when matching.

A person with no training record at all is flagged rather than simply scored as a failure, because that is more often a matching problem than somebody who has never been trained. The tool asks you to check before anybody is chased. IDs in the LMS that match nobody on the roster are listed too.

Course titles carry years and versions

“Harassment Prevention 2025” and “Harassment Prevention (2026 Refresh)” satisfy the same requirement. Titles that differ only by a year, a version number or words like refresher are offered as one requirement, with every title that counts toward it listed. If one of them is really a different course, split it.

New starters, leavers, and who needs what

Somebody who started last week is not out of compliance, so new starters get a grace period before a missing course counts, and until then they are left out of every rate. People with an end date are left out entirely. A requirement can apply to everybody or only to certain departments, sites or roles, whatever column your roster has.

What this does not do

It does not know which training the law or your policy requires, how often any of it must be renewed, or who it applies to. You set those, and the tool tracks against exactly what you set and lists it in the report. It is a matrix, not advice.

The download that matters most is the to-do list: every gap and every course due soon, one row each, ready to send. For the ID mismatches behind a large no-record count, the Spreadsheet Merger shows exactly which IDs fail to line up and why.