Skip to content

Commit

Permalink
feat(formula): today function, set numfmt data
Browse files Browse the repository at this point in the history
  • Loading branch information
Dushusir committed Jan 29, 2024
1 parent d8bc41a commit 5353a03
Show file tree
Hide file tree
Showing 19 changed files with 322 additions and 138 deletions.
6 changes: 6 additions & 0 deletions packages/engine-formula/src/basics/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ export interface IOtherFormulaData {
[unitId: string]: Nullable<{ [subUnitId: string]: Nullable<{ [formulaId: string]: IFormulaDataItem }> }>;
}

export interface INumfmtItemMap {
[unitId: string]: Nullable<{ [sheetId: string]: IObjectMatrixPrimitiveType<string> }>;
}

/**
* @f formulaString, the text string of the formula.
* @si The formula ID can be utilized in scenarios such as copy-pasting and drag-filling to convert formulas into references, eliminating the need for recreating the formulaString.
Expand All @@ -109,6 +113,7 @@ export interface IFormulaDataItem {
x?: number; // Offset from x direction
y?: number; // Offset from y direction
si?: string; // formulaId,
p?: string; // number format
// row: number;
// column: number;
// sheetId: string;
Expand Down Expand Up @@ -139,6 +144,7 @@ export interface IFormulaDatasetConfig {
dirtyRanges: IUnitRange[];
dirtyNameMap: IDirtyUnitSheetNameMap;
dirtyUnitFeatureMap: IDirtyUnitFeatureMap;
numfmtItemMap: INumfmtItemMap;
excludedCell?: IUnitExcludedCell;
allUnitData?: IUnitData;
unitSheetNameMap?: IUnitSheetNameMap;
Expand Down
27 changes: 27 additions & 0 deletions packages/engine-formula/src/basics/date.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* 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:https://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.
*/

/**
* Excel stores dates as sequential serial numbers so they can be used in calculations. By default, January 1, 1900 is serial number 1, and January 1, 2008 is serial number 39448 because it is 39,447 days after January 1, 1900.
*
* @param date
* @returns
*/
export function excelDateSerial(date: Date): number {
const baseDate = new Date(1900, 0, 1); // January 1, 1900
const dayDifference = (date.getTime() - baseDate.getTime()) / (1000 * 3600 * 24);
return Math.ceil(dayDifference) + 1; // +1 for adjusting for Excel's 1900 leap year error
}
10 changes: 10 additions & 0 deletions packages/engine-formula/src/basics/object-class-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@
import { Disposable } from '@univerjs/core';

