Formulas That Belong to the Column, Not the Cell

Row 340
Somewhere around row 340 of a long spreadsheet, the formula stops being a formula.
Nobody did it maliciously. Someone was in a hurry, knew the answer, and typed it. The cell now holds 1240 instead of =B340*C340, and it looks identical to every cell above it. The column has been quietly lying ever since, and it will keep lying until somebody audits a total they cannot explain.
This is not a discipline problem. It is a consequence of what a spreadsheet formula is: a value that happens to be computed, stored in a cell, indistinguishable at a glance from a value that was typed. Anything that can be typed over will eventually be typed over — at 11pm, by someone who is right about the number and wrong about the method.
CashSheet Workbooks takes a different position. A formula is a property of the column, not an occupant of a cell. This is what that changes, how it is implemented, and the one real thing it costs.
References by name, not by position
A Workbooks formula looks like this:
={Counted} - {Expected}
You write it once, on the column. Every row computes it. There is no dragging, no fill handle, no $B$4 to remember to anchor, and no row where the pattern silently differs from its neighbours.
The braces are column names, and that is the substantive change. =B340*C340 describes a position: whatever happens to be two columns over. ={Value} * {Count} describes a meaning. Insert a column, reorder the sheet, and a positional formula either breaks or — much worse — keeps working while pointing at something else. A named reference cannot drift that way, because it was never pointing at a location.
The practical effect is that the formula reads like the sentence a person would say. "Over/short is counted minus expected" and ={Counted} - {Expected} are the same statement. Someone who has never used the product can read the column definition and tell you whether it is right, which is not usually true of =IF($D5>0,$D5-$E5,0).
It is a real spreadsheet engine underneath
None of this means a reduced function set. Underneath is HyperFormula, a genuine spreadsheet calculation engine with the Excel-shaped library you would expect: SUM, IF, AVERAGE, ROUND, CONCATENATE and several hundred more.
The translation is mechanical. When a worksheet is evaluated, its rows and columns are laid out as a matrix that mirrors the grid, and each {Name} in a formula is resolved to the ordinary A1-style address of that column on the current row. Column three, row twelve, becomes C12. The engine then evaluates the whole sheet at once and hands back a computed value per formula column per row.
So you get the ergonomics of named references and the behaviour of a spreadsheet. The engine is doing exactly what a spreadsheet engine does; the naming layer sits in front of it.
Errors come back in the same vocabulary too. A formula referencing a column that does not exist evaluates to #NAME?. Divide by zero and you get #DIV/0!. If you have used a spreadsheet, you already know how to read the failure.
The money decision, and the tradeoff we made
This is the part worth reading, because it is where the design had to give something up.
Workbooks stores currency as exact integer cents. $1,234.56 is stored as 123456 — a whole number — which is why a column of ten thousand transactions sums to the penny and why exports tie out against a bank statement. Floating-point money drifts; integers do not.
But there is an obvious problem the moment you write a formula. If a currency cell is 123456 to the machine, then ={Counted} - {Expected} over two currency columns returns a number in cents, and every formula anyone writes has to end in /100. Forget it once and the column is off by two orders of magnitude, which is the kind of error that gets noticed immediately or never.
So the formula layer scales. Currency values are exposed to formulas in dollars — the stored integer divided by a hundred — while storage stays exactly as it was. ={Counted} - {Expected} reads in dollars because that is what a person means when they subtract two money columns. You never write /100, and you never should.
The honest tradeoff: there are now two representations of the same value, and you have to know which one you are looking at. Stored money is integer minor units; formula money is decimal major units. That distinction matters at exactly one boundary — the API, where a currency cell comes back as the integer — and nowhere else. We decided a single documented boundary was better than making every user of every formula perform a unit conversion correctly, forever. We think that is right. It is still a tradeoff rather than a free win, and pretending otherwise would be the kind of thing this blog exists not to do.
What a formula column will not let you do
Three constraints follow from formulas living on the column, and all three are deliberate.
You cannot type over a computed cell. That is the entire point. Row 340 is not available for editing, so row 340 cannot lie. If a computed value is wrong, the formula is wrong, and fixing it fixes every row at once — which is the correct blast radius for a wrong rule.
Automations cannot write into it either. An automation's update-cell action refuses formula, lookup and rollup columns. There is nothing to write; the value is derived. If you want a computed value to change, change its inputs. This catches people exactly once.
It computes per row, not down the column. A formula column answers a question about this row. For questions about many rows — a monthly total, a spend-by-category breakdown — the answer is a group summary or a rollup, not a formula. Group a cash book by month and the bands carry live sums with no formula involved at all. Reaching for a formula to produce a total is usually a sign that grouping is the tool you actually wanted.
The limit: renaming a column
Every article here names one thing the product does not do, and this is the one.
Because formulas reference columns by name, and because that resolution happens when the sheet is evaluated, renaming a referenced column breaks the formulas that reference it. They do not silently compute something wrong — they evaluate to #NAME?, visibly, on every row. But they do not follow the rename either.
The failure is loud, which is the important half. Still, if you rename Expected to Expected cash, go and update the formulas that referenced it. It is a real edge, we would rather you heard it from us than discovered it, and it is on the list to improve.
One more thing, on licensing
A note for anyone who cares about what is inside their tools. HyperFormula is GPL-3.0, and a browser bundle that links it carries distribution obligations. Rather than let that spread through the codebase, every direct import of the engine lives in exactly one package — @cashsheet/sheet-engine — which is GPL-3.0-only and published as source. The rest of the system depends on that package's interface and never on the engine directly, so the GPL surface is precisely one package wide, on purpose, and the obligation is met rather than ignored.
That is not a marketing feature. It is the sort of thing worth knowing about a vendor: whether they bothered.
Try it against a real column
The fastest test is a column you already maintain by hand. Take the one you drag a formula down every month, write it once as ={This} - {That}, and see whether anyone can break it.
Then look at what the AI assistant does with the same formula language — describing a calculation in a sentence and getting a valid formula back is the natural next step once formulas have names instead of coordinates.
Formula columns are on every plan, including Free. Start at app.cashsheet.com.


