Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(formula): today function, set numfmt data #1295

Merged
merged 24 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3fdffa5
feat(formula): today function, set numfmt data
Dushusir Jan 29, 2024
8b1fd3d
feat(formula): supports numfmt
Dushusir Jan 30, 2024
149152b
test(formula): set numfmt data
Dushusir Jan 30, 2024
26a9f6e
fix(formula): sum get numfmt from link cell
Dushusir Jan 30, 2024
616d6e7
fix(sheet): recover status bar
Dushusir Jan 30, 2024
8d2c5ea
fix(formula): set numfmt on formula cell
Dushusir Jan 30, 2024
8ce958c
feat(formula): date function single number
Dushusir Jan 30, 2024
9b3a463
feat(formula): date function with array
Dushusir Jan 31, 2024
4ecdf50
fix(formula): date function test, link to formatted cell supports format
Dushusir Jan 31, 2024
de9cc3e
fix(formula): date serial calculation
Dushusir Feb 3, 2024
814be41
fix(formula): function calculate null params, abs gets 0 when linked …
Dushusir Feb 3, 2024
b6cb67b
fix(formula): concatenate calculate zero value
Dushusir Feb 3, 2024
5cc3063
fix(formula): sum,max,min .etc add blank params check
Dushusir Feb 3, 2024
8aa1fb7
test(formula): new test template
Dushusir Feb 3, 2024
bb769ba
fix(formula): date function gets error when date before 1900.1.1
Dushusir Feb 3, 2024
dc4c6bd
feat(formula): add edate function
Dushusir Feb 6, 2024
df2b6ca
test(formula): test edate function
Dushusir Feb 6, 2024
7e49aea
feat(formula): year,month,day functions
Dushusir Feb 6, 2024
9598eb5
feat(formula): match, xmatch functions
Dushusir Feb 6, 2024
ba2c693
test(formula): xmatch function test case
Dushusir Feb 6, 2024
ddebc78
test(formula): nested functions test
Dushusir Feb 6, 2024
644fbb4
fix(formula): formula cell shows format, cell calculation sets percen…
Dushusir Feb 6, 2024
28e2f49
fix(formula): edate,month,year functions support blank cell
Dushusir Feb 6, 2024
38d9310
fix(formula): xmatch description
Dushusir Feb 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(formula): supports numfmt
  • Loading branch information
Dushusir committed Feb 19, 2024
commit 8b1fd3d9bd027a0ab082367c9c039f80caa804fb
3 changes: 1 addition & 2 deletions packages/engine-formula/src/basics/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export interface IOtherFormulaData {
}

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

