@univerjs/engine-formula 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/{en-US-DrAfIiBE.js → en-US-BYMYuEpp.js} +15 -15
- package/lib/cjs/facade.js +3 -18
- package/lib/cjs/index.js +450 -161
- package/lib/cjs/locale/en-US.js +1 -1
- package/lib/cjs/locale/fa-IR.js +1 -1
- package/lib/cjs/locale/zh-HK.js +1 -1
- package/lib/cjs/locale/zh-TW.js +1 -1
- package/lib/cjs/{zh-TW-CvMudVQy.js → zh-TW-B5pYt-NJ.js} +15 -15
- package/lib/es/facade.js +3 -18
- package/lib/es/index.js +424 -135
- package/lib/facade.js +3 -18
- package/lib/index.js +424 -135
- package/lib/types/basics/common.d.ts +8 -2
- package/lib/types/commands/mutations/set-formula-calculation.mutation.d.ts +2 -1
- package/lib/types/config/config.d.ts +0 -2
- package/lib/types/engine/dependency/dependency-groups.d.ts +21 -0
- package/lib/types/engine/dependency/dependency-tree.d.ts +1 -0
- package/lib/types/engine/dependency/formula-dependency.d.ts +1 -1
- package/lib/types/facade/f-formula.d.ts +0 -13
- package/lib/types/functions/lookup/xlookup/index.d.ts +2 -4
- package/lib/types/index.d.ts +4 -2
- package/lib/types/models/formula-data.model.d.ts +5 -0
- package/lib/types/services/active-dirty-manager.service.d.ts +1 -0
- package/lib/types/services/calculate-formula.service.d.ts +34 -2
- package/lib/types/services/current-data.service.d.ts +4 -2
- package/lib/types/services/formula-calculation-trigger.service.d.ts +5 -0
- package/lib/types/services/formula-changeset-calculation.service.d.ts +34 -0
- package/lib/types/services/runtime.service.d.ts +36 -2
- package/lib/umd/facade.js +1 -1
- package/lib/umd/index.js +4 -4
- package/package.json +5 -5
package/lib/es/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import IntervalTree from "@flatten-js/interval-tree";
|
|
2
|
-
import { AbsoluteRefType, AsyncLock, BooleanNumber, BuildTextUtils, CellValueType, CommandType, DataStreamTreeTokenType, DateSystem, Disposable, DisposableCollection, EXCEL_1904_OFFSET, ICommandService, IConfigService, IUniverInstanceService, Inject, Injector, LRUMap, LifecycleService, LifecycleStages, LocaleService, LocaleType, MAX_COLUMN_COUNT, MAX_ROW_COUNT, ObjectMatrix, Optional, Plugin, RANGE_TYPE, RTree, Rectangle, RichTextBuilder, Styles, Tools, UniverInstanceType, cellToRange, columnLabelToNumber, createBaseFormulaTableNameMap, createIdentifier, excelDateSerial, excelDateTimePartsToSerial, excelDateTimeSerial, excelSerialToDate, excelSerialToDateTime, excelSerialToDateTimeParts, generateRandomId, getBaseFormulaTableName, getDateSystemMaxSerial, getNumfmtParseValueFilter, hashAlgorithm, isFormulaId, isFormulaString, isNodeEnv, isNullCell, isRealNum, isTextFormat, isValidRange, merge, moveRangeByOffset, numfmt, regexp, requestImmediateMacroTask, sortRules, toDisposable, touchDependencies } from "@univerjs/core";
|
|
2
|
+
import { AbsoluteRefType, AsyncLock, BooleanNumber, BuildTextUtils, CellValueType, CommandType, DataStreamTreeTokenType, DateSystem, Disposable, DisposableCollection, EXCEL_1904_OFFSET, ICommandService, IConfigService, IUniverInstanceService, Inject, Injector, LRUMap, LifecycleService, LifecycleStages, LocaleService, LocaleType, MAX_COLUMN_COUNT, MAX_ROW_COUNT, ObjectMatrix, Optional, Plugin, RANGE_TYPE, RTree, Rectangle, RichTextBuilder, Styles, Tools, UniverInstanceType, cellToRange, columnLabelToNumber, createBaseFormulaTableNameMap, createIdentifier, excelDateSerial, excelDateTimePartsToSerial, excelDateTimeSerial, excelSerialToDate, excelSerialToDateTime, excelSerialToDateTimeParts, generateRandomId, getBaseFormulaTableName, getDateSystemMaxSerial, getNumfmtParseValueFilter, hashAlgorithm, isFormulaId, isFormulaString, isNodeEnv, isNullCell, isRealNum, isTextFormat, isValidRange, merge, moveRangeByOffset, normalizeWorkbookCalculationSettings, numfmt, regexp, requestImmediateMacroTask, sortRules, toDisposable, touchDependencies } from "@univerjs/core";
|
|
3
3
|
import { BehaviorSubject, Observable, Subject, combineLatest, distinctUntilChanged, filter, map, shareReplay, take } from "rxjs";
|
|
4
4
|
import Decimal from "decimal.js";
|
|
5
5
|
import { DataSyncPrimaryController } from "@univerjs/rpc";
|
|
@@ -328,7 +328,7 @@ function getSearchModeValue(searchModeValue) {
|
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
//#endregion
|
|
331
|
-
//#region \0@oxc-project+runtime@0.
|
|
331
|
+
//#region \0@oxc-project+runtime@0.153.0/helpers/esm/typeof.js
|
|
332
332
|
function _typeof(o) {
|
|
333
333
|
"@babel/helpers - typeof";
|
|
334
334
|
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
@@ -339,7 +339,7 @@ function _typeof(o) {
|
|
|
339
339
|
}
|
|
340
340
|
|
|
341
341
|
//#endregion
|
|
342
|
-
//#region \0@oxc-project+runtime@0.
|
|
342
|
+
//#region \0@oxc-project+runtime@0.153.0/helpers/esm/toPrimitive.js
|
|
343
343
|
function toPrimitive(t, r) {
|
|
344
344
|
if ("object" != _typeof(t) || !t) return t;
|
|
345
345
|
var e = t[Symbol.toPrimitive];
|
|
@@ -352,14 +352,14 @@ function toPrimitive(t, r) {
|
|
|
352
352
|
}
|
|
353
353
|
|
|
354
354
|
//#endregion
|
|
355
|
-
//#region \0@oxc-project+runtime@0.
|
|
355
|
+
//#region \0@oxc-project+runtime@0.153.0/helpers/esm/toPropertyKey.js
|
|
356
356
|
function toPropertyKey(t) {
|
|
357
357
|
var i = toPrimitive(t, "string");
|
|
358
358
|
return "symbol" == _typeof(i) ? i : i + "";
|
|
359
359
|
}
|
|
360
360
|
|
|
361
361
|
//#endregion
|
|
362
|
-
//#region \0@oxc-project+runtime@0.
|
|
362
|
+
//#region \0@oxc-project+runtime@0.153.0/helpers/esm/defineProperty.js
|
|
363
363
|
function _defineProperty(e, r, t) {
|
|
364
364
|
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
365
365
|
value: t,
|
|
@@ -1186,7 +1186,7 @@ function splitTableStructuredRef(ref) {
|
|
|
1186
1186
|
}
|
|
1187
1187
|
|
|
1188
1188
|
//#endregion
|
|
1189
|
-
//#region \0@oxc-project+runtime@0.
|
|
1189
|
+
//#region \0@oxc-project+runtime@0.153.0/helpers/esm/decorateParam.js
|
|
1190
1190
|
function __decorateParam(paramIndex, decorator) {
|
|
1191
1191
|
return function(target, key) {
|
|
1192
1192
|
decorator(target, key, paramIndex);
|
|
@@ -1194,7 +1194,7 @@ function __decorateParam(paramIndex, decorator) {
|
|
|
1194
1194
|
}
|
|
1195
1195
|
|
|
1196
1196
|
//#endregion
|
|
1197
|
-
//#region \0@oxc-project+runtime@0.
|
|
1197
|
+
//#region \0@oxc-project+runtime@0.153.0/helpers/esm/decorate.js
|
|
1198
1198
|
function __decorate(decorators, target, key, desc) {
|
|
1199
1199
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1200
1200
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1672,8 +1672,6 @@ const SetSuperTableOptionMutation = {
|
|
|
1672
1672
|
//#endregion
|
|
1673
1673
|
//#region src/config/config.ts
|
|
1674
1674
|
const ENGINE_FORMULA_PLUGIN_CONFIG_KEY = "engine-formula.config";
|
|
1675
|
-
const DEFAULT_CYCLE_REFERENCE_COUNT = 1;
|
|
1676
|
-
const ENGINE_FORMULA_CYCLE_REFERENCE_COUNT = "CYCLE_REFERENCE_COUNT";
|
|
1677
1675
|
const ENGINE_FORMULA_RETURN_DEPENDENCY_TREE = "RETURN_DEPENDENCY_TREE";
|
|
1678
1676
|
const configSymbol = Symbol(ENGINE_FORMULA_PLUGIN_CONFIG_KEY);
|
|
1679
1677
|
const defaultPluginConfig = {};
|
|
@@ -3094,9 +3092,8 @@ var LexerTreeBuilder = class extends Disposable {
|
|
|
3094
3092
|
const isCacheable = !/\b(?:LET|LAMBDA)\s*\(/iu.test(formulaString);
|
|
3095
3093
|
const cacheKey = injectDefinedNameParam == null ? formulaString : `${injectDefinedNameParam.unitId ?? ""}\0${injectDefinedNameParam.sheetId ?? ""}\0${injectDefinedNameParam.refOffsetX}\0${injectDefinedNameParam.refOffsetY}\0${formulaString}`;
|
|
3096
3094
|
if (transformSuffix === true && isCacheable) {
|
|
3097
|
-
var _this$_simpleCheckDef;
|
|
3098
3095
|
const lexerNode = FormulaLexerNodeCache.get(cacheKey);
|
|
3099
|
-
const simpleCheckDefinedNameResult = injectDefinedNameParam &&
|
|
3096
|
+
const simpleCheckDefinedNameResult = injectDefinedNameParam && this._simpleCheckDefinedName(formulaString, injectDefinedNameParam, lexerNode);
|
|
3100
3097
|
if (lexerNode && !simpleCheckDefinedNameResult) return lexerNode;
|
|
3101
3098
|
}
|
|
3102
3099
|
this._resetCurrentLexerNode();
|
|
@@ -3163,13 +3160,13 @@ var LexerTreeBuilder = class extends Disposable {
|
|
|
3163
3160
|
const definedNameToken = token.trim();
|
|
3164
3161
|
const definedContent = getValueByName(unitId, definedNameToken, sheetId);
|
|
3165
3162
|
if (definedContent) {
|
|
3163
|
+
definedNames.push(definedContent.name);
|
|
3166
3164
|
const refOffsetX = definedContent.localSheetId === "AllDefaultWorkbook" ? param.refOffsetX - 1 : param.refOffsetX;
|
|
3167
3165
|
const refString = definedContent.formulaOrRefString.startsWith("=") ? definedContent.formulaOrRefString : this._moveDefinedNameRefOffset(definedContent.formulaOrRefString, refOffsetX, param.refOffsetY);
|
|
3168
3166
|
const nestedDefinedNameParam = this._handleNestedDefinedName(refString, param);
|
|
3169
3167
|
if (nestedDefinedNameParam == null || typeof nestedDefinedNameParam !== "object") {
|
|
3170
3168
|
sequenceString += nestedDefinedNameParam || "#NAME?";
|
|
3171
3169
|
hasDefinedName = true;
|
|
3172
|
-
definedNames.push(definedNameToken);
|
|
3173
3170
|
} else if (typeof nestedDefinedNameParam === "object") {
|
|
3174
3171
|
const { sequenceString: nestedSequenceString, definedNames: nestedDefinedNames } = nestedDefinedNameParam;
|
|
3175
3172
|
sequenceString += nestedSequenceString;
|
|
@@ -3234,7 +3231,7 @@ var LexerTreeBuilder = class extends Disposable {
|
|
|
3234
3231
|
if (state === "#VALUE!" || sequenceArray.length === 0) return state;
|
|
3235
3232
|
return this._handleDefinedName(sequenceArray, param);
|
|
3236
3233
|
}
|
|
3237
|
-
_simpleCheckDefinedName(formulaString, injectDefinedNameParam) {
|
|
3234
|
+
_simpleCheckDefinedName(formulaString, injectDefinedNameParam, lexerNode) {
|
|
3238
3235
|
const { getDirtyDefinedNameMap, unitId } = injectDefinedNameParam;
|
|
3239
3236
|
const definedNameMap = getDirtyDefinedNameMap();
|
|
3240
3237
|
const executeUnitId = unitId;
|
|
@@ -3242,7 +3239,7 @@ var LexerTreeBuilder = class extends Disposable {
|
|
|
3242
3239
|
const names = Object.keys(definedNameMap[executeUnitId]);
|
|
3243
3240
|
for (let i = 0, len = names.length; i < len; i++) {
|
|
3244
3241
|
const name = names[i];
|
|
3245
|
-
if (formulaString.indexOf(name) > -1) return true;
|
|
3242
|
+
if (formulaString.indexOf(name) > -1 || (lexerNode === null || lexerNode === void 0 ? void 0 : lexerNode.getDefinedNames().includes(name))) return true;
|
|
3246
3243
|
}
|
|
3247
3244
|
}
|
|
3248
3245
|
return false;
|
|
@@ -4301,18 +4298,43 @@ let FormulaDataModel = class FormulaDataModel extends Disposable {
|
|
|
4301
4298
|
super();
|
|
4302
4299
|
this._univerInstanceService = _univerInstanceService;
|
|
4303
4300
|
this._lexerTreeBuilder = _lexerTreeBuilder;
|
|
4301
|
+
_defineProperty(this, "_circularReferences", /* @__PURE__ */ new Map());
|
|
4304
4302
|
_defineProperty(this, "_formulaIdMapData", Object.create(null));
|
|
4305
4303
|
_defineProperty(this, "_arrayFormulaRange", Object.create(null));
|
|
4306
4304
|
_defineProperty(this, "_arrayFormulaCellData", Object.create(null));
|
|
4307
4305
|
_defineProperty(this, "_unitImageFormulaData", Object.create(null));
|
|
4306
|
+
this.disposeWithMe(this._univerInstanceService.getTypeOfUnitDisposed$(UniverInstanceType.UNIVER_SHEET).subscribe((workbook) => {
|
|
4307
|
+
for (const [key, cell] of this._circularReferences) if (cell.unitId === workbook.getUnitId()) this._circularReferences.delete(key);
|
|
4308
|
+
}));
|
|
4308
4309
|
}
|
|
4309
4310
|
dispose() {
|
|
4310
4311
|
super.dispose();
|
|
4312
|
+
this._circularReferences.clear();
|
|
4311
4313
|
this._formulaIdMapData = Object.create(null);
|
|
4312
4314
|
this._arrayFormulaRange = Object.create(null);
|
|
4313
4315
|
this._arrayFormulaCellData = Object.create(null);
|
|
4314
4316
|
this._unitImageFormulaData = Object.create(null);
|
|
4315
4317
|
}
|
|
4318
|
+
setCircularReferences(cells) {
|
|
4319
|
+
this._circularReferences.clear();
|
|
4320
|
+
for (const cell of cells) this._circularReferences.set(JSON.stringify([
|
|
4321
|
+
cell.unitId,
|
|
4322
|
+
cell.sheetId,
|
|
4323
|
+
cell.row,
|
|
4324
|
+
cell.column
|
|
4325
|
+
]), { ...cell });
|
|
4326
|
+
}
|
|
4327
|
+
getCircularReferences(unitId) {
|
|
4328
|
+
return Array.from(this._circularReferences.values()).filter((cell) => cell.unitId === unitId).map((cell) => ({ ...cell }));
|
|
4329
|
+
}
|
|
4330
|
+
isCircularReference(unitId, sheetId, row, column) {
|
|
4331
|
+
return this._circularReferences.has(JSON.stringify([
|
|
4332
|
+
unitId,
|
|
4333
|
+
sheetId,
|
|
4334
|
+
row,
|
|
4335
|
+
column
|
|
4336
|
+
]));
|
|
4337
|
+
}
|
|
4316
4338
|
clearPreviousArrayFormulaCellData(clearArrayFormulaCellData) {
|
|
4317
4339
|
Object.keys(clearArrayFormulaCellData).forEach((unitId) => {
|
|
4318
4340
|
const clearSheetData = clearArrayFormulaCellData[unitId];
|
|
@@ -5151,6 +5173,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends Disp
|
|
|
5151
5173
|
this._localeService = _localeService;
|
|
5152
5174
|
this._formulaDataModel = _formulaDataModel;
|
|
5153
5175
|
this._sheetRowFilteredService = _sheetRowFilteredService;
|
|
5176
|
+
_defineProperty(this, "_dirtyIterationUnits", []);
|
|
5154
5177
|
_defineProperty(this, "_unitData", Object.create(null));
|
|
5155
5178
|
_defineProperty(this, "_unitStylesData", Object.create(null));
|
|
5156
5179
|
_defineProperty(this, "_arrayFormulaCellData", Object.create(null));
|
|
@@ -5331,6 +5354,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends Disp
|
|
|
5331
5354
|
}
|
|
5332
5355
|
if (config.rowData) this._applyUnitRowData(config.rowData);
|
|
5333
5356
|
this._formulaData = config.formulaData;
|
|
5357
|
+
this._dirtyIterationUnits = config.dirtyIterationUnits ?? [];
|
|
5334
5358
|
this._arrayFormulaCellData = convertUnitDataToRuntime(config.arrayFormulaCellData);
|
|
5335
5359
|
this._arrayFormulaRange = config.arrayFormulaRange;
|
|
5336
5360
|
this._forceCalculate = config.forceCalculate;
|
|
@@ -5358,6 +5382,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends Disp
|
|
|
5358
5382
|
}
|
|
5359
5383
|
getDirtyData() {
|
|
5360
5384
|
return {
|
|
5385
|
+
dirtyIterationUnits: this._dirtyIterationUnits,
|
|
5361
5386
|
forceCalculation: this._forceCalculate,
|
|
5362
5387
|
dirtyRanges: this._dirtyRanges,
|
|
5363
5388
|
dirtyNameMap: this._dirtyNameMap,
|
|
@@ -5370,6 +5395,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends Disp
|
|
|
5370
5395
|
};
|
|
5371
5396
|
}
|
|
5372
5397
|
loadDirtyRangesAndExcludedCell(dirtyRanges, excludedCell) {
|
|
5398
|
+
this._dirtyIterationUnits = [];
|
|
5373
5399
|
this._dirtyRanges = dirtyRanges;
|
|
5374
5400
|
this._excludedCell = excludedCell;
|
|
5375
5401
|
/**
|
|
@@ -10029,11 +10055,14 @@ let FormulaExecutedStateType = /* @__PURE__ */ function(FormulaExecutedStateType
|
|
|
10029
10055
|
return FormulaExecutedStateType;
|
|
10030
10056
|
}({});
|
|
10031
10057
|
let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
|
|
10032
|
-
constructor(_currentConfigService, _hyperlinkEngineFormulaService) {
|
|
10058
|
+
constructor(_currentConfigService, _hyperlinkEngineFormulaService, _univerInstanceService) {
|
|
10033
10059
|
super();
|
|
10034
10060
|
this._currentConfigService = _currentConfigService;
|
|
10035
10061
|
this._hyperlinkEngineFormulaService = _hyperlinkEngineFormulaService;
|
|
10062
|
+
this._univerInstanceService = _univerInstanceService;
|
|
10036
10063
|
_defineProperty(this, "_formulaExecuteStage", 0);
|
|
10064
|
+
_defineProperty(this, "_circularReferences", /* @__PURE__ */ new Map());
|
|
10065
|
+
_defineProperty(this, "_pendingCircularReferences", /* @__PURE__ */ new Map());
|
|
10037
10066
|
_defineProperty(this, "_stopState", false);
|
|
10038
10067
|
_defineProperty(this, "_externalReferenceUnavailable", false);
|
|
10039
10068
|
_defineProperty(this, "_currentRow", -1);
|
|
@@ -10063,6 +10092,9 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
|
|
|
10063
10092
|
_defineProperty(this, "_formulaCycleIndex", 0);
|
|
10064
10093
|
_defineProperty(this, "_isCycleDependency", false);
|
|
10065
10094
|
_defineProperty(this, "_dependencyTreeModelData", []);
|
|
10095
|
+
this.disposeWithMe(this._univerInstanceService.getTypeOfUnitDisposed$(UniverInstanceType.UNIVER_SHEET).subscribe((workbook) => {
|
|
10096
|
+
for (const references of [this._circularReferences, this._pendingCircularReferences]) for (const [key, cell] of references) if (cell.unitId === workbook.getUnitId()) references.delete(key);
|
|
10097
|
+
}));
|
|
10066
10098
|
}
|
|
10067
10099
|
get currentRow() {
|
|
10068
10100
|
return this._currentRow;
|
|
@@ -10087,6 +10119,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
|
|
|
10087
10119
|
dispose() {
|
|
10088
10120
|
super.dispose();
|
|
10089
10121
|
this.reset();
|
|
10122
|
+
this._circularReferences.clear();
|
|
10123
|
+
this._pendingCircularReferences.clear();
|
|
10090
10124
|
this._runtimeFeatureCellData = Object.create(null);
|
|
10091
10125
|
this._runtimeFeatureRange = Object.create(null);
|
|
10092
10126
|
this.clearReferenceAndNumberformatCache();
|
|
@@ -10180,8 +10214,60 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
|
|
|
10180
10214
|
clearStringToNumberPatternCache();
|
|
10181
10215
|
clearReferenceToRangeCache();
|
|
10182
10216
|
}
|
|
10217
|
+
beginCircularReferences() {
|
|
10218
|
+
this._pendingCircularReferences = new Map(this._circularReferences);
|
|
10219
|
+
const formulaData = this._currentConfigService.getFormulaData();
|
|
10220
|
+
for (const [key, cell] of this._pendingCircularReferences) {
|
|
10221
|
+
var _formulaData$cell$uni;
|
|
10222
|
+
if (!((_formulaData$cell$uni = formulaData[cell.unitId]) === null || _formulaData$cell$uni === void 0 || (_formulaData$cell$uni = _formulaData$cell$uni[cell.sheetId]) === null || _formulaData$cell$uni === void 0 || (_formulaData$cell$uni = _formulaData$cell$uni[cell.row]) === null || _formulaData$cell$uni === void 0 ? void 0 : _formulaData$cell$uni[cell.column])) this._pendingCircularReferences.delete(key);
|
|
10223
|
+
}
|
|
10224
|
+
}
|
|
10225
|
+
clearCircularReferenceCells(cells) {
|
|
10226
|
+
if (this._pendingCircularReferences.size === 0) return;
|
|
10227
|
+
for (const cell of cells) {
|
|
10228
|
+
this._pendingCircularReferences.delete(JSON.stringify([
|
|
10229
|
+
cell.unitId,
|
|
10230
|
+
cell.subUnitId,
|
|
10231
|
+
cell.row,
|
|
10232
|
+
cell.column
|
|
10233
|
+
]));
|
|
10234
|
+
if (this._pendingCircularReferences.size === 0) return;
|
|
10235
|
+
}
|
|
10236
|
+
}
|
|
10237
|
+
recordCircularReferences(cells) {
|
|
10238
|
+
for (const cell of cells) {
|
|
10239
|
+
if (cell.row < 0 || cell.column < 0) continue;
|
|
10240
|
+
this._pendingCircularReferences.set(JSON.stringify([
|
|
10241
|
+
cell.unitId,
|
|
10242
|
+
cell.sheetId,
|
|
10243
|
+
cell.row,
|
|
10244
|
+
cell.column
|
|
10245
|
+
]), { ...cell });
|
|
10246
|
+
}
|
|
10247
|
+
}
|
|
10248
|
+
completeCircularReferences() {
|
|
10249
|
+
if (!this.isStopExecution()) this._circularReferences = new Map(this._pendingCircularReferences);
|
|
10250
|
+
}
|
|
10251
|
+
preserveCurrentCellData() {
|
|
10252
|
+
var _this$_currentConfigS;
|
|
10253
|
+
const unitId = this.currentUnitId;
|
|
10254
|
+
const sheetId = this.currentSubUnitId;
|
|
10255
|
+
const cell = (_this$_currentConfigS = this._currentConfigService.getUnitData()[unitId]) === null || _this$_currentConfigS === void 0 || (_this$_currentConfigS = _this$_currentConfigS[sheetId]) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.cellData.getValue(this.currentRow, this.currentColumn);
|
|
10256
|
+
if ((cell === null || cell === void 0 ? void 0 : cell.v) != null) return;
|
|
10257
|
+
const sheets = this._runtimeData[unitId] ??= {};
|
|
10258
|
+
(sheets[sheetId] ??= new ObjectMatrix()).setValue(this.currentRow, this.currentColumn, {
|
|
10259
|
+
v: (cell === null || cell === void 0 ? void 0 : cell.v) ?? 0,
|
|
10260
|
+
t: (cell === null || cell === void 0 ? void 0 : cell.v) == null ? CellValueType.NUMBER : cell.t
|
|
10261
|
+
});
|
|
10262
|
+
if (this._currentSourceFormula) {
|
|
10263
|
+
const formulas = this._sourceFormulaData[unitId] ??= {};
|
|
10264
|
+
const sheet = formulas[sheetId] ??= {};
|
|
10265
|
+
const row = sheet[this.currentRow] ??= {};
|
|
10266
|
+
row[this.currentColumn] = { ...this._currentSourceFormula };
|
|
10267
|
+
}
|
|
10268
|
+
}
|
|
10183
10269
|
setCurrent(row, column, rowCount, columnCount, sheetId, unitId) {
|
|
10184
|
-
var _this$
|
|
10270
|
+
var _this$_currentConfigS2, _this$_currentConfigS3;
|
|
10185
10271
|
this._externalReferenceUnavailable = false;
|
|
10186
10272
|
this._currentRow = row;
|
|
10187
10273
|
this._currentColumn = column;
|
|
@@ -10189,8 +10275,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
|
|
|
10189
10275
|
this._currentColumnCount = columnCount;
|
|
10190
10276
|
this._currentSubUnitId = sheetId;
|
|
10191
10277
|
this._currentUnitId = unitId;
|
|
10192
|
-
const cell = (_this$
|
|
10193
|
-
const formula = (_this$
|
|
10278
|
+
const cell = (_this$_currentConfigS2 = this._currentConfigService.getUnitData()[unitId]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[sheetId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2.cellData.getValue(row, column);
|
|
10279
|
+
const formula = (_this$_currentConfigS3 = this._currentConfigService.getFormulaData()[unitId]) === null || _this$_currentConfigS3 === void 0 || (_this$_currentConfigS3 = _this$_currentConfigS3[sheetId]) === null || _this$_currentConfigS3 === void 0 || (_this$_currentConfigS3 = _this$_currentConfigS3[row]) === null || _this$_currentConfigS3 === void 0 ? void 0 : _this$_currentConfigS3[column];
|
|
10194
10280
|
if (formula) {
|
|
10195
10281
|
const isSharedFollower = (formula.x ?? 0) !== 0 || (formula.y ?? 0) !== 0;
|
|
10196
10282
|
this._currentSourceFormula = {
|
|
@@ -10251,9 +10337,9 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
|
|
|
10251
10337
|
}
|
|
10252
10338
|
setRuntimeData(functionVariant) {
|
|
10253
10339
|
if (this._externalReferenceUnavailable) {
|
|
10254
|
-
var _this$
|
|
10255
|
-
const cell = (_this$
|
|
10256
|
-
const formula = (_this$
|
|
10340
|
+
var _this$_currentConfigS4, _this$_currentConfigS5;
|
|
10341
|
+
const cell = (_this$_currentConfigS4 = this._currentConfigService.getUnitData()[this._currentUnitId]) === null || _this$_currentConfigS4 === void 0 || (_this$_currentConfigS4 = _this$_currentConfigS4[this._currentSubUnitId]) === null || _this$_currentConfigS4 === void 0 ? void 0 : _this$_currentConfigS4.cellData.getValue(this._currentRow, this._currentColumn);
|
|
10342
|
+
const formula = (_this$_currentConfigS5 = this._currentConfigService.getFormulaData()[this._currentUnitId]) === null || _this$_currentConfigS5 === void 0 || (_this$_currentConfigS5 = _this$_currentConfigS5[this._currentSubUnitId]) === null || _this$_currentConfigS5 === void 0 || (_this$_currentConfigS5 = _this$_currentConfigS5[this._currentRow]) === null || _this$_currentConfigS5 === void 0 || (_this$_currentConfigS5 = _this$_currentConfigS5[this._currentColumn]) === null || _this$_currentConfigS5 === void 0 ? void 0 : _this$_currentConfigS5.f;
|
|
10257
10343
|
if ((cell === null || cell === void 0 ? void 0 : cell.f) && cell.v != null && (formula == null || formula === cell.f)) return;
|
|
10258
10344
|
}
|
|
10259
10345
|
const row = this._currentRow;
|
|
@@ -10312,7 +10398,7 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
|
|
|
10312
10398
|
const hasDataInArrayFormulaRange = this._checkIfArrayFormulaRangeHasData(unitId, sheetId, row, column, arrayRange);
|
|
10313
10399
|
const isArrayFormulaExceeded = this._checkIfArrayFormulaExceeded(rowCount, columnCount, arrayRange);
|
|
10314
10400
|
if (hasDataInArrayFormulaRange || isArrayFormulaExceeded) {
|
|
10315
|
-
var _this$
|
|
10401
|
+
var _this$_currentConfigS6;
|
|
10316
10402
|
const errorObject = this._getValueObjectOfRuntimeData(ErrorValueObject.create("#SPILL!"));
|
|
10317
10403
|
sheetData.setValue(row, column, errorObject);
|
|
10318
10404
|
clearArrayUnitData.setValue(row, column, errorObject);
|
|
@@ -10323,7 +10409,7 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
|
|
|
10323
10409
|
*/
|
|
10324
10410
|
const unitData = this._currentConfigService.getUnitData();
|
|
10325
10411
|
const arrayData = this._currentConfigService.getArrayFormulaCellData();
|
|
10326
|
-
const previousArrayFormulaRange = (_this$
|
|
10412
|
+
const previousArrayFormulaRange = (_this$_currentConfigS6 = this._currentConfigService.getArrayFormulaRange()[unitId]) === null || _this$_currentConfigS6 === void 0 || (_this$_currentConfigS6 = _this$_currentConfigS6[sheetId]) === null || _this$_currentConfigS6 === void 0 || (_this$_currentConfigS6 = _this$_currentConfigS6[row]) === null || _this$_currentConfigS6 === void 0 ? void 0 : _this$_currentConfigS6[column];
|
|
10327
10413
|
objectValueRefOrArray.iterator((_, rowIndex, columnIndex) => {
|
|
10328
10414
|
var _unitData$unitId, _arrayData$unitId;
|
|
10329
10415
|
const currentRow = rowIndex - startRow + row;
|
|
@@ -10440,6 +10526,7 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
|
|
|
10440
10526
|
getAllRuntimeData() {
|
|
10441
10527
|
return {
|
|
10442
10528
|
unitData: this.getUnitData(),
|
|
10529
|
+
circularReferences: Array.from(this._circularReferences.values(), (cell) => ({ ...cell })),
|
|
10443
10530
|
sourceFormulaData: this._sourceFormulaData,
|
|
10444
10531
|
arrayFormulaRange: this.getUnitArrayFormula(),
|
|
10445
10532
|
arrayFormulaEmbedded: this.getUnitArrayFormulaEmbeddedMap(),
|
|
@@ -10460,6 +10547,7 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
|
|
|
10460
10547
|
totalArrayFormulasToCalculate: this.getTotalArrayFormulasToCalculate(),
|
|
10461
10548
|
completedArrayFormulasCount: this.getCompletedArrayFormulasCount(),
|
|
10462
10549
|
stage: this.getFormulaExecuteStage(),
|
|
10550
|
+
circularReferences: Array.from(this._circularReferences.values(), (cell) => ({ ...cell })),
|
|
10463
10551
|
formulaCycleIndex: this.getFormulaCycleIndex()
|
|
10464
10552
|
};
|
|
10465
10553
|
}
|
|
@@ -10467,11 +10555,11 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
|
|
|
10467
10555
|
FORMULA_REF_TO_ARRAY_CACHE.clear();
|
|
10468
10556
|
}
|
|
10469
10557
|
_checkIfArrayFormulaRangeHasData(formulaUnitId, formulaSheetId, formulaRow, formulaColumn, arrayRange) {
|
|
10470
|
-
var _this$
|
|
10558
|
+
var _this$_currentConfigS7;
|
|
10471
10559
|
const { startRow, startColumn, endRow, endColumn } = arrayRange;
|
|
10472
10560
|
const unitData = this._currentConfigService.getUnitData();
|
|
10473
10561
|
const arrayData = this._currentConfigService.getArrayFormulaCellData();
|
|
10474
|
-
const previousArrayFormulaRange = (_this$
|
|
10562
|
+
const previousArrayFormulaRange = (_this$_currentConfigS7 = this._currentConfigService.getArrayFormulaRange()[formulaUnitId]) === null || _this$_currentConfigS7 === void 0 || (_this$_currentConfigS7 = _this$_currentConfigS7[formulaSheetId]) === null || _this$_currentConfigS7 === void 0 || (_this$_currentConfigS7 = _this$_currentConfigS7[formulaRow]) === null || _this$_currentConfigS7 === void 0 ? void 0 : _this$_currentConfigS7[formulaColumn];
|
|
10475
10563
|
for (let r = startRow; r <= endRow; r++) for (let c = startColumn; c <= endColumn; c++) {
|
|
10476
10564
|
var _this$_runtimeData, _arrayData$formulaUni, _unitData$formulaUnit;
|
|
10477
10565
|
if (r === formulaRow && formulaColumn === c) continue;
|
|
@@ -10507,8 +10595,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
|
|
|
10507
10595
|
* @returns
|
|
10508
10596
|
*/
|
|
10509
10597
|
_isInOtherArrayFormulaRange(formulaUnitId, formulaSheetId, formulaRow, formulaColumn, r, c) {
|
|
10510
|
-
var _this$
|
|
10511
|
-
const arrayFormulaRange = (_this$
|
|
10598
|
+
var _this$_currentConfigS8;
|
|
10599
|
+
const arrayFormulaRange = (_this$_currentConfigS8 = this._currentConfigService.getArrayFormulaRange()[formulaUnitId]) === null || _this$_currentConfigS8 === void 0 ? void 0 : _this$_currentConfigS8[formulaSheetId];
|
|
10512
10600
|
if (arrayFormulaRange == null) return false;
|
|
10513
10601
|
let isCellOverlapping = false;
|
|
10514
10602
|
new ObjectMatrix(arrayFormulaRange).forValue((rangeRow, rangeCol, range) => {
|
|
@@ -10521,8 +10609,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
|
|
|
10521
10609
|
return isCellOverlapping;
|
|
10522
10610
|
}
|
|
10523
10611
|
_isCurrentSingleCellArrayFormulaRange(unitId, sheetId, row, column) {
|
|
10524
|
-
var _this$
|
|
10525
|
-
const range = (_this$
|
|
10612
|
+
var _this$_currentConfigS9;
|
|
10613
|
+
const range = (_this$_currentConfigS9 = this._currentConfigService.getArrayFormulaRange()[unitId]) === null || _this$_currentConfigS9 === void 0 || (_this$_currentConfigS9 = _this$_currentConfigS9[sheetId]) === null || _this$_currentConfigS9 === void 0 || (_this$_currentConfigS9 = _this$_currentConfigS9[row]) === null || _this$_currentConfigS9 === void 0 ? void 0 : _this$_currentConfigS9[column];
|
|
10526
10614
|
return range != null && range.startRow === range.endRow && range.startColumn === range.endColumn;
|
|
10527
10615
|
}
|
|
10528
10616
|
_isInArrayFormulaRange(range, r, c) {
|
|
@@ -10546,7 +10634,11 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
|
|
|
10546
10634
|
return isInDirtyRange(dirtyRanges, unitId, sheetId, row, column);
|
|
10547
10635
|
}
|
|
10548
10636
|
};
|
|
10549
|
-
FormulaRuntimeService = __decorate([
|
|
10637
|
+
FormulaRuntimeService = __decorate([
|
|
10638
|
+
__decorateParam(0, IFormulaCurrentConfigService),
|
|
10639
|
+
__decorateParam(1, IHyperlinkEngineFormulaService),
|
|
10640
|
+
__decorateParam(2, IUniverInstanceService)
|
|
10641
|
+
], FormulaRuntimeService);
|
|
10550
10642
|
const IFormulaRuntimeService = createIdentifier("univer.formula.runtime.service");
|
|
10551
10643
|
|
|
10552
10644
|
//#endregion
|
|
@@ -13550,6 +13642,90 @@ var OtherFormulaManagerService = class extends Disposable {
|
|
|
13550
13642
|
};
|
|
13551
13643
|
const IOtherFormulaManagerService = createIdentifier("univer.formula.other-formula-manager.service");
|
|
13552
13644
|
|
|
13645
|
+
//#endregion
|
|
13646
|
+
//#region src/engine/dependency/dependency-groups.ts
|
|
13647
|
+
/**
|
|
13648
|
+
* Copyright 2023-present DreamNum Co., Ltd.
|
|
13649
|
+
*
|
|
13650
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
13651
|
+
* you may not use this file except in compliance with the License.
|
|
13652
|
+
* You may obtain a copy of the License at
|
|
13653
|
+
*
|
|
13654
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
13655
|
+
*
|
|
13656
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13657
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13658
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13659
|
+
* See the License for the specific language governing permissions and
|
|
13660
|
+
* limitations under the License.
|
|
13661
|
+
*/
|
|
13662
|
+
/**
|
|
13663
|
+
* Returns strongly connected components in dependency order: precedents before their dependents.
|
|
13664
|
+
* Mutually dependent nodes stay together so only their group needs iterative calculation.
|
|
13665
|
+
* Uses iterative Kosaraju traversal to avoid overflowing the call stack on large dependency graphs.
|
|
13666
|
+
*/
|
|
13667
|
+
function getDependencyGroups(nodes, getId, getDependents) {
|
|
13668
|
+
const byId = new Map(nodes.map((node) => [getId(node), node]));
|
|
13669
|
+
const edges = /* @__PURE__ */ new Map();
|
|
13670
|
+
const reverse = /* @__PURE__ */ new Map();
|
|
13671
|
+
for (const node of nodes) {
|
|
13672
|
+
const id = getId(node);
|
|
13673
|
+
const dependents = Array.from(getDependents(node)).filter((dependent) => byId.has(dependent));
|
|
13674
|
+
edges.set(id, dependents);
|
|
13675
|
+
for (const dependent of dependents) {
|
|
13676
|
+
const incoming = reverse.get(dependent) ?? [];
|
|
13677
|
+
incoming.push(id);
|
|
13678
|
+
reverse.set(dependent, incoming);
|
|
13679
|
+
}
|
|
13680
|
+
}
|
|
13681
|
+
const visited = /* @__PURE__ */ new Set();
|
|
13682
|
+
const order = [];
|
|
13683
|
+
for (const id of byId.keys()) {
|
|
13684
|
+
if (visited.has(id)) continue;
|
|
13685
|
+
visited.add(id);
|
|
13686
|
+
const stack = [{
|
|
13687
|
+
id,
|
|
13688
|
+
next: 0
|
|
13689
|
+
}];
|
|
13690
|
+
while (stack.length) {
|
|
13691
|
+
const frame = stack[stack.length - 1];
|
|
13692
|
+
const children = edges.get(frame.id);
|
|
13693
|
+
if (frame.next === children.length) {
|
|
13694
|
+
order.push(frame.id);
|
|
13695
|
+
stack.pop();
|
|
13696
|
+
continue;
|
|
13697
|
+
}
|
|
13698
|
+
const child = children[frame.next++];
|
|
13699
|
+
if (!visited.has(child)) {
|
|
13700
|
+
visited.add(child);
|
|
13701
|
+
stack.push({
|
|
13702
|
+
id: child,
|
|
13703
|
+
next: 0
|
|
13704
|
+
});
|
|
13705
|
+
}
|
|
13706
|
+
}
|
|
13707
|
+
}
|
|
13708
|
+
visited.clear();
|
|
13709
|
+
const groups = [];
|
|
13710
|
+
for (let i = order.length - 1; i >= 0; i--) {
|
|
13711
|
+
const id = order[i];
|
|
13712
|
+
if (visited.has(id)) continue;
|
|
13713
|
+
const group = [];
|
|
13714
|
+
const stack = [id];
|
|
13715
|
+
visited.add(id);
|
|
13716
|
+
while (stack.length) {
|
|
13717
|
+
const current = stack.pop();
|
|
13718
|
+
group.push(byId.get(current));
|
|
13719
|
+
for (const parent of reverse.get(current) ?? []) if (!visited.has(parent)) {
|
|
13720
|
+
visited.add(parent);
|
|
13721
|
+
stack.push(parent);
|
|
13722
|
+
}
|
|
13723
|
+
}
|
|
13724
|
+
groups.push(group);
|
|
13725
|
+
}
|
|
13726
|
+
return groups;
|
|
13727
|
+
}
|
|
13728
|
+
|
|
13553
13729
|
//#endregion
|
|
13554
13730
|
//#region src/engine/dependency/dependency-tree.ts
|
|
13555
13731
|
let FormulaDependencyTreeType = /* @__PURE__ */ function(FormulaDependencyTreeType) {
|
|
@@ -13562,6 +13738,7 @@ var FormulaDependencyTreeCalculator = class {
|
|
|
13562
13738
|
constructor() {
|
|
13563
13739
|
_defineProperty(this, "_state", 0);
|
|
13564
13740
|
_defineProperty(this, "type", 0);
|
|
13741
|
+
_defineProperty(this, "cycleGroup", void 0);
|
|
13565
13742
|
_defineProperty(this, "treeId", void 0);
|
|
13566
13743
|
_defineProperty(this, "children", /* @__PURE__ */ new Set());
|
|
13567
13744
|
_defineProperty(this, "parents", /* @__PURE__ */ new Set());
|
|
@@ -13983,7 +14160,28 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
|
|
|
13983
14160
|
await this._generateTreeList(formulaData, otherFormulaData, unitData);
|
|
13984
14161
|
this._dependencyManagerService.openKdTree();
|
|
13985
14162
|
const updateTreeList = this._getUpdateTreeListAndMakeDependency();
|
|
13986
|
-
const
|
|
14163
|
+
const runList = this._calculateRunList(updateTreeList);
|
|
14164
|
+
const selfReferences = /* @__PURE__ */ new Set();
|
|
14165
|
+
const groups = getDependencyGroups(runList, (tree) => tree.treeId, (tree) => {
|
|
14166
|
+
const dependents = this._dependencyManagerService.searchDependency(tree.toRTreeItem());
|
|
14167
|
+
const addressDependents = this._dependencyRTreeCacheForAddressFunction.bulkSearch(tree.toRTreeItem());
|
|
14168
|
+
for (const dependent of addressDependents) dependents.add(dependent);
|
|
14169
|
+
if (dependents.has(tree.treeId)) selfReferences.add(tree.treeId);
|
|
14170
|
+
return dependents;
|
|
14171
|
+
});
|
|
14172
|
+
this._runtimeService.clearCircularReferenceCells(runList);
|
|
14173
|
+
for (const group of groups) {
|
|
14174
|
+
const cyclic = group.length > 1 || selfReferences.has(group[0].treeId);
|
|
14175
|
+
const groupId = cyclic ? group.map((tree) => tree.treeId).sort((a, b) => a - b).join(",") : void 0;
|
|
14176
|
+
for (const tree of group) {
|
|
14177
|
+
tree.cycleGroup = groupId;
|
|
14178
|
+
if (cyclic) {
|
|
14179
|
+
var _this$_runtimeService;
|
|
14180
|
+
(_this$_runtimeService = this._runtimeService.getUnitData()[tree.unitId]) === null || _this$_runtimeService === void 0 || (_this$_runtimeService = _this$_runtimeService[tree.subUnitId]) === null || _this$_runtimeService === void 0 || _this$_runtimeService.realDeleteValue(tree.row, tree.column);
|
|
14181
|
+
}
|
|
14182
|
+
}
|
|
14183
|
+
}
|
|
14184
|
+
const finalTreeList = groups.flat().reverse();
|
|
13987
14185
|
if (this._checkIsCycleDependency(finalTreeList)) this._runtimeService.enableCycleDependency();
|
|
13988
14186
|
if (isCalculateTreeModel) this._runtimeService.setDependencyTreeModelData(this._getAllDependencyJson(Array.from(this._dependencyTreeCache.values())));
|
|
13989
14187
|
this._dependencyTreeCache.clear();
|
|
@@ -13992,41 +14190,8 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
|
|
|
13992
14190
|
this._runtimeService.clearArrayObjectCache();
|
|
13993
14191
|
return Promise.resolve(finalTreeList);
|
|
13994
14192
|
}
|
|
13995
|
-
_isCyclicUtilMap(treeId, colorMap) {
|
|
13996
|
-
const WHITE = 0;
|
|
13997
|
-
const GRAY = 1;
|
|
13998
|
-
const BLACK = 2;
|
|
13999
|
-
const stack = [treeId];
|
|
14000
|
-
while (stack.length > 0) {
|
|
14001
|
-
const currentTreeId = stack[stack.length - 1];
|
|
14002
|
-
if ((colorMap.get(currentTreeId) || WHITE) === WHITE) {
|
|
14003
|
-
colorMap.set(currentTreeId, GRAY);
|
|
14004
|
-
const node = this._dependencyTreeCache.get(currentTreeId);
|
|
14005
|
-
if (node == null) {
|
|
14006
|
-
colorMap.set(currentTreeId, BLACK);
|
|
14007
|
-
stack.pop();
|
|
14008
|
-
continue;
|
|
14009
|
-
}
|
|
14010
|
-
const parents = this._dependencyManagerService.searchDependency(node.toRTreeItem());
|
|
14011
|
-
for (const parentTreeId of parents) {
|
|
14012
|
-
const parentColor = colorMap.get(parentTreeId) || WHITE;
|
|
14013
|
-
if (parentColor === GRAY) return true;
|
|
14014
|
-
else if (parentColor === WHITE) stack.push(parentTreeId);
|
|
14015
|
-
}
|
|
14016
|
-
} else {
|
|
14017
|
-
colorMap.set(currentTreeId, BLACK);
|
|
14018
|
-
stack.pop();
|
|
14019
|
-
}
|
|
14020
|
-
}
|
|
14021
|
-
return false;
|
|
14022
|
-
}
|
|
14023
14193
|
_checkIsCycleDependency(treeList) {
|
|
14024
|
-
|
|
14025
|
-
for (const tree of treeList) if (!colorMap.has(tree.treeId)) {
|
|
14026
|
-
if (this._isCyclicUtilMap(tree.treeId, colorMap)) return true;
|
|
14027
|
-
}
|
|
14028
|
-
colorMap.clear();
|
|
14029
|
-
return false;
|
|
14194
|
+
return treeList.some((tree) => tree.cycleGroup != null);
|
|
14030
14195
|
}
|
|
14031
14196
|
_getFeatureFormulaTree(featureId, treeId, params) {
|
|
14032
14197
|
const { unitId, subUnitId, dependencyRanges, getDirtyData } = params;
|
|
@@ -14410,11 +14575,17 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
|
|
|
14410
14575
|
if (node.nodeType === 12 && node.getToken() === "#") return true;
|
|
14411
14576
|
return false;
|
|
14412
14577
|
}
|
|
14578
|
+
_isStaticReference(node) {
|
|
14579
|
+
return node.nodeType === 1 || node.nodeType === 10 && node.getChildren().every((child) => this._isStaticReference(child));
|
|
14580
|
+
}
|
|
14413
14581
|
_nodeTraversalRef(node, result) {
|
|
14414
14582
|
const children = node.getChildren();
|
|
14415
14583
|
const childrenCount = children.length;
|
|
14584
|
+
const token = node.getToken();
|
|
14585
|
+
const readsReferenceMetadata = node.nodeType === 4 && (token === "ROW" || token === "ROWS" || token === "COLUMN" || token === "COLUMNS");
|
|
14416
14586
|
for (let i = 0; i < childrenCount; i++) {
|
|
14417
14587
|
const item = children[i];
|
|
14588
|
+
if (readsReferenceMetadata && this._isStaticReference(item)) continue;
|
|
14418
14589
|
if (this._isPreCalculateNode(item)) {
|
|
14419
14590
|
result.push(item);
|
|
14420
14591
|
if (item.nodeType === 10) {
|
|
@@ -14658,9 +14829,10 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
|
|
|
14658
14829
|
* @param tree
|
|
14659
14830
|
*/
|
|
14660
14831
|
_includeTree(tree, node) {
|
|
14661
|
-
var _this$_currentConfigS, _this$_currentConfigS2;
|
|
14832
|
+
var _this$_currentConfigS, _this$_currentConfigS2, _this$_currentConfigS3;
|
|
14662
14833
|
const unitId = tree.unitId;
|
|
14663
14834
|
const subUnitId = tree.subUnitId;
|
|
14835
|
+
if ((_this$_currentConfigS = this._currentConfigService.getDirtyData().dirtyIterationUnits) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.includes(unitId)) return true;
|
|
14664
14836
|
/**
|
|
14665
14837
|
* RAND, RANDBETWEEN, NOW, TODAY are volatile functions that are marked dirty and recalculated every time a calculation occurs.
|
|
14666
14838
|
*/
|
|
@@ -14668,13 +14840,13 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
|
|
|
14668
14840
|
if (this._includeTreeFeature(tree) === true) return true;
|
|
14669
14841
|
if (this._includeOtherFormula(tree) === true) return true;
|
|
14670
14842
|
if (includeDefinedName(tree, node, this._currentConfigService) === true) return true;
|
|
14671
|
-
const excludedCell = (_this$
|
|
14843
|
+
const excludedCell = (_this$_currentConfigS2 = this._currentConfigService.getExcludedRange()) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[unitId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2[subUnitId];
|
|
14672
14844
|
if ((excludedCell === null || excludedCell === void 0 ? void 0 : excludedCell.getValue(tree.row, tree.column)) != null) return false;
|
|
14673
14845
|
/**
|
|
14674
14846
|
* When a worksheet is inserted or deleted,
|
|
14675
14847
|
* the formulas within it need to be calculated.
|
|
14676
14848
|
*/
|
|
14677
|
-
if (((_this$
|
|
14849
|
+
if (((_this$_currentConfigS3 = this._currentConfigService.getDirtyNameMap()[unitId]) === null || _this$_currentConfigS3 === void 0 ? void 0 : _this$_currentConfigS3[subUnitId]) != null) return true;
|
|
14678
14850
|
if (!this._updateRangeFlattenCache.has(unitId)) return false;
|
|
14679
14851
|
const sheetRangeMap = this._updateRangeFlattenCache.get(unitId);
|
|
14680
14852
|
if (!sheetRangeMap.has(subUnitId)) return false;
|
|
@@ -14837,6 +15009,105 @@ FormulaDependencyGenerator = __decorate([
|
|
|
14837
15009
|
const DEFAULT_INTERVAL_COUNT = 500;
|
|
14838
15010
|
const ICalculateFormulaService = createIdentifier("engine-formula.calculate-formula.service");
|
|
14839
15011
|
let CalculateFormulaService = class CalculateFormulaService extends Disposable {
|
|
15012
|
+
_loadCalculationSettings(settings) {
|
|
15013
|
+
this._workbookCalculationSettings = settings ?? {};
|
|
15014
|
+
this._normalizedCalculationSettings.clear();
|
|
15015
|
+
}
|
|
15016
|
+
_getCalculationSettings(unitId) {
|
|
15017
|
+
let settings = this._normalizedCalculationSettings.get(unitId);
|
|
15018
|
+
if (settings == null) {
|
|
15019
|
+
settings = normalizeWorkbookCalculationSettings(this._workbookCalculationSettings[unitId]);
|
|
15020
|
+
this._normalizedCalculationSettings.set(unitId, settings);
|
|
15021
|
+
}
|
|
15022
|
+
return settings;
|
|
15023
|
+
}
|
|
15024
|
+
_getIterationCell(tree) {
|
|
15025
|
+
var _this$_runtimeService, _this$_currentConfigS;
|
|
15026
|
+
const cell = ((_this$_runtimeService = this._runtimeService.getUnitData()[tree.unitId]) === null || _this$_runtimeService === void 0 || (_this$_runtimeService = _this$_runtimeService[tree.subUnitId]) === null || _this$_runtimeService === void 0 ? void 0 : _this$_runtimeService.getValue(tree.row, tree.column)) ?? ((_this$_currentConfigS = this._currentConfigService.getUnitData()[tree.unitId]) === null || _this$_currentConfigS === void 0 || (_this$_currentConfigS = _this$_currentConfigS[tree.subUnitId]) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.cellData.getValue(tree.row, tree.column)) ?? { v: 0 };
|
|
15027
|
+
return cell.v == null ? {
|
|
15028
|
+
v: 0,
|
|
15029
|
+
t: CellValueType.NUMBER
|
|
15030
|
+
} : cell;
|
|
15031
|
+
}
|
|
15032
|
+
async *_iterateCalculationGroup(group, groupId) {
|
|
15033
|
+
const settings = group.map((item) => this._getCalculationSettings(item.unitId));
|
|
15034
|
+
if (group.every((item, i) => {
|
|
15035
|
+
var _this$_currentConfigS2;
|
|
15036
|
+
const cell = (_this$_currentConfigS2 = this._currentConfigService.getUnitData()[item.unitId]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[item.subUnitId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2.cellData.getValue(item.row, item.column);
|
|
15037
|
+
const formula = (item.formula ?? (cell === null || cell === void 0 ? void 0 : cell.f) ?? "").toUpperCase();
|
|
15038
|
+
const requiresRecalculation = formula.includes(`${"INDEX"}(`) && !(formula.includes(`${"LOOKUP"}(`) && !formula.includes(`${"XLOOKUP"}(`));
|
|
15039
|
+
return settings[i].iterativeCalculation && this._preserveCircularUnits.has(item.unitId) && (cell === null || cell === void 0 ? void 0 : cell.v) != null && !requiresRecalculation;
|
|
15040
|
+
})) {
|
|
15041
|
+
for (const tree of group) yield {
|
|
15042
|
+
tree,
|
|
15043
|
+
preserve: true,
|
|
15044
|
+
iteration: 0
|
|
15045
|
+
};
|
|
15046
|
+
this._runtimeService.recordCircularReferences(group.map((item) => ({
|
|
15047
|
+
unitId: item.unitId,
|
|
15048
|
+
sheetId: item.subUnitId,
|
|
15049
|
+
row: item.row,
|
|
15050
|
+
column: item.column,
|
|
15051
|
+
groupId,
|
|
15052
|
+
iterations: 0
|
|
15053
|
+
})));
|
|
15054
|
+
return;
|
|
15055
|
+
}
|
|
15056
|
+
const limit = settings.reduce((limit, setting) => Math.max(limit, setting.iterativeCalculation ? setting.maxIterations : 0), 1);
|
|
15057
|
+
let converged = false;
|
|
15058
|
+
let iterations = 0;
|
|
15059
|
+
const beforeValues = [];
|
|
15060
|
+
const beforeTypes = [];
|
|
15061
|
+
for (let iteration = 0; iteration < limit; iteration++) {
|
|
15062
|
+
for (let i = 0; i < group.length; i++) if (settings[i].iterativeCalculation) {
|
|
15063
|
+
const before = this._getIterationCell(group[i]);
|
|
15064
|
+
beforeValues[i] = before.v;
|
|
15065
|
+
beforeTypes[i] = before.t;
|
|
15066
|
+
}
|
|
15067
|
+
for (let i = 0; i < group.length; i++) if (iteration < (settings[i].iterativeCalculation ? settings[i].maxIterations : 1)) {
|
|
15068
|
+
FORMULA_REF_TO_ARRAY_CACHE.clear();
|
|
15069
|
+
yield {
|
|
15070
|
+
tree: group[i],
|
|
15071
|
+
preserve: !settings[i].iterativeCalculation,
|
|
15072
|
+
iteration
|
|
15073
|
+
};
|
|
15074
|
+
}
|
|
15075
|
+
iterations = iteration + 1;
|
|
15076
|
+
converged = group.every((item, i) => {
|
|
15077
|
+
if (!settings[i].iterativeCalculation) return true;
|
|
15078
|
+
const after = this._getIterationCell(item);
|
|
15079
|
+
const previousValue = beforeValues[i];
|
|
15080
|
+
return typeof after.v === "number" && typeof previousValue === "number" && (after.t == null || after.t === CellValueType.NUMBER) && (beforeTypes[i] == null || beforeTypes[i] === CellValueType.NUMBER) ? Number.isFinite(after.v) && Math.abs(after.v - previousValue) <= settings[i].maxChange : after.t === beforeTypes[i] && after.v === previousValue;
|
|
15081
|
+
});
|
|
15082
|
+
if (converged) break;
|
|
15083
|
+
}
|
|
15084
|
+
FORMULA_REF_TO_ARRAY_CACHE.clear();
|
|
15085
|
+
this._runtimeService.recordCircularReferences(group.map((item, i) => ({
|
|
15086
|
+
unitId: item.unitId,
|
|
15087
|
+
sheetId: item.subUnitId,
|
|
15088
|
+
row: item.row,
|
|
15089
|
+
column: item.column,
|
|
15090
|
+
groupId,
|
|
15091
|
+
iterations: settings[i].iterativeCalculation ? Math.min(iterations, settings[i].maxIterations) : 0,
|
|
15092
|
+
converged: settings[i].iterativeCalculation ? converged : void 0
|
|
15093
|
+
})));
|
|
15094
|
+
}
|
|
15095
|
+
async *_getCalculationSteps(trees) {
|
|
15096
|
+
while (trees.length) {
|
|
15097
|
+
const tree = trees.pop();
|
|
15098
|
+
if (tree.cycleGroup == null) {
|
|
15099
|
+
yield {
|
|
15100
|
+
tree,
|
|
15101
|
+
preserve: false,
|
|
15102
|
+
iteration: 0
|
|
15103
|
+
};
|
|
15104
|
+
continue;
|
|
15105
|
+
}
|
|
15106
|
+
const group = [tree];
|
|
15107
|
+
while (trees.length && trees[trees.length - 1].cycleGroup === tree.cycleGroup) group.push(trees.pop());
|
|
15108
|
+
yield* this._iterateCalculationGroup(group, tree.cycleGroup);
|
|
15109
|
+
}
|
|
15110
|
+
}
|
|
14840
15111
|
constructor(_configService, _lexer, _currentConfigService, _runtimeService, _formulaDependencyGenerator, _interpreter, _astTreeBuilder) {
|
|
14841
15112
|
super();
|
|
14842
15113
|
this._configService = _configService;
|
|
@@ -14852,6 +15123,9 @@ let CalculateFormulaService = class CalculateFormulaService extends Disposable {
|
|
|
14852
15123
|
_defineProperty(this, "executionCompleteListener$", this._executionCompleteListener$.asObservable());
|
|
14853
15124
|
_defineProperty(this, "_executeLock", new AsyncLock());
|
|
14854
15125
|
_defineProperty(this, "_isCalculateTreeModel", false);
|
|
15126
|
+
_defineProperty(this, "_workbookCalculationSettings", {});
|
|
15127
|
+
_defineProperty(this, "_preserveCircularUnits", /* @__PURE__ */ new Set());
|
|
15128
|
+
_defineProperty(this, "_normalizedCalculationSettings", /* @__PURE__ */ new Map());
|
|
14855
15129
|
}
|
|
14856
15130
|
dispose() {
|
|
14857
15131
|
super.dispose();
|
|
@@ -14887,15 +15161,12 @@ let CalculateFormulaService = class CalculateFormulaService extends Disposable {
|
|
|
14887
15161
|
this._executionInProgressListener$.next(this._runtimeService.getRuntimeState());
|
|
14888
15162
|
this._currentConfigService.load(formulaDatasetConfig);
|
|
14889
15163
|
this._runtimeService.reset();
|
|
14890
|
-
|
|
15164
|
+
this._loadCalculationSettings(formulaDatasetConfig.calculationSettings);
|
|
15165
|
+
this._preserveCircularUnits = new Set(formulaDatasetConfig.preserveCircularUnits);
|
|
15166
|
+
this._runtimeService.beginCircularReferences();
|
|
14891
15167
|
this._isCalculateTreeModel = formulaDatasetConfig.isCalculateTreeModel || false;
|
|
14892
|
-
|
|
14893
|
-
|
|
14894
|
-
const executed = await this._executeStep();
|
|
14895
|
-
FORMULA_REF_TO_ARRAY_CACHE.clear();
|
|
14896
|
-
const isCycleDependency = this._runtimeService.isCycleDependency();
|
|
14897
|
-
if (!executed || !isCycleDependency) break;
|
|
14898
|
-
}
|
|
15168
|
+
await this._executeStep();
|
|
15169
|
+
this._runtimeService.completeCircularReferences();
|
|
14899
15170
|
this._runtimeService.setFormulaExecuteStage(8);
|
|
14900
15171
|
this._executionInProgressListener$.next(this._runtimeService.getRuntimeState());
|
|
14901
15172
|
this._executionCompleteListener$.next(this._runtimeService.getAllRuntimeData());
|
|
@@ -14976,15 +15247,9 @@ let CalculateFormulaService = class CalculateFormulaService extends Disposable {
|
|
|
14976
15247
|
const intervalCount = (config === null || config === void 0 ? void 0 : config.intervalCount) || 500;
|
|
14977
15248
|
let i = 0;
|
|
14978
15249
|
const treeCount = treeList.length;
|
|
14979
|
-
|
|
14980
|
-
|
|
15250
|
+
for await (const { tree, preserve, iteration } of this._getCalculationSteps(treeList)) {
|
|
15251
|
+
this._runtimeService.setFormulaCycleIndex(iteration);
|
|
14981
15252
|
this._runtimeService.setCurrent(tree.row, tree.column, tree.rowCount, tree.columnCount, tree.subUnitId, tree.unitId);
|
|
14982
|
-
const node = generateAstNode(tree.unitId, tree.formula, this._lexer, this._astTreeBuilder, this._currentConfigService, tree.subUnitId, tree.column, tree.row);
|
|
14983
|
-
const nodeData = {
|
|
14984
|
-
node,
|
|
14985
|
-
refOffsetX: tree.refOffsetX,
|
|
14986
|
-
refOffsetY: tree.refOffsetY
|
|
14987
|
-
};
|
|
14988
15253
|
const getDirtyData = tree.getDirtyData;
|
|
14989
15254
|
if (i % intervalCount === 0) {
|
|
14990
15255
|
/**
|
|
@@ -15002,12 +15267,23 @@ let CalculateFormulaService = class CalculateFormulaService extends Disposable {
|
|
|
15002
15267
|
this._runtimeService.setCompletedFormulasCount(i + 1);
|
|
15003
15268
|
}
|
|
15004
15269
|
this._executionInProgressListener$.next(this._runtimeService.getRuntimeState());
|
|
15005
|
-
if (this._runtimeService.isStopExecution()
|
|
15270
|
+
if (this._runtimeService.isStopExecution()) {
|
|
15006
15271
|
this._runtimeService.setFormulaExecuteStage(0);
|
|
15007
15272
|
this._runtimeService.markedAsStopFunctionsExecuted();
|
|
15008
15273
|
return;
|
|
15009
15274
|
}
|
|
15010
15275
|
}
|
|
15276
|
+
if (preserve) {
|
|
15277
|
+
this._runtimeService.preserveCurrentCellData();
|
|
15278
|
+
i++;
|
|
15279
|
+
continue;
|
|
15280
|
+
}
|
|
15281
|
+
const node = generateAstNode(tree.unitId, tree.formula, this._lexer, this._astTreeBuilder, this._currentConfigService, tree.subUnitId, tree.column, tree.row);
|
|
15282
|
+
const nodeData = {
|
|
15283
|
+
node,
|
|
15284
|
+
refOffsetX: tree.refOffsetX,
|
|
15285
|
+
refOffsetY: tree.refOffsetY
|
|
15286
|
+
};
|
|
15011
15287
|
let value;
|
|
15012
15288
|
if (getDirtyData != null && tree.featureId != null) {
|
|
15013
15289
|
/**
|
|
@@ -15183,11 +15459,12 @@ let CalculateController = class CalculateController extends Disposable {
|
|
|
15183
15459
|
}));
|
|
15184
15460
|
}
|
|
15185
15461
|
async _calculate(formulaDirtyData) {
|
|
15186
|
-
const { forceCalculation: forceCalculate = false, dirtyRanges = [], dirtyNameMap = {}, dirtyDefinedNameMap = {}, dirtySuperTableMap = {}, dirtyUnitFeatureMap = {}, dirtyUnitOtherFormulaMap = {}, clearDependencyTreeCache = {},
|
|
15462
|
+
const { dirtyIterationUnits, forceCalculation: forceCalculate = false, dirtyRanges = [], dirtyNameMap = {}, dirtyDefinedNameMap = {}, dirtySuperTableMap = {}, dirtyUnitFeatureMap = {}, dirtyUnitOtherFormulaMap = {}, clearDependencyTreeCache = {}, calculationSettings, rowData, externalReferences, isCalculateTreeModel = false } = formulaDirtyData;
|
|
15187
15463
|
const formulaData = this._formulaDataModel.getFormulaData();
|
|
15188
15464
|
const arrayFormulaCellData = this._formulaDataModel.getArrayFormulaCellData();
|
|
15189
15465
|
const arrayFormulaRange = this._formulaDataModel.getArrayFormulaRange();
|
|
15190
15466
|
this._calculateFormulaService.execute({
|
|
15467
|
+
dirtyIterationUnits,
|
|
15191
15468
|
formulaData,
|
|
15192
15469
|
arrayFormulaCellData,
|
|
15193
15470
|
arrayFormulaRange,
|
|
@@ -15199,7 +15476,7 @@ let CalculateController = class CalculateController extends Disposable {
|
|
|
15199
15476
|
dirtyUnitFeatureMap,
|
|
15200
15477
|
dirtyUnitOtherFormulaMap,
|
|
15201
15478
|
clearDependencyTreeCache,
|
|
15202
|
-
|
|
15479
|
+
calculationSettings,
|
|
15203
15480
|
isCalculateTreeModel,
|
|
15204
15481
|
rowData,
|
|
15205
15482
|
externalReferences
|
|
@@ -15247,7 +15524,10 @@ let CalculateController = class CalculateController extends Disposable {
|
|
|
15247
15524
|
break;
|
|
15248
15525
|
case 0:
|
|
15249
15526
|
}
|
|
15250
|
-
this._commandService.executeCommand(SetFormulaCalculationNotificationMutation.id, {
|
|
15527
|
+
this._commandService.executeCommand(SetFormulaCalculationNotificationMutation.id, {
|
|
15528
|
+
functionsExecutedState,
|
|
15529
|
+
circularReferences: data.circularReferences
|
|
15530
|
+
}, { onlyLocal: true });
|
|
15251
15531
|
});
|
|
15252
15532
|
/**
|
|
15253
15533
|
* Assignment operation after formula calculation.
|
|
@@ -21325,13 +21605,13 @@ const weekendNumberMap = {
|
|
|
21325
21605
|
17: [6]
|
|
21326
21606
|
};
|
|
21327
21607
|
function isValidWeekend(weekend) {
|
|
21328
|
-
if (typeof weekend === "string" && /^[
|
|
21608
|
+
if (typeof weekend === "string") return weekend.length === 7 && /^[01]{7}$/.test(weekend);
|
|
21329
21609
|
if (weekendNumberMap[Number(weekend)]) return true;
|
|
21330
21610
|
return false;
|
|
21331
21611
|
}
|
|
21332
21612
|
function getWeekendArray(weekend) {
|
|
21333
21613
|
if (!isValidWeekend(weekend)) return [];
|
|
21334
|
-
if (typeof weekend === "string"
|
|
21614
|
+
if (typeof weekend === "string") {
|
|
21335
21615
|
const result = [];
|
|
21336
21616
|
for (let i = 1; i <= weekend.length; i++) if (`${weekend[i - 1]}` === "1") {
|
|
21337
21617
|
if (i === weekend.length) result.push(0);
|
|
@@ -32706,7 +32986,7 @@ var Sort = class extends BaseFunction {
|
|
|
32706
32986
|
_getResult(array, sortIndexValue, sortOrderValue, byColValue, arrayRowCount, arrayColumnCount) {
|
|
32707
32987
|
if (!byColValue) {
|
|
32708
32988
|
if (sortIndexValue > arrayColumnCount) return ErrorValueObject.create("#VALUE!");
|
|
32709
|
-
const arrayValue = array.getArrayValue();
|
|
32989
|
+
const arrayValue = array.getArrayValue().slice();
|
|
32710
32990
|
arrayValue.sort(this._sort(sortIndexValue - 1, sortOrderValue));
|
|
32711
32991
|
return ArrayValueObject.create({
|
|
32712
32992
|
calculateValueList: arrayValue,
|
|
@@ -33638,30 +33918,18 @@ var Xlookup = class extends BaseFunction {
|
|
|
33638
33918
|
else resultArray = returnArray.slice(void 0, [0, 1]);
|
|
33639
33919
|
if (resultArray == null) return ErrorValueObject.create("#N/A");
|
|
33640
33920
|
return lookupValue.map((value) => {
|
|
33641
|
-
|
|
33642
|
-
if (checkErrorCombination) return checkErrorCombination;
|
|
33643
|
-
const result = this._handleSingleObject(value, lookupArray, resultArray, matchModeValue, searchModeValue);
|
|
33644
|
-
if (result.isError()) return ifNotFound;
|
|
33645
|
-
return this._blankResultAsZero(result);
|
|
33921
|
+
return this._getLookupResult(value, lookupArray, resultArray, ifNotFound, matchModeValue, searchModeValue);
|
|
33646
33922
|
});
|
|
33647
33923
|
}
|
|
33648
33924
|
const _lookupValue = lookupValue.isArray() ? lookupValue.get(0, 0) : lookupValue;
|
|
33649
|
-
if (columnCountLookup === columnCountReturn && rowCountLookup === rowCountReturn)
|
|
33650
|
-
const checkErrorCombination = this._checkErrorCombination(matchModeValue, searchModeValue);
|
|
33651
|
-
if (checkErrorCombination) return checkErrorCombination;
|
|
33652
|
-
const result = this._handleSingleObject(_lookupValue, lookupArray, returnArray, matchModeValue, searchModeValue);
|
|
33653
|
-
if (result.isError()) return ifNotFound;
|
|
33654
|
-
return this._blankResultAsZero(result);
|
|
33655
|
-
}
|
|
33925
|
+
if (columnCountLookup === columnCountReturn && rowCountLookup === rowCountReturn) return this._getLookupResult(_lookupValue, lookupArray, returnArray, ifNotFound, matchModeValue, searchModeValue);
|
|
33656
33926
|
let axis = 0;
|
|
33657
33927
|
/**
|
|
33658
33928
|
* 0 for rows
|
|
33659
33929
|
* 1 for columns
|
|
33660
33930
|
*/
|
|
33661
33931
|
if (columnCountLookup === columnCountReturn) axis = 1;
|
|
33662
|
-
|
|
33663
|
-
if (resultArray == null) return ErrorValueObject.create("#N/A");
|
|
33664
|
-
return resultArray;
|
|
33932
|
+
return this._getLookupResult(_lookupValue, lookupArray, returnArray, ifNotFound, matchModeValue, searchModeValue, axis);
|
|
33665
33933
|
}
|
|
33666
33934
|
_legacyImplicitLookupValue(lookupValue) {
|
|
33667
33935
|
if (!lookupValue.isArray()) return lookupValue;
|
|
@@ -33689,35 +33957,37 @@ var Xlookup = class extends BaseFunction {
|
|
|
33689
33957
|
if (rowIndex < 0 || rowIndex >= rowCount || columnIndex < 0 || columnIndex >= columnCount) return ErrorValueObject.create("#VALUE!");
|
|
33690
33958
|
return array.get(rowIndex, columnIndex) || ErrorValueObject.create("#VALUE!");
|
|
33691
33959
|
}
|
|
33692
|
-
|
|
33960
|
+
_getLookupResult(value, searchArray, resultArray, ifNotFound, matchModeValue, searchModeValue, axis) {
|
|
33961
|
+
if (value.isError()) return value;
|
|
33962
|
+
const checkErrorCombination = this._checkErrorCombination(matchModeValue, searchModeValue);
|
|
33963
|
+
if (checkErrorCombination) return checkErrorCombination;
|
|
33964
|
+
const position = this._findPosition(value, searchArray, matchModeValue, searchModeValue);
|
|
33965
|
+
if (position == null) return ifNotFound;
|
|
33966
|
+
if (axis === 0) return resultArray.slice([position.row, position.row + 1]) ?? ErrorValueObject.create("#N/A");
|
|
33967
|
+
if (axis === 1) return resultArray.slice(void 0, [position.column, position.column + 1]) ?? ErrorValueObject.create("#N/A");
|
|
33968
|
+
const result = resultArray.get(position.row, position.column) ?? NullValueObject.create();
|
|
33969
|
+
return this._blankResultAsZero(result);
|
|
33970
|
+
}
|
|
33971
|
+
_findPosition(value, searchArray, matchModeValue, searchModeValue) {
|
|
33693
33972
|
if ((searchModeValue === 2 || searchModeValue === -2) && matchModeValue !== 2) {
|
|
33694
33973
|
const searchType = getSearchModeValue(searchModeValue);
|
|
33695
33974
|
const matchType = getMatchModeValue(matchModeValue);
|
|
33696
|
-
|
|
33975
|
+
const rowOrColumn = searchArray.binarySearch(value, searchType, matchType);
|
|
33976
|
+
if (rowOrColumn == null) return null;
|
|
33977
|
+
return searchArray.getRowCount() === 1 ? {
|
|
33978
|
+
row: 0,
|
|
33979
|
+
column: rowOrColumn
|
|
33980
|
+
} : {
|
|
33981
|
+
row: rowOrColumn,
|
|
33982
|
+
column: 0
|
|
33983
|
+
};
|
|
33697
33984
|
}
|
|
33698
|
-
if (matchModeValue === 2)
|
|
33699
|
-
|
|
33700
|
-
|
|
33701
|
-
}
|
|
33702
|
-
_handleSingleObject(value, searchArray, resultArray, matchModeValue, searchModeValue) {
|
|
33703
|
-
if ((searchModeValue === 2 || searchModeValue === -2) && matchModeValue !== 2) {
|
|
33704
|
-
const searchType = getSearchModeValue(searchModeValue);
|
|
33705
|
-
const matchType = getMatchModeValue(matchModeValue);
|
|
33706
|
-
return this.binarySearch(value, searchArray, resultArray, searchType, matchType);
|
|
33985
|
+
if (matchModeValue === 2) {
|
|
33986
|
+
const matches = searchArray.compare(value, "=");
|
|
33987
|
+
return searchModeValue === -1 ? matches.getLastTruePosition() : matches.getFirstTruePosition();
|
|
33707
33988
|
}
|
|
33708
|
-
if (matchModeValue ===
|
|
33709
|
-
|
|
33710
|
-
return this._exactSearch(value, searchArray, resultArray, searchModeValue !== -1);
|
|
33711
|
-
}
|
|
33712
|
-
_exactSearch(value, searchArray, resultArray, isFirst) {
|
|
33713
|
-
const position = this._findExactPosition(value, searchArray, isFirst);
|
|
33714
|
-
if (position == null) return ErrorValueObject.create("#N/A");
|
|
33715
|
-
return resultArray.get(position.row, position.column) ?? ErrorValueObject.create("#N/A");
|
|
33716
|
-
}
|
|
33717
|
-
_exactSearchExpand(value, searchArray, resultArray, isFirst, axis) {
|
|
33718
|
-
const position = this._findExactPosition(value, searchArray, isFirst);
|
|
33719
|
-
if (position == null) return ErrorValueObject.create("#N/A");
|
|
33720
|
-
return axis === 0 ? resultArray.slice([position.row, position.row + 1]) ?? ErrorValueObject.create("#N/A") : resultArray.slice(void 0, [position.column, position.column + 1]) ?? ErrorValueObject.create("#N/A");
|
|
33989
|
+
if (matchModeValue === -1 || matchModeValue === 1) return searchArray.orderSearch(value, matchModeValue === 1 ? 2 : 1, searchModeValue === -1, false, true);
|
|
33990
|
+
return this._findExactPosition(value, searchArray, searchModeValue !== -1);
|
|
33721
33991
|
}
|
|
33722
33992
|
_findExactPosition(value, searchArray, isFirst) {
|
|
33723
33993
|
let position;
|
|
@@ -43744,7 +44014,7 @@ function getObjectValue(result, isUseStrip = false) {
|
|
|
43744
44014
|
//#endregion
|
|
43745
44015
|
//#region package.json
|
|
43746
44016
|
var name = "@univerjs/engine-formula";
|
|
43747
|
-
var version = "1.0
|
|
44017
|
+
var version = "1.1.0";
|
|
43748
44018
|
|
|
43749
44019
|
//#endregion
|
|
43750
44020
|
//#region src/services/global-computing-status.service.ts
|
|
@@ -43830,6 +44100,7 @@ let FormulaCalculationTriggerService = class FormulaCalculationTriggerService ex
|
|
|
43830
44100
|
_defineProperty(this, "_executionInProgress", false);
|
|
43831
44101
|
_defineProperty(this, "_hasPendingCalculation", false);
|
|
43832
44102
|
_defineProperty(this, "_stopRequested", false);
|
|
44103
|
+
_defineProperty(this, "_suppressed", false);
|
|
43833
44104
|
this._registerGenericDirtyConversions();
|
|
43834
44105
|
this._initialize();
|
|
43835
44106
|
}
|
|
@@ -43838,6 +44109,16 @@ let FormulaCalculationTriggerService = class FormulaCalculationTriggerService ex
|
|
|
43838
44109
|
this._started = true;
|
|
43839
44110
|
this._scheduleFlush();
|
|
43840
44111
|
}
|
|
44112
|
+
/** Snapshot reconstruction calculates these synchronous mutations in its isolated runtime. */
|
|
44113
|
+
runWithoutTriggering(operation) {
|
|
44114
|
+
const previous = this._suppressed;
|
|
44115
|
+
this._suppressed = true;
|
|
44116
|
+
try {
|
|
44117
|
+
return operation();
|
|
44118
|
+
} finally {
|
|
44119
|
+
this._suppressed = previous;
|
|
44120
|
+
}
|
|
44121
|
+
}
|
|
43841
44122
|
dispose() {
|
|
43842
44123
|
clearTimeout(this._timer);
|
|
43843
44124
|
this._waitingCommandQueue = [];
|
|
@@ -43857,7 +44138,7 @@ let FormulaCalculationTriggerService = class FormulaCalculationTriggerService ex
|
|
|
43857
44138
|
return;
|
|
43858
44139
|
}
|
|
43859
44140
|
const conversion = this._activeDirtyManagerService.get(command.id);
|
|
43860
|
-
if (!conversion) return;
|
|
44141
|
+
if (!conversion || this._suppressed) return;
|
|
43861
44142
|
if (((_conversion$shouldTri = conversion.shouldTrigger) === null || _conversion$shouldTri === void 0 ? void 0 : _conversion$shouldTri.call(conversion, command, options)) === false) return;
|
|
43862
44143
|
this._waitingCommandQueue.push(command);
|
|
43863
44144
|
this._scheduleFlush();
|
|
@@ -43946,6 +44227,8 @@ function mergeDirtyData(left, right) {
|
|
|
43946
44227
|
return result;
|
|
43947
44228
|
}
|
|
43948
44229
|
function appendDirtyData(target, source, rangeKeys) {
|
|
44230
|
+
var _source$dirtyIteratio;
|
|
44231
|
+
if ((_source$dirtyIteratio = source.dirtyIterationUnits) === null || _source$dirtyIteratio === void 0 ? void 0 : _source$dirtyIteratio.length) target.dirtyIterationUnits = Array.from(/* @__PURE__ */ new Set([...target.dirtyIterationUnits ?? [], ...source.dirtyIterationUnits]));
|
|
43949
44232
|
mergeDirtyRanges(target.dirtyRanges, source.dirtyRanges ?? [], rangeKeys);
|
|
43950
44233
|
mergeDirtyUnitStringMap(target.dirtyNameMap, source.dirtyNameMap);
|
|
43951
44234
|
mergeDirtyUnitStringMap(target.dirtyDefinedNameMap, source.dirtyDefinedNameMap);
|
|
@@ -43989,7 +44272,8 @@ function mergeDirtyUnitNestedMap(target, right) {
|
|
|
43989
44272
|
});
|
|
43990
44273
|
}
|
|
43991
44274
|
function hasDirtyData(dirtyData) {
|
|
43992
|
-
|
|
44275
|
+
var _dirtyData$dirtyItera;
|
|
44276
|
+
return dirtyData.forceCalculation || Boolean((_dirtyData$dirtyItera = dirtyData.dirtyIterationUnits) === null || _dirtyData$dirtyItera === void 0 ? void 0 : _dirtyData$dirtyItera.length) || dirtyData.dirtyRanges.length > 0 || hasNestedValue(dirtyData.dirtyNameMap) || hasNestedValue(dirtyData.dirtyDefinedNameMap) || hasNestedValue(dirtyData.dirtySuperTableMap) || hasNestedValue(dirtyData.dirtyUnitFeatureMap) || hasNestedValue(dirtyData.dirtyUnitOtherFormulaMap) || hasNestedValue(dirtyData.clearDependencyTreeCache);
|
|
43993
44277
|
}
|
|
43994
44278
|
function hasNestedValue(value) {
|
|
43995
44279
|
if (value == null) return false;
|
|
@@ -43997,7 +44281,8 @@ function hasNestedValue(value) {
|
|
|
43997
44281
|
return Object.values(value).some(hasNestedValue);
|
|
43998
44282
|
}
|
|
43999
44283
|
function dirtyDataIntersects(left, right) {
|
|
44000
|
-
|
|
44284
|
+
var _left$dirtyIterationU, _right$dirtyIteration;
|
|
44285
|
+
if (left.forceCalculation || right.forceCalculation || ((_left$dirtyIterationU = left.dirtyIterationUnits) === null || _left$dirtyIterationU === void 0 ? void 0 : _left$dirtyIterationU.length) || ((_right$dirtyIteration = right.dirtyIterationUnits) === null || _right$dirtyIteration === void 0 ? void 0 : _right$dirtyIteration.length)) return true;
|
|
44001
44286
|
if (left.dirtyRanges.some((leftRange) => right.dirtyRanges.some((rightRange) => leftRange.unitId === rightRange.unitId && leftRange.sheetId === rightRange.sheetId && Rectangle.intersects(leftRange.range, rightRange.range))) || clearedSheetIntersects(left, right) || clearedSheetIntersects(right, left)) return true;
|
|
44002
44287
|
return [
|
|
44003
44288
|
[left.dirtyNameMap, right.dirtyNameMap],
|
|
@@ -57446,4 +57731,8 @@ _defineProperty(UniverFormulaEnginePlugin, "version", version);
|
|
|
57446
57731
|
UniverFormulaEnginePlugin = __decorate([__decorateParam(1, Inject(Injector)), __decorateParam(2, IConfigService)], UniverFormulaEnginePlugin);
|
|
57447
57732
|
|
|
57448
57733
|
//#endregion
|
|
57449
|
-
|
|
57734
|
+
//#region src/services/formula-changeset-calculation.service.ts
|
|
57735
|
+
const IFormulaChangesetCalculationService = createIdentifier("engine-formula.changeset-calculation.service");
|
|
57736
|
+
|
|
57737
|
+
//#endregion
|
|
57738
|
+
export { ALL_IMPLEMENTED_FUNCTIONS, ALL_IMPLEMENTED_FUNCTIONS_SET, ActiveDirtyManagerService, ArrayValueObject, AstRootNodeFactory, AstTreeBuilder, AsyncArrayObject, AsyncCustomFunction, AsyncObject, BaseFunction, BaseReferenceObject, BaseValueObject, BooleanValue, BooleanValueObject, CELL_INVERTED_INDEX_CACHE, CalculateController, CalculateFormulaService, CustomFunction, DEFAULT_INTERVAL_COUNT, DEFAULT_TOKEN_LAMBDA_FUNCTION_NAME, DEFAULT_TOKEN_LET_FUNCTION_NAME, DEFAULT_TOKEN_TYPE_LAMBDA_PARAMETER, DEFAULT_TOKEN_TYPE_PARAMETER, DEFAULT_TOKEN_TYPE_ROOT, DefinedNamesService, DependencyManagerBaseService, DependencyManagerService, DescriptionService, ENGINE_FORMULA_PLUGIN_CONFIG_KEY, ENGINE_FORMULA_RETURN_DEPENDENCY_TREE, ERROR_TYPE_SET, ErrorType, ErrorValueObject, FORMULA_REF_TO_ARRAY_CACHE, FUNCTION_LIST, FUNCTION_LIST_ARRAY, FUNCTION_LIST_COMPATIBILITY, FUNCTION_LIST_CUBE, FUNCTION_LIST_DATABASE, FUNCTION_LIST_DATE, FUNCTION_LIST_ENGINEERING, FUNCTION_LIST_FINANCIAL, FUNCTION_LIST_INFORMATION, FUNCTION_LIST_LOGICAL, FUNCTION_LIST_LOOKUP, FUNCTION_LIST_MATH, FUNCTION_LIST_STATISTICAL, FUNCTION_LIST_TEXT, FUNCTION_LIST_UNIVER, FUNCTION_LIST_WEB, FUNCTION_NAMES_ARRAY, FUNCTION_NAMES_COMPATIBILITY, FUNCTION_NAMES_CUBE, FUNCTION_NAMES_DATABASE, FUNCTION_NAMES_DATE, FUNCTION_NAMES_ENGINEERING, FUNCTION_NAMES_FINANCIAL, FUNCTION_NAMES_INFORMATION, FUNCTION_NAMES_LOGICAL, FUNCTION_NAMES_LOOKUP, FUNCTION_NAMES_MATH, FUNCTION_NAMES_STATISTICAL, FUNCTION_NAMES_TEXT, FUNCTION_NAMES_UNIVER, FUNCTION_NAMES_WEB, FeatureCalculationManagerService, FormulaCalculationSessionController, FormulaCalculationSessionService, FormulaCalculationTriggerService, FormulaCurrentConfigService, FormulaDataModel, FormulaDependencyGenerator, FormulaDependencyTree, FormulaDependencyTreeModel, FormulaDependencyTreeType, FormulaDependencyTreeVirtual, FormulaExecuteStageType, FormulaExecutedStateType, FormulaResultApplicationType, FormulaResultStatus, FormulaRuntimeService, FormulaUnitReferenceResolver, FunctionNodeFactory, FunctionService, FunctionType, GlobalComputingStatusService, HyperlinkEngineFormulaService, IActiveDirtyManagerService, ICalculateFormulaService, IDefinedNamesService, IDependencyManagerService, IDescriptionService, IFeatureCalculationManagerService, IFormulaChangesetCalculationService, IFormulaCurrentConfigService, IFormulaDependencyGenerator, IFormulaExternalReferenceDataLoader, IFormulaRuntimeService, IFormulaUnitReferenceResolver, IFunctionService, IHyperlinkEngineFormulaService, IOtherFormulaManagerService, IRegisterFunctionService, ISheetRowFilteredService, ISuperTableService, Interpreter, LambdaNodeFactory, LambdaParameterNodeFactory, LambdaValueObjectObject, Lexer, LexerNode, LexerTreeBuilder, NEW_EXCEL_FUNCTIONS, NoopFormulaExternalReferenceDataLoader, NullValueObject, NumberValueObject, OPERATOR_TOKEN_SET, OperatorNodeFactory, OtherFormulaBizType, OtherFormulaManagerService, OtherFormulaMarkDirty, PrefixNodeFactory, RangeReferenceObject, ReferenceNodeFactory, RegisterFunctionMutation, RegisterFunctionService, RegisterOtherFormulaService, RemoveDefinedNameMutation, RemoveFeatureCalculationMutation, RemoveOtherFormulaMutation, RemoveSuperTableMutation, SUFFIX_TOKEN_SET, SetArrayFormulaDataMutation, SetCellFormulaDependencyCalculationMutation, SetCellFormulaDependencyCalculationResultMutation, SetDefinedNameMutation, SetDefinedNameMutationFactory, SetFeatureCalculationMutation, SetFormulaCalculationNotificationMutation, SetFormulaCalculationResultMutation, SetFormulaCalculationStartMutation, SetFormulaCalculationStopMutation, SetFormulaDataMutation, SetFormulaDependencyCalculationMutation, SetFormulaDependencyCalculationResultMutation, SetFormulaStringBatchCalculationMutation, SetFormulaStringBatchCalculationResultMutation, SetImageFormulaDataMutation, SetOtherFormulaMutation, SetQueryFormulaDependencyAllMutation, SetQueryFormulaDependencyAllResultMutation, SetQueryFormulaDependencyMutation, SetQueryFormulaDependencyResultMutation, SetSuperTableMutation, SetSuperTableOptionMutation, SetTriggerFormulaCalculationStartMutation, SheetRowFilteredService, StringValueObject, SuffixNodeFactory, SuperTableActiveDirtyController, SuperTableService, UnionNodeFactory, UniverFormulaEnginePlugin, ValueNodeFactory, ValueObjectFactory, buildFormulaTextRuns, compareToken, convertUnitDataToRuntime, deserializeRangeForR1C1, deserializeRangeWithSheet, deserializeRangeWithSheetWithCache, extractFormulaError, findFormulaStructuredReferences, functionArray, functionCompatibility, functionCube, functionDatabase, functionDate, functionEngineering, functionFinancial, functionInformation, functionLogical, functionLookup, functionMath, functionMeta, functionStatistical, functionText, functionUniver, functionWeb, generateAstNode, generateExecuteAstNodeData, generateParam, generateRandomDependencyTreeId, generateStringWithSequence, getAbsoluteRefTypeWitString, getAbsoluteRefTypeWithSingleString, getFormulaHighlightDataStream, getFormulaReferenceIndex, getFormulaReplaceResult, getFormulaSequenceCharacterAtOffset, getFormulaSequenceNodeIndex, getFunctionName, getObjectValue, getRangeWithRefsString, handleNumfmtInCell, handleRefStringInfo, includeFormulaLexerToken, isFormulaLexerToken, isFormulaReferenceAddingContext, isFormulaReferenceAddingTextContext, isInDirtyRange, isReferenceString, isReferenceStringWithEffectiveColumn, isReferenceStrings, matchRefDrawToken, matchToken, mergeDirtyData, needsQuoting, normalizeFormulaUnitName, normalizeSheetName, operatorToken, prefixToken, quoteSheetName, refactorFormulaUnitQualifier, resolveFormulaReferenceEditingContext, searchFormulaFunctions, sequenceNodeType, serializeRange, serializeRangeToRefString, serializeRangeWithSheet, serializeRangeWithSpreadsheet, singleReferenceToGrid, splitTableStructuredRef, strip, stripErrorMargin, unquoteSheetName };
|