Add a sheet qualifier: "Blatt!Tabelle::Zelle", table names unique per sheet
Table names were document-unique; now they're unique per sheet only -- two different sheets may each hold a table called "Umsatz". A plain, unqualified reference (Umsatz!B2 / Umsatz::B2, unchanged from before) resolves to the table on the SAME sheet as the formula referencing it when the name is otherwise ambiguous, falling back to the single document-wide match when it isn't ambiguous at all -- exactly as before for every existing formula. The new explicit 3-part form (Analyse!Umsatz::B2, quoted where a name has spaces) always targets the named sheet's table regardless of where the formula itself lives, for the case that's still genuinely ambiguous. Engine: parser.ts's afterFirstQualifierToken() disambiguates via lookahead -- "X!Y::" (a name, then "::") is the new 3-part sheet+table form; a bare "X!Y" keeps its original single-qualifier meaning, so every formula written before this exists still parses identically. CellNode/RangeNode gain an optional sheetQualifier field. Workbook.resolveTableName(name, sheetName?) implements the resolution policy; TableModel gains sheetName. precedentsOf() now also sets homeTableId (previously only evaluateCell did), so graph edges use the same same-sheet-preference resolution an evaluation would. Store: table name uniqueness checks (addTable, renameObject) are now scoped to the target sheet instead of the whole document. Point-mode's qualifyRef() inserts the full "Blatt!Tabelle::" form only when the clicked table's name is genuinely ambiguous and lives on a different sheet than the editor; otherwise the simple form, unchanged. 200 tests passing (19 new), vue-tsc and eslint clean, verified live in the running app: renamed a Blatt-2 table to the same name as Analyse's seed "Umsatz", confirmed an unqualified reference resolves per-sheet, an explicit sheet-qualified one always targets the named sheet, and the original sheet's own formulas are unaffected. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+21
-7
@@ -70,19 +70,33 @@ export function parseKey(key: string): CellRef {
|
||||
* The document as seen by the engine. Implemented by the Vue store.
|
||||
*
|
||||
* The addressable unit is a **table** (a table object on a Numbers-style
|
||||
* canvas). Table names are unique across the whole document, so a qualified
|
||||
* reference like `Umsatz!B2` / `Umsatz::B2` resolves the same no matter which
|
||||
* sheet the formula or the target table sits on.
|
||||
* canvas). Table names are only unique *per sheet* -- two different sheets
|
||||
* may each hold a table called "Umsatz". An unqualified table reference
|
||||
* (`Umsatz!B2` / `Umsatz::B2`, no sheet given) resolves to whichever table
|
||||
* named "Umsatz" lives on the *same sheet* as the formula doing the
|
||||
* referencing, falling back to the single document-wide match when the name
|
||||
* isn't ambiguous there. The explicit 3-part form (`Analyse!Umsatz::B2`)
|
||||
* disambiguates when it would otherwise be genuinely ambiguous (name used on
|
||||
* two *other* sheets, neither of them the formula's own).
|
||||
*/
|
||||
export interface EngineHost {
|
||||
/** Id of the table the formula currently being evaluated lives on. */
|
||||
homeTableId: string;
|
||||
/**
|
||||
* Resolve a table *name* (as written in a formula) to its id. Matching is
|
||||
* case-insensitive and tolerant of surrounding whitespace. Returns `null`
|
||||
* for an unknown / deleted table.
|
||||
* Resolve a table *name* (as written in a formula) to its id, optionally
|
||||
* narrowed to a specific *sheet* name (the "Blatt!" part of a 3-part
|
||||
* `Blatt!Tabelle::Zelle` reference). Matching is case-insensitive and
|
||||
* tolerant of surrounding whitespace.
|
||||
*
|
||||
* - `sheetName` given: only a table with that name **on that sheet**
|
||||
* matches; otherwise `null` (including when the sheet itself is unknown).
|
||||
* - `sheetName` omitted/`null`: matches a table by name anywhere in the
|
||||
* document. Exactly one match resolves as before. Multiple matches (the
|
||||
* name exists on more than one sheet) prefer a table on the same sheet
|
||||
* as {@link homeTableId}; if that still doesn't narrow it to one, `null`
|
||||
* (`#REF` -- the formula needs an explicit sheet qualifier).
|
||||
*/
|
||||
resolveTableName(name: string): string | null;
|
||||
resolveTableName(name: string, sheetName?: string | null): string | null;
|
||||
/** Dimensions of a table, used for range clamping and #REF detection. */
|
||||
tableSize(tableId: string): { cols: number; rows: number } | null;
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user