Skip to content

Commit

Permalink
fix(formula): index function handles base value object (#1692)
Browse files Browse the repository at this point in the history
* fix(formula): index function handles base value object

* fix(formula): vlookup handle array

* fix(formula): vlookup reuse function

* fix(formula): vlookup handle single value object
  • Loading branch information
Dushusir committed Mar 28, 2024
1 parent 16a506e commit 1f0b700
Show file tree
Hide file tree
Showing 17 changed files with 691 additions and 161 deletions.
4 changes: 4 additions & 0 deletions packages/engine-formula/src/basics/object-class-type.ts
Expand Up @@ -47,6 +47,10 @@ export class ObjectClassType extends Disposable {
return false;
}

isArray() {
return false;
}

isValueObject() {
return false;
}
Expand Down
Expand Up @@ -94,7 +94,7 @@ export class BaseReferenceObject extends ObjectClassType {
isExceedRange() {
const { startRow, endRow, startColumn, endColumn } = this.getRangePosition();

if (startRow < 0 || startColumn < 0 || endRow >= this.getRowCount() || endColumn >= this.getColumnCount()) {
if (startRow < 0 || startColumn < 0 || endRow >= this.getActiveSheetRowCount() || endColumn >= this.getActiveSheetColumnCount()) {
return true;
}
return false;
Expand Down Expand Up @@ -127,11 +127,11 @@ export class BaseReferenceObject extends ObjectClassType {
}

if (Number.isNaN(endRow)) {
endRow = this.getRowCount() - 1;
endRow = this.getActiveSheetRowCount() - 1;
}

if (Number.isNaN(endColumn)) {
endColumn = this.getColumnCount() - 1;
endColumn = this.getActiveSheetColumnCount() - 1;
}

return {
Expand Down Expand Up @@ -324,14 +324,22 @@ export class BaseReferenceObject extends ObjectClassType {
this._numfmtItemData = numfmtItemData;
}

getRowCount() {
getActiveSheetRowCount() {
return this.getCurrentActiveSheetData().rowCount;
}

getColumnCount() {
getActiveSheetColumnCount() {
return this.getCurrentActiveSheetData().columnCount;
}

getRowCount() {
return this._rangeData.endRow - this._rangeData.startRow + 1;
}

getColumnCount() {
return this._rangeData.endColumn - this._rangeData.startColumn + 1;
}

getRowData() {
return this.getCurrentActiveSheetData().rowData;
}
Expand Down

This file was deleted.

@@ -0,0 +1,58 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { describe, expect, it } from 'vitest';

import { cellToRange } from '@univerjs/core';
import { convertTonNumber, isSingleValueObject } from '../value-object';
import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../value-object/primitive-object';
import { ErrorValueObject } from '../../value-object/base-value-object';
import { ErrorType } from '../../../basics/error-type';
import { ArrayValueObject } from '../../value-object/array-value-object';
import { CellReferenceObject } from '../../reference-object/cell-reference-object';
import { RowReferenceObject } from '../../reference-object/row-reference-object';
import { ColumnReferenceObject } from '../../reference-object/column-reference-object';
import { RangeReferenceObject } from '../../reference-object/range-reference-object';

describe('Test object cover', () => {
it('Function convertTonNumber', () => {
expect(convertTonNumber(BooleanValueObject.create(true)).getValue()).toBe(1);
expect(convertTonNumber(BooleanValueObject.create(false)).getValue()).toBe(0);
});

it('Function isSingleValueObject', () => {
expect(isSingleValueObject(BooleanValueObject.create(true))).toBe(true);
expect(isSingleValueObject(BooleanValueObject.create(false))).toBe(true);
expect(isSingleValueObject(NumberValueObject.create(1))).toBe(true);
expect(isSingleValueObject(StringValueObject.create('Univer'))).toBe(true);
expect(isSingleValueObject(NullValueObject.create())).toBe(true);
expect(isSingleValueObject(ErrorValueObject.create(ErrorType.VALUE))).toBe(true);

expect(isSingleValueObject(ArrayValueObject.create(/*ts*/ `{
1, 3;
8, 7
}`))).toBe(false);
expect(isSingleValueObject(ArrayValueObject.create(/*ts*/ `{
1
}`))).toBe(true);

expect(isSingleValueObject(new CellReferenceObject('A1'))).toBe(true);
expect(isSingleValueObject(new RowReferenceObject('1:1'))).toBe(false);
expect(isSingleValueObject(new ColumnReferenceObject('A:A'))).toBe(false);
expect(isSingleValueObject(new RangeReferenceObject(cellToRange(0, 1)))).toBe(true);
expect(isSingleValueObject(new RangeReferenceObject({ startRow: 0, endRow: 1, startColumn: 0, endColumn: 1 }))).toBe(false);
});
});
8 changes: 5 additions & 3 deletions packages/engine-formula/src/engine/utils/array-object.ts
Expand Up @@ -78,14 +78,16 @@ export function expandArrayValueObject(rowCount: number, columnCount: number, va
export function createNewArray(
result: BaseValueObject[][],
rowCount: number,
columnCount: number
columnCount: number,
unitId = '',
sheetId = ''
) {
const arrayValueObjectData: IArrayValueObject = {
calculateValueList: result,
rowCount,
columnCount,
unitId: '',
sheetId: '',
unitId,
sheetId,
row: -1,
column: -1,
};
Expand Down
27 changes: 0 additions & 27 deletions packages/engine-formula/src/engine/utils/object-covert.ts

This file was deleted.

55 changes: 55 additions & 0 deletions packages/engine-formula/src/engine/utils/value-object.ts
@@ -0,0 +1,55 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import type { BaseReferenceObject, FunctionVariantType } from '../reference-object/base-reference-object';
import type { ArrayValueObject } from '../value-object/array-value-object';
import type { BaseValueObject } from '../value-object/base-value-object';
import { NumberValueObject } from '../value-object/primitive-object';

export function convertTonNumber(valueObject: BaseValueObject) {
const currentValue = valueObject.getValue();
let result = 0;
if (currentValue) {
result = 1;
}
return NumberValueObject.create(result);
}

export function isSingleValueObject(valueObject: FunctionVariantType) {
if (valueObject.isArray() && (valueObject as ArrayValueObject).getRowCount() === 1 && (valueObject as ArrayValueObject).getColumnCount() === 1) {
return true;
}

if (valueObject.isReferenceObject()) {
if ((valueObject as BaseReferenceObject).isCell()) {
return true;
}

if ((valueObject as BaseReferenceObject).getRowCount() === 1 && (valueObject as BaseReferenceObject).getColumnCount() === 1) {
return true;
}

return false;
}

valueObject = valueObject as BaseValueObject;

if (valueObject.isString() || valueObject.isNumber() || valueObject.isBoolean() || valueObject.isError() || valueObject.isNull()) {
return true;
}

return false;
}
Expand Up @@ -76,10 +76,6 @@ export class BaseValueObject extends ObjectClassType {
return false;
}

isArray() {
return false;
}

isString() {
return false;
}
Expand Down
Expand Up @@ -53,6 +53,9 @@ import { FunctionService, IFunctionService } from '../../services/function.servi
import { IOtherFormulaManagerService, OtherFormulaManagerService } from '../../services/other-formula-manager.service';
import { FormulaRuntimeService, IFormulaRuntimeService } from '../../services/runtime.service';
import { ISuperTableService, SuperTableService } from '../../services/super-table.service';
import type { BaseValueObject, ErrorValueObject } from '../../engine/value-object/base-value-object';
import type { BaseReferenceObject, FunctionVariantType } from '../../engine/reference-object/base-reference-object';
import type { ArrayValueObject } from '../../engine/value-object/array-value-object';

const getTestWorkbookData = (): IWorkbookData => {
return {
Expand Down Expand Up @@ -231,3 +234,14 @@ export function createFunctionTestBed(workbookConfig?: IWorkbookData, dependenci
sheetData,
};
}

export function getObjectValue(result: FunctionVariantType) {
if ((result as ErrorValueObject).isError()) {
return (result as ErrorValueObject).getValue();
} else if ((result as BaseReferenceObject).isReferenceObject()) {
return (result as BaseReferenceObject).toArrayValueObject().toValue();
} else if ((result as ArrayValueObject).isArray()) {
return (result as ArrayValueObject).toValue();
}
return (result as BaseValueObject).getValue();
}
2 changes: 1 addition & 1 deletion packages/engine-formula/src/functions/base-function.ts
Expand Up @@ -26,7 +26,7 @@ import { ArrayOrderSearchType } from '../engine/utils/compare';
import type { ArrayValueObject } from '../engine/value-object/array-value-object';
import { type BaseValueObject, ErrorValueObject } from '../engine/value-object/base-value-object';
import { NullValueObject, NumberValueObject, type PrimitiveValueType } from '../engine/value-object/primitive-object';
import { convertTonNumber } from '../engine/utils/object-covert';
import { convertTonNumber } from '../engine/utils/value-object';
import { createNewArray } from '../engine/utils/array-object';
import { serializeRangeToRefString } from '../engine/utils/reference';
import { REFERENCE_REGEX_SINGLE_COLUMN, REFERENCE_REGEX_SINGLE_ROW, REFERENCE_SINGLE_RANGE_REGEX } from '../basics/regex';
Expand Down
Expand Up @@ -27,13 +27,10 @@ import { Interpreter } from '../../../../engine/interpreter/interpreter';
import { IFormulaCurrentConfigService } from '../../../../services/current-data.service';
import { IFunctionService } from '../../../../services/function.service';
import { IFormulaRuntimeService } from '../../../../services/runtime.service';
import { createFunctionTestBed } from '../../../__tests__/create-function-test-bed';
import { createFunctionTestBed, getObjectValue } from '../../../__tests__/create-function-test-bed';
import { FUNCTION_NAMES_LOOKUP } from '../../function-names';
import type { BaseValueObject, ErrorValueObject } from '../../../../engine/value-object/base-value-object';
import type { ArrayValueObject } from '../../../../engine/value-object/array-value-object';
import { Index } from '..';
import { ErrorType } from '../../../../basics/error-type';
import type { BaseReferenceObject } from '../../../../engine/reference-object/base-reference-object';

const getTestWorkbookData = (): IWorkbookData => {
return {
Expand Down Expand Up @@ -201,14 +198,7 @@ describe('Test index', () => {

const result = await interpreter.executeAsync(astNode as BaseAstNode);

if ((result as ErrorValueObject).isError()) {
return (result as ErrorValueObject).getValue();
} else if ((result as BaseReferenceObject).isReferenceObject()) {
return (result as BaseReferenceObject).toArrayValueObject().toValue();
} else if ((result as ArrayValueObject).isArray()) {
return (result as ArrayValueObject).toValue();
}
return (result as BaseValueObject).getValue();
return getObjectValue(result);
};
});

Expand Down Expand Up @@ -729,5 +719,23 @@ describe('Test index', () => {
expect(result).toStrictEqual([['Tom', ErrorType.VALUE, 'Tom', 'Tom', 'Tom', 'Tom'], ['Tom', ErrorType.REF, 'Sarah', ErrorType.VALUE, ErrorType.VALUE, 'Tom'], [ErrorType.NA, ErrorType.NA, ErrorType.NA, ErrorType.NA, ErrorType.NA, ErrorType.NA]]);
});
});
describe('Single base value object as referenceObject', () => {
it('Row number 1, column number 1', async () => {
// number
let result = await calculate('=INDEX(1,1,1)');

expect(result).toBe(1);

// boolean
result = await calculate('=INDEX(TRUE,1,1)');

expect(result).toBe(true);

// string
result = await calculate('=INDEX("Univer",1,1)');

expect(result).toBe('Univer');
});
});
// supports array string
});

0 comments on commit 1f0b700

Please sign in to comment.