From 0d6bcd3366048028ab6efd1433197a0565bf80d7 Mon Sep 17 00:00:00 2001 From: DR-Univer Date: Wed, 3 Apr 2024 17:37:17 +0800 Subject: [PATCH] fix(formula): today fill error --- .../__tests__/lexer-tree-builder.spec.ts | 73 +++++++++++++++++++ .../src/engine/analysis/lexer-tree-builder.ts | 72 ++++++++++++------ .../reference-object/base-reference-object.ts | 10 +-- 3 files changed, 126 insertions(+), 29 deletions(-) diff --git a/packages/engine-formula/src/engine/analysis/__tests__/lexer-tree-builder.spec.ts b/packages/engine-formula/src/engine/analysis/__tests__/lexer-tree-builder.spec.ts index 238d0837499..bd8ecd51a94 100644 --- a/packages/engine-formula/src/engine/analysis/__tests__/lexer-tree-builder.spec.ts +++ b/packages/engine-formula/src/engine/analysis/__tests__/lexer-tree-builder.spec.ts @@ -309,5 +309,78 @@ describe('lexer nodeMaker test', () => { ')', ]); }); + + it('No Parameter Function', () => { + expect(lexerTreeBuilder.sequenceNodesBuilder('=today()+today()+column()')).toStrictEqual([ + { + endIndex: 4, + nodeType: 3, + startIndex: 0, + token: 'today', + }, + '(', + ')', + '+', + { + endIndex: 12, + nodeType: 3, + startIndex: 8, + token: 'today', + }, + '(', + ')', + '+', + { + endIndex: 21, + nodeType: 3, + startIndex: 16, + token: 'column', + }, + '(', + ')', + ]); + }); + + it('No Parameter Today', () => { + expect(lexerTreeBuilder.sequenceNodesBuilder('=IF(TODAY()>1,"TRUE", "FALSE")')).toStrictEqual([ + { + endIndex: 1, + nodeType: 3, + startIndex: 0, + token: 'IF', + }, + '(', + { + endIndex: 7, + nodeType: 3, + startIndex: 3, + token: 'TODAY', + }, + '(', + ')', + '>', + { + endIndex: 11, + nodeType: 1, + startIndex: 11, + token: '1', + }, + ',', + { + endIndex: 18, + nodeType: 2, + startIndex: 13, + token: '"TRUE"', + }, + ',', + { + endIndex: 27, + nodeType: 2, + startIndex: 20, + token: ' "FALSE"', + }, + ')', + ]); + }); }); }); diff --git a/packages/engine-formula/src/engine/analysis/lexer-tree-builder.ts b/packages/engine-formula/src/engine/analysis/lexer-tree-builder.ts index 5c10bee15d9..4533cfff32d 100644 --- a/packages/engine-formula/src/engine/analysis/lexer-tree-builder.ts +++ b/packages/engine-formula/src/engine/analysis/lexer-tree-builder.ts @@ -1042,7 +1042,16 @@ export class LexerTreeBuilder extends Disposable { if (!this._setParentCurrentLexerNode() && cur !== formulaStringArrayCount - 1) { return ErrorType.VALUE; } + /** + * https://github.com/dream-num/univer/issues/1769 + * Formula example: =IF(TODAY()>1,"TRUE", "FALSE") + * Copy or auto-fill at complex formula get error formula offset + */ + this._addSequenceArray(sequenceArray, currentString, cur, isZeroAdded); cur++; + this._addSequenceArray(sequenceArray, nextCurrentString, cur, isZeroAdded); + cur++; + continue; } else if (nextCurrentString) { // const subLexerNode = new LexerNode(); // subLexerNode.token = DEFAULT_TOKEN_TYPE_PARAMETER; @@ -1356,14 +1365,16 @@ export class LexerTreeBuilder extends Disposable { if (this._negativeCondition(prevString)) { this._pushSegment(operatorToken.MINUS); - if (!(isZeroAdded && cur === 0)) { - sequenceArray?.push({ - segment: this._segment, - currentString, - cur, - currentLexerNode: this._currentLexerNode, - }); - } + // if (!(isZeroAdded && cur === 0)) { + // sequenceArray?.push({ + // segment: this._segment, + // currentString, + // cur, + // currentLexerNode: this._currentLexerNode, + // }); + // } + + this._addSequenceArray(sequenceArray, currentString, cur, isZeroAdded); cur++; continue; @@ -1371,14 +1382,15 @@ export class LexerTreeBuilder extends Disposable { } else if (this._segment.length > 0 && formulaStringArray[cur - 1] && formulaStringArray[cur - 1].toUpperCase() === 'E' && (currentString === operatorToken.MINUS || currentString === operatorToken.PLUS)) { this._pushSegment(currentString); - if (!(isZeroAdded && cur === 0)) { - sequenceArray?.push({ - segment: this._segment, - currentString, - cur, - currentLexerNode: this._currentLexerNode, - }); - } + // if (!(isZeroAdded && cur === 0)) { + // sequenceArray?.push({ + // segment: this._segment, + // currentString, + // cur, + // currentLexerNode: this._currentLexerNode, + // }); + // } + this._addSequenceArray(sequenceArray, currentString, cur, isZeroAdded); cur++; continue; @@ -1405,17 +1417,29 @@ export class LexerTreeBuilder extends Disposable { this._pushSegment(currentString); } - if (!(isZeroAdded && cur === 0)) { - sequenceArray?.push({ - segment: this._segment, - currentString, - cur, - currentLexerNode: this._currentLexerNode, - }); - } + // if (!(isZeroAdded && cur === 0)) { + // sequenceArray?.push({ + // segment: this._segment, + // currentString, + // cur, + // currentLexerNode: this._currentLexerNode, + // }); + // } + this._addSequenceArray(sequenceArray, currentString, cur, isZeroAdded); cur++; } this._pushNodeToChildren(this._segment); } + + private _addSequenceArray(sequenceArray: ISequenceArray[] | undefined, currentString: string, cur: number, isZeroAdded: boolean) { + if (!(isZeroAdded && cur === 0)) { + sequenceArray?.push({ + segment: this._segment, + currentString, + cur, + currentLexerNode: this._currentLexerNode, + }); + } + } } diff --git a/packages/engine-formula/src/engine/reference-object/base-reference-object.ts b/packages/engine-formula/src/engine/reference-object/base-reference-object.ts index 4f3c28f173f..113104d9eca 100644 --- a/packages/engine-formula/src/engine/reference-object/base-reference-object.ts +++ b/packages/engine-formula/src/engine/reference-object/base-reference-object.ts @@ -325,11 +325,11 @@ export class BaseReferenceObject extends ObjectClassType { } getActiveSheetRowCount() { - return this.getCurrentActiveSheetData().rowCount; + return this.getCurrentActiveSheetData()?.rowCount || 0; } getActiveSheetColumnCount() { - return this.getCurrentActiveSheetData().columnCount; + return this.getCurrentActiveSheetData()?.columnCount || 0; } getRowCount() { @@ -341,11 +341,11 @@ export class BaseReferenceObject extends ObjectClassType { } getRowData() { - return this.getCurrentActiveSheetData().rowData; + return this.getCurrentActiveSheetData()?.rowData || {}; } getColumnData() { - return this.getCurrentActiveSheetData().columnData; + return this.getCurrentActiveSheetData()?.columnData || {}; } isCell() { @@ -411,7 +411,7 @@ export class BaseReferenceObject extends ObjectClassType { } getCurrentActiveSheetData() { - return this._unitData[this.getUnitId()][this.getSheetId()]; + return this._unitData[this.getUnitId()]?.[this.getSheetId()]; } getCurrentRuntimeSheetData() {