From 96875a36e03653722bb0d96d9f1859f16ac15b26 Mon Sep 17 00:00:00 2001 From: OTime-Coder Date: Fri, 29 May 2026 19:06:46 +0800 Subject: [PATCH] fix(engine-formula): skip embedded refs for other formulas --- .../engine/dependency/formula-dependency.ts | 9 +++++--- .../__tests__/runtime.service.spec.ts | 13 ++++++++++++ .../src/services/calculate-formula.service.ts | 3 ++- .../src/services/runtime.service.ts | 21 +++++++++++++++++-- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/packages/engine-formula/src/engine/dependency/formula-dependency.ts b/packages/engine-formula/src/engine/dependency/formula-dependency.ts index 52dd5fca1058..5b796ce89e10 100644 --- a/packages/engine-formula/src/engine/dependency/formula-dependency.ts +++ b/packages/engine-formula/src/engine/dependency/formula-dependency.ts @@ -720,7 +720,8 @@ export class FormulaDependencyGenerator extends Disposable implements IFormulaDe tree.rowCount, tree.columnCount, tree.subUnitId, - tree.unitId + tree.unitId, + tree.type ); const rangeList = await this._getRangeListByNode({ @@ -1039,7 +1040,8 @@ export class FormulaDependencyGenerator extends Disposable implements IFormulaDe tree.rowCount, tree.columnCount, tree.subUnitId, - tree.unitId + tree.unitId, + tree.type ); const dirtyRanges: IUnitRange[] = []; @@ -1092,7 +1094,8 @@ export class FormulaDependencyGenerator extends Disposable implements IFormulaDe tree.rowCount, tree.columnCount, tree.subUnitId, - tree.unitId + tree.unitId, + tree.type ); let value: FunctionVariantType; diff --git a/packages/engine-formula/src/services/__tests__/runtime.service.spec.ts b/packages/engine-formula/src/services/__tests__/runtime.service.spec.ts index 55330992f0e2..5ba562e22831 100644 --- a/packages/engine-formula/src/services/__tests__/runtime.service.spec.ts +++ b/packages/engine-formula/src/services/__tests__/runtime.service.spec.ts @@ -17,6 +17,7 @@ import { ObjectMatrix } from '@univerjs/core'; import { describe, expect, it } from 'vitest'; import { ErrorType } from '../../basics/error-type'; +import { FormulaDependencyTreeType } from '../../engine/dependency/dependency-tree'; import { createNewArray } from '../../engine/utils/array-object'; import { NumberValueObject, StringValueObject } from '../../engine/value-object/primitive-object'; import { FormulaExecutedStateType, FormulaExecuteStageType, FormulaRuntimeService } from '../runtime.service'; @@ -402,6 +403,18 @@ describe('FormulaRuntimeService', () => { expect(runtime.getDependencyTreeModelData()).toEqual([{ treeId: 1 }]); }); + it('should collect embedded array refs only for normal worksheet formulas', () => { + const { runtime } = createRuntimeService(); + + runtime.setCurrent(1, 2, 20, 20, 'sheet', 'unit', FormulaDependencyTreeType.OTHER_FORMULA); + runtime.setUnitArrayFormulaEmbeddedMap(); + expect(runtime.getUnitArrayFormulaEmbeddedMap().unit?.sheet?.[1]?.[2]).toBeUndefined(); + + runtime.setCurrent(4, 5, 20, 20, 'sheet', 'unit', FormulaDependencyTreeType.NORMAL_FORMULA); + runtime.setUnitArrayFormulaEmbeddedMap(); + expect(runtime.getUnitArrayFormulaEmbeddedMap().unit?.sheet?.[4]?.[5]).toBe(true); + }); + it('should evaluate helper methods for range, overlap and dirty checks', () => { const { runtime, arrayFormulaRange } = createRuntimeService(); diff --git a/packages/engine-formula/src/services/calculate-formula.service.ts b/packages/engine-formula/src/services/calculate-formula.service.ts index 3ce796844f09..fbb59f772e68 100644 --- a/packages/engine-formula/src/services/calculate-formula.service.ts +++ b/packages/engine-formula/src/services/calculate-formula.service.ts @@ -341,7 +341,8 @@ export class CalculateFormulaService extends Disposable implements ICalculateFor tree.rowCount, tree.columnCount, tree.subUnitId, - tree.unitId + tree.unitId, + tree.type ); let value: FunctionVariantType; diff --git a/packages/engine-formula/src/services/runtime.service.ts b/packages/engine-formula/src/services/runtime.service.ts index b2fff5b7b737..afc04e4e9c0d 100644 --- a/packages/engine-formula/src/services/runtime.service.ts +++ b/packages/engine-formula/src/services/runtime.service.ts @@ -33,6 +33,7 @@ import { createIdentifier, Disposable, isNullCell, ObjectMatrix } from '@univerj import { isInDirtyRange } from '../basics/dirty'; import { ErrorType } from '../basics/error-type'; import { CELL_INVERTED_INDEX_CACHE } from '../basics/inverted-index-cache'; +import { FormulaDependencyTreeType } from '../engine/dependency/dependency-tree'; import { FORMULA_REF_TO_ARRAY_CACHE } from '../engine/reference-object/base-reference-object'; import { getRuntimeFeatureCell } from '../engine/utils/get-runtime-feature-cell'; import { clearNumberFormatTypeCache, clearStringToNumberPatternCache } from '../engine/utils/numfmt-kit'; @@ -112,7 +113,8 @@ export interface IFormulaRuntimeService { rowCount: number, columnCount: number, sheetId: string, - unitId: string + unitId: string, + formulaType?: FormulaDependencyTreeType ): void; registerFunctionDefinitionPrivacyVar(lambdaId: string, lambdaVar: Map>): void; @@ -211,6 +213,7 @@ export class FormulaRuntimeService extends Disposable implements IFormulaRuntime private _currentSubUnitId: string = ''; private _currentUnitId: string = ''; + private _currentFormulaType: FormulaDependencyTreeType = FormulaDependencyTreeType.NORMAL_FORMULA; private _runtimeData: IRuntimeUnitDataType = {}; @@ -405,13 +408,22 @@ export class FormulaRuntimeService extends Disposable implements IFormulaRuntime clearReferenceToRangeCache(); } - setCurrent(row: number, column: number, rowCount: number, columnCount: number, sheetId: string, unitId: string) { + setCurrent( + row: number, + column: number, + rowCount: number, + columnCount: number, + sheetId: string, + unitId: string, + formulaType: FormulaDependencyTreeType = FormulaDependencyTreeType.NORMAL_FORMULA + ) { this._currentRow = row; this._currentColumn = column; this._currentRowCount = rowCount; this._currentColumnCount = columnCount; this._currentSubUnitId = sheetId; this._currentUnitId = unitId; + this._currentFormulaType = formulaType; } clearFunctionDefinitionPrivacyVar() { @@ -723,6 +735,11 @@ export class FormulaRuntimeService extends Disposable implements IFormulaRuntime const rowIndex = this._currentRow; const columnIndex = this._currentColumn; + // Embedded array refs are worksheet cell metadata; other formula results stay in unitOtherData. + if (this._currentFormulaType !== FormulaDependencyTreeType.NORMAL_FORMULA) { + return; + } + const arrayFormulaEmbeddedMap = this._unitArrayFormulaEmbeddedMap; if (arrayFormulaEmbeddedMap[unitId] == null) { arrayFormulaEmbeddedMap[unitId] = {};