Whole-column and whole-row references (B:B, A:C, 1:1, 2:5)

Formulas accept B:B / A:C / $B:$B and 1:1 / 2:5 / $3:$3, also qualified
(Umsatz!B:B, Umsatz::1:1, 'Blatt 2'!Kosten::A:C). The open end is clamped
to the table's current size wherever cells are read (evaluation, the
dependency graph, SETVALUE targets, FOR sources), and typing past the
table's end now rebuilds the workbook so such a reference covers the new
cells. The Name Box selects the whole column/row.

The token-level rewriters handle the new shape: copy/fill shifts B:B only
sideways and 1:1 only up/down ($ stays), column insert/delete moves or
#REFs B:B like a range (rows leave it alone, and vice versa), and a table
rename rewrites its qualifier.

Also fixes renaming a table referenced with a quoted name ('Tabelle 1'!B2):
the rewriter replaced only as many characters as the unquoted name has,
leaving a stray quote (=Daten1'!B2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
wkh
2026-09-28 02:30:08 +02:00
co-authored by Claude Opus 5.5
parent c4d2712903
commit 452f13e774
9 changed files with 343 additions and 12 deletions
+23 -3
View File
@@ -12,7 +12,7 @@ Eine browserbasierte Tabellenkalkulation nach dem Vorbild von **Apple Numbers**.
```bash
npm install
npm run dev # Vite-Devserver
npm run test # Vitest-Suite (Engine + Store + IO), 553 Tests
npm run test # Vitest-Suite (Engine + Store + IO), 566 Tests
npm run build # Typecheck + Produktionsbuild
npm run lint # ESLint (flat config)
```
@@ -744,7 +744,11 @@ namedref = IDENT ; (* ein unqualifizierter,
außerhalb eines
Funktionskörpers *)
reference = [ sheetQualifier ] [ qualifier ] CELL [ ":" CELL ] ;
reference = [ sheetQualifier ] [ qualifier ]
( CELL [ ":" CELL ] | COLPART ":" COLPART | ROWPART ":" ROWPART ) ;
(* B:B / A:C = ganze
Spalten, 1:1 / 2:5 =
ganze Zeilen, s. u. *)
qualifier = (IDENT | QUOTED) ("!" | "::") ; (* Tabellenname *)
sheetQualifier = (IDENT | QUOTED) "!" ; (* Blattname -- nur erkannt,
wenn direkt gefolgt von
@@ -758,6 +762,8 @@ sheetQualifier = (IDENT | QUOTED) "!" ; (* Blattname -- nur erkannt,
IDENT = /[A-Za-z_][A-Za-z0-9_]*/ ;
QUOTED = /' ( [^'] | '' )* '/ ; (* Name mit Leerzeichen *)
CELL = /\$?[A-Za-z]{1,3}\$?[0-9]{1,7}/ ;
COLPART = /\$?[A-Za-z]{1,3}/ ;
ROWPART = /\$?[0-9]{1,7}/ ; (* 1-basiert, ab 1 *)
ERRORLIT = "#REF" | "#DIV/0!" | "#NAME?" | "#ERR" | "#CIRC" |
"#VALUE!" | "#N/A" ; (* ein Fehlercode, direkt
getippt oder von einem
@@ -915,6 +921,20 @@ genau eines. Dieselbe Wahrheits-Semantik wie überall sonst: jede Zahl außer
Funktioniert genauso in einer „Mit Schleife"-`IF`-Bedingung (s. o.), z. B.
`IF AND(x > 0; x < schwelle) THEN … END`.
**Ganze Spalten und Zeilen**: `B:B` (Spalte B), `A:C` (Spalten A bis C),
`1:1` (Zeile 1) und `2:5` (Zeilen 2 bis 5) — auch mit `$` (`$B:$B`) und mit
Tabellen-/Blattnamen (`Umsatz!B:B`, `Umsatz::1:1`, `'Blatt 2'!Kosten::A:C`).
So ein Bezug reicht immer bis zum aktuellen Ende der Tabelle: wächst die
Tabelle (neue Zeilen per Größenänderung oder durch Eintippen unterhalb),
zählt `=SUM(B:B)` die neuen Zellen automatisch mit. Einfügen/Löschen von
Spalten verschiebt `B:B` wie einen Bereich (Spalte vor B eingefügt → `C:C`,
Spalte B gelöscht → `#REF`), Zeilen-Änderungen lassen eine ganze Spalte
unberührt — für ganze Zeilen umgekehrt. Beim Kopieren verschiebt sich
`B:B` nur seitlich, `1:1` nur nach oben/unten, `$`-gesperrte Teile gar
nicht. Steht die Formel selbst in der summierten Spalte/Zeile, ist das ein
Zirkelbezug (`#CIRC`), wie in Excel — das Ergebnis also in eine andere
Spalte bzw. Zeile oder Tabelle schreiben.
**Datum & Zeit**: ein Datum ist — wie in jeder Tabellenkalkulation — intern
einfach eine **Zahl** (Tage seit dem 30.12.1899, Uhrzeit als Bruchteil eines
Tages), keine eigene Zellart. Deshalb funktioniert Datums-Arithmetik ganz
@@ -1112,7 +1132,7 @@ Grundrechenarten: `Übersicht!B2 = =SUM(Umsatz!B2:E2)`, `D2 = =B2-C2`,
## Tests
`npm run test` — Vitest, 553 Tests:
`npm run test` — Vitest, 566 Tests:
- **lexer / parser** — Präzedenz & Assoziativität (`^` vor `*/` vor `+-`, `^`
rechts, `-2^2 = -(2^2)`), lokale/qualifizierte/quoted Bezüge, `!` **und** `::`,