Tabellen-Umbenennung schreibt Referenzen dokumentweit um

Bisher speicherte eine Formel den Tabellennamen nur als Text im
Qualifier ("Umsatz!B2") – beim Umbenennen der Tabelle wurde nirgendwo
danach gesucht, sodass jede andere Formel, die noch den alten Namen
nannte, beim nächsten Neuberechnen #REF zeigte.

renameObject() ruft jetzt vor der eigentlichen Umbenennung eine neue
renameDocumentRefs()/rewriteRefsForRename() auf, die dieselbe
Token-Splice-Technik wiederverwendet, die für das dokumentweite
Umschreiben bei Zeilen-/Spalten-Einfügen bereits existiert: jede Formel
im Dokument wird tokenisiert, jeder Qualifier über die echte
wb.resolveTableName-Auflösung (nicht per String-Vergleich) auf die
umbenannte Tabelle geprüft, und nur die Tabellen-Namens-Textspanne
ersetzt – bei der 3-teiligen "Blatt!Tabelle::Zelle"-Form bleibt der
Blatt-Teil unangetastet, ein neuer Name mit Leerzeichen wird korrekt
gequotet. Umbenennen + Umschreiben zählen als ein Undo-Schritt.

Bewusst auf Tabellenzellen begrenzt, wie schon beim Zeilen-/Spalten-
Umschreiben (keine Makro-Aktionen, keine Funktionskörper).

