When the spreadsheet is the real system of record, integrate it
Migrating the finance model into the warehouse usually stalls. Landing the file as a governed source is faster, with a clear line for when it stops being enough.
The finance lead opens a workbook every Monday morning. It has more tabs than anyone has ever counted. One of them is the driver sheet, and someone renamed a column last quarter without telling anyone, which broke a lookup further down the file that nobody noticed for weeks. This file decides the hiring plan. It decides what gets said to the board. Nothing in the warehouse comes close to it in influence, and nothing in the warehouse knows it exists.
The standard data-team response to this is a migration project. Move the logic into dbt, retire the file, give everyone a dashboard. It is proposed with confidence and it fails more often than it succeeds, because the failure mode is not technical. The workbook changes weekly. The finance lead adds a scenario on a Tuesday afternoon because a supplier called. A warehouse model where every change needs an engineering ticket and a review cycle cannot serve a process that reshapes itself in twenty minutes.
So the sensible move, most of the time, is to stop treating the spreadsheet as an enemy and start treating it as a source system. Not a blessed one. Not a permanent one. A source, with the same expectations you would place on any other: it lands on a schedule, it arrives in a known shape, and when it does not, someone finds out before the numbers reach a meeting.
Why the file wins, and keeps winning
It is worth being precise about what a spreadsheet is good at, because the usual framing treats it as laziness and it is not. A workbook gives one person end-to-end control of a model with no deployment step, no review queue and no dependency on a team with its own backlog. The feedback loop between a thought and a result is measured in seconds. No governed platform matches that, and the ones that claim to are usually a governed platform with a spreadsheet grafted onto the front.
It is also worth being precise about what it is bad at. There is no history, so a number cannot be explained after the fact. There is no test, so a broken formula produces a plausible answer rather than an error. There is no lineage, so nobody can say which inputs a figure depends on. Access control is whoever has the link. Two people editing means two versions of the truth, and the reconciliation meeting that follows is where a great deal of professional-services time quietly goes.
The problem was never that finance used a spreadsheet. It was that the spreadsheet had no arrival gate.
The pattern, stated plainly
Treat it as a source, not a sin
The integration pattern is not complicated, and most of the work is social rather than technical. You are asking one team to accept a small amount of discipline about where a file lives and what its headers are called, in exchange for their numbers appearing alongside governed data instead of being argued with.
- 01Give the file one homeOne path, one owner, one filename that does not carry a date or the word final. If it lives in SharePoint or Drive, fine, but it lives in exactly one place and the copy on someone's desktop is not it.
- 02Split inputs from logicAsk for one tab that is a flat rectangle: header row, no merged cells, no blank spacer columns, no subtotals mixed into the body. The rest of the workbook can stay as baroque as it likes. You are only reading the rectangle.
- 03Land it on a scheduleA small job pulls the file, reads the rectangle and writes it to a raw table in Postgres or as a Parquet file. DuckDB will read an Excel sheet or a CSV directly and is more than enough for this class of job. Keep every version you land, keyed by load timestamp. That is your history, and it costs almost nothing.
- 04Validate on arrivalColumn names present, types coercible, primary key unique, row count inside a sane band, totals reconciling to a control figure the owner already trusts. If a check fails, the load stops and the owner hears about it, not the CFO in a meeting.
- 05Model it like anything elseFrom that raw table onward it is ordinary dbt work. Staging model, tests, documentation, joins to the governed dimensions. Downstream, in Power BI or wherever the reporting lives, nobody can tell the difference between a figure that came from the ERP and one that came from the workbook, which is the entire point.
What a data contract means when the counterparty is a person
Data contracts get discussed as though both sides are services. Here one side is a colleague who did not ask for any of this, so the contract has to be small enough that keeping it is easier than breaking it. In practice that means a named owner, an agreed set of column names on the input tab, a promised cadence, and a stated rule for what happens when a check fails.
The rule matters more than people expect. If a failed validation means the pipeline halts and yesterday's figures remain visible with a clear staleness marker, the arrangement survives. If a failure means the dashboard silently shows partial data, trust goes and the workbook owner goes back to emailing screenshots, correctly concluding that their file was more reliable on its own.
Two extra pieces earn their keep. Keep the landed snapshots so a number in last quarter's board pack can be reproduced from the version of the file that existed on that date. And add one reconciliation check that the owner already computes themselves. If your model agrees with their control total, the argument is over before it starts.
The line, which is the point of the piece
None of the above says spreadsheets are fine forever. There is a line, and it is not about size or complexity. It is about who is downstream of the number.
While the workbook feeds internal decisions, a wrong figure produces a bad decision that gets corrected when reality disagrees. That is a survivable cost, and the speed of the file is usually worth it. Once the workbook feeds statutory reporting, a regulator, an audit, an investor deck or a customer-facing figure, a wrong number produces a consequence that no amount of speed compensates for. At that point the logic needs review before change, a test suite, an approval trail and an author who is not also the approver. A spreadsheet can be made to do some of that. It cannot be made to do it cheaply, and the workarounds people build to try are usually worse than a migration.
- Integrate The model changes weekly, the audience is internal, the owner is close to the decision, and the value is in the speed of iteration.
- Migrate The logic has been stable for several quarters, more than one person needs to change it, or the output crosses a boundary where being wrong has a formal consequence.
- Neither, for now Nobody has opened the file in months and it is being kept alive out of politeness. Retire it and see who complains. Usually nobody does.
The failure worth avoiding is proposing migration by default. It reads as a data team asserting territory, it lands as a threat to the person who built the model, and it usually stalls halfway with the warehouse holding a stale copy of logic that has since moved on in the file. The workbook wins that standoff every time, because it is the thing that answers the question this week.
The uncomfortable version
There is a version of this that goes badly, and it should be said out loud. Integrating a spreadsheet legitimises it. Once the numbers flow into governed reporting and look like every other tile on the dashboard, the pressure to ever move the logic drops to zero, and years later you have a load-bearing workbook with a single human dependency and no test coverage feeding decisions it was never meant to reach.
The defence is to write down the line when you do the integration, not later. Agree in advance which change in audience triggers a migration, and put a date on the next review. That is not much of a control, but it is honest, and it beats the alternative of pretending the file will be gone by the end of the quarter.
The realistic goal is not a world without spreadsheets. It is a world where every spreadsheet that matters is versioned, validated on arrival, joinable to governed data, and owned by someone who knows they own it. That is achievable in weeks. A migration that removes the file entirely takes months and, in a fair number of cases, should not be attempted at all.