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:
@@ -67,7 +67,9 @@ function evalScalar(node: Node, host: EngineHost): CellValue {
|
||||
|
||||
case 'cell': {
|
||||
const tableId =
|
||||
node.qualifier == null ? host.homeTableId : host.resolveTableName(node.qualifier);
|
||||
node.qualifier == null
|
||||
? host.homeTableId
|
||||
: host.resolveTableName(node.qualifier, node.sheetQualifier ?? null);
|
||||
if (!tableId) return new FormulaError('#REF', `unknown table '${node.qualifier}'`);
|
||||
return host.getComputed(tableId, node.col, node.row);
|
||||
}
|
||||
@@ -104,7 +106,9 @@ function evalScalar(node: Node, host: EngineHost): CellValue {
|
||||
function evalArg(node: Node, host: EngineHost): FormulaError | CellValue[] {
|
||||
if (node.kind === 'range') {
|
||||
const tableId =
|
||||
node.qualifier == null ? host.homeTableId : host.resolveTableName(node.qualifier);
|
||||
node.qualifier == null
|
||||
? host.homeTableId
|
||||
: host.resolveTableName(node.qualifier, node.sheetQualifier ?? null);
|
||||
if (!tableId) return new FormulaError('#REF', `unknown table '${node.qualifier}'`);
|
||||
return expandRange(node.start, node.end).map((c) => host.getComputed(tableId, c.col, c.row));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user