Live per Playwright verifiziert: "Umsatz" per Doppelklick zu "Verkauf"
umbenannt, =SUM(Umsatz!B2:E2) in einer anderen Tabelle wurde automatisch
zu =SUM(Verkauf!B2:E2), Wert blieb unverändert (kein #REF).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
wkh
2026-09-09 12:10:23 +02:00
co-authored by Claude Sonnet 5
parent 3ae3d81066
commit 47c99bbeb6
3 changed files with 304 additions and 13 deletions
+41 -7
View File
@@ -206,9 +206,11 @@ eingebauter Funktionsname: `=MARGE(Umsatz!B2; Umsatz!C2)`.
Name/Parameter, ein nicht parsender Formelkörper, und ein **Funktions-
Zyklus** (A ruft B, B ruft A, auch über mehrere Stufen) — wird abgelehnt,
bevor je eine `#ERR`-Zelle entsteht.
- **Umbenennen/Löschen** aktualisiert **keine** bestehenden Formeltexte —
genau wie beim Umbenennen/Löschen einer Tabelle. Zellen, die die
betroffene Funktion aufrufen, zeigen danach `#NAME?`.
- **Umbenennen/Löschen** aktualisiert **keine** bestehenden Formeltexte.
Zellen, die die betroffene Funktion aufrufen, zeigen danach `#NAME?`.
Anders als bei einer **Tabelle** (s. u. „Referenzen bleiben nach dem
Umbenennen konsistent") — eine Funktion hat keine Referenz-Syntax, die
sich automatisch umschreiben ließe, nur ihren Aufruf-Namen.
- Ein Aufruf wird **beim Parsen der aufrufenden Zelle in ihre AST eingesetzt**
(Inlining, keine Laufzeit-Closures) — siehe
[`src/engine/userFunctions.ts`](src/engine/userFunctions.ts) und die
@@ -765,6 +767,27 @@ Die Formel-**Point-Mode**-Einfügung (s. o.) erkennt eine mehrdeutige
Zieltabelle selbst und fügt automatisch die volle 3-teilige Form ein, statt
einer Formel, die versehentlich die falsche Tabelle träfe.
**Referenzen bleiben nach dem Umbenennen konsistent.** Wird eine Tabelle
umbenannt (Doppelklick auf ihren Namen in der Kopfleiste), schreibt der
Store **dokumentweit jede** `Tabelle!Zelle`-/`Tabelle::Zelle`-Referenz auf
sie um — egal in welcher anderen Tabelle sie steht, egal ob 2- oder
3-teilige Form (bei der 3-teiligen Form wird nur der Tabellen-Teil
ersetzt, der Blatt-Teil bleibt unangetastet), egal ob Einzelzelle oder
Bereich. Nur die betroffene Qualifier-Textspanne wird ersetzt (nötigenfalls
mit `'...'` gequotet, wenn der neue Name Leerzeichen/Sonderzeichen
enthält) — der Rest der Formel, inklusive Whitespace, bleibt byte-identisch,
dieselbe Technik wie beim dokumentweiten Umschreiben durch Zeilen-/
Spalten-Einfügen (s. u.). Umbenennen + Umschreiben zählen zusammen als
**ein** Undo-Schritt. Damit bleibt eine Formel nach dem Umbenennen exakt
so gültig wie vorher — ohne dieses Umschreiben würde jede Formel, die noch
den alten Namen nennt, beim nächsten Neuberechnen `#REF` zeigen (der
Tabellenname existiert für sie dann schlicht nicht mehr). Bewusst
**begrenzt auf Tabellenzellen** — Makro-Aktionen adressieren eine Tabelle
über einen zur Laufzeit aufgelösten Text-String (s. „Makros" oben), nicht
über eine Formel-Qualifier-Syntax, und ein benutzerdefinierter
Funktionskörper wird ebenfalls nicht durchsucht (dieselbe, bereits
bestehende Begrenzung wie beim dokumentweiten Zeilen-/Spalten-Umschreiben).
**`$`-Bezüge sperren** (relativ/gemischt/absolut): `A1` (relativ) vs. `$A1` /
`A$1` (Spalte bzw. Zeile gesperrt) vs. `$A$1` (beide gesperrt). Für die
Auswertung selbst ist `$` irrelevant — sie ist rein positionsbasiert. Es zählt
@@ -1133,6 +1156,16 @@ Grundrechenarten: `Übersicht!B2 = =SUM(Umsatz!B2:E2)`, `D2 = =B2-C2`,
Bereich, `$`-Sperren bleiben wirkungslos (anders als beim Kopieren),
unveränderte Referenzen bleiben byte-identisch, Undo/Redo, Schutz gegen
Löschen der letzten verbleibenden Zeile/Spalte.
- **Tabellen-Umbenennung schreibt Referenzen um** — ein `Tabelle!Zelle`-
und ein `Tabelle::Zelle`-Bezug aus einer *anderen* Tabelle werden beide
umgeschrieben und liefern danach weiterhin denselben Wert (kein `#REF`),
ein Bereichsbezug behält seinen Bereich (nur der Qualifier ändert sich),
bei der 3-teiligen `Blatt!Tabelle::Zelle`-Form wird ausschließlich der
Tabellen-Teil ersetzt, ein neuer Name mit Leerzeichen wird korrekt
gequotet, eine Formel, die eine *andere*, nicht umbenannte Tabelle
referenziert, bleibt byte-identisch, ein redundanter Selbst-Qualifier
innerhalb der umbenannten Tabelle selbst wird ebenfalls erfasst,
Umbenennen + Umschreiben zählen als ein Undo-Schritt.
- **Abhängigkeiten erkunden** (`graphPrecedents`/`graphDependents` in
`workbook.spec.ts`, `cellGraphSelf`/`cellGraphNeighbors`/
`openDependencyGraph`/`closeDependencyGraph` in `document.spec.ts`) —
@@ -1314,10 +1347,11 @@ Grundrechenarten: `Übersicht!B2 = =SUM(Umsatz!B2:E2)`, `D2 = =B2-C2`,
- **Benutzerdefinierte Funktionen** (Phase 1, siehe oben) bewusst ohne:
Live-Vorschau des Ergebnisses im Bearbeiten-Dialog, variadische Parameter/
Default-Werte, und automatisches Nachführen bestehender Aufrufe bei
Umbenennung (Verhalten entspricht bewusst dem einer Tabellen-Umbenennung,
s. o.) — der Funktionsname selbst wird beim Formeltippen aber inzwischen
vervollständigt (s. o. „Funktions-Autovervollständigung"), auch für eigene
Funktionen.
Umbenennung — anders als bei einer Tabelle inzwischen (s. o.) bewusst
nicht nachgezogen, da eine Funktion nur einen Aufruf-Namen hat, keine
umschreibbare Referenz-Syntax. Der Funktionsname selbst wird beim
Formeltippen aber inzwischen vervollständigt (s. o. „Funktions-
Autovervollständigung"), auch für eigene Funktionen.
- **Funktions-Autovervollständigung** bewusst ohne: Zell-/Tabellennamen-
Vorschläge (dafür existiert der Point-Mode, s. o.), Vervollständigung, die
auch Text *nach* dem Cursor berücksichtigt (nur der Text bis zum Cursor