export class ObjectClassType extends Disposable {
pattern: string = '';

getPattern() {
return this.pattern;
}

setPattern(pattern: string) {
this.pattern = pattern;
}

isError() {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { CommandType } from '@univerjs/core';
import type {
IDirtyUnitFeatureMap,
IDirtyUnitSheetNameMap,
INumfmtItemMap,
IRuntimeOtherUnitDataType,
IRuntimeUnitDataType,
} from '../../basics/common';
Expand All @@ -30,6 +31,7 @@ export interface ISetFormulaCalculationStartMutation {
dirtyNameMap: IDirtyUnitSheetNameMap;
dirtyUnitFeatureMap: IDirtyUnitFeatureMap;
options: Nullable<IExecutionOptions>;
numfmtItemMap: INumfmtItemMap;
forceCalculation?: boolean;
}
/**
Expand Down
10 changes: 6 additions & 4 deletions packages/engine-formula/src/controller/calculate.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type { ICommandInfo, IUnitRange } from '@univerjs/core';
import { Disposable, ICommandService, IUniverInstanceService, LifecycleStages, OnLifecycle } from '@univerjs/core';
import { Inject } from '@wendellhu/redi';

import type { IDirtyUnitFeatureMap, IDirtyUnitSheetNameMap, IFormulaData } from '../basics/common';
import type { IDirtyUnitFeatureMap, IDirtyUnitSheetNameMap, IFormulaData, INumfmtItemMap } from '../basics/common';
import type { ISetArrayFormulaDataMutationParams } from '../commands/mutations/set-array-formula-data.mutation';
import { SetArrayFormulaDataMutation } from '../commands/mutations/set-array-formula-data.mutation';
import type { ISetFormulaCalculationStartMutation } from '../commands/mutations/set-formula-calculation.mutation';
Expand Down Expand Up @@ -69,9 +69,9 @@ export class CalculateController extends Disposable {
if (params.forceCalculation === true) {
this._calculate(true);
} else {
const { dirtyRanges, dirtyNameMap, dirtyUnitFeatureMap } = params;
const { dirtyRanges, dirtyNameMap, dirtyUnitFeatureMap, numfmtItemMap } = params;

this._calculate(false, dirtyRanges, dirtyNameMap, dirtyUnitFeatureMap);
this._calculate(false, dirtyRanges, dirtyNameMap, dirtyUnitFeatureMap, numfmtItemMap);
}
} else if (command.id === SetArrayFormulaDataMutation.id) {
const params = command.params as ISetArrayFormulaDataMutationParams;
Expand All @@ -92,7 +92,8 @@ export class CalculateController extends Disposable {
forceCalculate: boolean = false,
dirtyRanges: IUnitRange[] = [],
dirtyNameMap: IDirtyUnitSheetNameMap = {},
dirtyUnitFeatureMap: IDirtyUnitFeatureMap = {}
dirtyUnitFeatureMap: IDirtyUnitFeatureMap = {},
numfmtItemMap: INumfmtItemMap = {}
) {
if (
dirtyRanges.length === 0 &&
Expand All @@ -116,6 +117,7 @@ export class CalculateController extends Disposable {
dirtyRanges,
dirtyNameMap,
dirtyUnitFeatureMap,
numfmtItemMap,
});
}

Expand Down
2 changes: 2 additions & 0 deletions packages/engine-formula/src/engine/ast-node/reference-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ export class ReferenceNode extends BaseAstNode {

this._referenceObject.setRuntimeData(runtimeService.getUnitData());

this._referenceObject.setNumfmtItemData(currentConfigService.getNumfmtItemMap());

this._referenceObject.setRuntimeArrayFormulaCellData(runtimeService.getRuntimeArrayFormulaCellData());

this._referenceObject.setRuntimeFeatureCellData(runtimeService.getRuntimeFeatureCellData());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type { ICellData, IRange, Nullable } from '@univerjs/core';
import { CellValueType, isNullCell } from '@univerjs/core';

import { FormulaAstLRU } from '../../basics/cache-lru';
import type { IRuntimeUnitDataType, IUnitData, IUnitSheetNameMap } from '../../basics/common';
import type { INumfmtItemMap, IRuntimeUnitDataType, IUnitData, IUnitSheetNameMap } from '../../basics/common';
import { ERROR_TYPE_SET, ErrorType } from '../../basics/error-type';
import { ObjectClassType } from '../../basics/object-class-type';
import { ArrayValueObject, ValueObjectFactory } from '../value-object/array-value-object';
Expand Down Expand Up @@ -65,6 +65,8 @@ export class BaseReferenceObject extends ObjectClassType {

private _runtimeFeatureCellData: { [featureId: string]: IRuntimeUnitDataType } = {};

private _numfmtItemData: INumfmtItemMap = {};

private _refOffsetX = 0;

private _refOffsetY = 0;
Expand Down Expand Up @@ -288,6 +290,14 @@ export class BaseReferenceObject extends ObjectClassType {
this._runtimeFeatureCellData = unitData;
}

getNmfmtItemData() {
return this._numfmtItemData;
}

setNumfmtItemData(numfmtItemData: INumfmtItemMap) {
this._numfmtItemData = numfmtItemData;
}

getRowCount() {
return this.getCurrentActiveSheetData().rowCount;
}
Expand Down Expand Up @@ -461,6 +471,10 @@ export class BaseReferenceObject extends ObjectClassType {
}

arrayValueList[row][column] = valueObject;

if (rowIndex === startRow && columnIndex === startColumn) {
return false;
}
});

const arrayValueObjectData: IArrayValueObject = {
Expand Down
7 changes: 6 additions & 1 deletion packages/engine-formula/src/functions/date/function-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,9 @@
* limitations under the License.
*/

export const functionDate = [];
import { FUNCTION_NAMES_DATE } from './function-names';
import { Today } from './today';

export const functionDate = [
[Today, FUNCTION_NAMES_DATE.TODAY],
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* 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:https://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, vi } from 'vitest';

import { FUNCTION_NAMES_DATE } from '../../function-names';
import { Today } from '..';

// mock new Date() use V
const _Date = Date;
global.Date = vi.fn(() => new _Date('2024-01-01T00:00:00.000Z')) as any;

describe('Test today function', () => {
const textFunction = new Today(FUNCTION_NAMES_DATE.TODAY);

describe('Today', () => {
it('Value is normal', () => {
const result = textFunction.calculate();
expect(result.getValue()).toBe(1);
});
});
});
26 changes: 26 additions & 0 deletions packages/engine-formula/src/functions/date/today/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* 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:https://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 { NumberValueObject } from '../../..';
import { excelDateSerial } from '../../../basics/date';
import { BaseFunction } from '../../base-function';

export class Today extends BaseFunction {
override calculate() {
const currentSerial = excelDateSerial(new Date());
return new NumberValueObject(currentSerial);
}
}
1 change: 1 addition & 0 deletions packages/engine-formula/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type {
ISheetData,
IUnitData,
IUnitSheetNameMap,
INumfmtItemMap,
} from './basics/common';
export { isInDirtyRange } from './basics/dirty';
export { ErrorType } from './basics/error-type';
Expand Down
10 changes: 10 additions & 0 deletions packages/engine-formula/src/services/current-data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import type {
IDirtyUnitSheetNameMap,
IFormulaData,
IFormulaDatasetConfig,
INumfmtItemMap,
IRuntimeUnitDataType,
ISheetData,
IUnitData,
Expand Down Expand Up @@ -78,6 +79,8 @@ export class FormulaCurrentConfigService extends Disposable implements IFormulaC

private _dirtyNameMap: IDirtyUnitSheetNameMap = {};

private _numfmtItemMap: INumfmtItemMap = {};

private _dirtyUnitFeatureMap: IDirtyUnitFeatureMap = {};

private _excludedCell: Nullable<IUnitExcludedCell>;
Expand All @@ -93,6 +96,7 @@ export class FormulaCurrentConfigService extends Disposable implements IFormulaC
this._sheetNameMap = {};
this._dirtyRanges = [];
this._dirtyNameMap = {};
this._numfmtItemMap = {};
this._dirtyUnitFeatureMap = {};
this._excludedCell = {};
}
Expand Down Expand Up @@ -129,6 +133,10 @@ export class FormulaCurrentConfigService extends Disposable implements IFormulaC
return this._dirtyNameMap;
}

getNumfmtItemMap() {
return this._numfmtItemMap;
}

getDirtyUnitFeatureMap() {
return this._dirtyUnitFeatureMap;
}
Expand All @@ -155,6 +163,8 @@ export class FormulaCurrentConfigService extends Disposable implements IFormulaC

this._dirtyNameMap = config.dirtyNameMap;

this._numfmtItemMap = config.numfmtItemMap;

this._dirtyUnitFeatureMap = config.dirtyUnitFeatureMap;

this._excludedCell = config.excludedCell;
Expand Down
6 changes: 3 additions & 3 deletions packages/engine-formula/src/services/runtime.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import type {
import { isInDirtyRange } from '../basics/dirty';
import { ErrorType } from '../basics/error-type';
import type { BaseAstNode } from '../engine/ast-node/base-ast-node';
import { type BaseReferenceObject, type FunctionVariantType } from '../engine/reference-object/base-reference-object';
import type { BaseReferenceObject, FunctionVariantType } from '../engine/reference-object/base-reference-object';
import type { ArrayValueObject } from '../engine/value-object/array-value-object';
import { type BaseValueObject, ErrorValueObject } from '../engine/value-object/base-value-object';
import { IFormulaCurrentConfigService } from './current-data.service';
Expand Down Expand Up @@ -178,8 +178,8 @@ export class FormulaRuntimeService extends Disposable implements IFormulaRuntime
private _currentRow: number = -1;
private _currentColumn: number = -1;

private _currentRowCount: number = -Infinity;
private _currentColumnCount: number = -Infinity;
private _currentRowCount: number = Number.NEGATIVE_INFINITY;
private _currentColumnCount: number = Number.NEGATIVE_INFINITY;

private _currentSubUnitId: string = '';
private _currentUnitId: string = '';
Expand Down
Loading

0 comments on commit 5353a03

Please sign in to comment.