The Quiet Loop
Worked problem · accounting data09 of 09

The balanced report that is completely inverted

A report omitted a column on rows where it had no value, so reading cells by position moved every credit into the debit column — and the report still footed correctly.

An extraction that produces a report which balances is not thereby correct. It may be balanced and inverted at the same time.

The situation

A structured export from an accounting system, read programmatically into a comparison against a second source. The extraction ran cleanly, produced a row for every account, and the resulting totals balanced.

The comparison it fed nevertheless disagreed with the second source on a large number of accounts, in a way that looked like widespread miskeying rather than a technical fault.

The pattern

The export format identifies each cell with a column identifier rather than relying on order. On rows carrying values in every column, identifier order and physical order coincide, so reading positionally appears to work.

On a row that has no value for a column, that column is not emitted at all. It is absent, not empty. Every subsequent cell on that row therefore shifts one place to the left.

The consequence is specific and severe: on every row with a value in only one of the two paired columns, that value lands in the wrong one. A credit is read as a debit. Because this happens consistently to one whole class of row, the extraction produces a set of accounts whose sign is systematically inverted.

And the report still foots. The values are all present, all correct in magnitude, and the totals that were computed from the source rather than from the extraction remain right. Every internal check passes. There is no error, no warning, and no row count discrepancy — the only symptom is a downstream comparison that disagrees more than it should, which is easily mistaken for a data quality problem in the other system.

Two controls follow.

Place every value by the identifier the source declares, never by its position. This costs almost nothing to implement and eliminates the entire class of fault. Positional reading is an assumption about the data that the format explicitly declines to guarantee.

Keep the raw export alongside the parsed output. Report layouts vary between versions and editions of the same system, and a row an extractor misinterprets is a row silently missing from whatever it feeds. Retaining the source is what makes the fault investigable at all; without it, the only evidence is a disagreement with no way to establish which side is wrong.

Engineering takeaway — Place extracted values by the column identifier the source declares, never by position, and retain the raw source next to the extraction. A result that balances proves the arithmetic, not the reading.

More on bank statement data extraction

Send us the problem

Send us the problemThe files, or a sample. We reply in writing within one working day.