Skip to content

Keep constant error cells from an opened .xlsx, report them, write them back (#227) - #229

Merged
SuruchBoss merged 3 commits into
mainfrom
claude/new-session-m6mehm
Oct 4, 2026
Merged

SuruchBoss merged 3 commits into
mainfrom
claude/new-session-m6mehm

Conversation

@SuruchBoss

Copy link
Copy Markdown
Owner

What this changes

Closes #227. Queued right after #222, before #207.

The bug: a constant error cell, which Excel writes as <c t="e"><v>#DIV/0!</v></c> with no formula, opened blank, and nothing said so. cellValueToRaw in excelIO.ts had no branch for ExcelJS's { error } value, so it fell through to "". A total over it then came out as a clean number: =SUM(A1:A3) over #DIV/0!, #N/A, 5 read 5.

The fix (the minimum #227 asks for, until #226):

For PO: export changes for typed codes too

Writing the codes back as text was the smaller change, but it breaks the file in Excel itself. Open → export, and the file's own =SUM(A1:A3) now reads 5 in Excel too, because #DIV/0! has become text. So export writes error values.

That also covers a code someone types in the app: #N/A typed into a cell used to export as the text #N/A, and now exports as the error. That is what Excel does with #N/A typed into a cell, and what #226 will do in the grid too. The way to keep it as text is the same as in Excel: an apostrophe ('#N/A) or the Text format. Only the exact spelling is matched (#n/a stays text). I have not checked whether Excel accepts other spellings, so I did not guess.

If you'd rather typed codes keep exporting as text until #226, the alternative is to remember which cells came in as errors. That is a new field on the sheet model, and it would have to survive saving, undo and copy. I don't recommend it for a step #226 replaces anyway.

Reproduced on main first

A file written the way Excel writes it (the test checks the XML is t="e" with no <f>):

Cell In the file main after opening this PR after opening after export, in the file
A1 constant #DIV/0! blank #DIV/0! (text) t="e" #DIV/0!
A2 constant #N/A blank #N/A (text) t="e" #N/A
A3 5 5 5 5
A4 =SUM(A1:A3) 5, nothing said 5, and the report says why the formula
Open report nothing "2 cells hold an error value such as #DIV/0! or #N/A · sheet "ยอดขาย""

SUM still reading 5 in the app is #226's to fix; this PR makes it visible and keeps the file whole.

How it was verified

  • npm run verify (all ten gates): all ten gates green on 4088021 (the current head), result below
  • excelIO.test.ts (+3):
    • a real t="e" cell opens as its code, not blank;
    • it exports back as t="e" and is still there on a reopen;
    • '#N/A and a Text-formatted #N/A export as text, #REF! typed as Excel spells it exports as the error, and #n/a stays text.
  • fileLosses.test.ts (+2):
    • two constant errors on one sheet are reported with that sheet, and a formula erring on another sheet is not;
    • the same count after the file goes out of the app and back in.
  • Re-checked against the old code: on 03aa574 all five new tests fail (the importer gives "", export has no t="e", the report is empty). The first assertion, that the test file really holds t="e" with no formula, passes on both.
  • Both READMEs: a row in the "Told up front what a file can't keep" table, a bullet on what export does with error codes, the module map and the two test-file rows.
  • Recounted after merging main 5439196:
    • 1979 tests in 140 files (1974 on main plus this PR's 5);
    • picture 27 retaken in both languages and checked by eye, blessed after the retake;
    • social card rebuilt and checked by eye.
  • Tried on a production build of this branch (1280, both languages): the file above opens with A1 #DIV/0! and A2 #N/A in the grid instead of blank, A4 still reads 5 (An error code typed, pasted or imported into a cell stays text, so formulas that read it go silently wrong #226), and the report shows the new line with its sheet, in Thai and in English. No page errors.
Gate Result
lint · check:readme · check:screens pass
check:deps every advisory fixed or accounted for
test 1990 passed (1979 by the README's static count)
check:mutants 32/32 killed
build · check:bundle 3799/4200 KB, largest chunk 934/1300 KB
check:a11y 119 checks passed
check:e2e 57 flows passed

Anything reviewers should look at closely

🤖 Generated with Claude Code

https://claude.ai/code/session_013pmWZsbmugfpqtYazrzfjj


Generated by Claude Code

claude added 3 commits October 4, 2026 15:28
…em back (#227)

An error cell with no formula (<c t="e"><v>#DIV/0!</v></c>) opened blank because the
importer had no branch for ExcelJS's { error } value, and a SUM over it came out as a
clean number with nothing said.

- excelIO: cellValueToRaw keeps the code as text (an error value once #226 lands).
- excelIO: an exact Excel error code goes out as an error value, as Excel stores it,
  so a file that held #DIV/0! still reads #DIV/0! in Excel after a round trip. An
  apostrophe or the Text format keeps it text.
- fileLosses: a new 'errorValues' kind counts constant error cells per sheet from the
  package; a formula whose result is an error is not counted, since it recalculates.
- Both READMEs and both languages of the report.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013pmWZsbmugfpqtYazrzfjj
…140 files

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013pmWZsbmugfpqtYazrzfjj
@vercel

vercel Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
excel-to-go Ready Ready Preview Oct 4, 2026 4:30pm UTC

@SuruchBoss
SuruchBoss merged commit 5d28538 into main Oct 4, 2026
18 checks passed

Copy link
Copy Markdown
Owner Author

PO review — merged at 4088021 (main 5d28538).

Verify (local, full): green — 1990 tests, mutants 32/32 killed, a11y 119, e2e 57. CI 17/17 green on the same head.

Tried as a user on a production build (errs.xlsx: A1 #DIV/0! and A2 #N/A as constant t="e" cells, A3 5, A4 =SUM(A1:A3)):

  • 1280 and 390: A1/A2 show their codes instead of blank, the open report lists "2 cells hold an error value" on sheet "Errs" with the detail line, no page errors, no alerts. At 390 the report fits and reads cleanly.
  • Export → read back with ExcelJS: A1/A2 are {error} again, A4 keeps SUM(A1:A3), B1 untouched.
  • Typed in the app: #N/A exports as {error:"#N/A"}, '#N/A stays text, #VALUE!x stays text.
  • Re-opening the exported file: codes back, report counts 3 (A1, A2 and the typed C1).
  • A plain file (hours.xlsx) opens with no report.
  • Known limit, as agreed and tracked in An error code typed, pasted or imported into a cell stays text, so formulas that read it go silently wrong #226: A4 reads 5 in the app where Excel reads #DIV/0!.

The two decisions asked for:

  1. Typed #N/A now goes out as an error value — accepted. That is what Excel does with a typed #N/A, and the apostrophe / Text format escape still keeps text text. The in-app reading catches up in An error code typed, pasted or imported into a cell stays text, so formulas that read it go silently wrong #226.
  2. The report's intro ("…if you export and save over the original, some of them won't be kept") overstates when the only kinds listed are kept on export (error values now, unknown functions already). Not blocking: the detail line under each item says exactly what happens. Opened as a small follow-up so the intro only promises a loss when a listed kind is actually lost.

Next in the queue: #207 → #226 → #224.


Generated by Claude Code

This branch was successfully deployed

1 active deployment
Preview — 40880219 Deployed Oct 4, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Opening an .xlsx drops constant error cells to blank, and totals that read them come out as clean numbers

2 participants