Almost every compliance function keeps a spreadsheet, including the ones with a perfectly good LMS. It's worth understanding why, because the reason explains what a replacement actually has to do.
Why the spreadsheet exists
It isn't usually distrust of the system. It's that the system answers a different question.
An LMS dashboard reports that 94% of the organisation completed security awareness training this year. What compliance needs to answer is: did this named person complete this specific version of this policy, on what date, and can you produce it in a form someone outside the company will accept.
Those aren't the same question, and the second one is often several clicks and an export away — or genuinely unavailable if the system overwrites records on re-run. So someone starts a spreadsheet, and from that moment the real record and the system diverge.
What a defensible record contains
If you're replacing the spreadsheet, the replacement needs all of this:
- The person, named, unambiguously — not a count.
- The specific course or policy, ideally versioned, so you can show which text they agreed to.
- A timestamp, not a date bucket or a quarter.
- The outcome, if there was an assessment — passed, and ideally the score.
- Export, because the request usually comes from someone without access to your tools.
- History, retained rather than overwritten when the training runs again next year.
That last one catches people out. Annual compliance training that overwrites last year's completion leaves you unable to demonstrate coverage for the period an auditor is actually asking about.
The test worth running
Pick a person and a policy at random. Time how long it takes to produce a record showing they completed it, and when.
If it takes more than a minute, or involves asking someone, or involves the spreadsheet — the tracking hasn't replaced anything. This test is cheap and it's much better to fail it on a Tuesday than during an audit.
Fix the enrolment problem too
Tracking is only as good as the denominator, and the denominator is where compliance gaps actually hide.
If people are enrolled individually, someone who joined during a busy month simply isn't in the population. Completion reads 100% while a genuine gap exists — the most dangerous reporting error available, because nothing looks wrong.
Assigning to a channel, a group, or everyone who joins from a date forward keeps the population correct without anyone maintaining it. Any replacement for the spreadsheet has to solve this as well, or you've just automated an incorrect number.
Make it visible rather than chased
The other reason spreadsheets persist is chasing. Someone owns the number, so someone chases individuals, which is slow and unpleasant and gets deferred.
Team-level visibility works better. A manager who can see that three of their eight people haven't finished will usually close it with one message. That only happens if the number is somewhere they already look rather than in a report they'd have to run.
What this looks like in practice
Poplearn records completion as it happens, because modules are delivered as Slack direct messages and completed in place — there's no separate system to reconcile against.
/progress returns live completion by team and exports on demand, as a per-person timestamped record rather than an aggregate. /assign #support targets a person, a channel, or every new hire from that point on, so the population stays correct without maintenance.
Free under 20 seats, installs in about a minute. Then run the test above and see whether you still need the spreadsheet.

