Skip to content

Sheet names: quote R1C1 tokens, leading dots and cell names like Excel (#1458) - #2

Draft
isaac-levine wants to merge 416 commits into
mainfrom
fix-sheet-name-quoting
Draft

isaac-levine wants to merge 416 commits into
mainfrom
fix-sheet-name-quoting

Conversation

@isaac-levine

Copy link
Copy Markdown
Owner

Excel quotes a sheet name in a reference when the bare name could be read as something else. GridCraft had three separate rules for this (formula printer, pivot code, ADDRESS) and none matched. A sheet named .x was saved as .x!A1, which Excel 365 cannot open. Names like R1C1 or RC were left bare in formulas, and A1 was left bare in pivot sources and ADDRESS.

This adds sheet_needs_quotes and quote_sheet to gridcraft_core::addr. They quote a name that starts with a digit or ., holds characters other than letters, digits, _ and ., reads as an in-bounds A1 cell or an R1C1 token, or is TRUE/FALSE. The formula printer, engine::pivot::quote_sheet and ADDRESS now call it. ADDRESS keeps TRUE/FALSE bare, as Excel does.

I did not do the rest of the issue: the places that strip quotes again (split_sheet copies, the Name Box, Go To) are untouched. That part is a follow-up.

Commands run:

  • cargo fmt --all -- --check: clean
  • cargo clippy -p gridcraft-core -p gridcraft-formula -p gridcraft-functions -p gridcraft-engine --all-targets -- -D warnings: clean
  • cargo test -p gridcraft-core -p gridcraft-formula -p gridcraft-functions: all pass
  • cargo test -p gridcraft-engine: all pass
  • cargo xtask layers: OK, no violations
  • cargo xtask wasm: ok

Not verified: I did not run cargo xtask ci as a whole, did not run the xlsx or ui-egui tests, and could not check against Excel. I added no command, so I did not run cargo xtask parity. The issue mentions open PR storytold#829 also editing needs_quotes, so that may conflict. I could not read the issue comments from this sandbox.

Upstream issue: storytold#1458


Generated by Claude Code

neilcawse and others added 30 commits October 12, 2026 20:51
GridCraft imports XLSB (storytold#101) and ODS (storytold#100) files, and storytold#321 added both
to the Linux and Windows "Open with" lists, but the macOS Info.plist
still declared only .xlsx, .xlsm, .csv and .tsv, so Finder's Open With
didn't offer GridCraft for them. Add two CFBundleDocumentTypes entries
(Editor, rank Alternate) with the UTIs macOS reports for these files,
plus an imported UTI for .xlsb like the .xlsm one. A test now checks
that the macOS and Windows packaging offer the same file types.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A legacy array formula in a .xls file ({=FREQUENCY(...)}, {=TREND(...)}) is
stored as one ARRAY record plus a FORMULA record per cell of its range, each
with the cached result. The importer attached the formula to the anchor cell
but kept the cached values in the other cells as plain constants. On
recalculation the formula then found its range occupied and returned #SPILL!.
The .xlsx reader already drops those cached results; the .xls reader now does
the same once the formula is attached, and keeps the values when the formula
could not be imported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Following Excel's AutoFill series:
- a single time steps by an hour (9:00, 10:00, 11:00); it was copied.
- Qtr3 and Quarter3 wrap after 4 like Q3; they counted on to Qtr5.
- 1st Period continues as 2nd Period, 3rd Period; it gave 2st, 3st.
- a source without a common pattern (Product 1, On backorder) continues
  each cell's own series; it was copied as is.
A growth series with a step below 1 stopped at once when given a stop
value, since the stop was only checked for rising series. It now bounds
the series in the direction it runs.
A formula such as =A1+A2+…+A500 nests one level per operator, and the
evaluator recursed once per level, so past its depth limit (about 400
operators) the result was #CALC!. Excel allows such formulas up to its
8,192-character limit. Chains of arithmetic, comparison and & operators
are now folded in a loop.
home.manageRules took the number of rules once, before deleting, so
{"delete":0,"moveUp":1} with two rules swapped past the end of the
shortened list and panicked (index out of bounds; the session's guard
kept the workbook). The count is now taken after each step.
Merge & Center and Merge Cells kept only the upper-left value, but
Merge Across left the other values of each row in place, hidden under
the merge and still counted: with 1 2 / 3 4 in A1:B2, SUM(A1:B2) stayed
10 after Merge Across, where Excel gives 4. Each row's merged area now
keeps only its first value, as the other merges do.
 storytold#864)

[@col] is only Excel's display shorthand. Written verbatim into cell formulas and calculatedColumnFormula, it made Excel repair the file and drop the tables.
…part

Business Central's "Open in Excel" exports write booleans as
<c><f>TRUE()</f><v>1</v></c> with no t="b", so the cached value reads back
as the number 1 and the calc oracle reported every such cell as a
`number → bool` mismatch. A cached 1 or 0 now matches GridCraft's TRUE or
FALSE, and the cells are counted apart (`boolAsNumber` in --json, a note in
the text report) so a real number/logical disagreement stays visible.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
echelon and others added 30 commits October 13, 2026 01:06
# Conflicts:
#	crates/ui-egui/src/grid.rs
#	crates/ui-egui/src/tabs.rs
#	docs/ui-parity.md
…r track; drop the unused Color32 import

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	crates/ui-egui/src/dialogs.rs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	docs/ui-parity.md
# Conflicts:
#	crates/ui-egui/tests/interaction.rs
# Conflicts:
#	crates/xlsx/src/tests/passthrough_tests.rs
Brings the branch up to upstream's main (59 more commits). One conflict:

- docs/ui-parity.md: every line of both sides is kept, as upstream's own
  merges keep them, in the order of their dates, newest first (upstream
  has a change of the 13th now, which goes above this one of the 12th).

Gate: all eight steps, 1580 tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	ROADMAP.md
#	docs/gaps.md
#	docs/target-app-parity.md
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: skylartaylor <26588250+skylartaylor@users.noreply.github.com>
storytold#1458)

One quoting rule lives in gridcraft_core and the formula printer, the pivot source text and ADDRESS use it.
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.

8 participants