/**
Expand All @@ -113,7 +113,6 @@ 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* 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 type { IMutation } from '@univerjs/core';
import { CommandType } from '@univerjs/core';
import type { IAccessor } from '@wendellhu/redi';

import type { INumfmtItemMap } from '../../basics/common';
import { FormulaDataModel } from '../../models/formula-data.model';

export interface ISetNumfmtFormulaDataMutationParams {
numfmtItemMap: INumfmtItemMap;
}

export const SetNumfmtFormulaDataMutation: IMutation<ISetNumfmtFormulaDataMutationParams> = {
id: 'formula.mutation.set-numfmt-formula-data',
type: CommandType.MUTATION,
handler: (accessor: IAccessor, params: ISetNumfmtFormulaDataMutationParams) => {
const formulaDataModel = accessor.get(FormulaDataModel);
formulaDataModel.updateNumfmtItemMap(params.numfmtItemMap);
return true;
},
};
18 changes: 16 additions & 2 deletions packages/engine-formula/src/controller/calculate.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import type { ICommandInfo, IUnitRange } from '@univerjs/core';
import { Disposable, ICommandService, IUniverInstanceService, LifecycleStages, OnLifecycle } from '@univerjs/core';
import { Disposable, ICommandService, IUniverInstanceService, LifecycleStages, OnLifecycle, Tools } from '@univerjs/core';
import { Inject } from '@wendellhu/redi';

import type { IDirtyUnitFeatureMap, IDirtyUnitSheetNameMap, IFormulaData, INumfmtItemMap } from '../basics/common';
Expand All @@ -34,6 +34,7 @@ import { FormulaDataModel } from '../models/formula-data.model';
import { CalculateFormulaService } from '../services/calculate-formula.service';
import type { IAllRuntimeData } from '../services/runtime.service';
import { FormulaExecutedStateType } from '../services/runtime.service';
import { SetNumfmtFormulaDataMutation } from '../commands/mutations/set-numfmt-formula-data.mutation';

@OnLifecycle(LifecycleStages.Ready, CalculateController)
export class CalculateController extends Disposable {
Expand Down Expand Up @@ -188,7 +189,7 @@ export class CalculateController extends Disposable {
}

private async _applyFormula(data: IAllRuntimeData) {
const { unitData, unitOtherData, arrayFormulaRange, arrayFormulaCellData, clearArrayFormulaCellData } = data;
const { unitData, unitOtherData, arrayFormulaRange, arrayFormulaCellData, clearArrayFormulaCellData, numfmtItemMap } = data;

if (!unitData) {
console.error('No sheetData from Formula Engine!');
Expand Down Expand Up @@ -217,6 +218,19 @@ export class CalculateController extends Disposable {
);
}

// Synchronous to the main thread
if (!Tools.isEmptyObject(numfmtItemMap)) {
this._commandService.executeCommand(
SetNumfmtFormulaDataMutation.id,
{
numfmtItemMap,
},
{
onlyLocal: true,
}
);
}

this._commandService.executeCommand(
SetFormulaCalculationResultMutation.id,
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import { functionText } from '../functions/text/function-map';
import { functionUniver } from '../functions/univer/function-map';
import { functionWeb } from '../functions/web/function-map';
import { IFunctionService } from '../services/function.service';
import { SetNumfmtFormulaDataMutation } from '../commands/mutations/set-numfmt-formula-data.mutation';

@OnLifecycle(LifecycleStages.Ready, FormulaController)
export class FormulaController extends Disposable {
Expand Down Expand Up @@ -85,6 +86,7 @@ export class FormulaController extends Disposable {
SetFormulaCalculationStopMutation,
SetFormulaCalculationNotificationMutation,
SetFormulaCalculationResultMutation,
SetNumfmtFormulaDataMutation,

SetDefinedNameMutation,
RemoveDefinedNameMutation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ describe('Test indirect', () => {
formulaData: {},
arrayFormulaCellData: {},
forceCalculate: false,
numfmtItemMap: {},
dirtyRanges: [],
dirtyNameMap: {},
dirtyUnitFeatureMap: {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ export class BaseReferenceObject extends ObjectClassType {
return callback(new ErrorValueObject(ErrorType.VALUE), startRow, startColumn);
}

const unitId = this._forcedUnitId || this._defaultUnitId;
const sheetId = this._forcedSheetId || this._defaultSheetId;

for (let r = startRow; r <= endRow; r++) {
for (let c = startColumn; c <= endColumn; c++) {
if (r < 0 || c < 0) {
Expand All @@ -161,6 +164,9 @@ export class BaseReferenceObject extends ObjectClassType {

const resultObjectValue = this.getCellValueObject(cell);

const pattern = this._numfmtItemData[unitId]?.[sheetId]?.[r]?.[c];
pattern && resultObjectValue.setPattern(pattern);

result = callback(resultObjectValue, r, c);

if (result === false) {
Expand All @@ -178,7 +184,15 @@ export class BaseReferenceObject extends ObjectClassType {
return new NumberValueObject(0, true);
}

return this.getCellValueObject(cell);
const cellValueObject = this.getCellValueObject(cell);

// Set numfmt pattern
const unitId = this._forcedUnitId || this._defaultUnitId;
const sheetId = this._forcedSheetId || this._defaultSheetId;
const numfmtItem = this._numfmtItemData[unitId]?.[sheetId]?.[startRow]?.[startColumn];
numfmtItem && cellValueObject.setPattern(numfmtItem);

return cellValueObject;
}

getRangeData() {
Expand Down Expand Up @@ -291,7 +305,7 @@ export class BaseReferenceObject extends ObjectClassType {
this._runtimeFeatureCellData = unitData;
}

getNmfmtItemData() {
getNumfmtItemData() {
return this._numfmtItemData;
}

Expand Down Expand Up @@ -472,10 +486,6 @@ export class BaseReferenceObject extends ObjectClassType {
}

arrayValueList[row][column] = valueObject;

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

const arrayValueObjectData: IArrayValueObject = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ export class CellReferenceObject extends BaseReferenceObject {

rangeReferenceObject.setRuntimeData(this.getRuntimeData());

rangeReferenceObject.setNumfmtItemData(this.getNumfmtItemData());

rangeReferenceObject.setArrayFormulaCellData(this.getArrayFormulaCellData());

rangeReferenceObject.setRuntimeArrayFormulaCellData(this.getRuntimeArrayFormulaCellData());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,9 @@ export class NumberValueObject extends BaseValueObject {
return object;
}

// Set number format
object.setPattern(this.getPattern() || valueObject.getPattern());

return object;
}

Expand All @@ -420,14 +423,22 @@ export class NumberValueObject extends BaseValueObject {
return this;
}

// Set number format
object.setPattern(this.getPattern() || valueObject.getPattern());

return object;
}

override multiply(valueObject: BaseValueObject): BaseValueObject {
if (valueObject.isArray()) {
return valueObject.multiply(this);
}
return this.multiplyBy(valueObject.getValue());
const object = this.multiplyBy(valueObject.getValue());

// Set number format
object.setPattern(this.getPattern() || valueObject.getPattern());

return object;
}

override divided(valueObject: BaseValueObject): BaseValueObject {
Expand All @@ -438,7 +449,12 @@ export class NumberValueObject extends BaseValueObject {
}
return (o as BaseValueObject).multiply(this);
}
return this.dividedBy(valueObject.getValue());
const object = this.dividedBy(valueObject.getValue());

// Set number format
object.setPattern(this.getPattern() || valueObject.getPattern());

return object;
}

override concatenateFront(valueObject: BaseValueObject): BaseValueObject {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ describe('Test indirect', () => {
formulaData: {},
arrayFormulaCellData: {},
forceCalculate: false,
numfmtItemMap: {},
dirtyRanges: [],
dirtyNameMap: {},
dirtyUnitFeatureMap: {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ describe('Test offset', () => {
formulaData: {},
arrayFormulaCellData: {},
forceCalculate: false,
numfmtItemMap: {},
dirtyRanges: [],
dirtyNameMap: {},
dirtyUnitFeatureMap: {},
Expand Down
2 changes: 2 additions & 0 deletions packages/engine-formula/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,5 @@ export { IFunctionService } from './services/function.service';
export { type IOtherFormulaManagerService, OtherFormulaManagerService } from './services/other-formula-manager.service';
export { FormulaExecuteStageType, type IExecutionInProgressParams } from './services/runtime.service';
export { FormulaExecutedStateType, type IAllRuntimeData } from './services/runtime.service';
export { SetNumfmtFormulaDataMutation } from './commands/mutations/set-numfmt-formula-data.mutation';
export type { ISetNumfmtFormulaDataMutationParams } from './commands/mutations/set-numfmt-formula-data.mutation';
87 changes: 83 additions & 4 deletions packages/engine-formula/src/models/formula-data.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import type {
IArrayFormulaUnitCellType,
IFormulaData,
IFormulaDataItem,
INumfmtItemMap,
IRuntimeUnitDataType,
ISheetData,
IUnitData,
Expand All @@ -43,6 +44,9 @@ export class FormulaDataModel extends Disposable {

private _arrayFormulaCellData: IArrayFormulaUnitCellType = {};

// TODO@Dushusir: Determine the node.js environment and synchronize to the resource plugin when SSC is used
private _numfmtItemMap: INumfmtItemMap = {};

constructor(
@IUniverInstanceService private readonly _currentUniverService: IUniverInstanceService,
@Inject(LexerTreeBuilder) private readonly _lexerTreeBuilder: LexerTreeBuilder
Expand Down Expand Up @@ -161,20 +165,55 @@ export class FormulaDataModel extends Disposable {
this._formulaData = value;
}

getArrayFormulaRange(): IArrayFormulaRangeType {
return this._arrayFormulaRange;
}

setArrayFormulaRange(value: IArrayFormulaRangeType) {
this._arrayFormulaRange = value;
}

getArrayFormulaRange(): IArrayFormulaRangeType {
return this._arrayFormulaRange;
getArrayFormulaCellData() {
return this._arrayFormulaCellData;
}

setArrayFormulaCellData(value: IArrayFormulaUnitCellType) {
this._arrayFormulaCellData = value;
}

getArrayFormulaCellData() {
return this._arrayFormulaCellData;
getNumfmtItemMap() {
return this._numfmtItemMap;
}

updateNumfmtItemMap(value: INumfmtItemMap) {
Object.keys(value).forEach((unitId) => {
const sheetData = value[unitId];

if (sheetData == null) {
return true;
}

if (this._numfmtItemMap[unitId] == null) {
this._numfmtItemMap[unitId] = {};
}

Object.keys(sheetData).forEach((sheetId) => {
const numfmtItemMap = sheetData[sheetId];
const numfmtItemMatrix = new ObjectMatrix(numfmtItemMap);

if (this._numfmtItemMap[unitId]![sheetId] == null) {
this._numfmtItemMap[unitId]![sheetId] = {};
}

numfmtItemMatrix.forValue((r, c, numfmtItem) => {
if (this._numfmtItemMap[unitId]![sheetId][r] == null) {
this._numfmtItemMap[unitId]![sheetId][r] = {};
}

this._numfmtItemMap[unitId]![sheetId][r][c] = numfmtItem;
});
});
});
}

mergeArrayFormulaRange(formulaData: IArrayFormulaRangeType) {
Expand Down Expand Up @@ -450,6 +489,46 @@ export class FormulaDataModel extends Disposable {
});
}

updateNumfmtData(
unitId: string,
sheetId: string,
cellValue: IObjectMatrixPrimitiveType<Nullable<ICellData>>
) {
// remove the array formula range when cell value is null

const arrayFormulaRange = this._arrayFormulaRange[unitId]?.[sheetId];
const arrayFormulaRangeMatrix = new ObjectMatrix(arrayFormulaRange);

const numfmtData = this._numfmtItemMap[unitId]?.[sheetId];

if (!numfmtData) return;

const numfmtDataMatrix = new ObjectMatrix(numfmtData);

const cellMatrix = new ObjectMatrix(cellValue);
cellMatrix.forValue((r, c, cell) => {
const formulaString = cell?.f || '';
const formulaId = cell?.si || '';

const checkFormulaString = isFormulaString(formulaString);
const checkFormulaId = isFormulaId(formulaId);

if (!checkFormulaString && !checkFormulaId) {
numfmtDataMatrix.setValue(r, c, null);

const arrayFormulaRangeValue = arrayFormulaRangeMatrix.getValue(r, c);
if (arrayFormulaRangeValue) {
const { startRow, startColumn, endRow, endColumn } = arrayFormulaRangeValue;
for (let row = startRow; row <= endRow; row++) {
for (let column = startColumn; column <= endColumn; column++) {
numfmtDataMatrix.setValue(row, column, null);
}
}
}
}
});
}

getFormulaItemBySId(sId: string, sheetId: string, unitId: string): Nullable<IFormulaDataItem> {
const formulaData = this._formulaData;
if (formulaData[unitId] == null) {
Expand Down
Loading