diff --git a/packages/engine-formula/src/basics/date.ts b/packages/engine-formula/src/basics/date.ts index bc1cc4de1f8..175ae2255f0 100644 --- a/packages/engine-formula/src/basics/date.ts +++ b/packages/engine-formula/src/basics/date.ts @@ -265,13 +265,13 @@ export function countWorkingDays(startDateSerialNumber: number, endDateSerialNum export function getDateSerialNumberByWorkingDays(startDateSerialNumber: number, workingDays: number, weekend: number | string = 1, holidays?: number[]): (number | ErrorValueObject) { const weekendArray = getWeekendArray(weekend); - startDateSerialNumber = Math.floor(startDateSerialNumber); - let targetDateSerialNumber = startDateSerialNumber; + const _startDateSerialNumber = Math.floor(startDateSerialNumber); + let targetDateSerialNumber = _startDateSerialNumber; let days = Math.abs(workingDays); for (let i = 1; i <= days; i++) { - const currentDateSerialNumber = workingDays < 0 ? startDateSerialNumber - i : startDateSerialNumber + i; + const currentDateSerialNumber = workingDays < 0 ? _startDateSerialNumber - i : _startDateSerialNumber + i; if (currentDateSerialNumber < 0) { return ErrorValueObject.create(ErrorType.NUM); diff --git a/packages/engine-formula/src/engine/value-object/primitive-object.ts b/packages/engine-formula/src/engine/value-object/primitive-object.ts index 89a36c9a19d..b06b4840130 100644 --- a/packages/engine-formula/src/engine/value-object/primitive-object.ts +++ b/packages/engine-formula/src/engine/value-object/primitive-object.ts @@ -1370,15 +1370,18 @@ export class StringValueObject extends BaseValueObject { if (typeof value === 'string') { // Case sensitivity needs to be considered, most functions are case-insensitive, like VLOOKUP/HLOOKUP/XLOOKUP/MATCH/COUNTIF/COUNTIFS/SUMIF/SUMIFS/SEARCH/FIND(in SUBSTITUTE) // A few functions are case-sensitive, like EXACT/FIND/FINDB/REPLACE/REPLACEB/MIDB + let _value = value; + if (!isCaseSensitive) { currentValue = currentValue.toLocaleLowerCase(); - value = value.toLocaleLowerCase(); + _value = _value.toLocaleLowerCase(); } - if (isWildcard(value)) { - return this._checkWildcard(value, operator); + if (isWildcard(_value)) { + return this._checkWildcard(_value, operator); } - result = this._compareString(currentValue, value, operator); + + result = this._compareString(currentValue, _value, operator); } else if (typeof value === 'number') { result = this._compareNumber(operator); } else if (typeof value === 'boolean') { diff --git a/packages/engine-formula/src/functions/base-function.ts b/packages/engine-formula/src/functions/base-function.ts index 2b21e59c8c1..099c3615ed6 100644 --- a/packages/engine-formula/src/functions/base-function.ts +++ b/packages/engine-formula/src/functions/base-function.ts @@ -147,26 +147,28 @@ export class BaseFunction extends Disposable { * @param indexNum */ getIndexNumValue(indexNum: BaseValueObject, defaultValue = 1) { - if (indexNum.isArray()) { - indexNum = (indexNum as ArrayValueObject).getFirstCell(); + let _indexNum = indexNum; + + if (_indexNum.isArray()) { + _indexNum = (_indexNum as ArrayValueObject).getFirstCell(); } - if (indexNum.isBoolean()) { - const colIndexNumV = indexNum.getValue() as boolean; + if (_indexNum.isBoolean()) { + const colIndexNumV = _indexNum.getValue() as boolean; if (colIndexNumV === false) { return ErrorValueObject.create(ErrorType.VALUE); } return defaultValue; } - if (indexNum.isString()) { - const colIndexNumV = Number(indexNum.getValue() as string); + if (_indexNum.isString()) { + const colIndexNumV = Number(_indexNum.getValue() as string); if (Number.isNaN(colIndexNumV)) { return ErrorValueObject.create(ErrorType.REF); } return colIndexNumV; - } else if (indexNum.isNumber()) { - const colIndexNumV = indexNum.getValue() as number; + } else if (_indexNum.isNumber()) { + const colIndexNumV = _indexNum.getValue() as number; return colIndexNumV; } diff --git a/packages/engine-formula/src/functions/date/datedif/index.ts b/packages/engine-formula/src/functions/date/datedif/index.ts index 21cf26279b6..b1e01856200 100644 --- a/packages/engine-formula/src/functions/date/datedif/index.ts +++ b/packages/engine-formula/src/functions/date/datedif/index.ts @@ -27,37 +27,41 @@ export class Datedif extends BaseFunction { override maxParams = 3; override calculate(startDate: BaseValueObject, endDate: BaseValueObject, unit: BaseValueObject) { - if (startDate.isArray()) { - startDate = (startDate as ArrayValueObject).get(0, 0) as BaseValueObject; + let _startDate = startDate; + let _endDate = endDate; + let _unit = unit; + + if (_startDate.isArray()) { + _startDate = (_startDate as ArrayValueObject).get(0, 0) as BaseValueObject; } - if (endDate.isArray()) { - endDate = (endDate as ArrayValueObject).get(0, 0) as BaseValueObject; + if (_endDate.isArray()) { + _endDate = (_endDate as ArrayValueObject).get(0, 0) as BaseValueObject; } - if (unit.isArray()) { - unit = (unit as ArrayValueObject).get(0, 0) as BaseValueObject; + if (_unit.isArray()) { + _unit = (_unit as ArrayValueObject).get(0, 0) as BaseValueObject; } - if (startDate.isError()) { - return startDate; + if (_startDate.isError()) { + return _startDate; } - if (endDate.isError()) { - return endDate; + if (_endDate.isError()) { + return _endDate; } - if (unit.isError()) { - return unit; + if (_unit.isError()) { + return _unit; } - const startDateSerialNumber = getDateSerialNumberByObject(startDate); + const startDateSerialNumber = getDateSerialNumberByObject(_startDate); if (typeof startDateSerialNumber !== 'number') { return startDateSerialNumber; } - let endDateSerialNumber = getDateSerialNumberByObject(endDate); + const endDateSerialNumber = getDateSerialNumberByObject(_endDate); if (typeof endDateSerialNumber !== 'number') { return endDateSerialNumber; @@ -67,10 +71,14 @@ export class Datedif extends BaseFunction { return ErrorValueObject.create(ErrorType.NUM); } - if (!unit.isString()) { + if (!_unit.isString()) { return ErrorValueObject.create(ErrorType.NUM); } + return this._getResultByUnit(startDateSerialNumber, endDateSerialNumber, _unit); + } + + private _getResultByUnit(startDateSerialNumber: number, endDateSerialNumber: number, unit: BaseValueObject): BaseValueObject { const startDateDate = excelSerialToDate(startDateSerialNumber); const startYear = startDateDate.getUTCFullYear(); const startMonth = startDateDate.getUTCMonth() + 1; @@ -81,41 +89,33 @@ export class Datedif extends BaseFunction { const endMonth = endDateDate.getUTCMonth() + 1; const endDay = endDateDate.getUTCDate(); - const unitValue = String(unit.getValue()).toLocaleUpperCase(); + const unitValue = `${unit.getValue()}`.toLocaleUpperCase(); - let result: number; + let _endDateSerialNumber; switch (unitValue) { case 'Y': // The number of complete years in the period. - result = endYear - startYear; - break; + return NumberValueObject.create(endYear - startYear); case 'M': // The number of complete months in the period. - result = (endYear - startYear) * 12 + endMonth - startMonth; - break; + return NumberValueObject.create((endYear - startYear) * 12 + endMonth - startMonth); case 'D': // The number of days in the period. - result = Math.floor(endDateSerialNumber) - Math.floor(startDateSerialNumber); - break; + return NumberValueObject.create(Math.floor(endDateSerialNumber) - Math.floor(startDateSerialNumber)); case 'MD': // The difference between the days in start_date and end_date. The months and years of the dates are ignored. - result = endDay - startDay; - break; + return NumberValueObject.create(endDay - startDay); case 'YM': // The difference between the months in start_date and end_date. The days and years of the dates are ignored. - result = endMonth - startMonth; - break; + return NumberValueObject.create(endMonth - startMonth); case 'YD': // The difference between the days of start_date and end_date. The years of the dates are ignored. // The year is the year of the start date - endDateSerialNumber = excelDateSerial(new Date(Date.UTC(startYear, endMonth - 1, endDay))); - result = Math.floor(endDateSerialNumber) - Math.floor(startDateSerialNumber); - break; + _endDateSerialNumber = excelDateSerial(new Date(Date.UTC(startYear, endMonth - 1, endDay))); + return NumberValueObject.create(Math.floor(_endDateSerialNumber) - Math.floor(startDateSerialNumber)); default: return ErrorValueObject.create(ErrorType.NUM); } - - return NumberValueObject.create(result); } } diff --git a/packages/engine-formula/src/functions/date/days360/index.ts b/packages/engine-formula/src/functions/date/days360/index.ts index f585abbf7b8..9ece7748be1 100644 --- a/packages/engine-formula/src/functions/date/days360/index.ts +++ b/packages/engine-formula/src/functions/date/days360/index.ts @@ -28,6 +28,8 @@ export class Days360 extends BaseFunction { override maxParams = 3; override calculate(startDate: BaseValueObject, endDate: BaseValueObject, method?: BaseValueObject) { + const _method = method ?? BooleanValueObject.create(false); + if (startDate.isError()) { return startDate; } @@ -36,29 +38,29 @@ export class Days360 extends BaseFunction { return endDate; } - if (method?.isError()) { - return method; + if (_method.isError()) { + return _method; } const maxRowLength = Math.max( startDate.isArray() ? (startDate as ArrayValueObject).getRowCount() : 1, endDate.isArray() ? (endDate as ArrayValueObject).getRowCount() : 1, - method?.isArray() ? (method as ArrayValueObject).getRowCount() : 1 + _method.isArray() ? (_method as ArrayValueObject).getRowCount() : 1 ); const maxColumnLength = Math.max( startDate.isArray() ? (startDate as ArrayValueObject).getColumnCount() : 1, endDate.isArray() ? (endDate as ArrayValueObject).getColumnCount() : 1, - method?.isArray() ? (method as ArrayValueObject).getColumnCount() : 1 + _method.isArray() ? (_method as ArrayValueObject).getColumnCount() : 1 ); const startDateArray = expandArrayValueObject(maxRowLength, maxColumnLength, startDate, ErrorValueObject.create(ErrorType.NA)); const endDateArray = expandArrayValueObject(maxRowLength, maxColumnLength, endDate, ErrorValueObject.create(ErrorType.NA)); - const methodArray = method ? expandArrayValueObject(maxRowLength, maxColumnLength, method, ErrorValueObject.create(ErrorType.NA)) : []; + const methodArray = expandArrayValueObject(maxRowLength, maxColumnLength, _method, ErrorValueObject.create(ErrorType.NA)); const resultArray = startDateArray.map((startDateObject, rowIndex, columnIndex) => { const endDateObject = endDateArray.get(rowIndex, columnIndex) as BaseValueObject; - let methodObject = method ? (methodArray as ArrayValueObject).get(rowIndex, columnIndex) as BaseValueObject : BooleanValueObject.create(false); + let methodObject = methodArray.get(rowIndex, columnIndex) as BaseValueObject; if (startDateObject.isError()) { return startDateObject; @@ -80,10 +82,6 @@ export class Days360 extends BaseFunction { return endDateSerialNumber; } - if (methodObject.isError()) { - return methodObject; - } - if (methodObject.isString()) { methodObject = methodObject.convertToNumberObjectValue(); } @@ -92,61 +90,65 @@ export class Days360 extends BaseFunction { return methodObject; } - const startDateDate = excelSerialToDate(startDateSerialNumber); - const startYear = startDateSerialNumber > 0 ? startDateDate.getUTCFullYear() : 1900; - const startMonth = startDateSerialNumber > 0 ? startDateDate.getUTCMonth() + 1 : 1; - let startDay = startDateSerialNumber > 0 ? startDateDate.getUTCDate() : 0; - - let endDateDate = excelSerialToDate(endDateSerialNumber); - let endYear = endDateSerialNumber > 0 ? endDateDate.getUTCFullYear() : 1900; - let endMonth = endDateSerialNumber > 0 ? endDateDate.getUTCMonth() + 1 : 1; - let endDay = endDateSerialNumber > 0 ? endDateDate.getUTCDate() : 0; + return this._getResult(startDateSerialNumber, endDateSerialNumber, methodObject); + }); - const methodValue = +methodObject.getValue(); + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as NumberValueObject; + } - if (!methodValue) { - // U.S. (NASD) method. - // If the starting date is the last day of a month, it becomes equal to the 30th day of the same month. - // If the ending date is the last day of a month and the starting date is earlier than the 30th day of a month, the ending date becomes equal to the 1st day of the next month; otherwise the ending date becomes equal to the 30th day of the same month. - if (startDay === 31) { - startDay = 30; - } + return resultArray; + } - if (endDay === 31) { - if (startDay < 30) { - endDateDate = excelSerialToDate(endDateSerialNumber + 1); - endYear = endDateDate.getUTCFullYear(); - endMonth = endDateDate.getUTCMonth() + 1; - endDay = endDateDate.getUTCDate(); - } else { - endDay = 30; - } - } - } else { - // European method. Starting dates and ending dates that occur on the 31st day of a month become equal to the 30th day of the same month. - if (startDay === 31) { - startDay = 30; - } + private _getResult(startDateSerialNumber: number, endDateSerialNumber: number, methodObject: BaseValueObject) { + const startDateDate = excelSerialToDate(startDateSerialNumber); + const startYear = startDateSerialNumber > 0 ? startDateDate.getUTCFullYear() : 1900; + const startMonth = startDateSerialNumber > 0 ? startDateDate.getUTCMonth() + 1 : 1; + let startDay = startDateSerialNumber > 0 ? startDateDate.getUTCDate() : 0; + + let endDateDate = excelSerialToDate(endDateSerialNumber); + let endYear = endDateSerialNumber > 0 ? endDateDate.getUTCFullYear() : 1900; + let endMonth = endDateSerialNumber > 0 ? endDateDate.getUTCMonth() + 1 : 1; + let endDay = endDateSerialNumber > 0 ? endDateDate.getUTCDate() : 0; + + const methodValue = +methodObject.getValue(); + + if (!methodValue) { + // U.S. (NASD) method. + // If the starting date is the last day of a month, it becomes equal to the 30th day of the same month. + // If the ending date is the last day of a month and the starting date is earlier than the 30th day of a month, the ending date becomes equal to the 1st day of the next month; otherwise the ending date becomes equal to the 30th day of the same month. + if (startDay === 31) { + startDay = 30; + } - if (endDay === 31) { + if (endDay === 31) { + if (startDay < 30) { + endDateDate = excelSerialToDate(endDateSerialNumber + 1); + endYear = endDateDate.getUTCFullYear(); + endMonth = endDateDate.getUTCMonth() + 1; + endDay = endDateDate.getUTCDate(); + } else { endDay = 30; } } + } else { + // European method. Starting dates and ending dates that occur on the 31st day of a month become equal to the 30th day of the same month. + if (startDay === 31) { + startDay = 30; + } - const daysInYears = (endYear - startYear) * 360; - const daysInStartMonth = endDateSerialNumber >= startDateSerialNumber ? 30 - startDay : -startDay; - const daysInEndMonth = endDateSerialNumber >= startDateSerialNumber ? endDay : endDay - 30; - const daysInMidMonths = (endDateSerialNumber >= startDateSerialNumber ? (endMonth - startMonth - 1) : (endMonth - startMonth + 1)) * 30; - - const totalDays = daysInYears + daysInStartMonth + daysInEndMonth + daysInMidMonths; + if (endDay === 31) { + endDay = 30; + } + } - return NumberValueObject.create(totalDays); - }); + const daysInYears = (endYear - startYear) * 360; + const daysInStartMonth = endDateSerialNumber >= startDateSerialNumber ? 30 - startDay : -startDay; + const daysInEndMonth = endDateSerialNumber >= startDateSerialNumber ? endDay : endDay - 30; + const daysInMidMonths = (endDateSerialNumber >= startDateSerialNumber ? (endMonth - startMonth - 1) : (endMonth - startMonth + 1)) * 30; - if (maxRowLength === 1 && maxColumnLength === 1) { - return (resultArray as ArrayValueObject).get(0, 0) as NumberValueObject; - } + const totalDays = daysInYears + daysInStartMonth + daysInEndMonth + daysInMidMonths; - return resultArray; + return NumberValueObject.create(totalDays); } } diff --git a/packages/engine-formula/src/functions/date/edate/index.ts b/packages/engine-formula/src/functions/date/edate/index.ts index f611a6a4c63..1e7f478576b 100644 --- a/packages/engine-formula/src/functions/date/edate/index.ts +++ b/packages/engine-formula/src/functions/date/edate/index.ts @@ -78,18 +78,16 @@ export class Edate extends BaseFunction { const monthsValue = Math.floor(+monthsValueObject.getValue()); - const startDate = excelSerialToDate(startDateSerial); + const _startDate = excelSerialToDate(startDateSerial); - const year = startDate.getUTCFullYear(); - const month = startDate.getUTCMonth() + monthsValue; - const day = startDate.getUTCDate(); + const year = _startDate.getUTCFullYear(); + const month = _startDate.getUTCMonth() + monthsValue; + const day = _startDate.getUTCDate(); const resultDate = new Date(Date.UTC(year, month, day)); const currentSerial = excelDateSerial(resultDate); - const valueObject = NumberValueObject.create(currentSerial, DEFAULT_DATE_FORMAT); - - return valueObject; + return NumberValueObject.create(currentSerial, DEFAULT_DATE_FORMAT); }); } } diff --git a/packages/engine-formula/src/functions/date/eomonth/index.ts b/packages/engine-formula/src/functions/date/eomonth/index.ts index 29999aa62e2..356095d4597 100644 --- a/packages/engine-formula/src/functions/date/eomonth/index.ts +++ b/packages/engine-formula/src/functions/date/eomonth/index.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { isRealNum } from '@univerjs/core'; import { excelDateSerial, excelSerialToDate, getDateSerialNumberByObject } from '../../../basics/date'; import { ErrorType } from '../../../basics/error-type'; import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; @@ -28,58 +27,59 @@ export class Eomonth extends BaseFunction { override maxParams = 2; override calculate(startDate: BaseValueObject, months: BaseValueObject) { - if (startDate.isArray()) { - const rowCount = (startDate as ArrayValueObject).getRowCount(); - const columnCount = (startDate as ArrayValueObject).getColumnCount(); + let _startDate = startDate; + let _months = months; + + if (_startDate.isArray()) { + const rowCount = (_startDate as ArrayValueObject).getRowCount(); + const columnCount = (_startDate as ArrayValueObject).getColumnCount(); if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - startDate = (startDate as ArrayValueObject).get(0, 0) as BaseValueObject; + _startDate = (_startDate as ArrayValueObject).get(0, 0) as BaseValueObject; } - if (months.isArray()) { - const rowCount = (months as ArrayValueObject).getRowCount(); - const columnCount = (months as ArrayValueObject).getColumnCount(); + if (_months.isArray()) { + const rowCount = (_months as ArrayValueObject).getRowCount(); + const columnCount = (_months as ArrayValueObject).getColumnCount(); if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - months = (months as ArrayValueObject).get(0, 0) as BaseValueObject; + _months = (_months as ArrayValueObject).get(0, 0) as BaseValueObject; } - if (startDate.isError()) { - return startDate; + if (_startDate.isError()) { + return _startDate; } - if (months.isError()) { - return months; + if (_months.isError()) { + return _months; } - const startDateSerialNumber = getDateSerialNumberByObject(startDate); + const startDateSerialNumber = getDateSerialNumberByObject(_startDate); if (typeof startDateSerialNumber !== 'number') { return startDateSerialNumber; } + if (_months.isBoolean()) { + return ErrorValueObject.create(ErrorType.VALUE); + } + const startDateDate = excelSerialToDate(startDateSerialNumber); const startYear = startDateSerialNumber > 0 ? startDateDate.getUTCFullYear() : 1900; const startMonth = startDateSerialNumber > 0 ? startDateDate.getUTCMonth() : 0; - let monthsValue = months.getValue(); + const monthsValue = Math.floor(+_months.getValue()); - if (months.isBoolean()) { + if (Number.isNaN(monthsValue)) { return ErrorValueObject.create(ErrorType.VALUE); } - if (months.isString() && !isRealNum(monthsValue)) { - return ErrorValueObject.create(ErrorType.VALUE); - } - - monthsValue = Math.floor(+monthsValue); - const targetDate = new Date(Date.UTC(startYear, startMonth + monthsValue + 1, 0)); const result = excelDateSerial(targetDate); diff --git a/packages/engine-formula/src/functions/date/networkdays-intl/index.ts b/packages/engine-formula/src/functions/date/networkdays-intl/index.ts index aa9922af7d4..2b227f30142 100644 --- a/packages/engine-formula/src/functions/date/networkdays-intl/index.ts +++ b/packages/engine-formula/src/functions/date/networkdays-intl/index.ts @@ -52,109 +52,122 @@ export class NetworkdaysIntl extends BaseFunction { } private _handleSingleObject(startDate: BaseValueObject, endDate: BaseValueObject, weekend?: BaseValueObject, holidays?: BaseValueObject) { - let weekendValue: number | string = 1; + let _startDate = startDate; + let _endDate = endDate; - if (weekend) { - weekendValue = weekend.getValue() as number | string; + if (_startDate.isArray()) { + const rowCount = (_startDate as ArrayValueObject).getRowCount(); + const columnCount = (_startDate as ArrayValueObject).getColumnCount(); - if (weekend.isBoolean()) { - weekendValue = +weekendValue; - } - - if (weekend.isString() && !isValidWeekend(weekendValue)) { + if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - if (!isValidWeekend(weekendValue)) { - return ErrorValueObject.create(ErrorType.NUM); - } + _startDate = (_startDate as ArrayValueObject).get(0, 0) as BaseValueObject; } - if (startDate.isArray()) { - if ((startDate as ArrayValueObject).getRowCount() > 1 || (startDate as ArrayValueObject).getColumnCount() > 1) { + if (_startDate.isError()) { + return _startDate; + } + + if (_endDate.isArray()) { + const rowCount = (_endDate as ArrayValueObject).getRowCount(); + const columnCount = (_endDate as ArrayValueObject).getColumnCount(); + + if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - startDate = (startDate as ArrayValueObject).get(0, 0) as BaseValueObject; + _endDate = (_endDate as ArrayValueObject).get(0, 0) as BaseValueObject; + } - if (startDate.isError()) { - return startDate; - } + if (_endDate.isError()) { + return _endDate; } - if (endDate.isArray()) { - if ((endDate as ArrayValueObject).getRowCount() > 1 || (endDate as ArrayValueObject).getColumnCount() > 1) { - return ErrorValueObject.create(ErrorType.VALUE); + let weekendValue: number | string = 1; + + if (weekend) { + weekendValue = weekend.getValue() as number | string; + + if (weekend.isBoolean()) { + weekendValue = +weekendValue; } - endDate = (endDate as ArrayValueObject).get(0, 0) as BaseValueObject; + if (weekend.isString() && !isValidWeekend(weekendValue)) { + return ErrorValueObject.create(ErrorType.VALUE); + } - if (endDate.isError()) { - return endDate; + if (!isValidWeekend(weekendValue)) { + return ErrorValueObject.create(ErrorType.NUM); } } - if (startDate.isBoolean() || endDate.isBoolean()) { + if (_startDate.isBoolean() || _endDate.isBoolean()) { return ErrorValueObject.create(ErrorType.VALUE); } - const startDateSerialNumber = getDateSerialNumberByObject(startDate); + const startDateSerialNumber = getDateSerialNumberByObject(_startDate); if (typeof startDateSerialNumber !== 'number') { return startDateSerialNumber; } - const endDateSerialNumber = getDateSerialNumberByObject(endDate); + const endDateSerialNumber = getDateSerialNumberByObject(_endDate); if (typeof endDateSerialNumber !== 'number') { return endDateSerialNumber; } - let result: number; - if (holidays) { - const holidaysValueArray = []; + return this._getResultByHolidays(startDateSerialNumber, endDateSerialNumber, weekendValue, holidays); + } - if (holidays?.isArray()) { - const rowCount = (holidays as ArrayValueObject).getRowCount(); - const columnCount = (holidays as ArrayValueObject).getColumnCount(); + const result = countWorkingDays(startDateSerialNumber, endDateSerialNumber, weekendValue); - for (let r = 0; r < rowCount; r++) { - for (let c = 0; c < columnCount; c++) { - const cell = (holidays as ArrayValueObject).get(r, c) as BaseValueObject; + return NumberValueObject.create(result); + } - if (cell.isBoolean()) { - return ErrorValueObject.create(ErrorType.VALUE); - } + private _getResultByHolidays(startDateSerialNumber: number, endDateSerialNumber: number, weekendValue: number | string, holidays: BaseValueObject): BaseValueObject { + const holidaysValueArray = []; - const holidaySerialNumber = getDateSerialNumberByObject(cell); + if (holidays?.isArray()) { + const rowCount = (holidays as ArrayValueObject).getRowCount(); + const columnCount = (holidays as ArrayValueObject).getColumnCount(); - if (typeof holidaySerialNumber !== 'number') { - return holidaySerialNumber; - } + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const cell = (holidays as ArrayValueObject).get(r, c) as BaseValueObject; - holidaysValueArray.push(holidaySerialNumber); + if (cell.isBoolean()) { + return ErrorValueObject.create(ErrorType.VALUE); } - } - } else { - if (holidays.isBoolean()) { - return ErrorValueObject.create(ErrorType.VALUE); - } - const holidaySerialNumber = getDateSerialNumberByObject(holidays); + const holidaySerialNumber = getDateSerialNumberByObject(cell); + + if (typeof holidaySerialNumber !== 'number') { + return holidaySerialNumber; + } - if (typeof holidaySerialNumber !== 'number') { - return holidaySerialNumber; + holidaysValueArray.push(holidaySerialNumber); } + } + } else { + if (holidays.isBoolean()) { + return ErrorValueObject.create(ErrorType.VALUE); + } + + const holidaySerialNumber = getDateSerialNumberByObject(holidays); - holidaysValueArray.push(holidaySerialNumber); + if (typeof holidaySerialNumber !== 'number') { + return holidaySerialNumber; } - result = countWorkingDays(startDateSerialNumber, endDateSerialNumber, weekendValue, holidaysValueArray); - } else { - result = countWorkingDays(startDateSerialNumber, endDateSerialNumber, weekendValue); + holidaysValueArray.push(holidaySerialNumber); } + const result = countWorkingDays(startDateSerialNumber, endDateSerialNumber, weekendValue, holidaysValueArray); + return NumberValueObject.create(result); } } diff --git a/packages/engine-formula/src/functions/date/networkdays/index.ts b/packages/engine-formula/src/functions/date/networkdays/index.ts index c7318ac0eec..4cc3b53dcec 100644 --- a/packages/engine-formula/src/functions/date/networkdays/index.ts +++ b/packages/engine-formula/src/functions/date/networkdays/index.ts @@ -28,103 +28,108 @@ export class Networkdays extends BaseFunction { override maxParams = 3; override calculate(startDate: BaseValueObject, endDate: BaseValueObject, holidays?: BaseValueObject) { - if (startDate.isError()) { - return startDate; - } - - if (endDate.isError()) { - return endDate; - } + let _startDate = startDate; + let _endDate = endDate; - if (holidays?.isError()) { - return holidays; - } + if (_startDate.isArray()) { + const rowCount = (_startDate as ArrayValueObject).getRowCount(); + const columnCount = (_startDate as ArrayValueObject).getColumnCount(); - if (startDate.isArray()) { - if ((startDate as ArrayValueObject).getRowCount() > 1 || (startDate as ArrayValueObject).getColumnCount() > 1) { + if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - startDate = (startDate as ArrayValueObject).get(0, 0) as BaseValueObject; + _startDate = (_startDate as ArrayValueObject).get(0, 0) as BaseValueObject; + } - if (startDate.isError()) { - return startDate; - } + if (_startDate.isError()) { + return _startDate; } - if (endDate.isArray()) { - if ((endDate as ArrayValueObject).getRowCount() > 1 || (endDate as ArrayValueObject).getColumnCount() > 1) { + if (_endDate.isArray()) { + const rowCount = (_endDate as ArrayValueObject).getRowCount(); + const columnCount = (_endDate as ArrayValueObject).getColumnCount(); + + if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - endDate = (endDate as ArrayValueObject).get(0, 0) as BaseValueObject; + _endDate = (_endDate as ArrayValueObject).get(0, 0) as BaseValueObject; + } - if (endDate.isError()) { - return endDate; - } + if (_endDate.isError()) { + return _endDate; + } + + if (holidays?.isError()) { + return holidays; } - if (startDate.isBoolean() || endDate.isBoolean()) { + if (_startDate.isBoolean() || _endDate.isBoolean()) { return ErrorValueObject.create(ErrorType.VALUE); } - const startDateSerialNumber = getDateSerialNumberByObject(startDate); + const startDateSerialNumber = getDateSerialNumberByObject(_startDate); if (typeof startDateSerialNumber !== 'number') { return startDateSerialNumber; } - const endDateSerialNumber = getDateSerialNumberByObject(endDate); + const endDateSerialNumber = getDateSerialNumberByObject(_endDate); if (typeof endDateSerialNumber !== 'number') { return endDateSerialNumber; } - let result: number; - if (holidays) { - const holidaysValueArray = []; + return this._getResultByHolidays(startDateSerialNumber, endDateSerialNumber, holidays); + } - if (holidays?.isArray()) { - const rowCount = (holidays as ArrayValueObject).getRowCount(); - const columnCount = (holidays as ArrayValueObject).getColumnCount(); + const result = countWorkingDays(startDateSerialNumber, endDateSerialNumber); - for (let r = 0; r < rowCount; r++) { - for (let c = 0; c < columnCount; c++) { - const cell = (holidays as ArrayValueObject).get(r, c) as BaseValueObject; + return NumberValueObject.create(result); + } - if (cell.isBoolean()) { - return ErrorValueObject.create(ErrorType.VALUE); - } + private _getResultByHolidays(startDateSerialNumber: number, endDateSerialNumber: number, holidays: BaseValueObject): BaseValueObject { + const holidaysValueArray = []; - const holidaySerialNumber = getDateSerialNumberByObject(cell); + if (holidays?.isArray()) { + const rowCount = (holidays as ArrayValueObject).getRowCount(); + const columnCount = (holidays as ArrayValueObject).getColumnCount(); - if (typeof holidaySerialNumber !== 'number') { - return holidaySerialNumber; - } + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const cell = (holidays as ArrayValueObject).get(r, c) as BaseValueObject; - holidaysValueArray.push(holidaySerialNumber); + if (cell.isBoolean()) { + return ErrorValueObject.create(ErrorType.VALUE); } - } - } else { - if (holidays.isBoolean()) { - return ErrorValueObject.create(ErrorType.VALUE); - } - const holidaySerialNumber = getDateSerialNumberByObject(holidays); + const holidaySerialNumber = getDateSerialNumberByObject(cell); + + if (typeof holidaySerialNumber !== 'number') { + return holidaySerialNumber; + } - if (typeof holidaySerialNumber !== 'number') { - return holidaySerialNumber; + holidaysValueArray.push(holidaySerialNumber); } + } + } else { + if (holidays.isBoolean()) { + return ErrorValueObject.create(ErrorType.VALUE); + } - holidaysValueArray.push(holidaySerialNumber); + const holidaySerialNumber = getDateSerialNumberByObject(holidays); + + if (typeof holidaySerialNumber !== 'number') { + return holidaySerialNumber; } - result = countWorkingDays(startDateSerialNumber, endDateSerialNumber, 1, holidaysValueArray); - } else { - result = countWorkingDays(startDateSerialNumber, endDateSerialNumber); + holidaysValueArray.push(holidaySerialNumber); } + const result = countWorkingDays(startDateSerialNumber, endDateSerialNumber, 1, holidaysValueArray); + return NumberValueObject.create(result); } } diff --git a/packages/engine-formula/src/functions/date/time/index.ts b/packages/engine-formula/src/functions/date/time/index.ts index 2a1a71abc30..7f89fe59fa3 100644 --- a/packages/engine-formula/src/functions/date/time/index.ts +++ b/packages/engine-formula/src/functions/date/time/index.ts @@ -65,10 +65,12 @@ export class Time extends BaseFunction { } private _calculateTime(hourValueObject: BaseValueObject, minuteArray: ArrayValueObject, secondArray: ArrayValueObject, rowIndex: number, columnIndex: number) { + let _hourValueObject = hourValueObject; let minuteValueObject = minuteArray.get(rowIndex, columnIndex) || NullValueObject.create(); let secondValueObject = secondArray.get(rowIndex, columnIndex) || NullValueObject.create(); - if (hourValueObject.isString() || hourValueObject.isBoolean()) { - hourValueObject = hourValueObject.convertToNumberObjectValue(); + + if (_hourValueObject.isString() || _hourValueObject.isBoolean()) { + _hourValueObject = _hourValueObject.convertToNumberObjectValue(); } if (minuteValueObject.isString() || minuteValueObject.isBoolean()) { @@ -79,8 +81,8 @@ export class Time extends BaseFunction { secondValueObject = secondValueObject.convertToNumberObjectValue(); } - if (hourValueObject.isError()) { - return hourValueObject; + if (_hourValueObject.isError()) { + return _hourValueObject; } if (minuteValueObject.isError()) { @@ -91,7 +93,7 @@ export class Time extends BaseFunction { return secondValueObject; } - let hourValue = Math.floor(+hourValueObject.getValue()); + let hourValue = Math.floor(+_hourValueObject.getValue()); let minuteValue = Math.floor(+minuteValueObject.getValue()); let secondValue = Math.floor(+secondValueObject.getValue()); diff --git a/packages/engine-formula/src/functions/date/weekday/index.ts b/packages/engine-formula/src/functions/date/weekday/index.ts index 94cd0b0ba75..e8aac7fd9bd 100644 --- a/packages/engine-formula/src/functions/date/weekday/index.ts +++ b/packages/engine-formula/src/functions/date/weekday/index.ts @@ -22,58 +22,61 @@ import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-ob import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; +interface IReturnTypeMap { + [index: number]: number[]; +} + export class Weekday extends BaseFunction { override minParams = 1; override maxParams = 2; override calculate(serialNumber: BaseValueObject, returnType?: BaseValueObject) { + const _returnType = returnType ?? NumberValueObject.create(1); + if (serialNumber.isError()) { return serialNumber; } - if (returnType?.isError()) { - return returnType; + if (_returnType.isError()) { + return _returnType; } - // get max row length const maxRowLength = Math.max( serialNumber.isArray() ? (serialNumber as ArrayValueObject).getRowCount() : 1, - returnType?.isArray() ? (returnType as ArrayValueObject).getRowCount() : 1 + _returnType.isArray() ? (_returnType as ArrayValueObject).getRowCount() : 1 ); - // get max column length const maxColumnLength = Math.max( serialNumber.isArray() ? (serialNumber as ArrayValueObject).getColumnCount() : 1, - returnType?.isArray() ? (returnType as ArrayValueObject).getColumnCount() : 1 + _returnType.isArray() ? (_returnType as ArrayValueObject).getColumnCount() : 1 ); const serialNumberArray = expandArrayValueObject(maxRowLength, maxColumnLength, serialNumber, ErrorValueObject.create(ErrorType.NA)); - const returnTypeArray = returnType ? expandArrayValueObject(maxRowLength, maxColumnLength, returnType, ErrorValueObject.create(ErrorType.NA)) : []; + const returnTypeArray = expandArrayValueObject(maxRowLength, maxColumnLength, _returnType, ErrorValueObject.create(ErrorType.NA)); const resultArray = serialNumberArray.map((serialNumberObject, rowIndex, columnIndex) => { - if (returnType) { - const returnTypeObject = (returnTypeArray as ArrayValueObject).get(rowIndex, columnIndex) as BaseValueObject; - return this._handleSingleObject(serialNumberObject, returnTypeObject); - } else { - return this._handleSingleObject(serialNumberObject); - } + const returnTypeObject = returnTypeArray.get(rowIndex, columnIndex) as BaseValueObject; + + return this._handleSingleObject(serialNumberObject, returnTypeObject); }); - if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { - return resultArray.getArrayValue()[0][0] as NumberValueObject; + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; } return resultArray; } - private _handleSingleObject(serialNumberObject: BaseValueObject, returnTypeObject?: BaseValueObject) { + private _handleSingleObject(serialNumberObject: BaseValueObject, returnTypeObject: BaseValueObject) { + let _returnTypeObject = returnTypeObject; + if (serialNumberObject.isError()) { return serialNumberObject; } - if (returnTypeObject?.isError()) { - return returnTypeObject; + if (_returnTypeObject.isError()) { + return _returnTypeObject; } const dateSerialNumber = getDateSerialNumberByObject(serialNumberObject); @@ -82,43 +85,37 @@ export class Weekday extends BaseFunction { return dateSerialNumber; } - const returnTypeMap: { - [index: number]: number[]; - } = { - 1: [1, 2, 3, 4, 5, 6, 7], // Sunday = 1 ~ Saturday = 7 - 2: [7, 1, 2, 3, 4, 5, 6], // Monday = 1 ~ Sunday = 7 - 3: [6, 0, 1, 2, 3, 4, 5], // Monday = 0 ~ Sunday = 6 - 11: [7, 1, 2, 3, 4, 5, 6], // Monday = 1 ~ Sunday = 7 - 12: [6, 7, 1, 2, 3, 4, 5], // Tuesday = 1 ~ Monday = 7 - 13: [5, 6, 7, 1, 2, 3, 4], // Wednesday = 1 ~ Tuesday = 7 - 14: [4, 5, 6, 7, 1, 2, 3], // Thursday = 1 ~ Wednesday = 7 - 15: [3, 4, 5, 6, 7, 1, 2], // Friday = 1 ~ Thursday = 7 - 16: [2, 3, 4, 5, 6, 7, 1], // Saturday = 1 ~ Friday = 7 - 17: [1, 2, 3, 4, 5, 6, 7], // Sunday = 1 ~ Saturday = 7 - }; - - let returnType = 1; - - if (returnTypeObject) { - if (returnTypeObject.isString()) { - returnTypeObject = returnTypeObject.convertToNumberObjectValue(); - } + if (_returnTypeObject.isString()) { + _returnTypeObject = _returnTypeObject.convertToNumberObjectValue(); - if (returnTypeObject.isError()) { - return returnTypeObject; + if (_returnTypeObject.isError()) { + return _returnTypeObject; } + } - returnType = Math.floor(+returnTypeObject.getValue()); + const returnTypeValue = Math.floor(+_returnTypeObject.getValue()); - if (!returnTypeMap[returnType]) { - return ErrorValueObject.create(ErrorType.NUM); - } + if (!this._returnTypeMap[returnTypeValue]) { + return ErrorValueObject.create(ErrorType.NUM); } const weekDay = getWeekDayByDateSerialNumber(dateSerialNumber); - const result = returnTypeMap[returnType][weekDay]; + const result = this._returnTypeMap[returnTypeValue][weekDay]; return NumberValueObject.create(result); } + + private _returnTypeMap: IReturnTypeMap = { + 1: [1, 2, 3, 4, 5, 6, 7], // Sunday = 1 ~ Saturday = 7 + 2: [7, 1, 2, 3, 4, 5, 6], // Monday = 1 ~ Sunday = 7 + 3: [6, 0, 1, 2, 3, 4, 5], // Monday = 0 ~ Sunday = 6 + 11: [7, 1, 2, 3, 4, 5, 6], // Monday = 1 ~ Sunday = 7 + 12: [6, 7, 1, 2, 3, 4, 5], // Tuesday = 1 ~ Monday = 7 + 13: [5, 6, 7, 1, 2, 3, 4], // Wednesday = 1 ~ Tuesday = 7 + 14: [4, 5, 6, 7, 1, 2, 3], // Thursday = 1 ~ Wednesday = 7 + 15: [3, 4, 5, 6, 7, 1, 2], // Friday = 1 ~ Thursday = 7 + 16: [2, 3, 4, 5, 6, 7, 1], // Saturday = 1 ~ Friday = 7 + 17: [1, 2, 3, 4, 5, 6, 7], // Sunday = 1 ~ Saturday = 7 + }; } diff --git a/packages/engine-formula/src/functions/date/weeknum/index.ts b/packages/engine-formula/src/functions/date/weeknum/index.ts index 1ff875d4bc2..679c8292cd9 100644 --- a/packages/engine-formula/src/functions/date/weeknum/index.ts +++ b/packages/engine-formula/src/functions/date/weeknum/index.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { isRealNum } from '@univerjs/core'; import { excelDateSerial, excelSerialToDate, getDateSerialNumberByObject, getWeekDayByDateSerialNumber } from '../../../basics/date'; import { ErrorType } from '../../../basics/error-type'; import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; @@ -22,85 +21,77 @@ import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-ob import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; +interface IReturnTypeMap { + [index: number]: number; +} + export class Weeknum extends BaseFunction { override minParams = 1; override maxParams = 2; - private returnTypeMap: { - [index: number]: number; - } = { - 1: 0, - 2: 1, - 11: 1, - 12: 2, - 13: 3, - 14: 4, - 15: 5, - 16: 6, - 17: 0, - 21: 4, - }; - override calculate(serialNumber: BaseValueObject, returnType?: BaseValueObject) { - if (serialNumber.isArray()) { - const rowCount = (serialNumber as ArrayValueObject).getRowCount(); - const columnCount = (serialNumber as ArrayValueObject).getColumnCount(); + let _serialNumber = serialNumber; + let _returnType = returnType ?? NumberValueObject.create(1); + + if (_serialNumber.isArray()) { + const rowCount = (_serialNumber as ArrayValueObject).getRowCount(); + const columnCount = (_serialNumber as ArrayValueObject).getColumnCount(); if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - serialNumber = (serialNumber as ArrayValueObject).get(0, 0) as BaseValueObject; + _serialNumber = (_serialNumber as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_serialNumber.isError()) { + return _serialNumber; } - if (returnType?.isArray()) { - const rowCount = (returnType as ArrayValueObject).getRowCount(); - const columnCount = (returnType as ArrayValueObject).getColumnCount(); + if (_returnType.isArray()) { + const rowCount = (_returnType as ArrayValueObject).getRowCount(); + const columnCount = (_returnType as ArrayValueObject).getColumnCount(); if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - returnType = (returnType as ArrayValueObject).get(0, 0) as BaseValueObject; - } - - if (serialNumber.isError()) { - return serialNumber; + _returnType = (_returnType as ArrayValueObject).get(0, 0) as BaseValueObject; } - if (returnType?.isError()) { - return returnType; + if (_returnType.isError()) { + return _returnType; } - if (serialNumber.isBoolean()) { + if (_serialNumber.isBoolean()) { return ErrorValueObject.create(ErrorType.VALUE); } - const dateSerialNumber = getDateSerialNumberByObject(serialNumber); + const dateSerialNumber = getDateSerialNumberByObject(_serialNumber); if (typeof dateSerialNumber !== 'number') { return dateSerialNumber; } - let returnTypeValue = 1; - - if (returnType) { - returnTypeValue = Math.floor(+returnType.getValue()); + if (_returnType.isBoolean()) { + return ErrorValueObject.create(ErrorType.VALUE); + } - if (returnType.isBoolean()) { - return ErrorValueObject.create(ErrorType.VALUE); - } + const returnTypeValue = Math.floor(+_returnType.getValue()); - if (returnType.isString() && !isRealNum(returnTypeValue)) { - return ErrorValueObject.create(ErrorType.VALUE); - } + if (Number.isNaN(returnTypeValue)) { + return ErrorValueObject.create(ErrorType.VALUE); } - if (!(returnTypeValue in this.returnTypeMap)) { + if (!(returnTypeValue in this._returnTypeMap)) { return ErrorValueObject.create(ErrorType.NUM); } + return this._getResult(dateSerialNumber, returnTypeValue); + } + + private _getResult(dateSerialNumber: number, returnTypeValue: number) { const currentDate = excelSerialToDate(dateSerialNumber); const currentYear = dateSerialNumber > 0 ? currentDate.getUTCFullYear() : 1900; let yearStart = new Date(Date.UTC(currentYear, 0, 1)); @@ -136,7 +127,7 @@ export class Weeknum extends BaseFunction { } else { // System 1 // The week containing January 1 is the first week of the year, and is numbered week 1. - const weekDay = this.returnTypeMap[returnTypeValue]; + const weekDay = this._returnTypeMap[returnTypeValue]; if (yearStartWeekDay < weekDay) { yearWeekStartSerialNumber = yearStartSerialNumber - (yearStartWeekDay + 7 - weekDay); @@ -149,4 +140,17 @@ export class Weeknum extends BaseFunction { return NumberValueObject.create(result); } + + private _returnTypeMap: IReturnTypeMap = { + 1: 0, + 2: 1, + 11: 1, + 12: 2, + 13: 3, + 14: 4, + 15: 5, + 16: 6, + 17: 0, + 21: 4, + }; } diff --git a/packages/engine-formula/src/functions/date/workday-intl/index.ts b/packages/engine-formula/src/functions/date/workday-intl/index.ts index 4377f9d73b6..55ab395b92e 100644 --- a/packages/engine-formula/src/functions/date/workday-intl/index.ts +++ b/packages/engine-formula/src/functions/date/workday-intl/index.ts @@ -52,114 +52,125 @@ export class WorkdayIntl extends BaseFunction { } private _handleSingleObject(startDate: BaseValueObject, days: BaseValueObject, weekend?: BaseValueObject, holidays?: BaseValueObject) { - let weekendValue: number | string = 1; + const _weekend = weekend ?? NumberValueObject.create(1); - if (weekend) { - weekendValue = weekend.getValue() as number | string; + const _startDate = this._checkArrayError(startDate); - if (weekend.isBoolean()) { - weekendValue = +weekendValue; - } + if (_startDate.isError()) { + return _startDate; + } - // 1111111 is an invalid string. - if (weekend.isString() && (!isValidWeekend(weekendValue) || weekendValue === '1111111')) { - return ErrorValueObject.create(ErrorType.VALUE); - } + const _days = this._checkArrayError(days); - if (!isValidWeekend(weekendValue)) { - return ErrorValueObject.create(ErrorType.NUM); - } + if (_days.isError()) { + return _days; } - if (startDate.isArray()) { - if ((startDate as ArrayValueObject).getRowCount() > 1 || (startDate as ArrayValueObject).getColumnCount() > 1) { - return ErrorValueObject.create(ErrorType.VALUE); - } + if (_startDate.isBoolean() || _days.isBoolean()) { + return ErrorValueObject.create(ErrorType.VALUE); + } - startDate = (startDate as ArrayValueObject).get(0, 0) as BaseValueObject; + const startDateSerialNumber = getDateSerialNumberByObject(startDate); - if (startDate.isError()) { - return startDate; - } + if (typeof startDateSerialNumber !== 'number') { + return startDateSerialNumber; } - if (days.isArray()) { - if ((days as ArrayValueObject).getRowCount() > 1 || (days as ArrayValueObject).getColumnCount() > 1) { - return ErrorValueObject.create(ErrorType.VALUE); - } + const workingDays = +days.getValue(); - days = (days as ArrayValueObject).get(0, 0) as BaseValueObject; + if (Number.isNaN(workingDays)) { + return ErrorValueObject.create(ErrorType.VALUE); + } - if (days.isError()) { - return days; - } + let weekendValue = _weekend.getValue() as number | string; + + if (_weekend.isBoolean()) { + weekendValue = +weekendValue; } - if (startDate.isBoolean() || days.isBoolean()) { + // 1111111 is an invalid string. + if (_weekend.isString() && (!isValidWeekend(weekendValue) || weekendValue === '1111111')) { return ErrorValueObject.create(ErrorType.VALUE); } - const startDateSerialNumber = getDateSerialNumberByObject(startDate); + if (!isValidWeekend(weekendValue)) { + return ErrorValueObject.create(ErrorType.NUM); + } - if (typeof startDateSerialNumber !== 'number') { - return startDateSerialNumber; + if (holidays) { + return this._getResultByHolidays(startDateSerialNumber, workingDays, weekendValue, holidays); } - if (days.isString()) { - days = days.convertToNumberObjectValue(); + const result = getDateSerialNumberByWorkingDays(startDateSerialNumber, workingDays, weekendValue); - if (days.isError()) { - return days; - } + if (typeof result !== 'number') { + return result; } - const workingDays = +days.getValue(); + return NumberValueObject.create(result); + } - let result: number | ErrorValueObject; + private _checkArrayError(variant: BaseValueObject): BaseValueObject { + let _variant = variant; - if (holidays) { - const holidaysValueArray = []; + if (_variant.isArray()) { + const rowCount = (_variant as ArrayValueObject).getRowCount(); + const columnCount = (_variant as ArrayValueObject).getColumnCount(); - if (holidays?.isArray()) { - const rowCount = (holidays as ArrayValueObject).getRowCount(); - const columnCount = (holidays as ArrayValueObject).getColumnCount(); + if (rowCount > 1 || columnCount > 1) { + return ErrorValueObject.create(ErrorType.VALUE); + } + + _variant = (_variant as ArrayValueObject).get(0, 0) as BaseValueObject; + } - for (let r = 0; r < rowCount; r++) { - for (let c = 0; c < columnCount; c++) { - const cell = (holidays as ArrayValueObject).get(r, c) as BaseValueObject; + if (_variant.isError()) { + return _variant; + } - if (cell.isBoolean()) { - return ErrorValueObject.create(ErrorType.VALUE); - } + return _variant; + } - const holidaySerialNumber = getDateSerialNumberByObject(cell); + private _getResultByHolidays(startDateSerialNumber: number, workingDays: number, weekendValue: number | string, holidays: BaseValueObject): BaseValueObject { + const holidaysValueArray = []; - if (typeof holidaySerialNumber !== 'number') { - return holidaySerialNumber; - } + if (holidays?.isArray()) { + const rowCount = (holidays as ArrayValueObject).getRowCount(); + const columnCount = (holidays as ArrayValueObject).getColumnCount(); - holidaysValueArray.push(holidaySerialNumber); + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const cell = (holidays as ArrayValueObject).get(r, c) as BaseValueObject; + + if (cell.isBoolean()) { + return ErrorValueObject.create(ErrorType.VALUE); } - } - } else { - if (holidays.isBoolean()) { - return ErrorValueObject.create(ErrorType.VALUE); - } - const holidaySerialNumber = getDateSerialNumberByObject(holidays); + const holidaySerialNumber = getDateSerialNumberByObject(cell); - if (typeof holidaySerialNumber !== 'number') { - return holidaySerialNumber; + if (typeof holidaySerialNumber !== 'number') { + return holidaySerialNumber; + } + + holidaysValueArray.push(holidaySerialNumber); } + } + } else { + if (holidays.isBoolean()) { + return ErrorValueObject.create(ErrorType.VALUE); + } - holidaysValueArray.push(holidaySerialNumber); + const holidaySerialNumber = getDateSerialNumberByObject(holidays); + + if (typeof holidaySerialNumber !== 'number') { + return holidaySerialNumber; } - result = getDateSerialNumberByWorkingDays(startDateSerialNumber, workingDays, weekendValue, holidaysValueArray); - } else { - result = getDateSerialNumberByWorkingDays(startDateSerialNumber, workingDays, weekendValue); + holidaysValueArray.push(holidaySerialNumber); } + const result = getDateSerialNumberByWorkingDays(startDateSerialNumber, workingDays, weekendValue, holidaysValueArray); + if (typeof result !== 'number') { return result; } diff --git a/packages/engine-formula/src/functions/date/workday/index.ts b/packages/engine-formula/src/functions/date/workday/index.ts index 061e063a4c4..4913a3d42c7 100644 --- a/packages/engine-formula/src/functions/date/workday/index.ts +++ b/packages/engine-formula/src/functions/date/workday/index.ts @@ -28,107 +28,112 @@ export class Workday extends BaseFunction { override maxParams = 3; override calculate(startDate: BaseValueObject, days: BaseValueObject, holidays?: BaseValueObject) { - if (startDate.isError()) { - return startDate; - } - - if (days.isError()) { - return days; - } + let _startDate = startDate; + let _days = days; - if (holidays?.isError()) { - return holidays; - } + if (_startDate.isArray()) { + const rowCount = (_startDate as ArrayValueObject).getRowCount(); + const columnCount = (_startDate as ArrayValueObject).getColumnCount(); - if (startDate.isArray()) { - if ((startDate as ArrayValueObject).getRowCount() > 1 || (startDate as ArrayValueObject).getColumnCount() > 1) { + if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - startDate = (startDate as ArrayValueObject).get(0, 0) as BaseValueObject; + _startDate = (_startDate as ArrayValueObject).get(0, 0) as BaseValueObject; + } - if (startDate.isError()) { - return startDate; - } + if (_startDate.isError()) { + return _startDate; } - if (days.isArray()) { - if ((days as ArrayValueObject).getRowCount() > 1 || (days as ArrayValueObject).getColumnCount() > 1) { + if (_days.isArray()) { + const rowCount = (_days as ArrayValueObject).getRowCount(); + const columnCount = (_days as ArrayValueObject).getColumnCount(); + + if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - days = (days as ArrayValueObject).get(0, 0) as BaseValueObject; + _days = (_days as ArrayValueObject).get(0, 0) as BaseValueObject; + } - if (days.isError()) { - return days; - } + if (_days.isError()) { + return _days; + } + + if (holidays?.isError()) { + return holidays; } - if (startDate.isBoolean() || days.isBoolean()) { + if (_startDate.isBoolean() || _days.isBoolean()) { return ErrorValueObject.create(ErrorType.VALUE); } - const startDateSerialNumber = getDateSerialNumberByObject(startDate); + const startDateSerialNumber = getDateSerialNumberByObject(_startDate); if (typeof startDateSerialNumber !== 'number') { return startDateSerialNumber; } - if (days.isString()) { - days = days.convertToNumberObjectValue(); + const workingDays = +_days.getValue(); - if (days.isError()) { - return days; - } + if (Number.isNaN(workingDays)) { + return ErrorValueObject.create(ErrorType.VALUE); } - const workingDays = +days.getValue(); - - let result: number | ErrorValueObject; - if (holidays) { - const holidaysValueArray: number[] = []; + return this._getResultByHolidays(startDateSerialNumber, workingDays, holidays); + } - if (holidays?.isArray()) { - const rowCount = (holidays as ArrayValueObject).getRowCount(); - const columnCount = (holidays as ArrayValueObject).getColumnCount(); + const result = getDateSerialNumberByWorkingDays(startDateSerialNumber, workingDays); - for (let r = 0; r < rowCount; r++) { - for (let c = 0; c < columnCount; c++) { - const cell = (holidays as ArrayValueObject).get(r, c) as BaseValueObject; + if (typeof result !== 'number') { + return result; + } - if (cell.isBoolean()) { - return ErrorValueObject.create(ErrorType.VALUE); - } + return NumberValueObject.create(result); + } + + private _getResultByHolidays(startDateSerialNumber: number, workingDays: number, holidays: BaseValueObject) { + const holidaysValueArray: number[] = []; - const holidaySerialNumber = getDateSerialNumberByObject(cell); + if (holidays?.isArray()) { + const rowCount = (holidays as ArrayValueObject).getRowCount(); + const columnCount = (holidays as ArrayValueObject).getColumnCount(); - if (typeof holidaySerialNumber !== 'number') { - return holidaySerialNumber; - } + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const cell = (holidays as ArrayValueObject).get(r, c) as BaseValueObject; - holidaysValueArray.push(holidaySerialNumber); + if (cell.isBoolean()) { + return ErrorValueObject.create(ErrorType.VALUE); } - } - } else { - if (holidays.isBoolean()) { - return ErrorValueObject.create(ErrorType.VALUE); - } - const holidaySerialNumber = getDateSerialNumberByObject(holidays); + const holidaySerialNumber = getDateSerialNumberByObject(cell); - if (typeof holidaySerialNumber !== 'number') { - return holidaySerialNumber; + if (typeof holidaySerialNumber !== 'number') { + return holidaySerialNumber; + } + + holidaysValueArray.push(holidaySerialNumber); } + } + } else { + if (holidays.isBoolean()) { + return ErrorValueObject.create(ErrorType.VALUE); + } + + const holidaySerialNumber = getDateSerialNumberByObject(holidays); - holidaysValueArray.push(holidaySerialNumber); + if (typeof holidaySerialNumber !== 'number') { + return holidaySerialNumber; } - result = getDateSerialNumberByWorkingDays(startDateSerialNumber, workingDays, 1, holidaysValueArray); - } else { - result = getDateSerialNumberByWorkingDays(startDateSerialNumber, workingDays); + holidaysValueArray.push(holidaySerialNumber); } + const result = getDateSerialNumberByWorkingDays(startDateSerialNumber, workingDays, 1, holidaysValueArray); + if (typeof result !== 'number') { return result; } diff --git a/packages/engine-formula/src/functions/date/yearfrac/index.ts b/packages/engine-formula/src/functions/date/yearfrac/index.ts index 922a1e39fa5..2346e266737 100644 --- a/packages/engine-formula/src/functions/date/yearfrac/index.ts +++ b/packages/engine-formula/src/functions/date/yearfrac/index.ts @@ -27,67 +27,90 @@ export class Yearfrac extends BaseFunction { override maxParams = 3; override calculate(startDate: BaseValueObject, endDate: BaseValueObject, basis?: BaseValueObject) { - if (startDate.isArray()) { - const rowCount = (startDate as ArrayValueObject).getRowCount(); - const columnCount = (startDate as ArrayValueObject).getColumnCount(); + let _basis = basis ?? NumberValueObject.create(0); - if (rowCount > 1 || columnCount > 1) { - return ErrorValueObject.create(ErrorType.VALUE); - } + const _startDate = this._checkArrayError(startDate); - startDate = (startDate as ArrayValueObject).get(0, 0) as BaseValueObject; + if (_startDate.isError()) { + return _startDate; } - if (endDate.isArray()) { - const rowCount = (endDate as ArrayValueObject).getRowCount(); - const columnCount = (endDate as ArrayValueObject).getColumnCount(); + const _endDate = this._checkArrayError(endDate); - if (rowCount > 1 || columnCount > 1) { - return ErrorValueObject.create(ErrorType.VALUE); - } - - endDate = (endDate as ArrayValueObject).get(0, 0) as BaseValueObject; + if (_endDate.isError()) { + return _endDate; } - if (basis?.isArray()) { - const rowCount = (basis as ArrayValueObject).getRowCount(); - const columnCount = (basis as ArrayValueObject).getColumnCount(); - - if (rowCount > 1 || columnCount > 1) { - return ErrorValueObject.create(ErrorType.VALUE); - } + _basis = this._checkArrayError(_basis); - basis = (basis as ArrayValueObject).get(0, 0) as BaseValueObject; + if (_basis.isError()) { + return _basis; } - if (startDate.isError()) { - return startDate; + if (_startDate.isBoolean() || _endDate.isBoolean() || _basis.isBoolean()) { + return ErrorValueObject.create(ErrorType.VALUE); } - if (endDate.isError()) { - return endDate; + const startDateSerialNumber = getDateSerialNumberByObject(_startDate); + + if (typeof startDateSerialNumber !== 'number') { + return startDateSerialNumber; } - if (basis?.isError()) { - return basis; + const endDateSerialNumber = getDateSerialNumberByObject(_endDate); + + if (typeof endDateSerialNumber !== 'number') { + return endDateSerialNumber; } - if (startDate.isBoolean() || endDate.isBoolean() || basis?.isBoolean()) { + const basisValue = Math.floor(+_basis.getValue()); + + if (Number.isNaN(basisValue)) { return ErrorValueObject.create(ErrorType.VALUE); } - const startDateSerialNumber = getDateSerialNumberByObject(startDate); + if (basisValue < 0 || basisValue > 4) { + return ErrorValueObject.create(ErrorType.NUM); + } - if (typeof startDateSerialNumber !== 'number') { - return startDateSerialNumber; + switch (basisValue) { + case 0: + return this._getResultByNASD(startDateSerialNumber, endDateSerialNumber); + case 1: + return this._getResultByActual(startDateSerialNumber, endDateSerialNumber); + case 2: + return NumberValueObject.create(Math.abs(endDateSerialNumber - startDateSerialNumber) / 360); + case 3: + return NumberValueObject.create(Math.abs(endDateSerialNumber - startDateSerialNumber) / 365); + case 4: + return this._getResultByEuropean(startDateSerialNumber, endDateSerialNumber); + default: + return NumberValueObject.create(0); } + } - const endDateSerialNumber = getDateSerialNumberByObject(endDate); + private _checkArrayError(variant: BaseValueObject): BaseValueObject { + let _variant = variant; - if (typeof endDateSerialNumber !== 'number') { - return endDateSerialNumber; + if (_variant.isArray()) { + const rowCount = (_variant as ArrayValueObject).getRowCount(); + const columnCount = (_variant as ArrayValueObject).getColumnCount(); + + if (rowCount > 1 || columnCount > 1) { + return ErrorValueObject.create(ErrorType.VALUE); + } + + _variant = (_variant as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_variant.isError()) { + return _variant; } + return _variant; + } + + private _getResultByNASD(startDateSerialNumber: number, endDateSerialNumber: number): BaseValueObject { const startDateDate = excelSerialToDate(startDateSerialNumber); const startYear = startDateSerialNumber > 0 ? startDateDate.getUTCFullYear() : 1900; const startMonth = startDateSerialNumber > 0 ? startDateDate.getUTCMonth() + 1 : 1; @@ -98,102 +121,99 @@ export class Yearfrac extends BaseFunction { let endMonth = endDateSerialNumber > 0 ? endDateDate.getUTCMonth() + 1 : 1; let endDay = endDateSerialNumber > 0 ? endDateDate.getUTCDate() : 0; - let basisValue = 0; - - if (basis) { - basisValue = Math.floor(+basis.getValue()); - - if (Number.isNaN(basisValue)) { - return ErrorValueObject.create(ErrorType.VALUE); - } + if (startDay === 31) { + startDay = 30; + } - if (basisValue < 0 || basisValue > 4) { - return ErrorValueObject.create(ErrorType.NUM); + if (endDay === 31) { + if (startDay < 30) { + endDateDate = excelSerialToDate(endDateSerialNumber + 1); + endYear = endDateDate.getUTCFullYear(); + endMonth = endDateDate.getUTCMonth() + 1; + endDay = endDateDate.getUTCDate(); + } else { + endDay = 30; } } - let result = 0; + const daysInYears = (endYear - startYear) * 360; + const daysInStartMonth = endDateSerialNumber >= startDateSerialNumber ? 30 - startDay : -startDay; + const daysInEndMonth = endDateSerialNumber >= startDateSerialNumber ? endDay : endDay - 30; + const daysInMidMonths = (endDateSerialNumber >= startDateSerialNumber ? (endMonth - startMonth - 1) : (endMonth - startMonth + 1)) * 30; + const totalDays = Math.abs(daysInYears + daysInStartMonth + daysInEndMonth + daysInMidMonths); - if (basisValue === 0) { - // US (NASD) 30/360 - if (startDay === 31) { - startDay = 30; - } + const result = totalDays / 360; - if (endDay === 31) { - if (startDay < 30) { - endDateDate = excelSerialToDate(endDateSerialNumber + 1); - endYear = endDateDate.getUTCFullYear(); - endMonth = endDateDate.getUTCMonth() + 1; - endDay = endDateDate.getUTCDate(); - } else { - endDay = 30; - } - } + return NumberValueObject.create(result); + } - const daysInYears = (endYear - startYear) * 360; - const daysInStartMonth = endDateSerialNumber >= startDateSerialNumber ? 30 - startDay : -startDay; - const daysInEndMonth = endDateSerialNumber >= startDateSerialNumber ? endDay : endDay - 30; - const daysInMidMonths = (endDateSerialNumber >= startDateSerialNumber ? (endMonth - startMonth - 1) : (endMonth - startMonth + 1)) * 30; - const totalDays = Math.abs(daysInYears + daysInStartMonth + daysInEndMonth + daysInMidMonths); - result = totalDays / 360; - } else if (basisValue === 1) { - // Actual/actual - const totalDays = Math.abs(endDateSerialNumber - startDateSerialNumber); - const totalYear = Math.abs(endYear - startYear) + 1; - - let startYearFirstDaySerialNumber; - let endYearLastDaySerialNumber; - - if (endYear < startYear) { - const startYearFirstDay = new Date(Date.UTC(endYear, 0, 1)); - const endYearLastDay = new Date(Date.UTC(startYear, 11, 31)); - - startYearFirstDaySerialNumber = excelDateSerial(startYearFirstDay); - endYearLastDaySerialNumber = excelDateSerial(endYearLastDay); - - if (endYear === 1900) { // Special handle. excel 1900 days = 365, 1900/12/31 SerialNumber = 366. so start add 1 - startYearFirstDaySerialNumber += 1; - } - } else { - const startYearFirstDay = new Date(Date.UTC(startYear, 0, 1)); - const endYearLastDay = new Date(Date.UTC(endYear, 11, 31)); + private _getResultByActual(startDateSerialNumber: number, endDateSerialNumber: number): BaseValueObject { + const startDateDate = excelSerialToDate(startDateSerialNumber); + const startYear = startDateSerialNumber > 0 ? startDateDate.getUTCFullYear() : 1900; - startYearFirstDaySerialNumber = excelDateSerial(startYearFirstDay); - endYearLastDaySerialNumber = excelDateSerial(endYearLastDay); + const endDateDate = excelSerialToDate(endDateSerialNumber); + const endYear = endDateSerialNumber > 0 ? endDateDate.getUTCFullYear() : 1900; - if (startYear === 1900) { // Special handle. excel 1900 days = 365, 1900/12/31 SerialNumber = 366. so start add 1 - startYearFirstDaySerialNumber += 1; - } - } + const totalDays = Math.abs(endDateSerialNumber - startDateSerialNumber); + const totalYear = Math.abs(endYear - startYear) + 1; - result = totalDays / ((endYearLastDaySerialNumber - startYearFirstDaySerialNumber + 1) / totalYear); - } else if (basisValue === 2) { - // Actual/360 - const totalDays = Math.abs(endDateSerialNumber - startDateSerialNumber); - result = totalDays / 360; - } else if (basisValue === 3) { - // Actual/365 - const totalDays = Math.abs(endDateSerialNumber - startDateSerialNumber); - result = totalDays / 365; - } else if (basisValue === 4) { - // European 30/360 - if (startDay === 31) { - startDay = 30; + let startYearFirstDaySerialNumber; + let endYearLastDaySerialNumber; + + if (endYear < startYear) { + const startYearFirstDay = new Date(Date.UTC(endYear, 0, 1)); + const endYearLastDay = new Date(Date.UTC(startYear, 11, 31)); + + startYearFirstDaySerialNumber = excelDateSerial(startYearFirstDay); + endYearLastDaySerialNumber = excelDateSerial(endYearLastDay); + + if (endYear === 1900) { // Special handle. excel 1900 days = 365, 1900/12/31 SerialNumber = 366. so start add 1 + startYearFirstDaySerialNumber += 1; } + } else { + const startYearFirstDay = new Date(Date.UTC(startYear, 0, 1)); + const endYearLastDay = new Date(Date.UTC(endYear, 11, 31)); - if (endDay === 31) { - endDay = 30; + startYearFirstDaySerialNumber = excelDateSerial(startYearFirstDay); + endYearLastDaySerialNumber = excelDateSerial(endYearLastDay); + + if (startYear === 1900) { // Special handle. excel 1900 days = 365, 1900/12/31 SerialNumber = 366. so start add 1 + startYearFirstDaySerialNumber += 1; } + } + + const result = totalDays / ((endYearLastDaySerialNumber - startYearFirstDaySerialNumber + 1) / totalYear); - const daysInYears = (endYear - startYear) * 360; - const daysInStartMonth = endDateSerialNumber >= startDateSerialNumber ? 30 - startDay : -startDay; - const daysInEndMonth = endDateSerialNumber >= startDateSerialNumber ? endDay : endDay - 30; - const daysInMidMonths = (endDateSerialNumber >= startDateSerialNumber ? (endMonth - startMonth - 1) : (endMonth - startMonth + 1)) * 30; - const totalDays = Math.abs(daysInYears + daysInStartMonth + daysInEndMonth + daysInMidMonths); - result = totalDays / 360; + return NumberValueObject.create(result); + } + + private _getResultByEuropean(startDateSerialNumber: number, endDateSerialNumber: number): BaseValueObject { + const startDateDate = excelSerialToDate(startDateSerialNumber); + const startYear = startDateSerialNumber > 0 ? startDateDate.getUTCFullYear() : 1900; + const startMonth = startDateSerialNumber > 0 ? startDateDate.getUTCMonth() + 1 : 1; + let startDay = startDateSerialNumber > 0 ? startDateDate.getUTCDate() : 0; + + const endDateDate = excelSerialToDate(endDateSerialNumber); + const endYear = endDateSerialNumber > 0 ? endDateDate.getUTCFullYear() : 1900; + const endMonth = endDateSerialNumber > 0 ? endDateDate.getUTCMonth() + 1 : 1; + let endDay = endDateSerialNumber > 0 ? endDateDate.getUTCDate() : 0; + + if (startDay === 31) { + startDay = 30; } + if (endDay === 31) { + endDay = 30; + } + + const daysInYears = (endYear - startYear) * 360; + const daysInStartMonth = endDateSerialNumber >= startDateSerialNumber ? 30 - startDay : -startDay; + const daysInEndMonth = endDateSerialNumber >= startDateSerialNumber ? endDay : endDay - 30; + const daysInMidMonths = (endDateSerialNumber >= startDateSerialNumber ? (endMonth - startMonth - 1) : (endMonth - startMonth + 1)) * 30; + const totalDays = Math.abs(daysInYears + daysInStartMonth + daysInEndMonth + daysInMidMonths); + + const result = totalDays / 360; + return NumberValueObject.create(result); } } diff --git a/packages/engine-formula/src/functions/information/cell/index.ts b/packages/engine-formula/src/functions/information/cell/index.ts index c05b16d1e92..96fe8a8e784 100644 --- a/packages/engine-formula/src/functions/information/cell/index.ts +++ b/packages/engine-formula/src/functions/information/cell/index.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import type { IColumnData, IObjectArrayPrimitiveType } from '@univerjs/core'; import { Tools } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import type { BaseReferenceObject, FunctionVariantType } from '../../../engine/reference-object/base-reference-object'; @@ -30,25 +31,27 @@ export class Cell extends BaseFunction { override maxParams = 2; override calculate(infoType: FunctionVariantType, reference: FunctionVariantType) { - if (infoType.isError()) { - return infoType; + let _infoType = infoType; + + if (_infoType.isError()) { + return _infoType; } - if (infoType.isReferenceObject()) { - infoType = (infoType as BaseReferenceObject).toArrayValueObject(); + if (_infoType.isReferenceObject()) { + _infoType = (_infoType as BaseReferenceObject).toArrayValueObject(); } - if (infoType.isArray()) { - const rowCount = (infoType as ArrayValueObject).getRowCount(); - const columnCount = (infoType as ArrayValueObject).getColumnCount(); + if (_infoType.isArray()) { + const rowCount = (_infoType as ArrayValueObject).getRowCount(); + const columnCount = (_infoType as ArrayValueObject).getColumnCount(); if (rowCount === 1 && columnCount === 1) { - const infoTypeObject = (infoType as ArrayValueObject).get(0, 0) as BaseValueObject; + const infoTypeObject = (_infoType as ArrayValueObject).get(0, 0) as BaseValueObject; return this._handleSingleObject(infoTypeObject, reference); } - return (infoType as ArrayValueObject).map((infoTypeObject) => { + return (_infoType as ArrayValueObject).map((infoTypeObject) => { if (infoTypeObject.isError()) { return infoTypeObject; } @@ -57,27 +60,29 @@ export class Cell extends BaseFunction { }); } - return this._handleSingleObject(infoType as BaseValueObject, reference); + return this._handleSingleObject(_infoType as BaseValueObject, reference); } private _handleSingleObject(infoType: BaseValueObject, reference: FunctionVariantType, infoTypeIsArray: boolean = false) { - if (reference.isError()) { - return reference as ErrorValueObject; + let _reference = reference; + + if (_reference.isError()) { + return _reference as ErrorValueObject; } - if (!reference.isReferenceObject()) { + if (!_reference.isReferenceObject()) { return ErrorValueObject.create(ErrorType.NA); } - const currentActiveSheetData = (reference as BaseReferenceObject).getCurrentActiveSheetData(); + const currentActiveSheetData = (_reference as BaseReferenceObject).getCurrentActiveSheetData(); const { columnData, defaultColumnWidth } = currentActiveSheetData; - reference = (reference as BaseReferenceObject).toArrayValueObject(); + _reference = (_reference as BaseReferenceObject).toArrayValueObject(); - const _currentRow = (reference as ArrayValueObject).getCurrentRow(); - const _currentColumn = (reference as ArrayValueObject).getCurrentColumn(); + const _currentRow = (_reference as ArrayValueObject).getCurrentRow(); + const _currentColumn = (_reference as ArrayValueObject).getCurrentColumn(); - reference = (reference as ArrayValueObject).getFirstCell(); + _reference = (_reference as ArrayValueObject).getFirstCell(); const infoTypeValue = `${infoType.getValue()}`; @@ -92,7 +97,7 @@ export class Cell extends BaseFunction { // This value is not supported in Excel for the web. return 0. return NumberValueObject.create(0); case 'contents': - return reference; + return _reference; case 'filename': // This value is not supported in Excel for the web. google sheet return #VALUE!. return ErrorValueObject.create(ErrorType.VALUE); @@ -113,31 +118,35 @@ export class Cell extends BaseFunction { case 'type': result = 'v'; - if (reference.isNull()) { + if (_reference.isNull()) { result = 'b'; } - if (reference.isString()) { + if (_reference.isString()) { result = 'l'; } return StringValueObject.create(result); case 'width': - result = columnData[_currentColumn]?.w; - - if (!result && result !== 0) { - result = defaultColumnWidth as number; - } + return this._getWidthResult(columnData, defaultColumnWidth as number, _currentColumn, infoTypeIsArray); + default: + return ErrorValueObject.create(ErrorType.VALUE); + } + } - if (infoTypeIsArray) { - return NumberValueObject.create(result); - } + private _getWidthResult(columnData: IObjectArrayPrimitiveType>, defaultColumnWidth: number, _currentColumn: number, infoTypeIsArray: boolean): BaseValueObject { + let result = columnData[_currentColumn]?.w; - result = [[result, result === defaultColumnWidth]]; + if (!result && result !== 0) { + result = defaultColumnWidth as number; + } - return ArrayValueObject.createByArray(result); - default: - return ErrorValueObject.create(ErrorType.VALUE); + if (infoTypeIsArray) { + return NumberValueObject.create(result); } + + const resultArray = [[result, result === defaultColumnWidth]]; + + return ArrayValueObject.createByArray(resultArray); } } diff --git a/packages/engine-formula/src/functions/information/error-type/index.ts b/packages/engine-formula/src/functions/information/error-type/index.ts index 31051e7f1cd..a912669e0e1 100644 --- a/packages/engine-formula/src/functions/information/error-type/index.ts +++ b/packages/engine-formula/src/functions/information/error-type/index.ts @@ -32,7 +32,18 @@ export class ErrorType extends BaseFunction { return this._handleSingleObject(errorVal); } - private errorTypeValueMap = new Map([ + private _handleSingleObject(errorVal: BaseValueObject) { + const errorValValue = errorVal.getValue(); + const result = this._errorTypeValueMap.get(errorValValue as ErrorTypeBase); + + if (result) { + return NumberValueObject.create(result); + } + + return ErrorValueObject.create(ErrorTypeBase.NA); + } + + private _errorTypeValueMap = new Map([ [ErrorTypeBase.NULL, 1], [ErrorTypeBase.DIV_BY_ZERO, 2], [ErrorTypeBase.VALUE, 3], @@ -43,15 +54,4 @@ export class ErrorType extends BaseFunction { [ErrorTypeBase.CONNECT, 8], [ErrorTypeBase.CALC, 14], ]); - - private _handleSingleObject(errorVal: BaseValueObject) { - const errorValValue = errorVal.getValue(); - const result = this.errorTypeValueMap.get(errorValValue as ErrorTypeBase); - - if (result) { - return NumberValueObject.create(result); - } - - return ErrorValueObject.create(ErrorTypeBase.NA); - } } diff --git a/packages/engine-formula/src/functions/information/iseven/iseven.ts b/packages/engine-formula/src/functions/information/iseven/iseven.ts index 7dbf309be1d..4ff0d0817d9 100644 --- a/packages/engine-formula/src/functions/information/iseven/iseven.ts +++ b/packages/engine-formula/src/functions/information/iseven/iseven.ts @@ -26,18 +26,20 @@ export class Iseven extends BaseFunction { override maxParams = 1; override calculate(value: BaseValueObject) { - if (value.isArray() || value.isBoolean()) { + let _value = value; + + if (_value.isArray() || _value.isBoolean()) { return ErrorValueObject.create(ErrorType.VALUE); } - if (!value.isNumber()) { - value = value.convertToNumberObjectValue(); - if (!value.isNumber()) { + if (!_value.isNumber()) { + _value = _value.convertToNumberObjectValue(); + if (!_value.isNumber()) { return ErrorValueObject.create(ErrorType.VALUE); } } - const val = value.getValue() as number; + const val = _value.getValue() as number; const floored = Math.floor(Math.abs(val)); return BooleanValueObject.create(floored % 2 === 0); } diff --git a/packages/engine-formula/src/functions/information/isodd/isodd.ts b/packages/engine-formula/src/functions/information/isodd/isodd.ts index ba6b57116c5..581654f46c2 100644 --- a/packages/engine-formula/src/functions/information/isodd/isodd.ts +++ b/packages/engine-formula/src/functions/information/isodd/isodd.ts @@ -26,18 +26,20 @@ export class Isodd extends BaseFunction { override maxParams = 1; override calculate(value: BaseValueObject) { - if (value.isArray() || value.isBoolean()) { + let _value = value; + + if (_value.isArray() || _value.isBoolean()) { return ErrorValueObject.create(ErrorType.VALUE); } - if (!value.isNumber()) { - value = value.convertToNumberObjectValue(); - if (!value.isNumber()) { + if (!_value.isNumber()) { + _value = _value.convertToNumberObjectValue(); + if (!_value.isNumber()) { return ErrorValueObject.create(ErrorType.VALUE); } } - const val = value.getValue() as number; + const val = _value.getValue() as number; const floored = Math.floor(Math.abs(val)); return BooleanValueObject.create(floored % 2 !== 0); } diff --git a/packages/engine-formula/src/functions/information/type/index.ts b/packages/engine-formula/src/functions/information/type/index.ts index 3b6e2a9bbb4..81479dfb1d0 100644 --- a/packages/engine-formula/src/functions/information/type/index.ts +++ b/packages/engine-formula/src/functions/information/type/index.ts @@ -32,21 +32,21 @@ export class Type extends BaseFunction { const columnCount = (value as BaseReferenceObject).getColumnCount(); if (rowCount === 1 && columnCount === 1) { - value = (value as BaseReferenceObject).getFirstCell(); + const _value = (value as BaseReferenceObject).getFirstCell(); - if (value.isError()) { + if (_value.isError()) { return NumberValueObject.create(16); } - if ((value as BaseValueObject).isBoolean()) { + if ((_value as BaseValueObject).isBoolean()) { return NumberValueObject.create(4); } - if ((value as BaseValueObject).isString()) { + if ((_value as BaseValueObject).isString()) { return NumberValueObject.create(2); } - if ((value as BaseValueObject).isNumber() || (value as BaseValueObject).isNull()) { + if ((_value as BaseValueObject).isNumber() || (_value as BaseValueObject).isNull()) { return NumberValueObject.create(1); } } else { diff --git a/packages/engine-formula/src/functions/logical/if/index.ts b/packages/engine-formula/src/functions/logical/if/index.ts index 0b096952b33..4acf14ef169 100644 --- a/packages/engine-formula/src/functions/logical/if/index.ts +++ b/packages/engine-formula/src/functions/logical/if/index.ts @@ -36,27 +36,27 @@ export class If extends BaseFunction { } // get single value object - logicalTest = this._getSingleValueObject(logicalTest); + const _logicalTest = this._getSingleValueObject(logicalTest); - if (!logicalTest.isArray()) { - return logicalTest.getValue() ? valueIfTrue : valueIfFalse; + if (!_logicalTest.isArray()) { + return _logicalTest.getValue() ? valueIfTrue : valueIfFalse; } // get max row length const maxRowLength = Math.max( - logicalTest.isArray() ? (logicalTest as ArrayValueObject).getRowCount() : 1, + _logicalTest.isArray() ? (_logicalTest as ArrayValueObject).getRowCount() : 1, valueIfTrue.isArray() ? (valueIfTrue as ArrayValueObject).getRowCount() : 1, valueIfFalse.isArray() ? (valueIfFalse as ArrayValueObject).getRowCount() : 1 ); // get max column length const maxColumnLength = Math.max( - logicalTest.isArray() ? (logicalTest as ArrayValueObject).getColumnCount() : 1, + _logicalTest.isArray() ? (_logicalTest as ArrayValueObject).getColumnCount() : 1, valueIfTrue.isArray() ? (valueIfTrue as ArrayValueObject).getColumnCount() : 1, valueIfFalse.isArray() ? (valueIfFalse as ArrayValueObject).getColumnCount() : 1 ); - const logicalTestArray = expandArrayValueObject(maxRowLength, maxColumnLength, logicalTest); + const logicalTestArray = expandArrayValueObject(maxRowLength, maxColumnLength, _logicalTest); const valueIfTrueArray = expandArrayValueObject(maxRowLength, maxColumnLength, valueIfTrue, ErrorValueObject.create(ErrorType.NA)); const valueIfFalseArray = expandArrayValueObject(maxRowLength, maxColumnLength, valueIfFalse, ErrorValueObject.create(ErrorType.NA)); diff --git a/packages/engine-formula/src/functions/lookup/address/index.ts b/packages/engine-formula/src/functions/lookup/address/index.ts index 19de0e55614..a561282a83d 100644 --- a/packages/engine-formula/src/functions/lookup/address/index.ts +++ b/packages/engine-formula/src/functions/lookup/address/index.ts @@ -58,33 +58,33 @@ export class Address extends BaseFunction { return sheetText; } - absNumber = absNumber ?? NumberValueObject.create(1); - a1 = a1 ?? BooleanValueObject.create(true); - sheetText = sheetText ?? StringValueObject.create(''); + const _absNumber = absNumber ?? NumberValueObject.create(1); + const _a1 = a1 ?? BooleanValueObject.create(true); + const _sheetText = sheetText ?? StringValueObject.create(''); // get max row length const maxRowLength = Math.max( rowNumber.isArray() ? (rowNumber as ArrayValueObject).getRowCount() : 1, columnNumber.isArray() ? (columnNumber as ArrayValueObject).getRowCount() : 1, - absNumber.isArray() ? (absNumber as ArrayValueObject).getRowCount() : 1, - a1.isArray() ? (a1 as ArrayValueObject).getRowCount() : 1, - sheetText.isArray() ? (sheetText as ArrayValueObject).getRowCount() : 1 + _absNumber.isArray() ? (_absNumber as ArrayValueObject).getRowCount() : 1, + _a1.isArray() ? (_a1 as ArrayValueObject).getRowCount() : 1, + _sheetText.isArray() ? (_sheetText as ArrayValueObject).getRowCount() : 1 ); // get max column length const maxColumnLength = Math.max( rowNumber.isArray() ? (rowNumber as ArrayValueObject).getColumnCount() : 1, columnNumber.isArray() ? (columnNumber as ArrayValueObject).getColumnCount() : 1, - absNumber.isArray() ? (absNumber as ArrayValueObject).getColumnCount() : 1, - a1.isArray() ? (a1 as ArrayValueObject).getColumnCount() : 1, - sheetText.isArray() ? (sheetText as ArrayValueObject).getColumnCount() : 1 + _absNumber.isArray() ? (_absNumber as ArrayValueObject).getColumnCount() : 1, + _a1.isArray() ? (_a1 as ArrayValueObject).getColumnCount() : 1, + _sheetText.isArray() ? (_sheetText as ArrayValueObject).getColumnCount() : 1 ); const rowNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, rowNumber, ErrorValueObject.create(ErrorType.NA)); const columnNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, columnNumber, ErrorValueObject.create(ErrorType.NA)); - const absNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, absNumber, ErrorValueObject.create(ErrorType.NA)); - const a1Array = expandArrayValueObject(maxRowLength, maxColumnLength, a1, ErrorValueObject.create(ErrorType.NA)); - const sheetTextArray = expandArrayValueObject(maxRowLength, maxColumnLength, sheetText, ErrorValueObject.create(ErrorType.NA)); + const absNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, _absNumber, ErrorValueObject.create(ErrorType.NA)); + const a1Array = expandArrayValueObject(maxRowLength, maxColumnLength, _a1, ErrorValueObject.create(ErrorType.NA)); + const sheetTextArray = expandArrayValueObject(maxRowLength, maxColumnLength, _sheetText, ErrorValueObject.create(ErrorType.NA)); return rowNumArray.map((rowNumValue, rowIndex, columnIndex) => { const columnNumValue = columnNumArray.get(rowIndex, columnIndex) || ErrorValueObject.create(ErrorType.NA); diff --git a/packages/engine-formula/src/functions/lookup/choose/index.ts b/packages/engine-formula/src/functions/lookup/choose/index.ts index b43a60cd363..aa15f3cbe19 100644 --- a/packages/engine-formula/src/functions/lookup/choose/index.ts +++ b/packages/engine-formula/src/functions/lookup/choose/index.ts @@ -35,18 +35,18 @@ export class Choose extends BaseFunction { } override calculate(indexNum: FunctionVariantType, ...variants: FunctionVariantType[]) { - if (indexNum.isError()) { - return indexNum; - } + let _indexNum = indexNum; - if (indexNum.isReferenceObject()) { - indexNum = (indexNum as BaseReferenceObject).toArrayValueObject(); + if (_indexNum.isError()) { + return _indexNum; } - indexNum = indexNum as BaseValueObject; + if (_indexNum.isReferenceObject()) { + _indexNum = (_indexNum as BaseReferenceObject).toArrayValueObject(); + } - if (!indexNum.isArray()) { - const index = indexNum.convertToNumberObjectValue(); + if (!_indexNum.isArray()) { + const index = (_indexNum as BaseValueObject).convertToNumberObjectValue(); if (index.isError()) { return index; @@ -60,8 +60,8 @@ export class Choose extends BaseFunction { } // The size of the extended range is determined by the maximum width and height of the criteria range. - let maxRowLength = indexNum.isArray() ? (indexNum as ArrayValueObject).getRowCount() : 1; - let maxColumnLength = indexNum.isArray() ? (indexNum as ArrayValueObject).getColumnCount() : 1; + let maxRowLength = _indexNum.isArray() ? (_indexNum as ArrayValueObject).getRowCount() : 1; + let maxColumnLength = _indexNum.isArray() ? (_indexNum as ArrayValueObject).getColumnCount() : 1; variants.forEach((variant, i) => { if (variant.isArray()) { @@ -74,12 +74,15 @@ export class Choose extends BaseFunction { } }); - const indexNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, indexNum, ErrorValueObject.create(ErrorType.NA)); + const indexNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, _indexNum as BaseValueObject, ErrorValueObject.create(ErrorType.NA)); const arrayValueObjectList = variants.map((variant) => { - if (variant.isReferenceObject()) { - variant = (variant as BaseReferenceObject).toArrayValueObject(); + let _variant = variant; + + if (_variant.isReferenceObject()) { + _variant = (_variant as BaseReferenceObject).toArrayValueObject(); } - return expandArrayValueObject(maxRowLength, maxColumnLength, variant as BaseValueObject, ErrorValueObject.create(ErrorType.NA)); + + return expandArrayValueObject(maxRowLength, maxColumnLength, _variant as BaseValueObject, ErrorValueObject.create(ErrorType.NA)); }); return indexNumArray.map((indexNumValue, row, column) => { diff --git a/packages/engine-formula/src/functions/lookup/filter/index.ts b/packages/engine-formula/src/functions/lookup/filter/index.ts index 30c793632a1..fd41ebdca3d 100644 --- a/packages/engine-formula/src/functions/lookup/filter/index.ts +++ b/packages/engine-formula/src/functions/lookup/filter/index.ts @@ -27,7 +27,7 @@ export class Filter extends BaseFunction { override maxParams = 3; override calculate(array: BaseValueObject, include: BaseValueObject, ifEmpty?: BaseValueObject) { - ifEmpty = ifEmpty ?? ErrorValueObject.create(ErrorType.CALC); + const _ifEmpty = ifEmpty ?? ErrorValueObject.create(ErrorType.CALC); if (array.isError()) { return array; @@ -51,110 +51,147 @@ export class Filter extends BaseFunction { return ErrorValueObject.create(ErrorType.VALUE); } - const resultArray: BaseValueObject[][] = []; - if (arrayRowCount === 1 && arrayColumnCount === 1) { - if (array.isArray()) { - array = (array as ArrayValueObject).get(0, 0) as BaseValueObject; - } + return this._getResultArrayByR1C1(array, include, _ifEmpty); + } - if (include.isArray()) { - include = (include as ArrayValueObject).get(0, 0) as BaseValueObject; + if (includeRowCount === 1) { + if (includeColumnCount !== arrayColumnCount) { + return ErrorValueObject.create(ErrorType.VALUE); } - if (include.isString()) { - include = include.convertToNumberObjectValue(); - } + return this._getResultArrayByR1(arrayRowCount, arrayColumnCount, array, include, _ifEmpty); + } - if (include.isError()) { - return include; + if (includeColumnCount === 1) { + if (includeRowCount !== arrayRowCount) { + return ErrorValueObject.create(ErrorType.VALUE); } - const includeValue = +include.getValue(); + return this._getResultArrayByC1(arrayRowCount, arrayColumnCount, array, include, _ifEmpty); + } - if (includeValue) { - return array; - } + return _ifEmpty; + } - return ifEmpty; - } else if (includeRowCount === 1) { - if (includeColumnCount !== arrayColumnCount) { - return ErrorValueObject.create(ErrorType.VALUE); - } + private _getResultArrayByR1C1(array: BaseValueObject, include: BaseValueObject, ifEmpty: BaseValueObject): BaseValueObject { + let _array = array; + let _include = include; - for (let c = 0; c < arrayColumnCount; c++) { - let includeObject = (include as ArrayValueObject).get(0, c) as BaseValueObject; + if (_array.isArray()) { + _array = (_array as ArrayValueObject).get(0, 0) as BaseValueObject; + } - if (includeObject.isString()) { - includeObject = includeObject.convertToNumberObjectValue(); - } + if (_include.isArray()) { + _include = (_include as ArrayValueObject).get(0, 0) as BaseValueObject; + } - if (includeObject.isError()) { - return includeObject; - } + if (_include.isString()) { + _include = _include.convertToNumberObjectValue(); + } - const includeValue = +includeObject.getValue(); + if (_include.isError()) { + return _include; + } - if (!includeValue) { - continue; - } + const includeValue = +_include.getValue(); - for (let r = 0; r < arrayRowCount; r++) { - if (!resultArray[r]) { - resultArray[r] = []; - } + if (includeValue) { + return _array; + } - const arrayObject = (array as ArrayValueObject).get(r, c) as BaseValueObject; + return ifEmpty; + } - resultArray[r].push(arrayObject); - } + private _getResultArrayByR1(arrayRowCount: number, arrayColumnCount: number, array: BaseValueObject, include: BaseValueObject, ifEmpty: BaseValueObject): BaseValueObject { + const resultArray: Array> = []; + + for (let c = 0; c < arrayColumnCount; c++) { + let includeObject = (include as ArrayValueObject).get(0, c) as BaseValueObject; + + if (includeObject.isString()) { + includeObject = includeObject.convertToNumberObjectValue(); } - } else if (includeColumnCount === 1) { - if (includeRowCount !== arrayRowCount) { - return ErrorValueObject.create(ErrorType.VALUE); + + if (includeObject.isError()) { + return includeObject as ErrorValueObject; } - for (let r = 0; r < arrayRowCount; r++) { - let includeObject = (include as ArrayValueObject).get(r, 0) as BaseValueObject; + const includeValue = +includeObject.getValue(); - if (includeObject.isString()) { - includeObject = includeObject.convertToNumberObjectValue(); - } + if (!includeValue) { + continue; + } - if (includeObject.isError()) { - return includeObject; + for (let r = 0; r < arrayRowCount; r++) { + if (!resultArray[r]) { + resultArray[r] = []; } - const includeValue = +includeObject.getValue(); + const arrayObject = (array as ArrayValueObject).get(r, c) as BaseValueObject; - if (!includeValue) { - continue; - } + resultArray[r].push(arrayObject); + } + } + + if (resultArray.length === 0) { + return ifEmpty; + } - const row = []; + return ArrayValueObject.create({ + calculateValueList: resultArray, + rowCount: resultArray.length, + columnCount: resultArray[0].length || 0, + unitId: this.unitId as string, + sheetId: this.subUnitId as string, + row: this.row, + column: this.column, + }); + } - for (let c = 0; c < arrayColumnCount; c++) { - const arrayObject = (array as ArrayValueObject).get(r, c) as BaseValueObject; + private _getResultArrayByC1(arrayRowCount: number, arrayColumnCount: number, array: BaseValueObject, include: BaseValueObject, ifEmpty: BaseValueObject): BaseValueObject { + const resultArray: Array> = []; - row.push(arrayObject); - } + for (let r = 0; r < arrayRowCount; r++) { + let includeObject = (include as ArrayValueObject).get(r, 0) as BaseValueObject; + + if (includeObject.isString()) { + includeObject = includeObject.convertToNumberObjectValue(); + } + + if (includeObject.isError()) { + return includeObject; + } + + const includeValue = +includeObject.getValue(); - resultArray.push(row); + if (!includeValue) { + continue; } + + const row = []; + + for (let c = 0; c < arrayColumnCount; c++) { + const arrayObject = (array as ArrayValueObject).get(r, c) as BaseValueObject; + + row.push(arrayObject); + } + + resultArray.push(row); } if (resultArray.length === 0) { return ifEmpty; - } else { - return ArrayValueObject.create({ - calculateValueList: resultArray, - rowCount: resultArray.length, - columnCount: resultArray[0].length || 0, - unitId: this.unitId as string, - sheetId: this.subUnitId as string, - row: this.row, - column: this.column, - }); } + + return ArrayValueObject.create({ + calculateValueList: resultArray, + rowCount: resultArray.length, + columnCount: resultArray[0].length || 0, + unitId: this.unitId as string, + sheetId: this.subUnitId as string, + row: this.row, + column: this.column, + }); } } diff --git a/packages/engine-formula/src/functions/lookup/index/index.ts b/packages/engine-formula/src/functions/lookup/index/index.ts index 4e8ab0529f6..2e32b44b2d4 100644 --- a/packages/engine-formula/src/functions/lookup/index/index.ts +++ b/packages/engine-formula/src/functions/lookup/index/index.ts @@ -69,56 +69,57 @@ export class Index extends BaseFunction { return ErrorValueObject.create(ErrorType.VALUE); } + let _rowNum, _columnNum; // When there is only one row, the rowNum is considered to be the column number. // =INDEX(A6:B6,2) equals =INDEX(A6:B6,1,2) if (referenceRowCount === 1 && referenceColumnCount > 1 && columnNum == null) { - columnNum = rowNum ?? NumberValueObject.create(0); - rowNum = NumberValueObject.create(0); + _columnNum = rowNum ?? NumberValueObject.create(0); + _rowNum = NumberValueObject.create(0); } else { - rowNum = rowNum ?? NumberValueObject.create(0); - columnNum = columnNum ?? NumberValueObject.create(0); + _rowNum = rowNum ?? NumberValueObject.create(0); + _columnNum = columnNum ?? NumberValueObject.create(0); } - areaNum = areaNum ?? NumberValueObject.create(1); + let _areaNum = areaNum ?? NumberValueObject.create(1); - if (rowNum.isReferenceObject()) { - rowNum = (rowNum as BaseReferenceObject).toArrayValueObject(); + if (_rowNum.isReferenceObject()) { + _rowNum = (_rowNum as BaseReferenceObject).toArrayValueObject(); } - if (columnNum.isReferenceObject()) { - columnNum = (columnNum as BaseReferenceObject).toArrayValueObject(); + if (_columnNum.isReferenceObject()) { + _columnNum = (_columnNum as BaseReferenceObject).toArrayValueObject(); } - if (areaNum.isReferenceObject()) { - areaNum = (areaNum as BaseReferenceObject).toArrayValueObject(); + if (_areaNum.isReferenceObject()) { + _areaNum = (_areaNum as BaseReferenceObject).toArrayValueObject(); } // get max row length const maxRowLength = Math.max( - rowNum.isArray() ? (rowNum as ArrayValueObject).getRowCount() : 1, - columnNum.isArray() ? (columnNum as ArrayValueObject).getRowCount() : 1, - areaNum.isArray() ? (areaNum as ArrayValueObject).getRowCount() : 1 + _rowNum.isArray() ? (_rowNum as ArrayValueObject).getRowCount() : 1, + _columnNum.isArray() ? (_columnNum as ArrayValueObject).getRowCount() : 1, + _areaNum.isArray() ? (_areaNum as ArrayValueObject).getRowCount() : 1 ); // get max column length const maxColumnLength = Math.max( - rowNum.isArray() ? (rowNum as ArrayValueObject).getColumnCount() : 1, - columnNum.isArray() ? (columnNum as ArrayValueObject).getColumnCount() : 1, - areaNum.isArray() ? (areaNum as ArrayValueObject).getColumnCount() : 1 + _rowNum.isArray() ? (_rowNum as ArrayValueObject).getColumnCount() : 1, + _columnNum.isArray() ? (_columnNum as ArrayValueObject).getColumnCount() : 1, + _areaNum.isArray() ? (_areaNum as ArrayValueObject).getColumnCount() : 1 ); - rowNum = rowNum as BaseValueObject; - columnNum = columnNum as BaseValueObject; - areaNum = areaNum as BaseValueObject; + _rowNum = _rowNum as BaseValueObject; + _columnNum = _columnNum as BaseValueObject; + _areaNum = _areaNum as BaseValueObject; // If maxRowLength and maxColumnLength are both 1, pick the value from the reference array // Otherwise, filter the results from the reference according to the specified rowNum/columnNum/areaNum, take the upper left corner cell value of each result array, and then form an array with maxRowLength row number and maxColumnLength column number. if (maxRowLength === 1 && maxColumnLength === 1) { - return this._calculateSingleCell(reference, rowNum, columnNum, areaNum); + return this._calculateSingleCell(reference, _rowNum, _columnNum, _areaNum); } else { - const rowNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, rowNum, ErrorValueObject.create(ErrorType.NA)); - const columnNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, columnNum, ErrorValueObject.create(ErrorType.NA)); - const areaNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, areaNum, ErrorValueObject.create(ErrorType.NA)); + const rowNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, _rowNum, ErrorValueObject.create(ErrorType.NA)); + const columnNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, _columnNum, ErrorValueObject.create(ErrorType.NA)); + const areaNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, _areaNum, ErrorValueObject.create(ErrorType.NA)); return rowNumArray.map((rowNumValue, rowIndex, columnIndex) => { const columnNumValue = columnNumArray.get(rowIndex, columnIndex) || NullValueObject.create(); diff --git a/packages/engine-formula/src/functions/lookup/indirect/index.ts b/packages/engine-formula/src/functions/lookup/indirect/index.ts index 05319723d0a..b1d94aaeeac 100644 --- a/packages/engine-formula/src/functions/lookup/indirect/index.ts +++ b/packages/engine-formula/src/functions/lookup/indirect/index.ts @@ -38,8 +38,10 @@ export class Indirect extends BaseFunction { } override calculate(refText: BaseValueObject, a1?: BaseValueObject) { - if (refText.isError()) { - return refText; + let _refText = refText; + + if (_refText.isError()) { + return _refText; } let a1Value = this.getZeroOrOneByOneDefault(a1); @@ -48,10 +50,10 @@ export class Indirect extends BaseFunction { a1Value = 1; } - if (refText.isArray()) { - const refTextArray = refText as ArrayValueObject; + if (_refText.isArray()) { + const refTextArray = _refText as ArrayValueObject; if (refTextArray.getRowCount() === 1 && refTextArray.getColumnCount() === 1) { - refText = refTextArray.getFirstCell(); + _refText = refTextArray.getFirstCell(); } else { return refTextArray.map(() => { return ErrorValueObject.create(ErrorType.VALUE); @@ -59,11 +61,11 @@ export class Indirect extends BaseFunction { } } - if (!refText.isString()) { + if (!_refText.isString()) { return ErrorValueObject.create(ErrorType.REF); } - const refTextV = this._convertToDefinedName(refText.getValue() as string); + const refTextV = this._convertToDefinedName(_refText.getValue() as string); if (a1Value === 0) { const gridRange = deserializeRangeForR1C1(refTextV); diff --git a/packages/engine-formula/src/functions/lookup/lookup/index.ts b/packages/engine-formula/src/functions/lookup/lookup/index.ts index 648e944a8f1..07f6a146859 100644 --- a/packages/engine-formula/src/functions/lookup/lookup/index.ts +++ b/packages/engine-formula/src/functions/lookup/lookup/index.ts @@ -65,22 +65,24 @@ export class Lookup extends BaseFunction { lookupVector: ArrayValueObject, resultVector?: ArrayValueObject ) { - if (resultVector == null) { - resultVector = lookupVector; + let _resultVector = resultVector; + + if (_resultVector == null) { + _resultVector = lookupVector; } else if ( - resultVector.getRowCount() !== lookupVector.getRowCount() || - resultVector.getColumnCount() !== lookupVector.getColumnCount() + _resultVector.getRowCount() !== lookupVector.getRowCount() || + _resultVector.getColumnCount() !== lookupVector.getColumnCount() ) { return ErrorValueObject.create(ErrorType.REF); } if (lookupValue.isArray()) { return lookupValue.map((value) => { - return this.binarySearch(value, lookupVector, resultVector!); + return this.binarySearch(value, lookupVector, _resultVector!); }); } - return this.binarySearch(lookupValue, lookupVector, resultVector); + return this.binarySearch(lookupValue, lookupVector, _resultVector); } private _handleArray(lookupValue: BaseValueObject, lookupArray: ArrayValueObject) { diff --git a/packages/engine-formula/src/functions/lookup/offset/index.ts b/packages/engine-formula/src/functions/lookup/offset/index.ts index 6419009a530..34f6c5e65c2 100644 --- a/packages/engine-formula/src/functions/lookup/offset/index.ts +++ b/packages/engine-formula/src/functions/lookup/offset/index.ts @@ -66,64 +66,70 @@ export class Offset extends BaseFunction { return ErrorValueObject.create(ErrorType.VALUE); } - reference = reference as BaseReferenceObject; + const rowCount = (reference as BaseReferenceObject).getRowCount(); + const columnCount = (reference as BaseReferenceObject).getColumnCount(); - const rowCount = reference.getRowCount(); - const columnCount = reference.getColumnCount(); + let _rows = rows; - if (rows.isReferenceObject()) { - rows = (rows as BaseReferenceObject).toArrayValueObject(); + if (_rows.isReferenceObject()) { + _rows = (_rows as BaseReferenceObject).toArrayValueObject(); } - if (columns.isReferenceObject()) { - columns = (columns as BaseReferenceObject).toArrayValueObject(); + let _columns = columns; + + if (_columns.isReferenceObject()) { + _columns = (_columns as BaseReferenceObject).toArrayValueObject(); } + let _height = height; + // The default row height is the row height of reference. - if (!height) { - height = NumberValueObject.create(rowCount); - } else if (height.isReferenceObject()) { - height = (height as BaseReferenceObject).toArrayValueObject(); + if (!_height) { + _height = NumberValueObject.create(rowCount); + } else if (_height.isReferenceObject()) { + _height = (_height as BaseReferenceObject).toArrayValueObject(); } + let _width = width; + // The default column width is the column width of reference. - if (!width) { - width = NumberValueObject.create(columnCount); - } else if (width.isReferenceObject()) { - width = (width as BaseReferenceObject).toArrayValueObject(); + if (!_width) { + _width = NumberValueObject.create(columnCount); + } else if (_width.isReferenceObject()) { + _width = (_width as BaseReferenceObject).toArrayValueObject(); } // If rows/columns/height/width is a range, it needs to be extended // get max row length const maxRowLength = Math.max( - rows.isArray() ? (rows as ArrayValueObject).getRowCount() : 1, - columns.isArray() ? (columns as ArrayValueObject).getRowCount() : 1, - height.isArray() ? (height as ArrayValueObject).getRowCount() : 1, - width.isArray() ? (width as ArrayValueObject).getRowCount() : 1 + _rows.isArray() ? (_rows as ArrayValueObject).getRowCount() : 1, + _columns.isArray() ? (_columns as ArrayValueObject).getRowCount() : 1, + _height.isArray() ? (_height as ArrayValueObject).getRowCount() : 1, + _width.isArray() ? (_width as ArrayValueObject).getRowCount() : 1 ); // get max column length const maxColumnLength = Math.max( - rows.isArray() ? (rows as ArrayValueObject).getColumnCount() : 1, - columns.isArray() ? (columns as ArrayValueObject).getColumnCount() : 1, - height.isArray() ? (height as ArrayValueObject).getColumnCount() : 1, - width.isArray() ? (width as ArrayValueObject).getColumnCount() : 1 + _rows.isArray() ? (_rows as ArrayValueObject).getColumnCount() : 1, + _columns.isArray() ? (_columns as ArrayValueObject).getColumnCount() : 1, + _height.isArray() ? (_height as ArrayValueObject).getColumnCount() : 1, + _width.isArray() ? (_width as ArrayValueObject).getColumnCount() : 1 ); - rows = rows as BaseValueObject; - columns = columns as BaseValueObject; - height = height as BaseValueObject; - width = width as BaseValueObject; + _rows = _rows as BaseValueObject; + _columns = _columns as BaseValueObject; + _height = _height as BaseValueObject; + _width = _width as BaseValueObject; // If any parameter of row/columns/height/width is an array(not single cell reference), an error will be reported, and the error report also needs to be expanded and specific error information is required. Otherwise, calculate the offset. if (maxRowLength === 1 && maxColumnLength === 1) { - return this._handleSingleObject(reference, rows, columns, height, width); + return this._handleSingleObject(reference as BaseReferenceObject, _rows, _columns, _height, _width); } - const rowsArray = expandArrayValueObject(maxRowLength, maxColumnLength, rows, ErrorValueObject.create(ErrorType.NA)); - const columnsArray = expandArrayValueObject(maxRowLength, maxColumnLength, columns, ErrorValueObject.create(ErrorType.NA)); - const heightArray = expandArrayValueObject(maxRowLength, maxColumnLength, height, ErrorValueObject.create(ErrorType.NA)); - const widthArray = expandArrayValueObject(maxRowLength, maxColumnLength, width, ErrorValueObject.create(ErrorType.NA)); + const rowsArray = expandArrayValueObject(maxRowLength, maxColumnLength, _rows, ErrorValueObject.create(ErrorType.NA)); + const columnsArray = expandArrayValueObject(maxRowLength, maxColumnLength, _columns, ErrorValueObject.create(ErrorType.NA)); + const heightArray = expandArrayValueObject(maxRowLength, maxColumnLength, _height, ErrorValueObject.create(ErrorType.NA)); + const widthArray = expandArrayValueObject(maxRowLength, maxColumnLength, _width, ErrorValueObject.create(ErrorType.NA)); return rowsArray.mapValue((rowsValue, rowIndex, columnIndex) => { const columnsValue = columnsArray.get(rowIndex, columnIndex) as BaseValueObject; diff --git a/packages/engine-formula/src/functions/lookup/sort/index.ts b/packages/engine-formula/src/functions/lookup/sort/index.ts index f2e5bf78770..2df33d2cc4b 100644 --- a/packages/engine-formula/src/functions/lookup/sort/index.ts +++ b/packages/engine-formula/src/functions/lookup/sort/index.ts @@ -30,28 +30,28 @@ export class Sort extends BaseFunction { override maxParams = 4; override calculate(array: BaseValueObject, sortIndex?: BaseValueObject, sortOrder?: BaseValueObject, byCol?: BaseValueObject) { - sortIndex = sortIndex ?? NumberValueObject.create(1); - sortOrder = sortOrder ?? NumberValueObject.create(1); - byCol = byCol ?? BooleanValueObject.create(false); + const _sortIndex = sortIndex ?? NumberValueObject.create(1); + const _sortOrder = sortOrder ?? NumberValueObject.create(1); + const _byCol = byCol ?? BooleanValueObject.create(false); - if (byCol.isArray()) { - const byColRowCount = (byCol as ArrayValueObject).getRowCount(); - const byColColumnCount = (byCol as ArrayValueObject).getColumnCount(); + if (_byCol.isArray()) { + const byColRowCount = (_byCol as ArrayValueObject).getRowCount(); + const byColColumnCount = (_byCol as ArrayValueObject).getColumnCount(); if (byColRowCount === 1 && byColColumnCount === 1) { - const byColObject = (byCol as ArrayValueObject).get(0, 0) as BaseValueObject; + const byColObject = (_byCol as ArrayValueObject).get(0, 0) as BaseValueObject; - return this._handleSingleObject(array, sortIndex, sortOrder, byColObject); + return this._handleSingleObject(array, _sortIndex, _sortOrder, byColObject); } - return byCol.map((byColObject) => { - const result = this._handleSingleObject(array, sortIndex!, sortOrder!, byColObject); + return _byCol.map((byColObject) => { + const result = this._handleSingleObject(array, _sortIndex, _sortOrder, byColObject); return result.isArray() ? (result as ArrayValueObject).get(0, 0) as BaseValueObject : result; }); } - return this._handleSingleObject(array, sortIndex, sortOrder, byCol); + return this._handleSingleObject(array, _sortIndex, _sortOrder, _byCol); } private _handleSingleObject(array: BaseValueObject, sortIndex: BaseValueObject, sortOrder: BaseValueObject, byCol: BaseValueObject) { @@ -62,70 +62,71 @@ export class Sort extends BaseFunction { const arrayRowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; const arrayColumnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; - if (sortIndex.isArray()) { - const rowCount = (sortIndex as ArrayValueObject).getRowCount(); - const columnCount = (sortIndex as ArrayValueObject).getColumnCount(); + const _sortIndex = this._checkArrayError(sortIndex); - if (rowCount > 1 || columnCount > 1) { - return ErrorValueObject.create(ErrorType.VALUE); - } - - sortIndex = (sortIndex as ArrayValueObject).get(0, 0) as BaseValueObject; + if (_sortIndex.isError()) { + return _sortIndex; } - if (sortIndex.isString()) { - sortIndex = sortIndex.convertToNumberObjectValue(); + const sortIndexValue = Math.floor(+_sortIndex.getValue()); + + if (sortIndexValue < 1) { + return ErrorValueObject.create(ErrorType.VALUE); } - if (sortIndex.isError()) { - return sortIndex; + const _sortOrder = this._checkArrayError(sortOrder); + + if (_sortOrder.isError()) { + return _sortOrder; } - const sortIndexValue = Math.floor(+sortIndex.getValue()); + const sortOrderValue = Math.floor(+_sortOrder.getValue()); - if (sortIndexValue < 1) { + if (sortOrderValue !== -1 && sortOrderValue !== 1) { return ErrorValueObject.create(ErrorType.VALUE); } - if (sortOrder.isArray()) { - const rowCount = (sortOrder as ArrayValueObject).getRowCount(); - const columnCount = (sortOrder as ArrayValueObject).getColumnCount(); + let _byCol = byCol; - if (rowCount > 1 || columnCount > 1) { - return ErrorValueObject.create(ErrorType.VALUE); - } - - sortOrder = (sortOrder as ArrayValueObject).get(0, 0) as BaseValueObject; + if (_byCol.isString()) { + _byCol = _byCol.convertToNumberObjectValue(); } - if (sortOrder.isString()) { - sortOrder = sortOrder.convertToNumberObjectValue(); + if (_byCol.isError()) { + return _byCol; } - if (sortOrder.isError()) { - return sortOrder; + if (!array.isArray() || (arrayRowCount === 1 && arrayColumnCount === 1)) { + return array; } - const sortOrderValue = Math.floor(+sortOrder.getValue()); + const byColValue = +_byCol.getValue(); - if (sortOrderValue !== -1 && sortOrderValue !== 1) { - return ErrorValueObject.create(ErrorType.VALUE); - } + return this._getResult(array, sortIndexValue, sortOrderValue, byColValue, arrayRowCount, arrayColumnCount); + } - if (byCol.isString()) { - byCol = byCol.convertToNumberObjectValue(); - } + private _checkArrayError(variant: BaseValueObject): BaseValueObject { + let _variant = variant; + + if (_variant.isArray()) { + const rowCount = (_variant as ArrayValueObject).getRowCount(); + const columnCount = (_variant as ArrayValueObject).getColumnCount(); + + if (rowCount > 1 || columnCount > 1) { + return ErrorValueObject.create(ErrorType.VALUE); + } - if (byCol.isError()) { - return byCol; + _variant = (_variant as ArrayValueObject).get(0, 0) as BaseValueObject; } - if (!array.isArray() || (arrayRowCount === 1 && arrayColumnCount === 1)) { - return array; + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - const byColValue = +byCol.getValue(); + return _variant; + } + private _getResult(array: BaseValueObject, sortIndexValue: number, sortOrderValue: 1 | -1, byColValue: number, arrayRowCount: number, arrayColumnCount: number): BaseValueObject { if (!byColValue) { if (sortIndexValue > arrayColumnCount) { return ErrorValueObject.create(ErrorType.VALUE); @@ -169,111 +170,119 @@ export class Sort extends BaseFunction { const compare = getCompare(); if (sortOrder === 1) { - return (a: Nullable[], b: Nullable[]) => { - const columnA = a[sortIndex]; - const columnB = b[sortIndex]; - - if (columnA == null || columnA.isNull()) { - return 1; - } - - if (columnB == null || columnB.isNull()) { - return -1; - } - - if (columnA.isError() && columnB.isError()) { - return 0; - } - - if (columnA.isError()) { - return 1; - } - - if (columnB.isError()) { - return -1; - } - - const columnAValue = (columnA as BaseValueObject).getValue(); - const columnBValue = (columnB as BaseValueObject).getValue(); - - if (columnA.isBoolean() && columnAValue === true) { - return 1; - } - - if (columnB.isBoolean() && columnBValue === true) { - return -1; - } - - if (columnA.isBoolean() && columnAValue === false) { - return 1; - } - - if (columnB.isBoolean() && columnBValue === false) { - return -1; - } - - if (columnA.isNumber() && columnB.isNumber()) { - return (+columnAValue) - (+columnBValue); - } - - return compare( - columnAValue as string, - columnBValue as string - ); - }; + return this._sortAsc(sortIndex, compare); } else { - return (a: Nullable[], b: Nullable[]) => { - const columnA = a[sortIndex]; - const columnB = b[sortIndex]; - - if (columnA == null || columnA.isNull()) { - return 1; - } - - if (columnB == null || columnB.isNull()) { - return -1; - } - - if (columnA.isError() && columnB.isError()) { - return 0; - } - - if (columnA.isError()) { - return -1; - } - - if (columnB.isError()) { - return 1; - } - - const columnAValue = (columnA as BaseValueObject).getValue(); - const columnBValue = (columnB as BaseValueObject).getValue(); - - if (columnA.isBoolean() && columnAValue === true) { - return -1; - } - - if (columnB.isBoolean() && columnBValue === true) { - return 1; - } - - if (columnA.isBoolean() && columnAValue === false) { - return -1; - } - - if (columnB.isBoolean() && columnBValue === false) { - return 1; - } - - if (columnA.isNumber() && columnB.isNumber()) { - return (+columnBValue) - (+columnAValue); - } - - return compare( - columnBValue as string, - columnAValue as string - ); - }; + return this._sortDesc(sortIndex, compare); } } + + private _sortAsc(sortIndex: number, compare: Function) { + return (a: Nullable[], b: Nullable[]) => { + const columnA = a[sortIndex]; + const columnB = b[sortIndex]; + + if (columnA == null || columnA.isNull()) { + return 1; + } + + if (columnB == null || columnB.isNull()) { + return -1; + } + + if (columnA.isError() && columnB.isError()) { + return 0; + } + + if (columnA.isError()) { + return 1; + } + + if (columnB.isError()) { + return -1; + } + + const columnAValue = (columnA as BaseValueObject).getValue(); + const columnBValue = (columnB as BaseValueObject).getValue(); + + if (columnA.isBoolean() && columnAValue === true) { + return 1; + } + + if (columnB.isBoolean() && columnBValue === true) { + return -1; + } + + if (columnA.isBoolean() && columnAValue === false) { + return 1; + } + + if (columnB.isBoolean() && columnBValue === false) { + return -1; + } + + if (columnA.isNumber() && columnB.isNumber()) { + return (+columnAValue) - (+columnBValue); + } + + return compare( + columnAValue as string, + columnBValue as string + ); + }; + } + + private _sortDesc(sortIndex: number, compare: Function) { + return (a: Nullable[], b: Nullable[]) => { + const columnA = a[sortIndex]; + const columnB = b[sortIndex]; + + if (columnA == null || columnA.isNull()) { + return 1; + } + + if (columnB == null || columnB.isNull()) { + return -1; + } + + if (columnA.isError() && columnB.isError()) { + return 0; + } + + if (columnA.isError()) { + return -1; + } + + if (columnB.isError()) { + return 1; + } + + const columnAValue = (columnA as BaseValueObject).getValue(); + const columnBValue = (columnB as BaseValueObject).getValue(); + + if (columnA.isBoolean() && columnAValue === true) { + return -1; + } + + if (columnB.isBoolean() && columnBValue === true) { + return 1; + } + + if (columnA.isBoolean() && columnAValue === false) { + return -1; + } + + if (columnB.isBoolean() && columnBValue === false) { + return 1; + } + + if (columnA.isNumber() && columnB.isNumber()) { + return (+columnBValue) - (+columnAValue); + } + + return compare( + columnBValue as string, + columnAValue as string + ); + }; + } } diff --git a/packages/engine-formula/src/functions/lookup/sortby/index.ts b/packages/engine-formula/src/functions/lookup/sortby/index.ts index e035e2bbc7e..19984e09601 100644 --- a/packages/engine-formula/src/functions/lookup/sortby/index.ts +++ b/packages/engine-formula/src/functions/lookup/sortby/index.ts @@ -52,13 +52,7 @@ export class Sortby extends BaseFunction { return expandArray; } - const arrayRowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; - const arrayColumnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; - - const byArray1RowCount = variants[0].isArray() ? (variants[0] as ArrayValueObject).getRowCount() : 1; - const byArray1ColumnCount = variants[0].isArray() ? (variants[0] as ArrayValueObject).getColumnCount() : 1; - - variants = variants.map((variant, index) => { + const _variants = variants.map((variant, index) => { if (index % 2 === 0) { return variant; } @@ -68,60 +62,95 @@ export class Sortby extends BaseFunction { return variantArray; }); - const resultArray: BaseValueObject[][] = []; + const resultArray = this._getResultArray(array, _variants, maxRowLength, maxColumnLength); - for (let r = 0; r < maxRowLength; r++) { - resultArray[r] = [] as BaseValueObject[]; + if (maxRowLength === 1 && maxColumnLength === 1) { + return resultArray[0][0] as ArrayValueObject; + } - for (let c = 0; c < maxColumnLength; c++) { - const byArrays = []; - const sortOrders = []; + return ArrayValueObject.create({ + calculateValueList: resultArray, + rowCount: resultArray.length, + columnCount: resultArray[0].length || 0, + unitId: this.unitId as string, + sheetId: this.subUnitId as string, + row: this.row, + column: this.column, + }); + } + + // eslint-disable-next-line complexity + private _getVariantsError(array: BaseValueObject, ...variants: BaseValueObject[]): ErrorValueObject | BooleanValueObject { + if (array.isError()) { + return array as ErrorValueObject; + } - let isError: boolean = false; + for (let i = 0; i < variants.length; i++) { + const variant = variants[i]; - for (let i = 0; i < variants.length; i++) { - if (i % 2 === 1) { - continue; - } + if (variant.isError()) { + return variant as ErrorValueObject; + } + } - const byArray = variants[i]; + // byArray and sortOrder must be paired + if (variants.length < 2 || variants.length % 2 !== 0) { + return ErrorValueObject.create(ErrorType.VALUE); + } - let sortOrder = (variants[i + 1] as ArrayValueObject).get(r, c) as BaseValueObject; + const arrayRowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const arrayColumnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; - if (sortOrder.isString()) { - sortOrder = sortOrder.convertToNumberObjectValue(); - } + const byArray1RowCount = variants[0].isArray() ? (variants[0] as ArrayValueObject).getRowCount() : 1; + const byArray1ColumnCount = variants[0].isArray() ? (variants[0] as ArrayValueObject).getColumnCount() : 1; - if (sortOrder.isError()) { - resultArray[r].push(sortOrder); - isError = true; - break; - } + if (byArray1RowCount > 1 || byArray1ColumnCount > 1) { + if (byArray1RowCount > 1 && byArray1ColumnCount > 1) { + return ErrorValueObject.create(ErrorType.VALUE); + } - const sortOrderValue = Math.floor(+sortOrder.getValue()); + if (byArray1RowCount === 1 && byArray1ColumnCount !== arrayColumnCount) { + return ErrorValueObject.create(ErrorType.VALUE); + } - if (sortOrderValue !== -1 && sortOrderValue !== 1) { - resultArray[r].push(ErrorValueObject.create(ErrorType.VALUE)); - isError = true; - break; - } + if (byArray1ColumnCount === 1 && byArray1RowCount !== arrayRowCount) { + return ErrorValueObject.create(ErrorType.VALUE); + } + } - sortOrders.push(sortOrderValue); + for (let i = 2; i < variants.length; i++) { + if (i % 2 === 1) { + continue; + } - if (byArray.isArray()) { - let byArrayValue = byArray.getArrayValue(); + const byArrayRowCount = variants[i].isArray() ? (variants[i] as ArrayValueObject).getRowCount() : 1; + const byArrayColumnCount = variants[i].isArray() ? (variants[i] as ArrayValueObject).getColumnCount() : 1; - if (byArray1ColumnCount === 1) { - byArrayValue = this._transposeArray(byArrayValue); - } + if (byArrayRowCount !== byArray1RowCount || byArrayColumnCount !== byArray1ColumnCount) { + return ErrorValueObject.create(ErrorType.VALUE); + } + } - byArrays.push(byArrayValue[0]); - } else { - byArrays.push([byArray]); - } - } + return BooleanValueObject.create(true); + } + + private _getResultArray(array: BaseValueObject, variants: BaseValueObject[], maxRowLength: number, maxColumnLength: number): Array> { + const arrayRowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const arrayColumnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; + + const byArray1RowCount = variants[0].isArray() ? (variants[0] as ArrayValueObject).getRowCount() : 1; + const byArray1ColumnCount = variants[0].isArray() ? (variants[0] as ArrayValueObject).getColumnCount() : 1; + + const resultArray: Array> = []; + + for (let r = 0; r < maxRowLength; r++) { + resultArray[r] = [] as BaseValueObject[]; + + for (let c = 0; c < maxColumnLength; c++) { + const { isError, errorObject, byArrays, sortOrders } = this._getByArraysAndSortOrders(variants, r, c, byArray1ColumnCount); if (isError) { + resultArray[r].push(errorObject as ErrorValueObject); continue; } @@ -166,73 +195,64 @@ export class Sortby extends BaseFunction { } } - if (maxRowLength === 1 && maxColumnLength === 1) { - return resultArray[0][0] as ArrayValueObject; - } - - return ArrayValueObject.create({ - calculateValueList: resultArray, - rowCount: resultArray.length, - columnCount: resultArray[0].length || 0, - unitId: this.unitId as string, - sheetId: this.subUnitId as string, - row: this.row, - column: this.column, - }); + return resultArray; } - private _getVariantsError(array: BaseValueObject, ...variants: BaseValueObject[]): ErrorValueObject | BooleanValueObject { - if (array.isError()) { - return array as ErrorValueObject; - } + private _getByArraysAndSortOrders(variants: BaseValueObject[], r: number, c: number, byArray1ColumnCount: number) { + const byArrays = []; + const sortOrders = []; - for (let i = 0; i < variants.length; i++) { - const variant = variants[i]; + let isError: boolean = false; + let errorObject: ErrorValueObject | null = null; - if (variant.isError()) { - return variant as ErrorValueObject; + for (let i = 0; i < variants.length; i++) { + if (i % 2 === 1) { + continue; } - } - // byArray and sortOrder must be paired - if (variants.length < 2 || variants.length % 2 !== 0) { - return ErrorValueObject.create(ErrorType.VALUE); - } + const byArray = variants[i]; - const arrayRowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; - const arrayColumnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; - - const byArray1RowCount = variants[0].isArray() ? (variants[0] as ArrayValueObject).getRowCount() : 1; - const byArray1ColumnCount = variants[0].isArray() ? (variants[0] as ArrayValueObject).getColumnCount() : 1; + let sortOrder = (variants[i + 1] as ArrayValueObject).get(r, c) as BaseValueObject; - if (byArray1RowCount > 1 || byArray1ColumnCount > 1) { - if (byArray1RowCount > 1 && byArray1ColumnCount > 1) { - return ErrorValueObject.create(ErrorType.VALUE); + if (sortOrder.isString()) { + sortOrder = sortOrder.convertToNumberObjectValue(); } - if (byArray1RowCount === 1 && byArray1ColumnCount !== arrayColumnCount) { - return ErrorValueObject.create(ErrorType.VALUE); + if (sortOrder.isError()) { + isError = true; + errorObject = sortOrder as ErrorValueObject; + break; } - if (byArray1ColumnCount === 1 && byArray1RowCount !== arrayRowCount) { - return ErrorValueObject.create(ErrorType.VALUE); - } - } + const sortOrderValue = Math.floor(+sortOrder.getValue()); - for (let i = 2; i < variants.length; i++) { - if (i % 2 === 1) { - continue; + if (sortOrderValue !== -1 && sortOrderValue !== 1) { + isError = true; + errorObject = ErrorValueObject.create(ErrorType.VALUE); + break; } - const byArrayRowCount = variants[i].isArray() ? (variants[i] as ArrayValueObject).getRowCount() : 1; - const byArrayColumnCount = variants[i].isArray() ? (variants[i] as ArrayValueObject).getColumnCount() : 1; + sortOrders.push(sortOrderValue); - if (byArrayRowCount !== byArray1RowCount || byArrayColumnCount !== byArray1ColumnCount) { - return ErrorValueObject.create(ErrorType.VALUE); + if (byArray.isArray()) { + let byArrayValue = byArray.getArrayValue(); + + if (byArray1ColumnCount === 1) { + byArrayValue = this._transposeArray(byArrayValue); + } + + byArrays.push(byArrayValue[0]); + } else { + byArrays.push([byArray]); } } - return BooleanValueObject.create(true); + return { + isError, + errorObject, + byArrays, + sortOrders, + }; } private _transposeArray(array: Nullable[][]) { @@ -280,103 +300,111 @@ export class Sortby extends BaseFunction { }; } - private _compare(columnA: BaseValueObject, columnB: BaseValueObject, sortOrder: 1 | -1, compare: Function) { + private _compare(columnA: BaseValueObject, columnB: BaseValueObject, sortOrder: 1 | -1, compare: Function): number { if (sortOrder === 1) { - if (columnA == null || columnA.isNull()) { - return 1; - } + return this._asc(columnA, columnB, compare); + } else { + return this._desc(columnA, columnB, compare); + } + } - if (columnB == null || columnB.isNull()) { - return -1; - } + private _asc(columnA: BaseValueObject, columnB: BaseValueObject, compare: Function): number { + if (columnA == null || columnA.isNull()) { + return 1; + } - if (columnA.isError() && columnB.isError()) { - return 0; - } + if (columnB == null || columnB.isNull()) { + return -1; + } - if (columnA.isError()) { - return 1; - } + if (columnA.isError() && columnB.isError()) { + return 0; + } - if (columnB.isError()) { - return -1; - } + if (columnA.isError()) { + return 1; + } - const columnAValue = (columnA as BaseValueObject).getValue(); - const columnBValue = (columnB as BaseValueObject).getValue(); + if (columnB.isError()) { + return -1; + } - if (columnA.isBoolean() && columnAValue === true) { - return 1; - } + const columnAValue = (columnA as BaseValueObject).getValue(); + const columnBValue = (columnB as BaseValueObject).getValue(); - if (columnB.isBoolean() && columnBValue === true) { - return -1; - } + if (columnA.isBoolean() && columnAValue === true) { + return 1; + } - if (columnA.isBoolean() && columnAValue === false) { - return 1; - } + if (columnB.isBoolean() && columnBValue === true) { + return -1; + } - if (columnB.isBoolean() && columnBValue === false) { - return -1; - } + if (columnA.isBoolean() && columnAValue === false) { + return 1; + } - if (columnA.isNumber() && columnB.isNumber()) { - return (+columnAValue) - (+columnBValue); - } + if (columnB.isBoolean() && columnBValue === false) { + return -1; + } - return compare( - columnAValue as string, - columnBValue as string - ); - } else { - if (columnA == null || columnA.isNull()) { - return 1; - } + if (columnA.isNumber() && columnB.isNumber()) { + return (+columnAValue) - (+columnBValue); + } - if (columnB == null || columnB.isNull()) { - return -1; - } + return compare( + columnAValue as string, + columnBValue as string + ); + } - if (columnA.isError() && columnB.isError()) { - return 0; - } + private _desc(columnA: BaseValueObject, columnB: BaseValueObject, compare: Function): number { + if (columnA == null || columnA.isNull()) { + return 1; + } - if (columnA.isError()) { - return -1; - } + if (columnB == null || columnB.isNull()) { + return -1; + } - if (columnB.isError()) { - return 1; - } + if (columnA.isError() && columnB.isError()) { + return 0; + } - const columnAValue = (columnA as BaseValueObject).getValue(); - const columnBValue = (columnB as BaseValueObject).getValue(); + if (columnA.isError()) { + return -1; + } - if (columnA.isBoolean() && columnAValue === true) { - return -1; - } + if (columnB.isError()) { + return 1; + } - if (columnB.isBoolean() && columnBValue === true) { - return 1; - } + const columnAValue = (columnA as BaseValueObject).getValue(); + const columnBValue = (columnB as BaseValueObject).getValue(); - if (columnA.isBoolean() && columnAValue === false) { - return -1; - } + if (columnA.isBoolean() && columnAValue === true) { + return -1; + } - if (columnB.isBoolean() && columnBValue === false) { - return 1; - } + if (columnB.isBoolean() && columnBValue === true) { + return 1; + } - if (columnA.isNumber() && columnB.isNumber()) { - return (+columnBValue) - (+columnAValue); - } + if (columnA.isBoolean() && columnAValue === false) { + return -1; + } - return compare( - columnBValue as string, - columnAValue as string - ); + if (columnB.isBoolean() && columnBValue === false) { + return 1; } + + if (columnA.isNumber() && columnB.isNumber()) { + return (+columnBValue) - (+columnAValue); + } + + return compare( + columnBValue as string, + columnAValue as string + ); } } diff --git a/packages/engine-formula/src/functions/lookup/unique/index.ts b/packages/engine-formula/src/functions/lookup/unique/index.ts index d27ce62a5b3..f6511c82755 100644 --- a/packages/engine-formula/src/functions/lookup/unique/index.ts +++ b/packages/engine-formula/src/functions/lookup/unique/index.ts @@ -24,7 +24,7 @@ import { BooleanValueObject } from '../../../engine/value-object/primitive-objec import { BaseFunction } from '../../base-function'; import { expandArrayValueObject } from '../../../engine/utils/array-object'; -interface ObjectMapType { +interface IObjectMapType { r: number; valueObject: BaseValueObject; } @@ -35,38 +35,39 @@ export class Unique extends BaseFunction { override maxParams = 3; override calculate(array: BaseValueObject, byCol?: BaseValueObject, exactlyOnce?: BaseValueObject) { - byCol = byCol ?? BooleanValueObject.create(false); - exactlyOnce = exactlyOnce ?? BooleanValueObject.create(false); + const _byCol = byCol ?? BooleanValueObject.create(false); + const _exactlyOnce = exactlyOnce ?? BooleanValueObject.create(false); const arrayRowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; const arrayColumnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; const maxRowLength = Math.max( - byCol.isArray() ? (byCol as ArrayValueObject).getRowCount() : 1, - exactlyOnce.isArray() ? (exactlyOnce as ArrayValueObject).getRowCount() : 1 + _byCol.isArray() ? (_byCol as ArrayValueObject).getRowCount() : 1, + _exactlyOnce.isArray() ? (_exactlyOnce as ArrayValueObject).getRowCount() : 1 ); const maxColumnLength = Math.max( - byCol.isArray() ? (byCol as ArrayValueObject).getColumnCount() : 1, - exactlyOnce.isArray() ? (exactlyOnce as ArrayValueObject).getColumnCount() : 1 + _byCol.isArray() ? (_byCol as ArrayValueObject).getColumnCount() : 1, + _exactlyOnce.isArray() ? (_exactlyOnce as ArrayValueObject).getColumnCount() : 1 ); - const byColArray = expandArrayValueObject(maxRowLength, maxColumnLength, byCol, ErrorValueObject.create(ErrorType.NA)); - const exactlyOnceArray = expandArrayValueObject(maxRowLength, maxColumnLength, exactlyOnce, ErrorValueObject.create(ErrorType.NA)); + const byColArray = expandArrayValueObject(maxRowLength, maxColumnLength, _byCol, ErrorValueObject.create(ErrorType.NA)); + const exactlyOnceArray = expandArrayValueObject(maxRowLength, maxColumnLength, _exactlyOnce, ErrorValueObject.create(ErrorType.NA)); const resultArray = byColArray.map((byColObject, rowIndex, columnIndex) => { + let _byColObject = byColObject; let exactlyOnceObject = exactlyOnceArray.get(rowIndex, columnIndex) as BaseValueObject; if (array.isError()) { return array; } - if (byColObject.isString()) { - byColObject = byColObject.convertToNumberObjectValue(); + if (_byColObject.isString()) { + _byColObject = _byColObject.convertToNumberObjectValue(); } - if (byColObject.isError()) { - return byColObject; + if (_byColObject.isError()) { + return _byColObject; } if (exactlyOnceObject.isString()) { @@ -77,7 +78,7 @@ export class Unique extends BaseFunction { return exactlyOnceObject; } - const byColValue = +byColObject.getValue(); + const byColValue = +_byColObject.getValue(); const exactlyOnceValue = +exactlyOnceObject.getValue(); let result: Nullable; @@ -85,100 +86,113 @@ export class Unique extends BaseFunction { if ((!byColValue && arrayRowCount === 1) || (byColValue && arrayColumnCount === 1)) { result = array; } else { - let arrayValue = array.getArrayValue(); - let arrayRows = arrayRowCount; - let arrayColumns = arrayColumnCount; - - if (byColValue) { - arrayValue = this._transposeArray(arrayValue); - arrayRows = arrayColumnCount; - arrayColumns = arrayRowCount; - } + result = this._getResult(array, byColValue, exactlyOnceValue); + } - let repeatRows: Array> = []; + if ((maxRowLength > 1 || maxColumnLength > 1) && result?.isArray()) { + return (result as ArrayValueObject).get(0, 0) as BaseValueObject; + } - for (let c = 0; c < arrayColumns; c++) { - if (c === 0) { - const objects: Array = new Array(arrayRows).fill(null).map((item, index) => { - return { - r: index, - valueObject: arrayValue[index][c] as BaseValueObject, - }; - }); + return result; + }); - repeatRows = this._getRepeatRows(objects); - } else { - if (repeatRows.length === 0) { - break; - } + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } - let newRepeatRows: Array> = []; + return resultArray; + } - repeatRows.forEach((item) => { - const objects = item.map((r) => { - return { - r, - valueObject: arrayValue[r][c] as BaseValueObject, - }; - }); + private _getResult(array: BaseValueObject, byColValue: number, exactlyOnceValue: number) { + const arrayRowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const arrayColumnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; + + let arrayValue = array.getArrayValue(); + let arrayRows = arrayRowCount; + let arrayColumns = arrayColumnCount; - const _repeatRows = this._getRepeatRows(objects); + if (byColValue) { + arrayValue = this._transposeArray(arrayValue); + arrayRows = arrayColumnCount; + arrayColumns = arrayRowCount; + } + + const repeatRows = this._getRepeatRows(arrayValue as Array>, arrayRows, arrayColumns); - newRepeatRows = newRepeatRows.concat(_repeatRows); - }); + if (repeatRows.length > 0) { + const spliceRows: number[] = []; - repeatRows = newRepeatRows; + repeatRows.forEach((rows) => { + rows.forEach((r, index) => { + if (index !== 0 || exactlyOnceValue) { + spliceRows.push(r); } - } + }); + }); - if (repeatRows.length > 0) { - const spliceRows: number[] = []; + arrayValue = arrayValue.filter((row, rowIndex) => !spliceRows.includes(rowIndex)); + } - repeatRows.forEach((rows) => { - rows.forEach((r, index) => { - if (index !== 0 || exactlyOnceValue) { - spliceRows.push(r); - } - }); - }); + if (arrayValue.length === 0) { + return ErrorValueObject.create(ErrorType.CALC); + } - arrayValue = arrayValue.filter((row, rowIndex) => !spliceRows.includes(rowIndex)); - } + if (byColValue) { + arrayValue = this._transposeArray(arrayValue); + } - if (arrayValue.length === 0) { - return ErrorValueObject.create(ErrorType.CALC); - } + return ArrayValueObject.create({ + calculateValueList: arrayValue, + rowCount: arrayValue.length, + columnCount: arrayValue[0].length || 0, + unitId: this.unitId as string, + sheetId: this.subUnitId as string, + row: this.row, + column: this.column, + }); + } - if (byColValue) { - arrayValue = this._transposeArray(arrayValue); - } + private _getRepeatRows(arrayValue: Array>, arrayRows: number, arrayColumns: number): Array> { + let repeatRows: Array> = []; - result = ArrayValueObject.create({ - calculateValueList: arrayValue, - rowCount: arrayValue.length, - columnCount: arrayValue[0].length || 0, - unitId: this.unitId as string, - sheetId: this.subUnitId as string, - row: this.row, - column: this.column, + for (let c = 0; c < arrayColumns; c++) { + if (c === 0) { + const objects: Array = new Array(arrayRows).fill(null).map((item, index) => { + return { + r: index, + valueObject: arrayValue[index][c] as BaseValueObject, + }; }); - } - if ((maxRowLength > 1 || maxColumnLength > 1) && result?.isArray()) { - return (result as ArrayValueObject).get(0, 0) as BaseValueObject; - } + repeatRows = this._getRepeatRowsByObjects(objects); + } else { + if (repeatRows.length === 0) { + break; + } - return result; - }); + let newRepeatRows: Array> = []; - if (maxRowLength === 1 && maxColumnLength === 1) { - return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + repeatRows.forEach((item) => { + const objects = item.map((r) => { + return { + r, + valueObject: arrayValue[r][c] as BaseValueObject, + }; + }); + + const _repeatRows = this._getRepeatRowsByObjects(objects); + + newRepeatRows = newRepeatRows.concat(_repeatRows); + }); + + repeatRows = newRepeatRows; + } } - return resultArray; + return repeatRows; } - private _getRepeatRows(objects: Array): Array> { + private _getRepeatRowsByObjects(objects: Array): Array> { const valueMap = new Map(); objects.forEach((item) => { diff --git a/packages/engine-formula/src/functions/lookup/vlookup/index.ts b/packages/engine-formula/src/functions/lookup/vlookup/index.ts index 1713a28b47d..28d82d38bea 100644 --- a/packages/engine-formula/src/functions/lookup/vlookup/index.ts +++ b/packages/engine-formula/src/functions/lookup/vlookup/index.ts @@ -55,16 +55,16 @@ export class Vlookup extends BaseFunction { return rangeLookup; } - rangeLookup = rangeLookup ?? BooleanValueObject.create(true); + const _rangeLookup = rangeLookup ?? BooleanValueObject.create(true); // When neither lookupValue nor rangeLookup is an array, but colIndexNum is an array, expansion is allowed based on the value of colIndexNum. However, if an error is encountered in subsequent matching, the first error needs to be returned (not the entire array) // Otherwise colIndexNum takes the first value - if (isSingleValueObject(lookupValue) && isSingleValueObject(rangeLookup) && colIndexNum.isArray()) { - return this._handleArrayColIndexNum(lookupValue, tableArray, colIndexNum, rangeLookup); + if (isSingleValueObject(lookupValue) && isSingleValueObject(_rangeLookup) && colIndexNum.isArray()) { + return this._handleArrayColIndexNum(lookupValue, tableArray, colIndexNum, _rangeLookup); } - return this._handleNonArrayColIndexNum(lookupValue, tableArray, colIndexNum, rangeLookup); + return this._handleNonArrayColIndexNum(lookupValue, tableArray, colIndexNum, _rangeLookup); } private _handleArrayColIndexNum( @@ -73,7 +73,7 @@ export class Vlookup extends BaseFunction { colIndexNum: BaseValueObject, rangeLookup: BaseValueObject ) { - lookupValue = lookupValue.isArray() ? (lookupValue as ArrayValueObject).getFirstCell() : lookupValue; + const _lookupValue = lookupValue.isArray() ? (lookupValue as ArrayValueObject).getFirstCell() : lookupValue; const rangeLookupValue = this.getZeroOrOneByOneDefault(rangeLookup); @@ -90,7 +90,7 @@ export class Vlookup extends BaseFunction { return false; } - const searchObject = this._handleTableArray(lookupValue, tableArray, colIndexNumValueObject, rangeLookupValue); + const searchObject = this._handleTableArray(_lookupValue, tableArray, colIndexNumValueObject, rangeLookupValue); if (searchObject.isError()) { errorValue = searchObject; diff --git a/packages/engine-formula/src/functions/lookup/xlookup/index.ts b/packages/engine-formula/src/functions/lookup/xlookup/index.ts index 9c4a2a15202..2af132bad9d 100644 --- a/packages/engine-formula/src/functions/lookup/xlookup/index.ts +++ b/packages/engine-formula/src/functions/lookup/xlookup/index.ts @@ -41,53 +41,28 @@ export class Xlookup extends BaseFunction { return lookupValue; } - if (lookupArray.isError()) { + if (lookupArray.isError() || returnArray.isError()) { return ErrorValueObject.create(ErrorType.REF); } - if (!lookupArray.isArray()) { + if (!lookupArray.isArray() || !returnArray.isArray()) { return ErrorValueObject.create(ErrorType.VALUE); } const rowCountLookup = lookupArray.getRowCount(); - const columnCountLookup = lookupArray.getColumnCount(); - - if (rowCountLookup !== 1 && columnCountLookup !== 1) { - return ErrorValueObject.create(ErrorType.VALUE); - } - - if (returnArray.isError()) { - return ErrorValueObject.create(ErrorType.REF); - } - - if (!returnArray.isArray()) { - return ErrorValueObject.create(ErrorType.VALUE); - } - const rowCountReturn = returnArray.getRowCount(); - const columnCountReturn = returnArray.getColumnCount(); - if (rowCountLookup !== rowCountReturn && columnCountLookup !== columnCountReturn) { + if ((rowCountLookup !== 1 && columnCountLookup !== 1) || (rowCountLookup !== rowCountReturn && columnCountLookup !== columnCountReturn)) { return ErrorValueObject.create(ErrorType.VALUE); } - if (ifNotFound?.isError()) { + if (ifNotFound?.isError() || matchMode?.isError() || searchMode?.isError()) { return ErrorValueObject.create(ErrorType.NA); } - if (matchMode?.isError()) { - return ErrorValueObject.create(ErrorType.NA); - } - - if (searchMode?.isError()) { - return ErrorValueObject.create(ErrorType.NA); - } - - if (ifNotFound == null) { - ifNotFound = ErrorValueObject.create(ErrorType.NA); - } + const _ifNotFound = ifNotFound ?? ErrorValueObject.create(ErrorType.NA); const matchModeValue = this.getIndexNumValue(matchMode || NumberValueObject.create(0)); @@ -101,6 +76,32 @@ export class Xlookup extends BaseFunction { return searchModeValue; } + return this._getResult( + lookupValue, + lookupArray, + returnArray, + _ifNotFound, + matchModeValue, + searchModeValue, + rowCountLookup, + columnCountLookup, + rowCountReturn, + columnCountReturn + ); + } + + private _getResult( + lookupValue: BaseValueObject, + lookupArray: ArrayValueObject, + returnArray: ArrayValueObject, + ifNotFound: BaseValueObject, + matchModeValue: number, + searchModeValue: number, + rowCountLookup: number, + columnCountLookup: number, + rowCountReturn: number, + columnCountReturn: number + ) { if (lookupValue.isArray()) { let resultArray: Nullable; @@ -115,16 +116,10 @@ export class Xlookup extends BaseFunction { } return lookupValue.map((value) => { - const result = this._handleSingleObject( - value, - lookupArray, - resultArray!, - matchModeValue, - searchModeValue - ); + const result = this._handleSingleObject(value, lookupArray, resultArray!, matchModeValue, searchModeValue); if (result.isError()) { - return ifNotFound!; + return ifNotFound; } return result; @@ -132,13 +127,7 @@ export class Xlookup extends BaseFunction { } if (columnCountLookup === columnCountReturn && rowCountLookup === rowCountReturn) { - const result = this._handleSingleObject( - lookupValue, - lookupArray, - returnArray!, - matchModeValue, - searchModeValue - ); + const result = this._handleSingleObject(lookupValue, lookupArray, returnArray!, matchModeValue, searchModeValue); if (result.isError()) { return ifNotFound!; @@ -156,44 +145,13 @@ export class Xlookup extends BaseFunction { axis = 1; } - const resultArray = this._handleExpandObject( - lookupValue, - lookupArray, - returnArray, - matchModeValue, - searchModeValue, - axis - ); + const resultArray = this._handleExpandObject(lookupValue, lookupArray, returnArray, matchModeValue, searchModeValue, axis); if (resultArray == null) { return ErrorValueObject.create(ErrorType.NA); } return resultArray; - - // if (rowCountLookup === 1) { - // resultArray = (returnArray as ArrayValueObject).slice([0, 1]); - // } else { - // resultArray = (returnArray as ArrayValueObject).slice(undefined, [0, 1]); - // } - - // return ErrorValueObject.create(ErrorType.NA); - - // const searchArray = (tableArray as ArrayValueObject).slice([0, 1]); - - // const resultArray = (tableArray as ArrayValueObject).slice([rowIndexNumValue - 1, rowIndexNumValue]); - - // if (searchArray == null || resultArray == null) { - // return ErrorValueObject.create(ErrorType.VALUE); - // } - - // if (lookupValue.isArray()) { - // return lookupValue.map((value) => { - // return this._handleSingleObject(value, searchArray, resultArray, rangeLookupValue); - // }); - // } - - // return this._handleSingleObject(lookupValue, searchArray, resultArray, rangeLookupValue); } private _handleExpandObject( diff --git a/packages/engine-formula/src/functions/math/abs/index.ts b/packages/engine-formula/src/functions/math/abs/index.ts index 1b1ec904074..3db481b2818 100644 --- a/packages/engine-formula/src/functions/math/abs/index.ts +++ b/packages/engine-formula/src/functions/math/abs/index.ts @@ -23,14 +23,16 @@ export class Abs extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.abs(); + return _variant.abs(); } } diff --git a/packages/engine-formula/src/functions/math/acos/index.ts b/packages/engine-formula/src/functions/math/acos/index.ts index eebee7b36b8..df6a58e3d48 100644 --- a/packages/engine-formula/src/functions/math/acos/index.ts +++ b/packages/engine-formula/src/functions/math/acos/index.ts @@ -23,14 +23,16 @@ export class Acos extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.acos(); + return _variant.acos(); } } diff --git a/packages/engine-formula/src/functions/math/acosh/index.ts b/packages/engine-formula/src/functions/math/acosh/index.ts index 2bb3c01a8f5..0febd74b3b0 100644 --- a/packages/engine-formula/src/functions/math/acosh/index.ts +++ b/packages/engine-formula/src/functions/math/acosh/index.ts @@ -23,13 +23,15 @@ export class Acosh extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.acosh(); + return _variant.acosh(); } } diff --git a/packages/engine-formula/src/functions/math/acot/index.ts b/packages/engine-formula/src/functions/math/acot/index.ts index b8d2f855948..e7e8995543d 100644 --- a/packages/engine-formula/src/functions/math/acot/index.ts +++ b/packages/engine-formula/src/functions/math/acot/index.ts @@ -26,16 +26,18 @@ export class Acot extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - if ((variant as BaseValueObject).isArray()) { - return (variant as BaseValueObject).map((currentValue) => { + if ((_variant as BaseValueObject).isArray()) { + return (_variant as BaseValueObject).map((currentValue) => { if (currentValue.isError()) { return currentValue; } @@ -43,7 +45,7 @@ export class Acot extends BaseFunction { }); } - return acot(variant as BaseValueObject); + return acot(_variant as BaseValueObject); } } diff --git a/packages/engine-formula/src/functions/math/acoth/index.ts b/packages/engine-formula/src/functions/math/acoth/index.ts index 0b2793cc7fe..46d19299f37 100644 --- a/packages/engine-formula/src/functions/math/acoth/index.ts +++ b/packages/engine-formula/src/functions/math/acoth/index.ts @@ -26,16 +26,18 @@ export class Acoth extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - if ((variant as BaseValueObject).isArray()) { - return (variant as BaseValueObject).map((currentValue) => { + if ((_variant as BaseValueObject).isArray()) { + return (_variant as BaseValueObject).map((currentValue) => { if (currentValue.isError()) { return currentValue; } @@ -43,7 +45,7 @@ export class Acoth extends BaseFunction { }); } - return acoth(variant as BaseValueObject); + return acoth(_variant as BaseValueObject); } } diff --git a/packages/engine-formula/src/functions/math/asin/index.ts b/packages/engine-formula/src/functions/math/asin/index.ts index 6263f43ba81..ed6855850b3 100644 --- a/packages/engine-formula/src/functions/math/asin/index.ts +++ b/packages/engine-formula/src/functions/math/asin/index.ts @@ -23,14 +23,16 @@ export class Asin extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.asin(); + return _variant.asin(); } } diff --git a/packages/engine-formula/src/functions/math/asinh/index.ts b/packages/engine-formula/src/functions/math/asinh/index.ts index eb277fa2a15..d8c40d21f6a 100644 --- a/packages/engine-formula/src/functions/math/asinh/index.ts +++ b/packages/engine-formula/src/functions/math/asinh/index.ts @@ -23,14 +23,16 @@ export class Asinh extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.asinh(); + return _variant.asinh(); } } diff --git a/packages/engine-formula/src/functions/math/atan/index.ts b/packages/engine-formula/src/functions/math/atan/index.ts index 3d5bfda69e0..b5185cfe5fe 100644 --- a/packages/engine-formula/src/functions/math/atan/index.ts +++ b/packages/engine-formula/src/functions/math/atan/index.ts @@ -23,14 +23,16 @@ export class Atan extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.atan(); + return _variant.atan(); } } diff --git a/packages/engine-formula/src/functions/math/atan2/index.ts b/packages/engine-formula/src/functions/math/atan2/index.ts index 6cafa4d766a..913d35e8a24 100644 --- a/packages/engine-formula/src/functions/math/atan2/index.ts +++ b/packages/engine-formula/src/functions/math/atan2/index.ts @@ -23,23 +23,26 @@ export class Atan2 extends BaseFunction { override maxParams = 2; override calculate(xNum: BaseValueObject, yNum: BaseValueObject) { - if (xNum.isString()) { - xNum = xNum.convertToNumberObjectValue(); + let _xNum = xNum; + let _yNum = yNum; + + if (_xNum.isString()) { + _xNum = _xNum.convertToNumberObjectValue(); } - if (xNum.isError()) { - return xNum; + if (_xNum.isError()) { + return _xNum; } - if (yNum.isString()) { - yNum = yNum.convertToNumberObjectValue(); + if (_yNum.isString()) { + _yNum = _yNum.convertToNumberObjectValue(); } - if (yNum.isError()) { - return yNum; + if (_yNum.isError()) { + return _yNum; } // Note that the order of parameters is different from JavaScript - return yNum.atan2(xNum); + return _yNum.atan2(_xNum); } } diff --git a/packages/engine-formula/src/functions/math/atanh/index.ts b/packages/engine-formula/src/functions/math/atanh/index.ts index c36d07116df..c2e0861e8f5 100644 --- a/packages/engine-formula/src/functions/math/atanh/index.ts +++ b/packages/engine-formula/src/functions/math/atanh/index.ts @@ -23,14 +23,16 @@ export class Atanh extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.atanh(); + return _variant.atanh(); } } diff --git a/packages/engine-formula/src/functions/math/base/index.ts b/packages/engine-formula/src/functions/math/base/index.ts index c4eff897f7d..c78cadc3f33 100644 --- a/packages/engine-formula/src/functions/math/base/index.ts +++ b/packages/engine-formula/src/functions/math/base/index.ts @@ -28,6 +28,8 @@ export class Base extends BaseFunction { override maxParams = 3; override calculate(number: BaseValueObject, radix: BaseValueObject, minLength?: BaseValueObject) { + const _minLength = minLength ?? NumberValueObject.create(0); + if (number.isError()) { return number; } @@ -36,93 +38,97 @@ export class Base extends BaseFunction { return radix; } - if (minLength?.isError()) { - return minLength; + if (_minLength.isError()) { + return _minLength; } - // get max row length const maxRowLength = Math.max( number.isArray() ? (number as ArrayValueObject).getRowCount() : 1, radix.isArray() ? (radix as ArrayValueObject).getRowCount() : 1, - minLength?.isArray() ? (minLength as ArrayValueObject).getRowCount() : 1 + _minLength.isArray() ? (_minLength as ArrayValueObject).getRowCount() : 1 ); - // get max column length const maxColumnLength = Math.max( number.isArray() ? (number as ArrayValueObject).getColumnCount() : 1, radix.isArray() ? (radix as ArrayValueObject).getColumnCount() : 1, - minLength?.isArray() ? (minLength as ArrayValueObject).getColumnCount() : 1 + _minLength.isArray() ? (_minLength as ArrayValueObject).getColumnCount() : 1 ); const numberArray = expandArrayValueObject(maxRowLength, maxColumnLength, number, ErrorValueObject.create(ErrorType.NA)); const radixArray = expandArrayValueObject(maxRowLength, maxColumnLength, radix, ErrorValueObject.create(ErrorType.NA)); - const minLengthArray = minLength ? expandArrayValueObject(maxRowLength, maxColumnLength, minLength, ErrorValueObject.create(ErrorType.NA)) : []; + const minLengthArray = expandArrayValueObject(maxRowLength, maxColumnLength, _minLength, ErrorValueObject.create(ErrorType.NA)); const resultArray = numberArray.map((numberObject, rowIndex, columnIndex) => { - let radixObject = radixArray.get(rowIndex, columnIndex) as BaseValueObject; - let minLengthObject = minLength ? (minLengthArray as ArrayValueObject).get(rowIndex, columnIndex) : NumberValueObject.create(0); + const radixObject = radixArray.get(rowIndex, columnIndex) as BaseValueObject; + const minLengthObject = minLengthArray.get(rowIndex, columnIndex) as BaseValueObject; - if (numberObject.isString()) { - numberObject = numberObject.convertToNumberObjectValue(); - } + return this._handleSingleObject(numberObject, radixObject, minLengthObject); + }); - if (radixObject.isString()) { - radixObject = radixObject.convertToNumberObjectValue(); - } + if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { + return resultArray.getArrayValue()[0][0] as StringValueObject; + } - if (minLength && (minLengthObject as BaseValueObject).isString()) { - minLengthObject = (minLengthObject as BaseValueObject).convertToNumberObjectValue(); - } + return resultArray; + } - if (numberObject.isString() || radixObject.isString() || (minLength && (minLengthObject as BaseValueObject).isString())) { - return ErrorValueObject.create(ErrorType.VALUE); - } + private _handleSingleObject(numberObject: BaseValueObject, radixObject: BaseValueObject, minLengthObject: BaseValueObject): BaseValueObject { + let _numberObject = numberObject; - if (numberObject.isError()) { - return numberObject; - } + if (_numberObject.isString()) { + _numberObject = _numberObject.convertToNumberObjectValue(); + } - if (radixObject.isError()) { - return radixObject as BaseValueObject; - } + if (_numberObject.isError()) { + return _numberObject; + } - if (minLength && (minLengthObject as BaseValueObject).isError()) { - return minLengthObject as BaseValueObject; - } + let _radixObject = radixObject; - // Any non-integer number entered as an argument is truncated to an integer. - const numberValue = Math.floor(+numberObject.getValue()); - const radixValue = Math.floor(+radixObject.getValue()); - const minLengthValue = minLength ? Math.floor(+(minLengthObject as BaseValueObject).getValue()) : 0; + if (_radixObject.isString()) { + _radixObject = _radixObject.convertToNumberObjectValue(); + } - // The number that you want to convert. Must be an integer greater than or equal to 0 and less than 2^53. - if (numberValue < 0 || numberValue >= 2 ** 53) { - return ErrorValueObject.create(ErrorType.NUM); - } + if (_radixObject.isError()) { + return _radixObject as BaseValueObject; + } - // The base radix that you want to convert the number into. Must be an integer greater than or equal to 2 and less than or equal to 36. - if (radixValue < 2 || radixValue > 36) { - return ErrorValueObject.create(ErrorType.NUM); - } + let _minLengthObject = minLengthObject; - // The minimum length of the returned string. Must be an integer greater than or equal to 0. - if (minLengthValue < 0) { - return ErrorValueObject.create(ErrorType.NUM); - } + if (_minLengthObject.isString()) { + _minLengthObject = _minLengthObject.convertToNumberObjectValue(); + } - let result = numberValue.toString(radixValue); + if (_minLengthObject.isError()) { + return _minLengthObject; + } - if (minLength && result.length < minLengthValue) { - result = new Array(minLengthValue - result.length + 1).join('0') + result; - } + // Any non-integer number entered as an argument is truncated to an integer. + const numberValue = Math.floor(+_numberObject.getValue()); + const radixValue = Math.floor(+_radixObject.getValue()); + const minLengthValue = Math.floor(+_minLengthObject.getValue()); - return StringValueObject.create(result.toLocaleUpperCase()); - }); + // The number that you want to convert. Must be an integer greater than or equal to 0 and less than 2^53. + if (numberValue < 0 || numberValue >= 2 ** 53) { + return ErrorValueObject.create(ErrorType.NUM); + } - if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { - return resultArray.getArrayValue()[0][0] as StringValueObject; + // The base radix that you want to convert the number into. Must be an integer greater than or equal to 2 and less than or equal to 36. + if (radixValue < 2 || radixValue > 36) { + return ErrorValueObject.create(ErrorType.NUM); } - return resultArray; + // The minimum length of the returned string. Must be an integer greater than or equal to 0. + if (minLengthValue < 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + let result = numberValue.toString(radixValue); + + if (result.length < minLengthValue) { + result = new Array(minLengthValue - result.length + 1).join('0') + result; + } + + return StringValueObject.create(result.toLocaleUpperCase()); } } diff --git a/packages/engine-formula/src/functions/math/ceiling-math/index.ts b/packages/engine-formula/src/functions/math/ceiling-math/index.ts index 80cdbff5ad8..a72ea0c6d61 100644 --- a/packages/engine-formula/src/functions/math/ceiling-math/index.ts +++ b/packages/engine-formula/src/functions/math/ceiling-math/index.ts @@ -28,46 +28,48 @@ export class CeilingMath extends BaseFunction { override maxParams = 3; override calculate(number: BaseValueObject, significance?: BaseValueObject, mode?: BaseValueObject) { + const _significance = significance ?? NumberValueObject.create(1); + const _mode = mode ?? NumberValueObject.create(0); + if (number.isError()) { return number; } - if (significance?.isError()) { - return significance; + if (_significance.isError()) { + return _significance; } - if (mode?.isError()) { - return mode; + if (_mode.isError()) { + return _mode; } - // get max row length const maxRowLength = Math.max( number.isArray() ? (number as ArrayValueObject).getRowCount() : 1, - significance?.isArray() ? (significance as ArrayValueObject).getRowCount() : 1, - mode?.isArray() ? (mode as ArrayValueObject).getRowCount() : 1 + _significance.isArray() ? (_significance as ArrayValueObject).getRowCount() : 1, + _mode.isArray() ? (_mode as ArrayValueObject).getRowCount() : 1 ); - // get max column length const maxColumnLength = Math.max( number.isArray() ? (number as ArrayValueObject).getColumnCount() : 1, - significance?.isArray() ? (significance as ArrayValueObject).getColumnCount() : 1, - mode?.isArray() ? (mode as ArrayValueObject).getColumnCount() : 1 + _significance.isArray() ? (_significance as ArrayValueObject).getColumnCount() : 1, + _mode.isArray() ? (_mode as ArrayValueObject).getColumnCount() : 1 ); const numberArray = expandArrayValueObject(maxRowLength, maxColumnLength, number, ErrorValueObject.create(ErrorType.NA)); - const significanceArray = significance ? expandArrayValueObject(maxRowLength, maxColumnLength, significance, ErrorValueObject.create(ErrorType.NA)) : []; - const modeArray = mode ? expandArrayValueObject(maxRowLength, maxColumnLength, mode, ErrorValueObject.create(ErrorType.NA)) : []; + const significanceArray = expandArrayValueObject(maxRowLength, maxColumnLength, _significance, ErrorValueObject.create(ErrorType.NA)); + const modeArray = expandArrayValueObject(maxRowLength, maxColumnLength, _mode, ErrorValueObject.create(ErrorType.NA)); const resultArray = numberArray.map((numberObject, rowIndex, columnIndex) => { - let significanceObject = significance ? (significanceArray as ArrayValueObject).get(rowIndex, columnIndex) as BaseValueObject : NumberValueObject.create(1); - let modeObject = mode ? (modeArray as ArrayValueObject).get(rowIndex, columnIndex) as BaseValueObject : NumberValueObject.create(0); + let _numberObject = numberObject; + let significanceObject = significanceArray.get(rowIndex, columnIndex) as BaseValueObject; + let modeObject = modeArray.get(rowIndex, columnIndex) as BaseValueObject; - if (numberObject.isString()) { - numberObject = numberObject.convertToNumberObjectValue(); + if (_numberObject.isString()) { + _numberObject = _numberObject.convertToNumberObjectValue(); } - if (numberObject.isError()) { - return numberObject; + if (_numberObject.isError()) { + return _numberObject; } if (significanceObject.isString()) { @@ -86,7 +88,7 @@ export class CeilingMath extends BaseFunction { return modeObject; } - const numberValue = +numberObject.getValue(); + const numberValue = +_numberObject.getValue(); const significanceValue = +significanceObject.getValue(); const modeValue = +modeObject.getValue(); @@ -94,21 +96,25 @@ export class CeilingMath extends BaseFunction { return NumberValueObject.create(0); } - let result: number; - - if (numberValue < 0 && modeValue !== 0) { - result = (significanceValue < 0 ? ceil(Math.abs(numberValue) / Math.abs(significanceValue), 0) : -ceil(Math.abs(numberValue) / significanceValue, 0)) * significanceValue; - } else { - result = (significanceValue < 0 ? -ceil(numberValue / Math.abs(significanceValue), 0) : ceil(numberValue / significanceValue, 0)) * significanceValue; - } - - return NumberValueObject.create(result); + return this._getResult(numberValue, significanceValue, modeValue); }); - if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { - return resultArray.getArrayValue()[0][0] as NumberValueObject; + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; } return resultArray; } + + private _getResult(numberValue: number, significanceValue: number, modeValue: number): NumberValueObject { + let result: number; + + if (numberValue < 0 && modeValue !== 0) { + result = (significanceValue < 0 ? ceil(Math.abs(numberValue) / Math.abs(significanceValue), 0) : -ceil(Math.abs(numberValue) / significanceValue, 0)) * significanceValue; + } else { + result = (significanceValue < 0 ? -ceil(numberValue / Math.abs(significanceValue), 0) : ceil(numberValue / significanceValue, 0)) * significanceValue; + } + + return NumberValueObject.create(result); + } } diff --git a/packages/engine-formula/src/functions/math/ceiling-precise/index.ts b/packages/engine-formula/src/functions/math/ceiling-precise/index.ts index 41165ad6190..cc019611c6c 100644 --- a/packages/engine-formula/src/functions/math/ceiling-precise/index.ts +++ b/packages/engine-formula/src/functions/math/ceiling-precise/index.ts @@ -28,38 +28,42 @@ export class CeilingPrecise extends BaseFunction { override maxParams = 2; override calculate(number: BaseValueObject, significance?: BaseValueObject) { + const _significance = significance ?? NumberValueObject.create(1); + if (number.isError()) { return number; } - if (significance?.isError()) { - return significance; + if (_significance.isError()) { + return _significance; } // get max row length const maxRowLength = Math.max( number.isArray() ? (number as ArrayValueObject).getRowCount() : 1, - significance?.isArray() ? (significance as ArrayValueObject).getRowCount() : 1 + _significance.isArray() ? (_significance as ArrayValueObject).getRowCount() : 1 ); // get max column length const maxColumnLength = Math.max( number.isArray() ? (number as ArrayValueObject).getColumnCount() : 1, - significance?.isArray() ? (significance as ArrayValueObject).getColumnCount() : 1 + _significance.isArray() ? (_significance as ArrayValueObject).getColumnCount() : 1 ); const numberArray = expandArrayValueObject(maxRowLength, maxColumnLength, number, ErrorValueObject.create(ErrorType.NA)); - const significanceArray = significance ? expandArrayValueObject(maxRowLength, maxColumnLength, significance, ErrorValueObject.create(ErrorType.NA)) : []; + const significanceArray = expandArrayValueObject(maxRowLength, maxColumnLength, _significance, ErrorValueObject.create(ErrorType.NA)); const resultArray = numberArray.map((numberObject, rowIndex, columnIndex) => { - let significanceObject = significance ? (significanceArray as ArrayValueObject).get(rowIndex, columnIndex) as BaseValueObject : NumberValueObject.create(1); + let significanceObject = significanceArray.get(rowIndex, columnIndex) as BaseValueObject; + + let _numberObject = numberObject; - if (numberObject.isString()) { - numberObject = numberObject.convertToNumberObjectValue(); + if (_numberObject.isString()) { + _numberObject = _numberObject.convertToNumberObjectValue(); } - if (numberObject.isError()) { - return numberObject; + if (_numberObject.isError()) { + return _numberObject; } if (significanceObject.isString()) { @@ -70,7 +74,7 @@ export class CeilingPrecise extends BaseFunction { return significanceObject; } - const numberValue = +numberObject.getValue(); + const numberValue = +_numberObject.getValue(); const significanceValue = +significanceObject.getValue(); if (numberValue === 0 || significanceValue === 0) { @@ -82,8 +86,8 @@ export class CeilingPrecise extends BaseFunction { return NumberValueObject.create(result); }); - if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { - return resultArray.getArrayValue()[0][0] as NumberValueObject; + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; } return resultArray; diff --git a/packages/engine-formula/src/functions/math/ceiling/index.ts b/packages/engine-formula/src/functions/math/ceiling/index.ts index f498a29298e..c16824897fe 100644 --- a/packages/engine-formula/src/functions/math/ceiling/index.ts +++ b/packages/engine-formula/src/functions/math/ceiling/index.ts @@ -52,14 +52,15 @@ export class Ceiling extends BaseFunction { const significanceArray = expandArrayValueObject(maxRowLength, maxColumnLength, significance, ErrorValueObject.create(ErrorType.NA)); const resultArray = numberArray.map((numberObject, rowIndex, columnIndex) => { + let _numberObject = numberObject; let significanceObject = significanceArray.get(rowIndex, columnIndex) as BaseValueObject; - if (numberObject.isString()) { - numberObject = numberObject.convertToNumberObjectValue(); + if (_numberObject.isString()) { + _numberObject = _numberObject.convertToNumberObjectValue(); } - if (numberObject.isError()) { - return numberObject; + if (_numberObject.isError()) { + return _numberObject; } if (significanceObject.isString()) { @@ -70,7 +71,7 @@ export class Ceiling extends BaseFunction { return significanceObject; } - const numberValue = +numberObject.getValue(); + const numberValue = +_numberObject.getValue(); const significanceValue = +significanceObject.getValue(); if (numberValue > 0 && significanceValue < 0) { diff --git a/packages/engine-formula/src/functions/math/cos/index.ts b/packages/engine-formula/src/functions/math/cos/index.ts index df13bad3b10..6e4e4b8e585 100644 --- a/packages/engine-formula/src/functions/math/cos/index.ts +++ b/packages/engine-formula/src/functions/math/cos/index.ts @@ -23,14 +23,16 @@ export class Cos extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.cos(); + return _variant.cos(); } } diff --git a/packages/engine-formula/src/functions/math/cosh/index.ts b/packages/engine-formula/src/functions/math/cosh/index.ts index 8ddf7cdaaef..6eabbc0e208 100644 --- a/packages/engine-formula/src/functions/math/cosh/index.ts +++ b/packages/engine-formula/src/functions/math/cosh/index.ts @@ -23,14 +23,16 @@ export class Cosh extends BaseFunction { override maxParams = 1; override calculate(number: BaseValueObject) { - if (number.isString()) { - number = number.convertToNumberObjectValue(); + let _number = number; + + if (_number.isString()) { + _number = _number.convertToNumberObjectValue(); } - if (number.isError()) { - return number; + if (_number.isError()) { + return _number; } - return number.cosh(); + return _number.cosh(); } } diff --git a/packages/engine-formula/src/functions/math/cot/index.ts b/packages/engine-formula/src/functions/math/cot/index.ts index a12c43e7f9a..0c721339fb3 100644 --- a/packages/engine-formula/src/functions/math/cot/index.ts +++ b/packages/engine-formula/src/functions/math/cot/index.ts @@ -25,44 +25,36 @@ export class Cot extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + if (variant.isArray()) { + return variant.map((numberObject) => this._handleSingleObject(numberObject)); } - if (variant.isError()) { - return variant; - } + return this._handleSingleObject(variant); + } + + private _handleSingleObject(number: BaseValueObject) { + let numberObject = number; - if ((variant as BaseValueObject).isArray()) { - return (variant as BaseValueObject).map((currentValue) => { - if (currentValue.isString()) { - currentValue = currentValue.convertToNumberObjectValue(); - } - if (currentValue.isError()) { - return currentValue; - } - return cot(currentValue as BaseValueObject); - }); + if (numberObject.isString()) { + numberObject = numberObject.convertToNumberObjectValue(); } - return cot(variant as BaseValueObject); - } -} + if (numberObject.isError()) { + return numberObject; + } -function cot(num: BaseValueObject) { - let currentValue = num.getValue(); + const numberValue = +numberObject.getValue(); - currentValue = Number(currentValue); + // The absolute value of Number must be less than 2^27. If Number is outside its constraints, COT returns the #NUM! error value. + if (Math.abs(numberValue) >= 2 ** 27) { + return ErrorValueObject.create(ErrorType.NUM); + } - // The absolute value of Number must be less than 2^27. If Number is outside its constraints, COT returns the #NUM! error value. - if (Math.abs(currentValue) >= 2 ** 27) { - return ErrorValueObject.create(ErrorType.NUM); - } + // COT(0) returns the #DIV/0! error value. + if (numberValue === 0) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } - // COT(0) returns the #DIV/0! error value. - if (currentValue === 0) { - return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + return numberObject.tan().getReciprocal(); } - - return num.tan().getReciprocal(); } diff --git a/packages/engine-formula/src/functions/math/coth/index.ts b/packages/engine-formula/src/functions/math/coth/index.ts index c4e949537fb..4d8ab984555 100644 --- a/packages/engine-formula/src/functions/math/coth/index.ts +++ b/packages/engine-formula/src/functions/math/coth/index.ts @@ -25,39 +25,31 @@ export class Coth extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + if (variant.isArray()) { + return variant.map((numberObject) => this._handleSingleObject(numberObject)); } - if (variant.isError()) { - return variant; - } + return this._handleSingleObject(variant); + } - if ((variant as BaseValueObject).isArray()) { - return (variant as BaseValueObject).map((currentValue) => { - if (currentValue.isString()) { - currentValue = currentValue.convertToNumberObjectValue(); - } - if (currentValue.isError()) { - return currentValue; - } - return coth(currentValue as BaseValueObject); - }); + private _handleSingleObject(number: BaseValueObject) { + let numberObject = number; + + if (numberObject.isString()) { + numberObject = numberObject.convertToNumberObjectValue(); } - return coth(variant as BaseValueObject); - } -} + if (numberObject.isError()) { + return numberObject; + } -function coth(num: BaseValueObject) { - let currentValue = num.getValue(); + const numberValue = +numberObject.getValue(); - currentValue = Number(currentValue); + // COTH(0) returns the #DIV/0! error value. + if (numberValue === 0) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } - // COTH(0) returns the #DIV/0! error value. - if (currentValue === 0) { - return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + return numberObject.tanh().getReciprocal(); } - - return num.tanh().getReciprocal(); } diff --git a/packages/engine-formula/src/functions/math/csc/index.ts b/packages/engine-formula/src/functions/math/csc/index.ts index 7a09b9a1ed8..c2d2eb55cfa 100644 --- a/packages/engine-formula/src/functions/math/csc/index.ts +++ b/packages/engine-formula/src/functions/math/csc/index.ts @@ -25,44 +25,36 @@ export class Csc extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + if (variant.isArray()) { + return variant.map((numberObject) => this._handleSingleObject(numberObject)); } - if (variant.isError()) { - return variant; - } + return this._handleSingleObject(variant); + } + + private _handleSingleObject(number: BaseValueObject) { + let numberObject = number; - if ((variant as BaseValueObject).isArray()) { - return (variant as BaseValueObject).map((currentValue) => { - if (currentValue.isString()) { - currentValue = currentValue.convertToNumberObjectValue(); - } - if (currentValue.isError()) { - return currentValue; - } - return csc(currentValue as BaseValueObject); - }); + if (numberObject.isString()) { + numberObject = numberObject.convertToNumberObjectValue(); } - return csc(variant as BaseValueObject); - } -} + if (numberObject.isError()) { + return numberObject; + } -function csc(num: BaseValueObject) { - let currentValue = num.getValue(); + const numberValue = +numberObject.getValue(); - currentValue = Number(currentValue); + // The absolute value of Number must be less than 2^27. If Number is outside its constraints, COT returns the #NUM! error value. + if (Math.abs(numberValue) >= 2 ** 27) { + return ErrorValueObject.create(ErrorType.NUM); + } - // The absolute value of Number must be less than 2^27. If Number is outside its constraints, COT returns the #NUM! error value. - if (Math.abs(currentValue) >= 2 ** 27) { - return ErrorValueObject.create(ErrorType.NUM); - } + // CSC(0) returns the #DIV/0! error value. + if (numberValue === 0) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } - // CSC(0) returns the #DIV/0! error value. - if (currentValue === 0) { - return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + return numberObject.sin().getReciprocal(); } - - return num.sin().getReciprocal(); } diff --git a/packages/engine-formula/src/functions/math/csch/index.ts b/packages/engine-formula/src/functions/math/csch/index.ts index db222e41e89..e4b165b3b2f 100644 --- a/packages/engine-formula/src/functions/math/csch/index.ts +++ b/packages/engine-formula/src/functions/math/csch/index.ts @@ -26,44 +26,36 @@ export class Csch extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + if (variant.isArray()) { + return variant.map((numberObject) => this._handleSingleObject(numberObject)); } - if (variant.isError()) { - return variant; - } + return this._handleSingleObject(variant); + } + + private _handleSingleObject(number: BaseValueObject) { + let numberObject = number; - if ((variant as BaseValueObject).isArray()) { - return (variant as BaseValueObject).map((currentValue) => { - if (currentValue.isString()) { - currentValue = currentValue.convertToNumberObjectValue(); - } - if (currentValue.isError()) { - return currentValue; - } - return csch(currentValue as BaseValueObject); - }); + if (numberObject.isString()) { + numberObject = numberObject.convertToNumberObjectValue(); } - return csch(variant as BaseValueObject); - } -} + if (numberObject.isError()) { + return numberObject; + } -function csch(num: BaseValueObject) { - let currentValue = num.getValue(); + const numberValue = +numberObject.getValue(); - currentValue = Number(currentValue); + // CSCH(0) returns the #DIV/0! error value. + if (numberValue === 0) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } - // CSCH(0) returns the #DIV/0! error value. - if (currentValue === 0) { - return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); - } + // sinh(number) = Infinity return 0 + if (!Number.isNaN(numberValue) && !Number.isFinite(Math.sinh(numberValue))) { + return NumberValueObject.create(0); + } - // sinh(number) = Infinity return 0 - if (!Number.isNaN(currentValue) && !Number.isFinite(Math.sinh(currentValue))) { - return NumberValueObject.create(0); + return numberObject.sinh().getReciprocal(); } - - return num.sinh().getReciprocal(); } diff --git a/packages/engine-formula/src/functions/math/decimal/index.ts b/packages/engine-formula/src/functions/math/decimal/index.ts index ef0c40f7b9f..dc13d4a5152 100644 --- a/packages/engine-formula/src/functions/math/decimal/index.ts +++ b/packages/engine-formula/src/functions/math/decimal/index.ts @@ -37,13 +37,11 @@ export class Decimal extends BaseFunction { return radix; } - // get max row length const maxRowLength = Math.max( text.isArray() ? (text as ArrayValueObject).getRowCount() : 1, radix.isArray() ? (radix as ArrayValueObject).getRowCount() : 1 ); - // get max column length const maxColumnLength = Math.max( text.isArray() ? (text as ArrayValueObject).getColumnCount() : 1, radix.isArray() ? (radix as ArrayValueObject).getColumnCount() : 1 @@ -53,20 +51,16 @@ export class Decimal extends BaseFunction { const radixArray = expandArrayValueObject(maxRowLength, maxColumnLength, radix, ErrorValueObject.create(ErrorType.NA)); const resultArray = textArray.map((textObject, rowIndex, columnIndex) => { + if (textObject.isError()) { + return textObject; + } + let radixObject = radixArray.get(rowIndex, columnIndex) as BaseValueObject; if (radixObject.isString()) { radixObject = radixObject.convertToNumberObjectValue(); } - if (radixObject.isString()) { - return ErrorValueObject.create(ErrorType.VALUE); - } - - if (textObject.isError()) { - return textObject; - } - if (radixObject.isError()) { return radixObject; } @@ -92,7 +86,7 @@ export class Decimal extends BaseFunction { return NumberValueObject.create(0); } - if (!this.isValidCharForRadix(textValue, radixValue)) { + if (!this._isValidCharForRadix(textValue, radixValue)) { return ErrorValueObject.create(ErrorType.NUM); } @@ -105,14 +99,14 @@ export class Decimal extends BaseFunction { return NumberValueObject.create(result); }); - if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { - return resultArray.getArrayValue()[0][0] as NumberValueObject; + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; } return resultArray; } - private isValidCharForRadix(text: string, radix: number): boolean { + private _isValidCharForRadix(text: string, radix: number): boolean { for (const char of text) { const charCode = char.toUpperCase().charCodeAt(0); diff --git a/packages/engine-formula/src/functions/math/degrees/index.ts b/packages/engine-formula/src/functions/math/degrees/index.ts index 5ddfe15fbdd..8914f7c8e0e 100644 --- a/packages/engine-formula/src/functions/math/degrees/index.ts +++ b/packages/engine-formula/src/functions/math/degrees/index.ts @@ -26,37 +26,25 @@ export class Degrees extends BaseFunction { override maxParams = 1; override calculate(angle: BaseValueObject) { - if (angle.isString()) { - angle = angle.convertToNumberObjectValue(); - } - - if (angle.isError()) { - return angle; - } - if (angle.isArray()) { - return angle.map((angleObject) => { - if (angleObject.isError()) { - return angleObject; - } - - return this._handleSingleObject(angleObject); - }); + return angle.map((angleObject) => this._handleSingleObject(angleObject)); } return this._handleSingleObject(angle); } private _handleSingleObject(angle: BaseValueObject) { - if (angle.isString()) { - angle = angle.convertToNumberObjectValue(); + let angleObject = angle; + + if (angleObject.isString()) { + angleObject = angleObject.convertToNumberObjectValue(); } - if (angle.isError()) { - return angle; + if (angleObject.isError()) { + return angleObject; } - const angleValue = +angle.getValue(); + const angleValue = +angleObject.getValue(); if (!Number.isFinite(angleValue)) { return ErrorValueObject.create(ErrorType.VALUE); diff --git a/packages/engine-formula/src/functions/math/even/index.ts b/packages/engine-formula/src/functions/math/even/index.ts index 331f91d1213..26c9305a8ab 100644 --- a/packages/engine-formula/src/functions/math/even/index.ts +++ b/packages/engine-formula/src/functions/math/even/index.ts @@ -27,37 +27,25 @@ export class Even extends BaseFunction { override maxParams = 1; override calculate(number: BaseValueObject) { - if (number.isString()) { - number = number.convertToNumberObjectValue(); - } - - if (number.isError()) { - return number; - } - if (number.isArray()) { - return number.map((numberObject) => { - if (numberObject.isError()) { - return numberObject; - } - - return this._handleSingleObject(numberObject); - }); + return number.map((numberObject) => this._handleSingleObject(numberObject)); } return this._handleSingleObject(number); } private _handleSingleObject(number: BaseValueObject) { - if (number.isString()) { - number = number.convertToNumberObjectValue(); + let numberObject = number; + + if (numberObject.isString()) { + numberObject = numberObject.convertToNumberObjectValue(); } - if (number.isError()) { - return number; + if (numberObject.isError()) { + return numberObject; } - const numberValue = +number.getValue(); + const numberValue = +numberObject.getValue(); if (!Number.isFinite(numberValue)) { return ErrorValueObject.create(ErrorType.VALUE); diff --git a/packages/engine-formula/src/functions/math/exp/index.ts b/packages/engine-formula/src/functions/math/exp/index.ts index 069fceceb73..859ce90a6b4 100644 --- a/packages/engine-formula/src/functions/math/exp/index.ts +++ b/packages/engine-formula/src/functions/math/exp/index.ts @@ -23,14 +23,16 @@ export class Exp extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.exp(); + return _variant.exp(); } } diff --git a/packages/engine-formula/src/functions/math/floor-math/index.ts b/packages/engine-formula/src/functions/math/floor-math/index.ts index 4c43fd09742..37e4c42272f 100644 --- a/packages/engine-formula/src/functions/math/floor-math/index.ts +++ b/packages/engine-formula/src/functions/math/floor-math/index.ts @@ -28,37 +28,38 @@ export class FloorMath extends BaseFunction { override maxParams = 3; override calculate(number: BaseValueObject, significance?: BaseValueObject, mode?: BaseValueObject) { - significance = significance ?? NumberValueObject.create(1); - mode = mode ?? NumberValueObject.create(0); + const _significance = significance ?? NumberValueObject.create(1); + const _mode = mode ?? NumberValueObject.create(0); // get max row length const maxRowLength = Math.max( number.isArray() ? (number as ArrayValueObject).getRowCount() : 1, - significance.isArray() ? (significance as ArrayValueObject).getRowCount() : 1, - mode.isArray() ? (mode as ArrayValueObject).getRowCount() : 1 + _significance.isArray() ? (_significance as ArrayValueObject).getRowCount() : 1, + _mode.isArray() ? (_mode as ArrayValueObject).getRowCount() : 1 ); // get max column length const maxColumnLength = Math.max( number.isArray() ? (number as ArrayValueObject).getColumnCount() : 1, - significance.isArray() ? (significance as ArrayValueObject).getColumnCount() : 1, - mode.isArray() ? (mode as ArrayValueObject).getColumnCount() : 1 + _significance.isArray() ? (_significance as ArrayValueObject).getColumnCount() : 1, + _mode.isArray() ? (_mode as ArrayValueObject).getColumnCount() : 1 ); const numberArray = expandArrayValueObject(maxRowLength, maxColumnLength, number, ErrorValueObject.create(ErrorType.NA)); - const significanceArray = expandArrayValueObject(maxRowLength, maxColumnLength, significance, ErrorValueObject.create(ErrorType.NA)); - const modeArray = expandArrayValueObject(maxRowLength, maxColumnLength, mode, ErrorValueObject.create(ErrorType.NA)); + const significanceArray = expandArrayValueObject(maxRowLength, maxColumnLength, _significance, ErrorValueObject.create(ErrorType.NA)); + const modeArray = expandArrayValueObject(maxRowLength, maxColumnLength, _mode, ErrorValueObject.create(ErrorType.NA)); const resultArray = numberArray.map((numberObject, rowIndex, columnIndex) => { + let _numberObject = numberObject; let significanceObject = significanceArray.get(rowIndex, columnIndex) as BaseValueObject; let modeObject = modeArray.get(rowIndex, columnIndex) as BaseValueObject; - if (numberObject.isString()) { - numberObject = numberObject.convertToNumberObjectValue(); + if (_numberObject.isString()) { + _numberObject = _numberObject.convertToNumberObjectValue(); } - if (numberObject.isError()) { - return numberObject; + if (_numberObject.isError()) { + return _numberObject; } if (significanceObject.isString()) { @@ -77,7 +78,7 @@ export class FloorMath extends BaseFunction { return modeObject; } - const numberValue = +numberObject.getValue(); + const numberValue = +_numberObject.getValue(); const significanceValue = +significanceObject.getValue(); const modeValue = +modeObject.getValue(); @@ -96,8 +97,8 @@ export class FloorMath extends BaseFunction { return NumberValueObject.create(result); }); - if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { - return resultArray.getArrayValue()[0][0] as NumberValueObject; + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; } return resultArray; diff --git a/packages/engine-formula/src/functions/math/floor-precise/index.ts b/packages/engine-formula/src/functions/math/floor-precise/index.ts index a9cb04387a1..40180b66bd6 100644 --- a/packages/engine-formula/src/functions/math/floor-precise/index.ts +++ b/packages/engine-formula/src/functions/math/floor-precise/index.ts @@ -28,38 +28,40 @@ export class FloorPrecise extends BaseFunction { override maxParams = 2; override calculate(number: BaseValueObject, significance?: BaseValueObject) { + const _significance = significance ?? NumberValueObject.create(1); + if (number.isError()) { return number; } - if (significance?.isError()) { - return significance; + if (_significance.isError()) { + return _significance; } - // get max row length const maxRowLength = Math.max( number.isArray() ? (number as ArrayValueObject).getRowCount() : 1, - significance?.isArray() ? (significance as ArrayValueObject).getRowCount() : 1 + _significance.isArray() ? (_significance as ArrayValueObject).getRowCount() : 1 ); - // get max column length const maxColumnLength = Math.max( number.isArray() ? (number as ArrayValueObject).getColumnCount() : 1, - significance?.isArray() ? (significance as ArrayValueObject).getColumnCount() : 1 + _significance.isArray() ? (_significance as ArrayValueObject).getColumnCount() : 1 ); const numberArray = expandArrayValueObject(maxRowLength, maxColumnLength, number, ErrorValueObject.create(ErrorType.NA)); - const significanceArray = significance ? expandArrayValueObject(maxRowLength, maxColumnLength, significance, ErrorValueObject.create(ErrorType.NA)) : []; + const significanceArray = expandArrayValueObject(maxRowLength, maxColumnLength, _significance, ErrorValueObject.create(ErrorType.NA)); const resultArray = numberArray.map((numberObject, rowIndex, columnIndex) => { - let significanceObject = significance ? (significanceArray as ArrayValueObject).get(rowIndex, columnIndex) as BaseValueObject : NumberValueObject.create(1); + let significanceObject = significanceArray.get(rowIndex, columnIndex) as BaseValueObject; + + let _numberObject = numberObject; - if (numberObject.isString()) { - numberObject = numberObject.convertToNumberObjectValue(); + if (_numberObject.isString()) { + _numberObject = _numberObject.convertToNumberObjectValue(); } - if (numberObject.isError()) { - return numberObject; + if (_numberObject.isError()) { + return _numberObject; } if (significanceObject.isString()) { @@ -70,7 +72,7 @@ export class FloorPrecise extends BaseFunction { return significanceObject; } - const numberValue = +numberObject.getValue(); + const numberValue = +_numberObject.getValue(); const significanceValue = +significanceObject.getValue(); if (numberValue === 0 || significanceValue === 0) { @@ -82,8 +84,8 @@ export class FloorPrecise extends BaseFunction { return NumberValueObject.create(result); }); - if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { - return resultArray.getArrayValue()[0][0] as NumberValueObject; + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; } return resultArray; diff --git a/packages/engine-formula/src/functions/math/floor/index.ts b/packages/engine-formula/src/functions/math/floor/index.ts index 4e7b1f1a942..53f7b4ca4b0 100644 --- a/packages/engine-formula/src/functions/math/floor/index.ts +++ b/packages/engine-formula/src/functions/math/floor/index.ts @@ -54,12 +54,14 @@ export class Floor extends BaseFunction { const resultArray = numberArray.map((numberObject, rowIndex, columnIndex) => { let significanceObject = significanceArray.get(rowIndex, columnIndex) as BaseValueObject; - if (numberObject.isString()) { - numberObject = numberObject.convertToNumberObjectValue(); + let _numberObject = numberObject; + + if (_numberObject.isString()) { + _numberObject = _numberObject.convertToNumberObjectValue(); } - if (numberObject.isError()) { - return numberObject; + if (_numberObject.isError()) { + return _numberObject; } if (significanceObject.isString()) { @@ -70,7 +72,7 @@ export class Floor extends BaseFunction { return significanceObject; } - const numberValue = +numberObject.getValue(); + const numberValue = +_numberObject.getValue(); const significanceValue = +significanceObject.getValue(); if (numberValue > 0 && significanceValue < 0) { @@ -90,8 +92,8 @@ export class Floor extends BaseFunction { return NumberValueObject.create(result); }); - if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { - return resultArray.getArrayValue()[0][0] as NumberValueObject; + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; } return resultArray; diff --git a/packages/engine-formula/src/functions/math/ln/index.ts b/packages/engine-formula/src/functions/math/ln/index.ts index da26d0433b8..29416ba170a 100644 --- a/packages/engine-formula/src/functions/math/ln/index.ts +++ b/packages/engine-formula/src/functions/math/ln/index.ts @@ -23,14 +23,16 @@ export class Ln extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.log(); + return _variant.log(); } } diff --git a/packages/engine-formula/src/functions/math/log/index.ts b/packages/engine-formula/src/functions/math/log/index.ts index 0906a8b3334..48aab3ac68b 100644 --- a/packages/engine-formula/src/functions/math/log/index.ts +++ b/packages/engine-formula/src/functions/math/log/index.ts @@ -27,38 +27,40 @@ export class Log extends BaseFunction { override maxParams = 2; override calculate(number: BaseValueObject, base?: BaseValueObject) { + const _base = base ?? NumberValueObject.create(10); + if (number.isError()) { return number; } - if (base?.isError()) { - return base; + if (_base.isError()) { + return _base; } - // get max row length const maxRowLength = Math.max( number.isArray() ? (number as ArrayValueObject).getRowCount() : 1, - base?.isArray() ? (base as ArrayValueObject).getRowCount() : 1 + _base.isArray() ? (_base as ArrayValueObject).getRowCount() : 1 ); - // get max column length const maxColumnLength = Math.max( number.isArray() ? (number as ArrayValueObject).getColumnCount() : 1, - base?.isArray() ? (base as ArrayValueObject).getColumnCount() : 1 + _base.isArray() ? (_base as ArrayValueObject).getColumnCount() : 1 ); const numberArray = expandArrayValueObject(maxRowLength, maxColumnLength, number, ErrorValueObject.create(ErrorType.NA)); - const baseArray = base ? expandArrayValueObject(maxRowLength, maxColumnLength, base, ErrorValueObject.create(ErrorType.NA)) : []; + const baseArray = expandArrayValueObject(maxRowLength, maxColumnLength, _base, ErrorValueObject.create(ErrorType.NA)); const resultArray = numberArray.map((numberObject, rowIndex, columnIndex) => { - let baseObject = base ? (baseArray as ArrayValueObject).get(rowIndex, columnIndex) as BaseValueObject : NumberValueObject.create(10); + let baseObject = baseArray.get(rowIndex, columnIndex) as BaseValueObject; + + let _numberObject = numberObject; - if (numberObject.isString()) { - numberObject = numberObject.convertToNumberObjectValue(); + if (_numberObject.isString()) { + _numberObject = _numberObject.convertToNumberObjectValue(); } - if (numberObject.isError()) { - return numberObject; + if (_numberObject.isError()) { + return _numberObject; } if (baseObject.isString()) { @@ -69,7 +71,7 @@ export class Log extends BaseFunction { return baseObject; } - const numberValue = +numberObject.getValue(); + const numberValue = +_numberObject.getValue(); const baseValue = +baseObject.getValue(); if (numberValue <= 0 || baseValue <= 0) { @@ -87,8 +89,8 @@ export class Log extends BaseFunction { return NumberValueObject.create(result); }); - if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { - return resultArray.getArrayValue()[0][0] as NumberValueObject; + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; } return resultArray; diff --git a/packages/engine-formula/src/functions/math/log10/index.ts b/packages/engine-formula/src/functions/math/log10/index.ts index 676b4f9190f..17b17d9c593 100644 --- a/packages/engine-formula/src/functions/math/log10/index.ts +++ b/packages/engine-formula/src/functions/math/log10/index.ts @@ -23,14 +23,16 @@ export class Log10 extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.log10(); + return _variant.log10(); } } diff --git a/packages/engine-formula/src/functions/math/mod/index.ts b/packages/engine-formula/src/functions/math/mod/index.ts index 900e6dc526e..e7a02ea8b0f 100644 --- a/packages/engine-formula/src/functions/math/mod/index.ts +++ b/packages/engine-formula/src/functions/math/mod/index.ts @@ -23,22 +23,26 @@ export class Mod extends BaseFunction { override maxParams = 2; override calculate(number: BaseValueObject, divisor: BaseValueObject) { - if (number.isString()) { - number = number.convertToNumberObjectValue(); + let _number = number; + + if (_number.isString()) { + _number = _number.convertToNumberObjectValue(); } - if (number.isError()) { - return number; + if (_number.isError()) { + return _number; } - if (divisor.isString()) { - divisor = divisor.convertToNumberObjectValue(); + let _divisor = divisor; + + if (_divisor.isString()) { + _divisor = _divisor.convertToNumberObjectValue(); } - if (divisor.isError()) { - return divisor; + if (_divisor.isError()) { + return _divisor; } - return number.mod(divisor); + return _number.mod(_divisor); } } diff --git a/packages/engine-formula/src/functions/math/mround/index.ts b/packages/engine-formula/src/functions/math/mround/index.ts index 828f160ae53..4316c9304d6 100644 --- a/packages/engine-formula/src/functions/math/mround/index.ts +++ b/packages/engine-formula/src/functions/math/mround/index.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { isRealNum } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; @@ -28,68 +27,51 @@ export class Mround extends BaseFunction { override maxParams = 2; override calculate(number: BaseValueObject, multiple: BaseValueObject) { - if (number.isError()) { - return number; - } - - if (multiple.isError()) { - return multiple; - } + let _number = number; - if (number.isArray()) { - const rowCount = (number as ArrayValueObject).getRowCount(); - const columnCount = (number as ArrayValueObject).getColumnCount(); + if (_number.isArray()) { + const rowCount = (_number as ArrayValueObject).getRowCount(); + const columnCount = (_number as ArrayValueObject).getColumnCount(); if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - number = (number as ArrayValueObject).get(0, 0) as BaseValueObject; + _number = (_number as ArrayValueObject).get(0, 0) as BaseValueObject; + } - if (number.isError()) { - return number; - } + if (_number.isError()) { + return _number; } - if (multiple.isArray()) { - const rowCount = (multiple as ArrayValueObject).getRowCount(); - const columnCount = (multiple as ArrayValueObject).getColumnCount(); + let _multiple = multiple; + + if (_multiple.isArray()) { + const rowCount = (_multiple as ArrayValueObject).getRowCount(); + const columnCount = (_multiple as ArrayValueObject).getColumnCount(); if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - multiple = (multiple as ArrayValueObject).get(0, 0) as BaseValueObject; - - if (multiple.isError()) { - return multiple; - } + _multiple = (_multiple as ArrayValueObject).get(0, 0) as BaseValueObject; } - let numberValue = number.getValue(); - - if (number.isNull()) { - numberValue = 0; + if (_multiple.isError()) { + return _multiple; } - if (!isRealNum(numberValue)) { + if (_number.isBoolean() || _multiple.isBoolean()) { return ErrorValueObject.create(ErrorType.VALUE); } - numberValue = +numberValue; - - let multipleValue = multiple.getValue(); + const numberValue = +_number.getValue(); + const multipleValue = +_multiple.getValue(); - if (multiple.isNull()) { - multipleValue = 0; - } - - if (!isRealNum(multipleValue)) { + if (Number.isNaN(numberValue) || Number.isNaN(multipleValue)) { return ErrorValueObject.create(ErrorType.VALUE); } - multipleValue = +multipleValue; - if (multipleValue === 0) { return NumberValueObject.create(0); } diff --git a/packages/engine-formula/src/functions/math/odd/index.ts b/packages/engine-formula/src/functions/math/odd/index.ts index be546fe3fd0..755cd30a342 100644 --- a/packages/engine-formula/src/functions/math/odd/index.ts +++ b/packages/engine-formula/src/functions/math/odd/index.ts @@ -27,37 +27,25 @@ export class Odd extends BaseFunction { override maxParams = 1; override calculate(number: BaseValueObject) { - if (number.isString()) { - number = number.convertToNumberObjectValue(); - } - - if (number.isError()) { - return number; - } - if (number.isArray()) { - return number.map((numberObject) => { - if (numberObject.isError()) { - return numberObject; - } - - return this._handleSingleObject(numberObject); - }); + return number.map((numberObject) => this._handleSingleObject(numberObject)); } return this._handleSingleObject(number); } private _handleSingleObject(number: BaseValueObject) { - if (number.isString()) { - number = number.convertToNumberObjectValue(); + let numberObject = number; + + if (numberObject.isString()) { + numberObject = numberObject.convertToNumberObjectValue(); } - if (number.isError()) { - return number; + if (numberObject.isError()) { + return numberObject; } - const numberValue = +number.getValue(); + const numberValue = +numberObject.getValue(); if (!Number.isFinite(numberValue)) { return ErrorValueObject.create(ErrorType.VALUE); diff --git a/packages/engine-formula/src/functions/math/power/index.ts b/packages/engine-formula/src/functions/math/power/index.ts index 6eb4e5c789d..2b9b37dba1c 100644 --- a/packages/engine-formula/src/functions/math/power/index.ts +++ b/packages/engine-formula/src/functions/math/power/index.ts @@ -23,22 +23,26 @@ export class Power extends BaseFunction { override maxParams = 2; override calculate(number: BaseValueObject, power: BaseValueObject) { - if (number.isString()) { - number = number.convertToNumberObjectValue(); + let _number = number; + + if (_number.isString()) { + _number = _number.convertToNumberObjectValue(); } - if (number.isError()) { - return number; + if (_number.isError()) { + return _number; } - if (power.isString()) { - power = power.convertToNumberObjectValue(); + let _power = power; + + if (_power.isString()) { + _power = _power.convertToNumberObjectValue(); } - if (power.isError()) { - return power; + if (_power.isError()) { + return _power; } - return number.pow(power); + return _number.pow(_power); } } diff --git a/packages/engine-formula/src/functions/math/radians/index.ts b/packages/engine-formula/src/functions/math/radians/index.ts index e28e2b099ce..16baf5276b7 100644 --- a/packages/engine-formula/src/functions/math/radians/index.ts +++ b/packages/engine-formula/src/functions/math/radians/index.ts @@ -26,37 +26,25 @@ export class Radians extends BaseFunction { override maxParams = 1; override calculate(angle: BaseValueObject) { - if (angle.isString()) { - angle = angle.convertToNumberObjectValue(); - } - - if (angle.isError()) { - return angle; - } - if (angle.isArray()) { - return angle.map((angleObject) => { - if (angleObject.isError()) { - return angleObject; - } - - return this._handleSingleObject(angleObject); - }); + return angle.map((angleObject) => this._handleSingleObject(angleObject)); } return this._handleSingleObject(angle); } private _handleSingleObject(angle: BaseValueObject) { - if (angle.isString()) { - angle = angle.convertToNumberObjectValue(); + let angleObject = angle; + + if (angleObject.isString()) { + angleObject = angleObject.convertToNumberObjectValue(); } - if (angle.isError()) { - return angle; + if (angleObject.isError()) { + return angleObject; } - const angleValue = +angle.getValue(); + const angleValue = +angleObject.getValue(); if (!Number.isFinite(angleValue)) { return ErrorValueObject.create(ErrorType.VALUE); diff --git a/packages/engine-formula/src/functions/math/randarray/index.ts b/packages/engine-formula/src/functions/math/randarray/index.ts index a89c953756d..8dc8d4158cd 100644 --- a/packages/engine-formula/src/functions/math/randarray/index.ts +++ b/packages/engine-formula/src/functions/math/randarray/index.ts @@ -47,28 +47,30 @@ export class Randarray extends BaseFunction { return wholeNumber; } - rows = rows ?? NumberValueObject.create(1); - columns = columns ?? NumberValueObject.create(1); - min = min ?? NumberValueObject.create(0); - max = max ?? NumberValueObject.create(1); - wholeNumber = wholeNumber ?? NumberValueObject.create(0); + const _rows = rows ?? NumberValueObject.create(1); + const _columns = columns ?? NumberValueObject.create(1); + const _min = min ?? NumberValueObject.create(0); + const _max = max ?? NumberValueObject.create(1); + const _wholeNumber = wholeNumber ?? NumberValueObject.create(0); - // get max row length + return this._calculateResult(_rows, _columns, _min, _max, _wholeNumber); + } + + private _calculateResult(rows: BaseValueObject, columns: BaseValueObject, min: BaseValueObject, max: BaseValueObject, wholeNumber: BaseValueObject) { const maxRowLength = Math.max( - rows?.isArray() ? (rows as ArrayValueObject).getRowCount() : 1, - columns?.isArray() ? (columns as ArrayValueObject).getRowCount() : 1, - min?.isArray() ? (min as ArrayValueObject).getRowCount() : 1, - max?.isArray() ? (max as ArrayValueObject).getRowCount() : 1, - wholeNumber?.isArray() ? (wholeNumber as ArrayValueObject).getRowCount() : 1 + rows.isArray() ? (rows as ArrayValueObject).getRowCount() : 1, + columns.isArray() ? (columns as ArrayValueObject).getRowCount() : 1, + min.isArray() ? (min as ArrayValueObject).getRowCount() : 1, + max.isArray() ? (max as ArrayValueObject).getRowCount() : 1, + wholeNumber.isArray() ? (wholeNumber as ArrayValueObject).getRowCount() : 1 ); - // get max column length const maxColumnLength = Math.max( - rows?.isArray() ? (rows as ArrayValueObject).getColumnCount() : 1, - columns?.isArray() ? (columns as ArrayValueObject).getColumnCount() : 1, - min?.isArray() ? (min as ArrayValueObject).getColumnCount() : 1, - max?.isArray() ? (max as ArrayValueObject).getColumnCount() : 1, - wholeNumber?.isArray() ? (wholeNumber as ArrayValueObject).getColumnCount() : 1 + rows.isArray() ? (rows as ArrayValueObject).getColumnCount() : 1, + columns.isArray() ? (columns as ArrayValueObject).getColumnCount() : 1, + min.isArray() ? (min as ArrayValueObject).getColumnCount() : 1, + max.isArray() ? (max as ArrayValueObject).getColumnCount() : 1, + wholeNumber.isArray() ? (wholeNumber as ArrayValueObject).getColumnCount() : 1 ); if (maxRowLength === 1 && maxColumnLength === 1) { @@ -89,8 +91,8 @@ export class Randarray extends BaseFunction { const _handleError = this._handleError(rowsObject, columnsObject, minObject, maxObject, wholeNumberObject); - if (_handleError.error) { - return _handleError.error; + if (_handleError.errorObject) { + return _handleError.errorObject; } let { minValue, maxValue, wholeNumberValue } = _handleError; @@ -114,31 +116,41 @@ export class Randarray extends BaseFunction { }); } - private _calculateSingleCell(rows?: BaseValueObject, columns?: BaseValueObject, min?: BaseValueObject, max?: BaseValueObject, wholeNumber?: BaseValueObject) { - if (rows?.isArray()) { - rows = (rows as ArrayValueObject).get(0, 0) as BaseValueObject; + private _calculateSingleCell(rows: BaseValueObject, columns: BaseValueObject, min: BaseValueObject, max: BaseValueObject, wholeNumber: BaseValueObject) { + let _rows = rows; + + if (_rows.isArray()) { + _rows = (_rows as ArrayValueObject).get(0, 0) as BaseValueObject; } - if (columns?.isArray()) { - columns = (columns as ArrayValueObject).get(0, 0) as BaseValueObject; + let _columns = columns; + + if (_columns.isArray()) { + _columns = (_columns as ArrayValueObject).get(0, 0) as BaseValueObject; } - if (min?.isArray()) { - min = (min as ArrayValueObject).get(0, 0) as BaseValueObject; + let _min = min; + + if (_min.isArray()) { + _min = (_min as ArrayValueObject).get(0, 0) as BaseValueObject; } - if (max?.isArray()) { - max = (max as ArrayValueObject).get(0, 0) as BaseValueObject; + let _max = max; + + if (_max.isArray()) { + _max = (_max as ArrayValueObject).get(0, 0) as BaseValueObject; } - if (wholeNumber?.isArray()) { - wholeNumber = (wholeNumber as ArrayValueObject).get(0, 0) as BaseValueObject; + let _wholeNumber = wholeNumber; + + if (_wholeNumber.isArray()) { + _wholeNumber = (_wholeNumber as ArrayValueObject).get(0, 0) as BaseValueObject; } - const _handleError = this._handleError(rows, columns, min, max, wholeNumber); + const _handleError = this._handleError(_rows, _columns, _min, _max, _wholeNumber); - if (_handleError.error) { - return _handleError.error; + if (_handleError.errorObject) { + return _handleError.errorObject; } let { rowsValue, columnsValue, minValue, maxValue, wholeNumberValue } = _handleError; @@ -175,85 +187,99 @@ export class Randarray extends BaseFunction { return ArrayValueObject.createByArray(result); } - private _handleError(rowsObject?: BaseValueObject, columnsObject?: BaseValueObject, minObject?: BaseValueObject, maxObject?: BaseValueObject, wholeNumberObject?: BaseValueObject) { - if (rowsObject?.isString()) { - rowsObject = rowsObject.convertToNumberObjectValue(); + private _handleError(rowsObject: BaseValueObject, columnsObject: BaseValueObject, minObject: BaseValueObject, maxObject: BaseValueObject, wholeNumberObject: BaseValueObject) { + let _rowsObject = rowsObject; + + if (_rowsObject.isString()) { + _rowsObject = _rowsObject.convertToNumberObjectValue(); } - if (rowsObject?.isError()) { + if (_rowsObject.isError()) { return { - error: rowsObject, + errorObject: _rowsObject, }; } - if (columnsObject?.isString()) { - columnsObject = columnsObject.convertToNumberObjectValue(); + let _columnsObject = columnsObject; + + if (_columnsObject.isString()) { + _columnsObject = _columnsObject.convertToNumberObjectValue(); } - if (columnsObject?.isError()) { + if (_columnsObject.isError()) { return { - error: columnsObject, + errorObject: _columnsObject, }; } - if (minObject?.isString()) { - minObject = minObject.convertToNumberObjectValue(); + let _minObject = minObject; + + if (_minObject.isString()) { + _minObject = _minObject.convertToNumberObjectValue(); } - if (minObject?.isError()) { + if (_minObject.isError()) { return { - error: minObject, + errorObject: _minObject, }; } - if (maxObject?.isString()) { - maxObject = maxObject.convertToNumberObjectValue(); + let _maxObject = maxObject; + + if (_maxObject.isString()) { + _maxObject = _maxObject.convertToNumberObjectValue(); } - if (maxObject?.isError()) { + if (_maxObject.isError()) { return { - error: maxObject, + errorObject: _maxObject, }; } - if (wholeNumberObject?.isString()) { - wholeNumberObject = wholeNumberObject.convertToNumberObjectValue(); + let _wholeNumberObject = wholeNumberObject; + + if (_wholeNumberObject.isString()) { + _wholeNumberObject = _wholeNumberObject.convertToNumberObjectValue(); } - if (wholeNumberObject?.isError()) { + if (_wholeNumberObject.isError()) { return { - error: wholeNumberObject, + errorObject: _wholeNumberObject, }; } - const rowsValue = rowsObject ? Math.floor(+rowsObject.getValue()) : 1; - const columnsValue = columnsObject ? Math.floor(+columnsObject.getValue()) : 1; + return this._getValue(_rowsObject, _columnsObject, _minObject, _maxObject, _wholeNumberObject); + } + + private _getValue(rowsObject: BaseValueObject, columnsObject: BaseValueObject, minObject: BaseValueObject, maxObject: BaseValueObject, wholeNumberObject: BaseValueObject) { + const rowsValue = Math.floor(+rowsObject.getValue()); + const columnsValue = Math.floor(+columnsObject.getValue()); if (rowsValue === 0 || columnsValue === 0) { return { - error: ErrorValueObject.create(ErrorType.CALC), + errorObject: ErrorValueObject.create(ErrorType.CALC), }; } if (rowsValue < 0 || columnsValue < 0) { return { - error: ErrorValueObject.create(ErrorType.VALUE), + errorObject: ErrorValueObject.create(ErrorType.VALUE), }; } - const minValue = minObject ? +minObject.getValue() : 0; - const maxValue = maxObject ? +maxObject.getValue() : 1; - const wholeNumberValue = wholeNumberObject ? +wholeNumberObject.getValue() : 0; + const minValue = +minObject.getValue(); + const maxValue = +maxObject.getValue(); + const wholeNumberValue = +wholeNumberObject.getValue(); if (minValue > maxValue) { return { - error: ErrorValueObject.create(ErrorType.VALUE), + errorObject: ErrorValueObject.create(ErrorType.VALUE), }; } if (wholeNumberValue && (!Number.isInteger(minValue) || !Number.isInteger(maxValue))) { return { - error: ErrorValueObject.create(ErrorType.VALUE), + errorObject: ErrorValueObject.create(ErrorType.VALUE), }; } diff --git a/packages/engine-formula/src/functions/math/randbetween/index.ts b/packages/engine-formula/src/functions/math/randbetween/index.ts index e76ef6fc00d..9dcc2970ebe 100644 --- a/packages/engine-formula/src/functions/math/randbetween/index.ts +++ b/packages/engine-formula/src/functions/math/randbetween/index.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { isRealNum } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; @@ -27,61 +26,48 @@ export class Randbetween extends BaseFunction { override maxParams = 2; override calculate(bottom: BaseValueObject, top: BaseValueObject) { - if (bottom.isError()) { - return bottom; - } - - if (top.isError()) { - return top; - } + let _bottom = bottom; - if (bottom.isArray()) { - const rowCount = (bottom as ArrayValueObject).getRowCount(); - const columnCount = (bottom as ArrayValueObject).getColumnCount(); + if (_bottom.isArray()) { + const rowCount = (_bottom as ArrayValueObject).getRowCount(); + const columnCount = (_bottom as ArrayValueObject).getColumnCount(); if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - bottom = (bottom as ArrayValueObject).get(0, 0) as BaseValueObject; + _bottom = (_bottom as ArrayValueObject).get(0, 0) as BaseValueObject; + } - if (bottom.isError()) { - return bottom; - } + if (_bottom.isError()) { + return _bottom; } - if (top.isArray()) { - const rowCount = (top as ArrayValueObject).getRowCount(); - const columnCount = (top as ArrayValueObject).getColumnCount(); + let _top = top; + + if (_top.isArray()) { + const rowCount = (_top as ArrayValueObject).getRowCount(); + const columnCount = (_top as ArrayValueObject).getColumnCount(); if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - top = (top as ArrayValueObject).get(0, 0) as BaseValueObject; - - if (top.isError()) { - return top; - } + _top = (_top as ArrayValueObject).get(0, 0) as BaseValueObject; } - let bottomValue = bottom.getValue(); - - if (bottom.isNull()) { - bottomValue = 0; + if (_top.isError()) { + return _top; } - if (!isRealNum(bottomValue)) { + if (_bottom.isBoolean() || _top.isBoolean()) { return ErrorValueObject.create(ErrorType.VALUE); } - let topValue = top.getValue(); - - if (top.isNull()) { - topValue = 0; - } + let bottomValue = +_bottom.getValue(); + let topValue = +_top.getValue(); - if (!isRealNum(topValue)) { + if (Number.isNaN(bottomValue) || Number.isNaN(topValue)) { return ErrorValueObject.create(ErrorType.VALUE); } diff --git a/packages/engine-formula/src/functions/math/round/index.ts b/packages/engine-formula/src/functions/math/round/index.ts index ec35d57769b..6027ee1d2a6 100644 --- a/packages/engine-formula/src/functions/math/round/index.ts +++ b/packages/engine-formula/src/functions/math/round/index.ts @@ -23,23 +23,27 @@ export class Round extends BaseFunction { override maxParams = 2; override calculate(number: BaseValueObject, numDigits: BaseValueObject) { - if (number.isString()) { - number = number.convertToNumberObjectValue(); + let _number = number; + + if (_number.isString()) { + _number = _number.convertToNumberObjectValue(); } - if (number.isError()) { - return number; + if (_number.isError()) { + return _number; } - if (numDigits.isString()) { - numDigits = numDigits.convertToNumberObjectValue(); + let _numDigits = numDigits; + + if (_numDigits.isString()) { + _numDigits = _numDigits.convertToNumberObjectValue(); } - if (numDigits.isError()) { - return numDigits; + if (_numDigits.isError()) { + return _numDigits; } // Note that the order of parameters is different from JavaScript - return number.round(numDigits); + return _number.round(_numDigits); } } diff --git a/packages/engine-formula/src/functions/math/rounddown/index.ts b/packages/engine-formula/src/functions/math/rounddown/index.ts index c4271a3e77d..a986203109a 100644 --- a/packages/engine-formula/src/functions/math/rounddown/index.ts +++ b/packages/engine-formula/src/functions/math/rounddown/index.ts @@ -23,23 +23,27 @@ export class Rounddown extends BaseFunction { override maxParams = 2; override calculate(number: BaseValueObject, numDigits: BaseValueObject) { - if (number.isString()) { - number = number.convertToNumberObjectValue(); + let _number = number; + + if (_number.isString()) { + _number = _number.convertToNumberObjectValue(); } - if (number.isError()) { - return number; + if (_number.isError()) { + return _number; } - if (numDigits.isString()) { - numDigits = numDigits.convertToNumberObjectValue(); + let _numDigits = numDigits; + + if (_numDigits.isString()) { + _numDigits = _numDigits.convertToNumberObjectValue(); } - if (numDigits.isError()) { - return numDigits; + if (_numDigits.isError()) { + return _numDigits; } // Note that the order of parameters is different from JavaScript - return number.floor(numDigits); + return _number.floor(_numDigits); } } diff --git a/packages/engine-formula/src/functions/math/roundup/index.ts b/packages/engine-formula/src/functions/math/roundup/index.ts index 70892faffd4..d2009420bb7 100644 --- a/packages/engine-formula/src/functions/math/roundup/index.ts +++ b/packages/engine-formula/src/functions/math/roundup/index.ts @@ -23,23 +23,27 @@ export class Roundup extends BaseFunction { override maxParams = 2; override calculate(number: BaseValueObject, numDigits: BaseValueObject) { - if (number.isString()) { - number = number.convertToNumberObjectValue(); + let _number = number; + + if (_number.isString()) { + _number = _number.convertToNumberObjectValue(); } - if (number.isError()) { - return number; + if (_number.isError()) { + return _number; } - if (numDigits.isString()) { - numDigits = numDigits.convertToNumberObjectValue(); + let _numDigits = numDigits; + + if (_numDigits.isString()) { + _numDigits = _numDigits.convertToNumberObjectValue(); } - if (numDigits.isError()) { - return numDigits; + if (_numDigits.isError()) { + return _numDigits; } // Note that the order of parameters is different from JavaScript - return number.ceil(numDigits); + return _number.ceil(_numDigits); } } diff --git a/packages/engine-formula/src/functions/math/sec/index.ts b/packages/engine-formula/src/functions/math/sec/index.ts index 5b5080ab125..9b4d88f0170 100644 --- a/packages/engine-formula/src/functions/math/sec/index.ts +++ b/packages/engine-formula/src/functions/math/sec/index.ts @@ -25,38 +25,30 @@ export class Sec extends BaseFunction { override maxParams = 1; override calculate(number: BaseValueObject) { - if (number.isString()) { - number = number.convertToNumberObjectValue(); - } - - if (number.isError()) { - return number; - } - if (number.isArray()) { - return number.map((numberObject) => { - if (numberObject.isString()) { - numberObject = numberObject.convertToNumberObjectValue(); - } - - if (numberObject.isError()) { - return numberObject; - } - - return this._handleSingleObject(numberObject); - }); + return number.map((numberObject) => this._handleSingleObject(numberObject)); } return this._handleSingleObject(number); } private _handleSingleObject(number: BaseValueObject) { - const numberValue = +number.getValue(); + let numberObject = number; + + if (numberObject.isString()) { + numberObject = numberObject.convertToNumberObjectValue(); + } + + if (numberObject.isError()) { + return numberObject; + } + + const numberValue = +numberObject.getValue(); if (Math.abs(numberValue) >= 2 ** 27) { return ErrorValueObject.create(ErrorType.NUM); } - return number.cos().getReciprocal(); + return numberObject.cos().getReciprocal(); } } diff --git a/packages/engine-formula/src/functions/math/sech/index.ts b/packages/engine-formula/src/functions/math/sech/index.ts index af9e422f08d..9a6e6b42df7 100644 --- a/packages/engine-formula/src/functions/math/sech/index.ts +++ b/packages/engine-formula/src/functions/math/sech/index.ts @@ -26,33 +26,25 @@ export class Sech extends BaseFunction { override maxParams = 1; override calculate(number: BaseValueObject) { - if (number.isString()) { - number = number.convertToNumberObjectValue(); - } - - if (number.isError()) { - return number; - } - if (number.isArray()) { - return number.map((numberObject) => { - if (numberObject.isString()) { - numberObject = numberObject.convertToNumberObjectValue(); - } - - if (numberObject.isError()) { - return numberObject; - } - - return this._handleSingleObject(numberObject); - }); + return number.map((numberObject) => this._handleSingleObject(numberObject)); } return this._handleSingleObject(number); } private _handleSingleObject(number: BaseValueObject) { - const numberValue = +number.getValue(); + let numberObject = number; + + if (numberObject.isString()) { + numberObject = numberObject.convertToNumberObjectValue(); + } + + if (numberObject.isError()) { + return numberObject; + } + + const numberValue = +numberObject.getValue(); if (!Number.isFinite(Math.cosh(numberValue))) { return NumberValueObject.create(0); @@ -62,6 +54,6 @@ export class Sech extends BaseFunction { return ErrorValueObject.create(ErrorType.NUM); } - return number.cosh().getReciprocal(); + return numberObject.cosh().getReciprocal(); } } diff --git a/packages/engine-formula/src/functions/math/sin/index.ts b/packages/engine-formula/src/functions/math/sin/index.ts index 73702b7f947..d5ff4ca1ff9 100644 --- a/packages/engine-formula/src/functions/math/sin/index.ts +++ b/packages/engine-formula/src/functions/math/sin/index.ts @@ -23,14 +23,16 @@ export class Sin extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.sin(); + return _variant.sin(); } } diff --git a/packages/engine-formula/src/functions/math/sinh/index.ts b/packages/engine-formula/src/functions/math/sinh/index.ts index 05598c2fd10..98a61101e8c 100644 --- a/packages/engine-formula/src/functions/math/sinh/index.ts +++ b/packages/engine-formula/src/functions/math/sinh/index.ts @@ -23,14 +23,16 @@ export class Sinh extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.sinh(); + return _variant.sinh(); } } diff --git a/packages/engine-formula/src/functions/math/sqrt/index.ts b/packages/engine-formula/src/functions/math/sqrt/index.ts index fb29d48d233..94456428f88 100644 --- a/packages/engine-formula/src/functions/math/sqrt/index.ts +++ b/packages/engine-formula/src/functions/math/sqrt/index.ts @@ -23,14 +23,16 @@ export class Sqrt extends BaseFunction { override maxParams = 1; override calculate(number: BaseValueObject) { - if (number.isString()) { - number = number.convertToNumberObjectValue(); + let _number = number; + + if (_number.isString()) { + _number = _number.convertToNumberObjectValue(); } - if (number.isError()) { - return number; + if (_number.isError()) { + return _number; } - return number.sqrt(); + return _number.sqrt(); } } diff --git a/packages/engine-formula/src/functions/math/sqrtpi/index.ts b/packages/engine-formula/src/functions/math/sqrtpi/index.ts index 9322f2967c1..81cf3997008 100644 --- a/packages/engine-formula/src/functions/math/sqrtpi/index.ts +++ b/packages/engine-formula/src/functions/math/sqrtpi/index.ts @@ -26,26 +26,28 @@ export class Sqrtpi extends BaseFunction { override maxParams = 1; override calculate(number: BaseValueObject) { - if (number.isArray()) { - const rowCount = (number as ArrayValueObject).getRowCount(); - const columnCount = (number as ArrayValueObject).getColumnCount(); + let _number = number; + + if (_number.isArray()) { + const rowCount = (_number as ArrayValueObject).getRowCount(); + const columnCount = (_number as ArrayValueObject).getColumnCount(); if (rowCount > 1 || columnCount > 1) { return ErrorValueObject.create(ErrorType.VALUE); } - number = (number as ArrayValueObject).get(0, 0) as BaseValueObject; + _number = (_number as ArrayValueObject).get(0, 0) as BaseValueObject; } - if (number.isString()) { - number = number.convertToNumberObjectValue(); + if (_number.isString()) { + _number = _number.convertToNumberObjectValue(); } - if (number.isError()) { - return number; + if (_number.isError()) { + return _number; } - const numberValue = +number.getValue(); + const numberValue = +_number.getValue(); if (numberValue < 0) { return ErrorValueObject.create(ErrorType.NUM); diff --git a/packages/engine-formula/src/functions/math/sumproduct/index.ts b/packages/engine-formula/src/functions/math/sumproduct/index.ts index eb635b952fc..ac7d2c967e2 100644 --- a/packages/engine-formula/src/functions/math/sumproduct/index.ts +++ b/packages/engine-formula/src/functions/math/sumproduct/index.ts @@ -32,45 +32,18 @@ export class Sumproduct extends BaseFunction { return array1; } - if (!array1.isArray()) { - array1 = ArrayValueObject.create({ - calculateValueList: [[array1]], - rowCount: 1, - columnCount: 1, - unitId: '', - sheetId: '', - row: 0, - column: 0, - }); - } + const _array1 = this._initArray1(array1); if (variants.length > 0) { - const rowCount = (array1 as ArrayValueObject).getRowCount(); - const columnCount = (array1 as ArrayValueObject).getColumnCount(); - - const resultArray: number[][] = []; + const rowCount = _array1.getRowCount(); + const columnCount = _array1.getColumnCount(); - for (let r = 0; r < rowCount; r++) { - const row: number[] = []; + let resultArray = this._getResultArrayByArray1(rowCount, columnCount, _array1); - for (let c = 0; c < columnCount; c++) { - const array1ValueObject = (array1 as ArrayValueObject).get(r, c) as BaseValueObject; - - if (array1ValueObject.isError()) { - return array1ValueObject; - } - - const array1Value = array1ValueObject.getValue(); - - if (!array1Value || !isRealNum(array1Value)) { - row.push(0); - } else { - row.push(+array1Value); - } - } - - resultArray.push(row); + if (resultArray instanceof ErrorValueObject) { + return resultArray; } + resultArray = resultArray as number[][]; for (let i = 0; i < variants.length; i++) { if (variants[i].isError()) { @@ -120,7 +93,53 @@ export class Sumproduct extends BaseFunction { return NumberValueObject.create(result); } else { - return array1.sum(); + return _array1.sum(); } } + + private _initArray1(array1: BaseValueObject): ArrayValueObject { + let _array1 = array1; + + if (!_array1.isArray()) { + _array1 = ArrayValueObject.create({ + calculateValueList: [[_array1]], + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + } + + return _array1 as ArrayValueObject; + } + + private _getResultArrayByArray1(rowCount: number, columnCount: number, array1: ArrayValueObject) { + const resultArray: number[][] = []; + + for (let r = 0; r < rowCount; r++) { + const row: number[] = []; + + for (let c = 0; c < columnCount; c++) { + const array1ValueObject = array1.get(r, c) as BaseValueObject; + + if (array1ValueObject.isError()) { + return array1ValueObject; + } + + const array1Value = array1ValueObject.getValue(); + + if (!array1Value || !isRealNum(array1Value)) { + row.push(0); + } else { + row.push(+array1Value); + } + } + + resultArray.push(row); + } + + return resultArray; + } } diff --git a/packages/engine-formula/src/functions/math/sumx2my2/index.ts b/packages/engine-formula/src/functions/math/sumx2my2/index.ts index ec47a0337c7..5ec1039270e 100644 --- a/packages/engine-formula/src/functions/math/sumx2my2/index.ts +++ b/packages/engine-formula/src/functions/math/sumx2my2/index.ts @@ -35,23 +35,13 @@ export class Sumx2my2 extends BaseFunction { return arrayY; } - let arrayXRowCount = 1; - let arrayXColumnCount = 1; - - if (arrayX.isArray()) { - arrayXRowCount = (arrayX as ArrayValueObject).getRowCount(); - arrayXColumnCount = (arrayX as ArrayValueObject).getColumnCount(); - } + const arrayXRowCount = arrayX.isArray() ? (arrayX as ArrayValueObject).getRowCount() : 1; + const arrayXColumnCount = arrayX.isArray() ? (arrayX as ArrayValueObject).getColumnCount() : 1; const arrayXCount = arrayXRowCount * arrayXColumnCount; - let arrayYRowCount = 1; - let arrayYColumnCount = 1; - - if (arrayY.isArray()) { - arrayYRowCount = (arrayY as ArrayValueObject).getRowCount(); - arrayYColumnCount = (arrayY as ArrayValueObject).getColumnCount(); - } + const arrayYRowCount = arrayY.isArray() ? (arrayY as ArrayValueObject).getRowCount() : 1; + const arrayYColumnCount = arrayY.isArray() ? (arrayY as ArrayValueObject).getColumnCount() : 1; const arrayYCount = arrayYRowCount * arrayYColumnCount; @@ -60,36 +50,7 @@ export class Sumx2my2 extends BaseFunction { } if (arrayXCount === 1) { - if (arrayX.isArray()) { - arrayX = (arrayX as ArrayValueObject).get(0, 0) as BaseValueObject; - } - - if (arrayY.isArray()) { - arrayY = (arrayY as ArrayValueObject).get(0, 0) as BaseValueObject; - } - - if (arrayX.isError()) { - return arrayX; - } - - if (arrayY.isError()) { - return arrayY; - } - - if (arrayX.isNull() || arrayY.isNull()) { - return ErrorValueObject.create(ErrorType.VALUE); - } - - const arrayXValue = +arrayX.getValue(); - const arrayYValue = +arrayY.getValue(); - - if ((arrayX.isString() && !isRealNum(arrayXValue)) || arrayX.isBoolean() || (arrayY.isString() && !isRealNum(arrayYValue)) || arrayY.isBoolean()) { - return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); - } - - const result = arrayXValue ** 2 - arrayYValue ** 2; - - return NumberValueObject.create(result); + return this._calculateSingleCell(arrayX, arrayY); } else { const arrayXFlatten = (arrayX as ArrayValueObject).flatten(); const arrayYFlatten = (arrayY as ArrayValueObject).flatten(); @@ -140,4 +101,41 @@ export class Sumx2my2 extends BaseFunction { return NumberValueObject.create(result); } } + + private _calculateSingleCell(arrayX: BaseValueObject, arrayY: BaseValueObject) { + let _arrayX = arrayX; + + if (_arrayX.isArray()) { + _arrayX = (_arrayX as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_arrayX.isError()) { + return _arrayX; + } + + let _arrayY = arrayY; + + if (_arrayY.isArray()) { + _arrayY = (_arrayY as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_arrayY.isError()) { + return _arrayY; + } + + if (_arrayX.isNull() || _arrayY.isNull()) { + return ErrorValueObject.create(ErrorType.VALUE); + } + + const arrayXValue = +_arrayX.getValue(); + const arrayYValue = +_arrayY.getValue(); + + if ((_arrayX.isString() && !isRealNum(arrayXValue)) || _arrayX.isBoolean() || (_arrayY.isString() && !isRealNum(arrayYValue)) || _arrayY.isBoolean()) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + const result = arrayXValue ** 2 - arrayYValue ** 2; + + return NumberValueObject.create(result); + } } diff --git a/packages/engine-formula/src/functions/math/sumx2py2/index.ts b/packages/engine-formula/src/functions/math/sumx2py2/index.ts index 38cd8226e38..b2a1f535fbf 100644 --- a/packages/engine-formula/src/functions/math/sumx2py2/index.ts +++ b/packages/engine-formula/src/functions/math/sumx2py2/index.ts @@ -35,23 +35,13 @@ export class Sumx2py2 extends BaseFunction { return arrayY; } - let arrayXRowCount = 1; - let arrayXColumnCount = 1; - - if (arrayX.isArray()) { - arrayXRowCount = (arrayX as ArrayValueObject).getRowCount(); - arrayXColumnCount = (arrayX as ArrayValueObject).getColumnCount(); - } + const arrayXRowCount = arrayX.isArray() ? (arrayX as ArrayValueObject).getRowCount() : 1; + const arrayXColumnCount = arrayX.isArray() ? (arrayX as ArrayValueObject).getColumnCount() : 1; const arrayXCount = arrayXRowCount * arrayXColumnCount; - let arrayYRowCount = 1; - let arrayYColumnCount = 1; - - if (arrayY.isArray()) { - arrayYRowCount = (arrayY as ArrayValueObject).getRowCount(); - arrayYColumnCount = (arrayY as ArrayValueObject).getColumnCount(); - } + const arrayYRowCount = arrayY.isArray() ? (arrayY as ArrayValueObject).getRowCount() : 1; + const arrayYColumnCount = arrayY.isArray() ? (arrayY as ArrayValueObject).getColumnCount() : 1; const arrayYCount = arrayYRowCount * arrayYColumnCount; @@ -60,36 +50,7 @@ export class Sumx2py2 extends BaseFunction { } if (arrayXCount === 1) { - if (arrayX.isArray()) { - arrayX = (arrayX as ArrayValueObject).get(0, 0) as BaseValueObject; - } - - if (arrayY.isArray()) { - arrayY = (arrayY as ArrayValueObject).get(0, 0) as BaseValueObject; - } - - if (arrayX.isError()) { - return arrayX; - } - - if (arrayY.isError()) { - return arrayY; - } - - if (arrayX.isNull() || arrayY.isNull()) { - return ErrorValueObject.create(ErrorType.VALUE); - } - - const arrayXValue = +arrayX.getValue(); - const arrayYValue = +arrayY.getValue(); - - if ((arrayX.isString() && !isRealNum(arrayXValue)) || arrayX.isBoolean() || (arrayY.isString() && !isRealNum(arrayYValue)) || arrayY.isBoolean()) { - return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); - } - - const result = arrayXValue ** 2 + arrayYValue ** 2; - - return NumberValueObject.create(result); + return this._calculateSingleCell(arrayX, arrayY); } else { const arrayXFlatten = (arrayX as ArrayValueObject).flatten(); const arrayYFlatten = (arrayY as ArrayValueObject).flatten(); @@ -140,4 +101,41 @@ export class Sumx2py2 extends BaseFunction { return NumberValueObject.create(result); } } + + private _calculateSingleCell(arrayX: BaseValueObject, arrayY: BaseValueObject) { + let _arrayX = arrayX; + + if (_arrayX.isArray()) { + _arrayX = (_arrayX as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_arrayX.isError()) { + return _arrayX; + } + + let _arrayY = arrayY; + + if (_arrayY.isArray()) { + _arrayY = (_arrayY as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_arrayY.isError()) { + return _arrayY; + } + + if (_arrayX.isNull() || _arrayY.isNull()) { + return ErrorValueObject.create(ErrorType.VALUE); + } + + const arrayXValue = +_arrayX.getValue(); + const arrayYValue = +_arrayY.getValue(); + + if ((_arrayX.isString() && !isRealNum(arrayXValue)) || _arrayX.isBoolean() || (_arrayY.isString() && !isRealNum(arrayYValue)) || _arrayY.isBoolean()) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + const result = arrayXValue ** 2 + arrayYValue ** 2; + + return NumberValueObject.create(result); + } } diff --git a/packages/engine-formula/src/functions/math/sumxmy2/index.ts b/packages/engine-formula/src/functions/math/sumxmy2/index.ts index b6881b25f18..f41942011c1 100644 --- a/packages/engine-formula/src/functions/math/sumxmy2/index.ts +++ b/packages/engine-formula/src/functions/math/sumxmy2/index.ts @@ -35,23 +35,13 @@ export class Sumxmy2 extends BaseFunction { return arrayY; } - let arrayXRowCount = 1; - let arrayXColumnCount = 1; - - if (arrayX.isArray()) { - arrayXRowCount = (arrayX as ArrayValueObject).getRowCount(); - arrayXColumnCount = (arrayX as ArrayValueObject).getColumnCount(); - } + const arrayXRowCount = arrayX.isArray() ? (arrayX as ArrayValueObject).getRowCount() : 1; + const arrayXColumnCount = arrayX.isArray() ? (arrayX as ArrayValueObject).getColumnCount() : 1; const arrayXCount = arrayXRowCount * arrayXColumnCount; - let arrayYRowCount = 1; - let arrayYColumnCount = 1; - - if (arrayY.isArray()) { - arrayYRowCount = (arrayY as ArrayValueObject).getRowCount(); - arrayYColumnCount = (arrayY as ArrayValueObject).getColumnCount(); - } + const arrayYRowCount = arrayY.isArray() ? (arrayY as ArrayValueObject).getRowCount() : 1; + const arrayYColumnCount = arrayY.isArray() ? (arrayY as ArrayValueObject).getColumnCount() : 1; const arrayYCount = arrayYRowCount * arrayYColumnCount; @@ -60,36 +50,7 @@ export class Sumxmy2 extends BaseFunction { } if (arrayXCount === 1) { - if (arrayX.isArray()) { - arrayX = (arrayX as ArrayValueObject).get(0, 0) as BaseValueObject; - } - - if (arrayY.isArray()) { - arrayY = (arrayY as ArrayValueObject).get(0, 0) as BaseValueObject; - } - - if (arrayX.isError()) { - return arrayX; - } - - if (arrayY.isError()) { - return arrayY; - } - - if (arrayX.isNull() || arrayY.isNull()) { - return ErrorValueObject.create(ErrorType.VALUE); - } - - const arrayXValue = +arrayX.getValue(); - const arrayYValue = +arrayY.getValue(); - - if ((arrayX.isString() && !isRealNum(arrayXValue)) || arrayX.isBoolean() || (arrayY.isString() && !isRealNum(arrayYValue)) || arrayY.isBoolean()) { - return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); - } - - const result = (arrayXValue - arrayYValue) ** 2; - - return NumberValueObject.create(result); + return this._calculateSingleCell(arrayX, arrayY); } else { const arrayXFlatten = (arrayX as ArrayValueObject).flatten(); const arrayYFlatten = (arrayY as ArrayValueObject).flatten(); @@ -140,4 +101,41 @@ export class Sumxmy2 extends BaseFunction { return NumberValueObject.create(result); } } + + private _calculateSingleCell(arrayX: BaseValueObject, arrayY: BaseValueObject) { + let _arrayX = arrayX; + + if (_arrayX.isArray()) { + _arrayX = (_arrayX as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_arrayX.isError()) { + return _arrayX; + } + + let _arrayY = arrayY; + + if (_arrayY.isArray()) { + _arrayY = (_arrayY as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_arrayY.isError()) { + return _arrayY; + } + + if (_arrayX.isNull() || _arrayY.isNull()) { + return ErrorValueObject.create(ErrorType.VALUE); + } + + const arrayXValue = +_arrayX.getValue(); + const arrayYValue = +_arrayY.getValue(); + + if ((_arrayX.isString() && !isRealNum(arrayXValue)) || _arrayX.isBoolean() || (_arrayY.isString() && !isRealNum(arrayYValue)) || _arrayY.isBoolean()) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + const result = (arrayXValue - arrayYValue) ** 2; + + return NumberValueObject.create(result); + } } diff --git a/packages/engine-formula/src/functions/math/tan/index.ts b/packages/engine-formula/src/functions/math/tan/index.ts index 210ec2f1135..617b94859fb 100644 --- a/packages/engine-formula/src/functions/math/tan/index.ts +++ b/packages/engine-formula/src/functions/math/tan/index.ts @@ -23,14 +23,16 @@ export class Tan extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.tan(); + return _variant.tan(); } } diff --git a/packages/engine-formula/src/functions/math/tanh/index.ts b/packages/engine-formula/src/functions/math/tanh/index.ts index 468fc85681b..01321ffe606 100644 --- a/packages/engine-formula/src/functions/math/tanh/index.ts +++ b/packages/engine-formula/src/functions/math/tanh/index.ts @@ -23,14 +23,16 @@ export class Tanh extends BaseFunction { override maxParams = 1; override calculate(variant: BaseValueObject) { - if (variant.isString()) { - variant = variant.convertToNumberObjectValue(); + let _variant = variant; + + if (_variant.isString()) { + _variant = _variant.convertToNumberObjectValue(); } - if (variant.isError()) { - return variant; + if (_variant.isError()) { + return _variant; } - return variant.tanh(); + return _variant.tanh(); } } diff --git a/packages/engine-formula/src/functions/math/trunc/index.ts b/packages/engine-formula/src/functions/math/trunc/index.ts index 57384d89bc0..0b9d410a72e 100644 --- a/packages/engine-formula/src/functions/math/trunc/index.ts +++ b/packages/engine-formula/src/functions/math/trunc/index.ts @@ -28,30 +28,32 @@ export class Trunc extends BaseFunction { override maxParams = 2; override calculate(number: BaseValueObject, numDigits?: BaseValueObject) { - numDigits = numDigits ?? NumberValueObject.create(0); + const _numDigits = numDigits ?? NumberValueObject.create(0); const maxRowLength = Math.max( number.isArray() ? (number as ArrayValueObject).getRowCount() : 1, - numDigits.isArray() ? (numDigits as ArrayValueObject).getRowCount() : 1 + _numDigits.isArray() ? (_numDigits as ArrayValueObject).getRowCount() : 1 ); const maxColumnLength = Math.max( number.isArray() ? (number as ArrayValueObject).getColumnCount() : 1, - numDigits.isArray() ? (numDigits as ArrayValueObject).getColumnCount() : 1 + _numDigits.isArray() ? (_numDigits as ArrayValueObject).getColumnCount() : 1 ); const numberArray = expandArrayValueObject(maxRowLength, maxColumnLength, number, ErrorValueObject.create(ErrorType.NA)); - const numDigitsArray = expandArrayValueObject(maxRowLength, maxColumnLength, numDigits, ErrorValueObject.create(ErrorType.NA)); + const numDigitsArray = expandArrayValueObject(maxRowLength, maxColumnLength, _numDigits, ErrorValueObject.create(ErrorType.NA)); const resultArray = numberArray.map((numberObject, rowIndex, columnIndex) => { let numDigitsObject = numDigitsArray.get(rowIndex, columnIndex) as BaseValueObject; - if (numberObject.isString()) { - numberObject = numberObject.convertToNumberObjectValue(); + let _numberObject = numberObject; + + if (_numberObject.isString()) { + _numberObject = _numberObject.convertToNumberObjectValue(); } - if (numberObject.isError()) { - return numberObject; + if (_numberObject.isError()) { + return _numberObject; } if (numDigitsObject.isString()) { @@ -62,7 +64,7 @@ export class Trunc extends BaseFunction { return numDigitsObject; } - const numberValue = +numberObject.getValue(); + const numberValue = +_numberObject.getValue(); const numDigitsValue = +numDigitsObject.getValue(); const factor = 10 ** Math.trunc(numDigitsValue); diff --git a/packages/engine-formula/src/functions/statistical/averagea/index.ts b/packages/engine-formula/src/functions/statistical/averagea/index.ts index 42e6a0aeca5..737e710b351 100644 --- a/packages/engine-formula/src/functions/statistical/averagea/index.ts +++ b/packages/engine-formula/src/functions/statistical/averagea/index.ts @@ -44,23 +44,26 @@ export class Averagea extends BaseFunction { return true; // continue } - if (valueObject.isString()) { - valueObject = valueObject.convertToNumberObjectValue(); - if (valueObject.isError()) { - valueObject = NumberValueObject.create(0); + let _valueObject = valueObject; + + if (_valueObject.isString()) { + _valueObject = _valueObject.convertToNumberObjectValue(); + + if (_valueObject.isError()) { + _valueObject = NumberValueObject.create(0); } } - if (valueObject.isBoolean()) { - valueObject = valueObject.convertToNumberObjectValue(); + if (_valueObject.isBoolean()) { + _valueObject = _valueObject.convertToNumberObjectValue(); } - if (valueObject.isError()) { - accumulatorSum = valueObject; + if (_valueObject.isError()) { + accumulatorSum = _valueObject; return false; // break } - accumulatorSum = accumulatorSum.plus(valueObject); + accumulatorSum = accumulatorSum.plus(_valueObject); accumulatorCount = accumulatorCount.plus(NumberValueObject.create(1)); }); diff --git a/packages/engine-formula/src/functions/statistical/averageif/index.ts b/packages/engine-formula/src/functions/statistical/averageif/index.ts index 441f78eb176..4ce59bb0b64 100644 --- a/packages/engine-formula/src/functions/statistical/averageif/index.ts +++ b/packages/engine-formula/src/functions/statistical/averageif/index.ts @@ -43,29 +43,33 @@ export class Averageif extends BaseFunction { return averageRange; } - if (range.isReferenceObject()) { - range = (range as BaseReferenceObject).toArrayValueObject(); + let _range = range; + + if (_range.isReferenceObject()) { + _range = (_range as BaseReferenceObject).toArrayValueObject(); } - if (!range.isArray()) { - range = createNewArray([[range as BaseValueObject]], 1, 1); + if (!_range.isArray()) { + _range = createNewArray([[_range as BaseValueObject]], 1, 1); } - if (criteria.isReferenceObject()) { - criteria = (criteria as BaseReferenceObject).toArrayValueObject(); + let _criteria = criteria; + + if (_criteria.isReferenceObject()) { + _criteria = (_criteria as BaseReferenceObject).toArrayValueObject(); } if (averageRange && !averageRange?.isReferenceObject()) { return ErrorValueObject.create(ErrorType.NA); } - criteria = criteria as BaseValueObject; + _criteria = _criteria as BaseValueObject; - if (criteria.isArray()) { - return (criteria as ArrayValueObject).map((criteriaItem) => this._handleSingleObject(range as BaseValueObject, criteriaItem, averageRange as BaseReferenceObject)); + if (_criteria.isArray()) { + return (_criteria as ArrayValueObject).map((criteriaItem) => this._handleSingleObject(_range as BaseValueObject, criteriaItem, averageRange as BaseReferenceObject)); } - return this._handleSingleObject(range as BaseValueObject, criteria, averageRange as BaseReferenceObject); + return this._handleSingleObject(_range as BaseValueObject, _criteria, averageRange as BaseReferenceObject); } private _handleSingleObject(range: BaseValueObject, criteria: BaseValueObject, averageRange?: BaseReferenceObject) { diff --git a/packages/engine-formula/src/functions/statistical/max/index.ts b/packages/engine-formula/src/functions/statistical/max/index.ts index f285bfb716c..9f579ab6d41 100644 --- a/packages/engine-formula/src/functions/statistical/max/index.ts +++ b/packages/engine-formula/src/functions/statistical/max/index.ts @@ -56,9 +56,13 @@ export class Max extends BaseFunction { private _validator(accumulatorAll: BaseValueObject, valueObject: BaseValueObject) { const validator = accumulatorAll.isLessThan(valueObject); + + let _accumulatorAll = accumulatorAll; + if (validator.getValue()) { - accumulatorAll = valueObject; + _accumulatorAll = valueObject; } - return accumulatorAll; + + return _accumulatorAll; } } diff --git a/packages/engine-formula/src/functions/statistical/maxa/index.ts b/packages/engine-formula/src/functions/statistical/maxa/index.ts index c2195c36958..c23e60e129c 100644 --- a/packages/engine-formula/src/functions/statistical/maxa/index.ts +++ b/packages/engine-formula/src/functions/statistical/maxa/index.ts @@ -43,21 +43,23 @@ export class Maxa extends BaseFunction { if (variant.isArray()) { (variant as ArrayValueObject).iterator((valueObject) => { + let _valueObject = valueObject; + // Empty cells and text values in the array or reference are ignored. - if (valueObject == null || valueObject.isNull() || valueObject.isString()) { - valueObject = NumberValueObject.create(0); + if (_valueObject == null || _valueObject.isNull() || _valueObject.isString()) { + _valueObject = NumberValueObject.create(0); } - if (valueObject.isBoolean()) { - valueObject = valueObject.convertToNumberObjectValue(); + if (_valueObject.isBoolean()) { + _valueObject = _valueObject.convertToNumberObjectValue(); } - if (valueObject.isError()) { - accumulatorAll = valueObject; + if (_valueObject.isError()) { + accumulatorAll = _valueObject; return false; // break } - accumulatorAll = this._validator(accumulatorAll, valueObject as BaseValueObject); + accumulatorAll = this._validator(accumulatorAll, _valueObject as BaseValueObject); }); } @@ -77,9 +79,13 @@ export class Maxa extends BaseFunction { private _validator(accumulatorAll: BaseValueObject, valueObject: BaseValueObject) { const validator = accumulatorAll.isLessThan(valueObject); + + let _accumulatorAll = accumulatorAll; + if (validator.getValue()) { - accumulatorAll = valueObject; + _accumulatorAll = valueObject; } - return accumulatorAll; + + return _accumulatorAll; } } diff --git a/packages/engine-formula/src/functions/statistical/min/index.ts b/packages/engine-formula/src/functions/statistical/min/index.ts index 5b9383deb94..33cb1560bde 100644 --- a/packages/engine-formula/src/functions/statistical/min/index.ts +++ b/packages/engine-formula/src/functions/statistical/min/index.ts @@ -56,9 +56,13 @@ export class Min extends BaseFunction { private _validator(accumulatorAll: BaseValueObject, valueObject: BaseValueObject) { const validator = accumulatorAll.isGreaterThan(valueObject); + + let _accumulatorAll = accumulatorAll; + if (validator.getValue()) { - accumulatorAll = valueObject; + _accumulatorAll = valueObject; } - return accumulatorAll; + + return _accumulatorAll; } } diff --git a/packages/engine-formula/src/functions/statistical/mina/index.ts b/packages/engine-formula/src/functions/statistical/mina/index.ts index 1fce7989e9d..beca3b001f3 100644 --- a/packages/engine-formula/src/functions/statistical/mina/index.ts +++ b/packages/engine-formula/src/functions/statistical/mina/index.ts @@ -43,21 +43,23 @@ export class Mina extends BaseFunction { if (variant.isArray()) { (variant as ArrayValueObject).iterator((valueObject) => { + let _valueObject = valueObject; + // Empty cells and text values in the array or reference are ignored. - if (valueObject == null || valueObject.isNull() || valueObject.isString()) { - valueObject = NumberValueObject.create(0); + if (_valueObject == null || _valueObject.isNull() || _valueObject.isString()) { + _valueObject = NumberValueObject.create(0); } - if (valueObject.isBoolean()) { - valueObject = valueObject.convertToNumberObjectValue(); + if (_valueObject.isBoolean()) { + _valueObject = _valueObject.convertToNumberObjectValue(); } - if (valueObject.isError()) { - accumulatorAll = valueObject; + if (_valueObject.isError()) { + accumulatorAll = _valueObject; return false; // break } - accumulatorAll = this._validator(accumulatorAll, valueObject as BaseValueObject); + accumulatorAll = this._validator(accumulatorAll, _valueObject as BaseValueObject); }); } @@ -77,9 +79,13 @@ export class Mina extends BaseFunction { private _validator(accumulatorAll: BaseValueObject, valueObject: BaseValueObject) { const validator = accumulatorAll.isGreaterThan(valueObject); + + let _accumulatorAll = accumulatorAll; + if (validator.getValue()) { - accumulatorAll = valueObject; + _accumulatorAll = valueObject; } - return accumulatorAll; + + return _accumulatorAll; } } diff --git a/packages/engine-formula/src/functions/text/text/index.ts b/packages/engine-formula/src/functions/text/text/index.ts index d45b8f73492..54c6b790423 100644 --- a/packages/engine-formula/src/functions/text/text/index.ts +++ b/packages/engine-formula/src/functions/text/text/index.ts @@ -19,7 +19,7 @@ import { getFormatPreview } from '../../../basics/format'; import { expandArrayValueObject } from '../../../engine/utils/array-object'; import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; -import { NumberValueObject, StringValueObject } from '../../../engine/value-object/primitive-object'; +import { StringValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; export class Text extends BaseFunction { @@ -72,12 +72,12 @@ export class Text extends BaseFunction { const formatTextValueString = `${formatTextValue.getValue()}`; + let textValueNumber = textValue.getValue() as number; + if (textValue.isNull()) { - textValue = NumberValueObject.create(0); + textValueNumber = 0; } - const textValueNumber = textValue.getValue() as number; - const previewText = getFormatPreview(formatTextValueString, textValueNumber); return StringValueObject.create(previewText); diff --git a/packages/engine-formula/src/functions/text/textafter/index.ts b/packages/engine-formula/src/functions/text/textafter/index.ts index 9a0933c8f41..449f141f771 100644 --- a/packages/engine-formula/src/functions/text/textafter/index.ts +++ b/packages/engine-formula/src/functions/text/textafter/index.ts @@ -18,7 +18,7 @@ import { ErrorType } from '../../../basics/error-type'; import { expandArrayValueObject } from '../../../engine/utils/array-object'; import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; -import { NumberValueObject, StringValueObject } from '../../../engine/value-object/primitive-object'; +import { BooleanValueObject, NumberValueObject, StringValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; export class Textafter extends BaseFunction { @@ -27,138 +27,91 @@ export class Textafter extends BaseFunction { override maxParams = 6; override calculate(text: BaseValueObject, delimiter: BaseValueObject, instanceNum?: BaseValueObject, matchMode?: BaseValueObject, matchEnd?: BaseValueObject, ifNotFound?: BaseValueObject) { - let instanceNumIsNull = false; // special handle - const onlyThreeVariant = !matchMode; + let _delimiter = delimiter; + + if (_delimiter.isArray()) { + _delimiter = (_delimiter as ArrayValueObject).get(0, 0) as BaseValueObject; + } - instanceNum = instanceNum ?? NumberValueObject.create(1); - matchMode = matchMode ?? NumberValueObject.create(0); - matchEnd = matchEnd ?? NumberValueObject.create(0); - ifNotFound = ifNotFound ?? ErrorValueObject.create(ErrorType.NA); + let instanceNumIsNull = false; // special handle + let _instanceNum = instanceNum ?? NumberValueObject.create(1); - if (instanceNum.isNull()) { + if (_instanceNum.isNull()) { instanceNumIsNull = true; - instanceNum = NumberValueObject.create(1); + _instanceNum = NumberValueObject.create(1); } - if (delimiter.isArray()) { - delimiter = (delimiter as ArrayValueObject).get(0, 0) as BaseValueObject; - } + const onlyThreeVariant = !matchMode; + const _matchMode = matchMode ?? NumberValueObject.create(0); + const _matchEnd = matchEnd ?? NumberValueObject.create(0); + const _ifNotFound = ifNotFound ?? ErrorValueObject.create(ErrorType.NA); - // get max row length const maxRowLength = Math.max( text.isArray() ? (text as ArrayValueObject).getRowCount() : 1, - instanceNum.isArray() ? (instanceNum as ArrayValueObject).getRowCount() : 1, - matchMode.isArray() ? (matchMode as ArrayValueObject).getRowCount() : 1, - matchEnd.isArray() ? (matchEnd as ArrayValueObject).getRowCount() : 1, - ifNotFound.isArray() ? (ifNotFound as ArrayValueObject).getRowCount() : 1 + _instanceNum.isArray() ? (_instanceNum as ArrayValueObject).getRowCount() : 1, + _matchMode.isArray() ? (_matchMode as ArrayValueObject).getRowCount() : 1, + _matchEnd.isArray() ? (_matchEnd as ArrayValueObject).getRowCount() : 1, + _ifNotFound.isArray() ? (_ifNotFound as ArrayValueObject).getRowCount() : 1 ); - // get max column length const maxColumnLength = Math.max( text.isArray() ? (text as ArrayValueObject).getColumnCount() : 1, - instanceNum.isArray() ? (instanceNum as ArrayValueObject).getColumnCount() : 1, - matchMode.isArray() ? (matchMode as ArrayValueObject).getColumnCount() : 1, - matchEnd.isArray() ? (matchEnd as ArrayValueObject).getColumnCount() : 1, - ifNotFound.isArray() ? (ifNotFound as ArrayValueObject).getColumnCount() : 1 + _instanceNum.isArray() ? (_instanceNum as ArrayValueObject).getColumnCount() : 1, + _matchMode.isArray() ? (_matchMode as ArrayValueObject).getColumnCount() : 1, + _matchEnd.isArray() ? (_matchEnd as ArrayValueObject).getColumnCount() : 1, + _ifNotFound.isArray() ? (_ifNotFound as ArrayValueObject).getColumnCount() : 1 ); const textArray = expandArrayValueObject(maxRowLength, maxColumnLength, text, ErrorValueObject.create(ErrorType.NA)); - const instanceNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, instanceNum, ErrorValueObject.create(ErrorType.NA)); - const matchModeArray = expandArrayValueObject(maxRowLength, maxColumnLength, matchMode, ErrorValueObject.create(ErrorType.NA)); - const matchEndArray = expandArrayValueObject(maxRowLength, maxColumnLength, matchEnd, ErrorValueObject.create(ErrorType.NA)); - const ifNotFoundArray = expandArrayValueObject(maxRowLength, maxColumnLength, ifNotFound, ErrorValueObject.create(ErrorType.NA)); - - const resultArray = textArray.map((textObject, rowIndex, columnIndex) => { - let instanceNumObject = instanceNumArray.get(rowIndex, columnIndex) as BaseValueObject; - let matchModeObject = matchModeArray.get(rowIndex, columnIndex) as BaseValueObject; - let matchEndObject = matchEndArray.get(rowIndex, columnIndex) as BaseValueObject; - const ifNotFoundObject = ifNotFoundArray.get(rowIndex, columnIndex) as BaseValueObject; - - // variant error order (text > instanceNum > matchMode > matchEnd > delimiter) - if (textObject.isError()) { - return textObject; - } - - if (instanceNumObject.isError()) { - return instanceNumObject; - } + const instanceNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, _instanceNum, ErrorValueObject.create(ErrorType.NA)); + const matchModeArray = expandArrayValueObject(maxRowLength, maxColumnLength, _matchMode, ErrorValueObject.create(ErrorType.NA)); + const matchEndArray = expandArrayValueObject(maxRowLength, maxColumnLength, _matchEnd, ErrorValueObject.create(ErrorType.NA)); + const ifNotFoundArray = expandArrayValueObject(maxRowLength, maxColumnLength, _ifNotFound, ErrorValueObject.create(ErrorType.NA)); - if (matchModeObject.isError()) { - return matchModeObject; - } + const resultArray = this._getResultArray(textArray, _delimiter, instanceNumArray, matchModeArray, matchEndArray, ifNotFoundArray, instanceNumIsNull, onlyThreeVariant); - if (matchEndObject.isError()) { - return matchEndObject; - } - - if (delimiter.isError()) { - return delimiter; - } - - let textValue = textObject.getValue() as string; - - if (textObject.isNull()) { - textValue = ''; - } - - if (textObject.isBoolean()) { - textValue = textValue ? 'TRUE' : 'FALSE'; - } - - textValue += ''; - - let delimiterValue = delimiter.getValue() as string; - - if (delimiter.isNull()) { - delimiterValue = ''; - } - - if (delimiter.isBoolean()) { - delimiterValue = delimiterValue ? 'TRUE' : 'FALSE'; - } - - delimiterValue += ''; - - if (instanceNumObject.isString()) { - instanceNumObject = instanceNumObject.convertToNumberObjectValue(); - - if (instanceNumObject.isError()) { - return instanceNumObject; - } - } + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as StringValueObject; + } - const instanceNumValue = Math.floor(+instanceNumObject.getValue()); + return resultArray; + } - // if instance_num = 0 returns a #VALUE! error - if (instanceNumValue === 0) { - return ErrorValueObject.create(ErrorType.VALUE); - } + private _getResultArray( + textArray: ArrayValueObject, + delimiterObject: BaseValueObject, + instanceNumArray: ArrayValueObject, + matchModeArray: ArrayValueObject, + matchEndArray: ArrayValueObject, + ifNotFoundArray: ArrayValueObject, + instanceNumIsNull: boolean, + onlyThreeVariant: boolean + ): ArrayValueObject { + const resultArray = textArray.map((textObject, rowIndex, columnIndex) => { + const instanceNumObject = instanceNumArray.get(rowIndex, columnIndex) as BaseValueObject; + const matchModeObject = matchModeArray.get(rowIndex, columnIndex) as BaseValueObject; + const matchEndObject = matchEndArray.get(rowIndex, columnIndex) as BaseValueObject; + const ifNotFoundObject = ifNotFoundArray.get(rowIndex, columnIndex) as BaseValueObject; - if (matchModeObject.isString()) { - matchModeObject = matchModeObject.convertToNumberObjectValue(); + // variant error order (text > instanceNum > matchMode > matchEnd > delimiter) + const _variantsError = this._checkVariantsError(textObject, instanceNumObject, matchModeObject, matchEndObject, delimiterObject); - if (matchModeObject.isError()) { - return matchModeObject; - } + if (_variantsError.isError()) { + return _variantsError; } - const matchModeValue = Math.floor(+matchModeObject.getValue()); - - if (matchModeValue < 0 || matchModeValue > 1) { - return ErrorValueObject.create(ErrorType.VALUE); - } + const textValue = this._getStringValue(textObject); + const delimiterValue = this._getStringValue(delimiterObject); - if (matchEndObject.isString()) { - matchEndObject = matchEndObject.convertToNumberObjectValue(); + const _variantsNumberFloorValue = this._getVariantsNumberFloorValue(instanceNumObject, matchModeObject, matchEndObject); - if (matchEndObject.isError()) { - return matchEndObject; - } + if (_variantsNumberFloorValue instanceof ErrorValueObject) { + return _variantsNumberFloorValue; } - const matchEndValue = Math.floor(+matchEndObject.getValue()); + const [instanceNumValue, matchModeValue, matchEndValue] = _variantsNumberFloorValue as number[]; - if (matchEndValue < 0 || matchEndValue > 1) { + if (instanceNumValue === 0 || matchModeValue < 0 || matchModeValue > 1 || matchEndValue < 0 || matchEndValue > 1) { return ErrorValueObject.create(ErrorType.VALUE); } @@ -181,51 +134,107 @@ export class Textafter extends BaseFunction { return ErrorValueObject.create(ErrorType.NA); } - const matchNum = textValue.match(new RegExp(delimiterValue, `g${!matchModeValue ? '' : 'i'}`)); + return this._getResult(textValue, delimiterValue, instanceNumValue, matchModeValue, matchEndValue, ifNotFoundObject, onlyThreeVariant); + }); - // only three variant and if instance_num is greater than the number of occurrences of delimiter. returns a #N/A error - if (matchNum && matchNum.length < Math.abs(instanceNumValue) && onlyThreeVariant) { - return ErrorValueObject.create(ErrorType.NA); + return resultArray as ArrayValueObject; + } + + private _checkVariantsError(...variantas: BaseValueObject[]) { + for (let i = 0; i < variantas.length; i++) { + const variant = variantas[i]; + + if (variant.isError()) { + return variant; } + } - if (!matchNum || matchNum.length < Math.abs(instanceNumValue)) { - if (matchEndValue) { - if (instanceNumValue > 0) { - return StringValueObject.create(''); - } else { - return StringValueObject.create(textValue); - } - } + return BooleanValueObject.create(true); + } + + private _getStringValue(variant: BaseValueObject): string { + let value = `${variant.getValue()}`; + + if (variant.isNull()) { + value = ''; + } + + if (variant.isBoolean()) { + value = value.toLocaleUpperCase(); + } + + return value; + } + + private _getVariantsNumberFloorValue(...variants: BaseValueObject[]) { + const values: number[] = []; + + for (let i = 0; i < variants.length; i++) { + let variant = variants[i]; - return ifNotFoundObject; + if (variant.isString()) { + variant = variant.convertToNumberObjectValue(); } - let substrText = !matchModeValue ? textValue : textValue.toLocaleLowerCase(); - delimiterValue = !matchModeValue ? delimiterValue : delimiterValue.toLocaleLowerCase(); + if (variant.isError()) { + return variant; + } + + const value = Math.floor(+variant.getValue()); - let resultIndex = 0; + values.push(value); + } - for (let i = 0; i < Math.abs(instanceNumValue); i++) { - if (instanceNumValue < 0) { - const index = substrText.lastIndexOf(delimiterValue); - resultIndex = index; - substrText = substrText.substr(0, index); + return values; + } + + private _getResult( + textValue: string, + delimiterValue: string, + instanceNumValue: number, + matchModeValue: number, + matchEndValue: number, + ifNotFoundObject: BaseValueObject, + onlyThreeVariant: boolean + ): BaseValueObject { + const matchNum = textValue.match(new RegExp(delimiterValue, `g${!matchModeValue ? '' : 'i'}`)); + + // only three variant and if instance_num is greater than the number of occurrences of delimiter. returns a #N/A error + if (matchNum && matchNum.length < Math.abs(instanceNumValue) && onlyThreeVariant) { + return ErrorValueObject.create(ErrorType.NA); + } + + if (!matchNum || matchNum.length < Math.abs(instanceNumValue)) { + if (matchEndValue) { + if (instanceNumValue > 0) { + return StringValueObject.create(''); } else { - const index = substrText.indexOf(delimiterValue); - resultIndex += (index + i * delimiterValue.length); - substrText = substrText.substr(index + delimiterValue.length); + return StringValueObject.create(textValue); } } - const result = textValue.substr(resultIndex + delimiterValue.length); + return ifNotFoundObject; + } - return StringValueObject.create(result); - }); + let substrText = !matchModeValue ? textValue : textValue.toLocaleLowerCase(); + const _delimiterValue = !matchModeValue ? delimiterValue : delimiterValue.toLocaleLowerCase(); - if (maxRowLength === 1 && maxColumnLength === 1) { - return (resultArray as ArrayValueObject).get(0, 0) as StringValueObject; + let resultIndex = 0; + + for (let i = 0; i < Math.abs(instanceNumValue); i++) { + if (instanceNumValue < 0) { + const index = substrText.lastIndexOf(_delimiterValue); + resultIndex = index; + substrText = substrText.substr(0, index); + } else { + const index = substrText.indexOf(_delimiterValue); + resultIndex += (index + i * _delimiterValue.length); + substrText = substrText.substr(index + _delimiterValue.length); + } } - return resultArray; + const result = textValue.substr(resultIndex + _delimiterValue.length); + + return StringValueObject.create(result); } } diff --git a/packages/engine-formula/src/functions/text/textbefore/index.ts b/packages/engine-formula/src/functions/text/textbefore/index.ts index 1bfbe17810d..e34b4e8d86d 100644 --- a/packages/engine-formula/src/functions/text/textbefore/index.ts +++ b/packages/engine-formula/src/functions/text/textbefore/index.ts @@ -18,7 +18,7 @@ import { ErrorType } from '../../../basics/error-type'; import { expandArrayValueObject } from '../../../engine/utils/array-object'; import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; -import { NumberValueObject, StringValueObject } from '../../../engine/value-object/primitive-object'; +import { BooleanValueObject, NumberValueObject, StringValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; export class Textbefore extends BaseFunction { @@ -27,138 +27,91 @@ export class Textbefore extends BaseFunction { override maxParams = 6; override calculate(text: BaseValueObject, delimiter: BaseValueObject, instanceNum?: BaseValueObject, matchMode?: BaseValueObject, matchEnd?: BaseValueObject, ifNotFound?: BaseValueObject) { - let instanceNumIsNull = false; // special handle - const onlyThreeVariant = !matchMode; + let _delimiter = delimiter; + + if (_delimiter.isArray()) { + _delimiter = (_delimiter as ArrayValueObject).get(0, 0) as BaseValueObject; + } - instanceNum = instanceNum ?? NumberValueObject.create(1); - matchMode = matchMode ?? NumberValueObject.create(0); - matchEnd = matchEnd ?? NumberValueObject.create(0); - ifNotFound = ifNotFound ?? ErrorValueObject.create(ErrorType.NA); + let instanceNumIsNull = false; // special handle + let _instanceNum = instanceNum ?? NumberValueObject.create(1); - if (instanceNum.isNull()) { + if (_instanceNum.isNull()) { instanceNumIsNull = true; - instanceNum = NumberValueObject.create(1); + _instanceNum = NumberValueObject.create(1); } - if (delimiter.isArray()) { - delimiter = (delimiter as ArrayValueObject).get(0, 0) as BaseValueObject; - } + const onlyThreeVariant = !matchMode; + const _matchMode = matchMode ?? NumberValueObject.create(0); + const _matchEnd = matchEnd ?? NumberValueObject.create(0); + const _ifNotFound = ifNotFound ?? ErrorValueObject.create(ErrorType.NA); - // get max row length const maxRowLength = Math.max( text.isArray() ? (text as ArrayValueObject).getRowCount() : 1, - instanceNum.isArray() ? (instanceNum as ArrayValueObject).getRowCount() : 1, - matchMode.isArray() ? (matchMode as ArrayValueObject).getRowCount() : 1, - matchEnd.isArray() ? (matchEnd as ArrayValueObject).getRowCount() : 1, - ifNotFound.isArray() ? (ifNotFound as ArrayValueObject).getRowCount() : 1 + _instanceNum.isArray() ? (_instanceNum as ArrayValueObject).getRowCount() : 1, + _matchMode.isArray() ? (_matchMode as ArrayValueObject).getRowCount() : 1, + _matchEnd.isArray() ? (_matchEnd as ArrayValueObject).getRowCount() : 1, + _ifNotFound.isArray() ? (_ifNotFound as ArrayValueObject).getRowCount() : 1 ); - // get max column length const maxColumnLength = Math.max( text.isArray() ? (text as ArrayValueObject).getColumnCount() : 1, - instanceNum.isArray() ? (instanceNum as ArrayValueObject).getColumnCount() : 1, - matchMode.isArray() ? (matchMode as ArrayValueObject).getColumnCount() : 1, - matchEnd.isArray() ? (matchEnd as ArrayValueObject).getColumnCount() : 1, - ifNotFound.isArray() ? (ifNotFound as ArrayValueObject).getColumnCount() : 1 + _instanceNum.isArray() ? (_instanceNum as ArrayValueObject).getColumnCount() : 1, + _matchMode.isArray() ? (_matchMode as ArrayValueObject).getColumnCount() : 1, + _matchEnd.isArray() ? (_matchEnd as ArrayValueObject).getColumnCount() : 1, + _ifNotFound.isArray() ? (_ifNotFound as ArrayValueObject).getColumnCount() : 1 ); const textArray = expandArrayValueObject(maxRowLength, maxColumnLength, text, ErrorValueObject.create(ErrorType.NA)); - const instanceNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, instanceNum, ErrorValueObject.create(ErrorType.NA)); - const matchModeArray = expandArrayValueObject(maxRowLength, maxColumnLength, matchMode, ErrorValueObject.create(ErrorType.NA)); - const matchEndArray = expandArrayValueObject(maxRowLength, maxColumnLength, matchEnd, ErrorValueObject.create(ErrorType.NA)); - const ifNotFoundArray = expandArrayValueObject(maxRowLength, maxColumnLength, ifNotFound, ErrorValueObject.create(ErrorType.NA)); - - const resultArray = textArray.map((textObject, rowIndex, columnIndex) => { - let instanceNumObject = instanceNumArray.get(rowIndex, columnIndex) as BaseValueObject; - let matchModeObject = matchModeArray.get(rowIndex, columnIndex) as BaseValueObject; - let matchEndObject = matchEndArray.get(rowIndex, columnIndex) as BaseValueObject; - const ifNotFoundObject = ifNotFoundArray.get(rowIndex, columnIndex) as BaseValueObject; - - // variant error order (text > instanceNum > matchMode > matchEnd > delimiter) - if (textObject.isError()) { - return textObject; - } - - if (instanceNumObject.isError()) { - return instanceNumObject; - } - - if (matchModeObject.isError()) { - return matchModeObject; - } - - if (matchEndObject.isError()) { - return matchEndObject; - } - - if (delimiter.isError()) { - return delimiter; - } - - let textValue = textObject.getValue() as string; + const instanceNumArray = expandArrayValueObject(maxRowLength, maxColumnLength, _instanceNum, ErrorValueObject.create(ErrorType.NA)); + const matchModeArray = expandArrayValueObject(maxRowLength, maxColumnLength, _matchMode, ErrorValueObject.create(ErrorType.NA)); + const matchEndArray = expandArrayValueObject(maxRowLength, maxColumnLength, _matchEnd, ErrorValueObject.create(ErrorType.NA)); + const ifNotFoundArray = expandArrayValueObject(maxRowLength, maxColumnLength, _ifNotFound, ErrorValueObject.create(ErrorType.NA)); - if (textObject.isNull()) { - textValue = ''; - } - - if (textObject.isBoolean()) { - textValue = textValue ? 'TRUE' : 'FALSE'; - } - - textValue += ''; - - let delimiterValue = delimiter.getValue() as string; - - if (delimiter.isNull()) { - delimiterValue = ''; - } - - if (delimiter.isBoolean()) { - delimiterValue = delimiterValue ? 'TRUE' : 'FALSE'; - } - - delimiterValue += ''; - - if (instanceNumObject.isString()) { - instanceNumObject = instanceNumObject.convertToNumberObjectValue(); + const resultArray = this._getResultArray(textArray, _delimiter, instanceNumArray, matchModeArray, matchEndArray, ifNotFoundArray, instanceNumIsNull, onlyThreeVariant); - if (instanceNumObject.isError()) { - return instanceNumObject; - } - } + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as StringValueObject; + } - const instanceNumValue = Math.floor(+instanceNumObject.getValue()); + return resultArray; + } - // if instance_num = 0 returns a #VALUE! error - if (instanceNumValue === 0) { - return ErrorValueObject.create(ErrorType.VALUE); - } + private _getResultArray( + textArray: ArrayValueObject, + delimiterObject: BaseValueObject, + instanceNumArray: ArrayValueObject, + matchModeArray: ArrayValueObject, + matchEndArray: ArrayValueObject, + ifNotFoundArray: ArrayValueObject, + instanceNumIsNull: boolean, + onlyThreeVariant: boolean + ): ArrayValueObject { + const resultArray = textArray.map((textObject, rowIndex, columnIndex) => { + const instanceNumObject = instanceNumArray.get(rowIndex, columnIndex) as BaseValueObject; + const matchModeObject = matchModeArray.get(rowIndex, columnIndex) as BaseValueObject; + const matchEndObject = matchEndArray.get(rowIndex, columnIndex) as BaseValueObject; + const ifNotFoundObject = ifNotFoundArray.get(rowIndex, columnIndex) as BaseValueObject; - if (matchModeObject.isString()) { - matchModeObject = matchModeObject.convertToNumberObjectValue(); + // variant error order (text > instanceNum > matchMode > matchEnd > delimiter) + const _variantsError = this._checkVariantsError(textObject, instanceNumObject, matchModeObject, matchEndObject, delimiterObject); - if (matchModeObject.isError()) { - return matchModeObject; - } + if (_variantsError.isError()) { + return _variantsError; } - const matchModeValue = Math.floor(+matchModeObject.getValue()); - - if (matchModeValue < 0 || matchModeValue > 1) { - return ErrorValueObject.create(ErrorType.VALUE); - } + const textValue = this._getStringValue(textObject); + const delimiterValue = this._getStringValue(delimiterObject); - if (matchEndObject.isString()) { - matchEndObject = matchEndObject.convertToNumberObjectValue(); + const _variantsNumberFloorValue = this._getVariantsNumberFloorValue(instanceNumObject, matchModeObject, matchEndObject); - if (matchEndObject.isError()) { - return matchEndObject; - } + if (_variantsNumberFloorValue instanceof ErrorValueObject) { + return _variantsNumberFloorValue; } - const matchEndValue = Math.floor(+matchEndObject.getValue()); + const [instanceNumValue, matchModeValue, matchEndValue] = _variantsNumberFloorValue as number[]; - if (matchEndValue < 0 || matchEndValue > 1) { + if (instanceNumValue === 0 || matchModeValue < 0 || matchModeValue > 1 || matchEndValue < 0 || matchEndValue > 1) { return ErrorValueObject.create(ErrorType.VALUE); } @@ -181,51 +134,107 @@ export class Textbefore extends BaseFunction { return ErrorValueObject.create(ErrorType.NA); } - const matchNum = textValue.match(new RegExp(delimiterValue, `g${!matchModeValue ? '' : 'i'}`)); + return this._getResult(textValue, delimiterValue, instanceNumValue, matchModeValue, matchEndValue, ifNotFoundObject, onlyThreeVariant); + }); - // only three variant and if instance_num is greater than the number of occurrences of delimiter. returns a #N/A error - if (matchNum && matchNum.length < Math.abs(instanceNumValue) && onlyThreeVariant) { - return ErrorValueObject.create(ErrorType.NA); + return resultArray as ArrayValueObject; + } + + private _checkVariantsError(...variantas: BaseValueObject[]) { + for (let i = 0; i < variantas.length; i++) { + const variant = variantas[i]; + + if (variant.isError()) { + return variant; } + } - if (!matchNum || matchNum.length < Math.abs(instanceNumValue)) { - if (matchEndValue) { - if (instanceNumValue > 0) { - return StringValueObject.create(textValue); - } else { - return StringValueObject.create(''); - } - } + return BooleanValueObject.create(true); + } + + private _getStringValue(variant: BaseValueObject): string { + let value = `${variant.getValue()}`; + + if (variant.isNull()) { + value = ''; + } + + if (variant.isBoolean()) { + value = value.toLocaleUpperCase(); + } + + return value; + } - return ifNotFoundObject; + private _getVariantsNumberFloorValue(...variants: BaseValueObject[]) { + const values: number[] = []; + + for (let i = 0; i < variants.length; i++) { + let variant = variants[i]; + + if (variant.isString()) { + variant = variant.convertToNumberObjectValue(); + } + + if (variant.isError()) { + return variant; } - let substrText = !matchModeValue ? textValue : textValue.toLocaleLowerCase(); - delimiterValue = !matchModeValue ? delimiterValue : delimiterValue.toLocaleLowerCase(); + const value = Math.floor(+variant.getValue()); + + values.push(value); + } - let resultIndex = 0; + return values; + } + + private _getResult( + textValue: string, + delimiterValue: string, + instanceNumValue: number, + matchModeValue: number, + matchEndValue: number, + ifNotFoundObject: BaseValueObject, + onlyThreeVariant: boolean + ): BaseValueObject { + const matchNum = textValue.match(new RegExp(delimiterValue, `g${!matchModeValue ? '' : 'i'}`)); + + // only three variant and if instance_num is greater than the number of occurrences of delimiter. returns a #N/A error + if (matchNum && matchNum.length < Math.abs(instanceNumValue) && onlyThreeVariant) { + return ErrorValueObject.create(ErrorType.NA); + } - for (let i = 0; i < Math.abs(instanceNumValue); i++) { - if (instanceNumValue < 0) { - const index = substrText.lastIndexOf(delimiterValue); - resultIndex = index; - substrText = substrText.substr(0, index); + if (!matchNum || matchNum.length < Math.abs(instanceNumValue)) { + if (matchEndValue) { + if (instanceNumValue > 0) { + return StringValueObject.create(textValue); } else { - const index = substrText.indexOf(delimiterValue); - resultIndex += (index + i * delimiterValue.length); - substrText = substrText.substr(index + delimiterValue.length); + return StringValueObject.create(''); } } - const result = textValue.substr(0, resultIndex); + return ifNotFoundObject; + } - return StringValueObject.create(result); - }); + let substrText = !matchModeValue ? textValue : textValue.toLocaleLowerCase(); + const _delimiterValue = !matchModeValue ? delimiterValue : delimiterValue.toLocaleLowerCase(); - if (maxRowLength === 1 && maxColumnLength === 1) { - return (resultArray as ArrayValueObject).get(0, 0) as StringValueObject; + let resultIndex = 0; + + for (let i = 0; i < Math.abs(instanceNumValue); i++) { + if (instanceNumValue < 0) { + const index = substrText.lastIndexOf(_delimiterValue); + resultIndex = index; + substrText = substrText.substr(0, index); + } else { + const index = substrText.indexOf(_delimiterValue); + resultIndex += (index + i * _delimiterValue.length); + substrText = substrText.substr(index + _delimiterValue.length); + } } - return resultArray; + const result = textValue.substr(0, resultIndex); + + return StringValueObject.create(result); } } diff --git a/packages/engine-formula/src/functions/text/textsplit/index.ts b/packages/engine-formula/src/functions/text/textsplit/index.ts index a946a9a7086..6d3d64e694d 100644 --- a/packages/engine-formula/src/functions/text/textsplit/index.ts +++ b/packages/engine-formula/src/functions/text/textsplit/index.ts @@ -18,7 +18,7 @@ import { ErrorType } from '../../../basics/error-type'; import { expandArrayValueObject } from '../../../engine/utils/array-object'; import { ArrayValueObject } from '../../../engine/value-object/array-value-object'; import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; -import { NumberValueObject, StringValueObject } from '../../../engine/value-object/primitive-object'; +import { BooleanValueObject, NumberValueObject, StringValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; export class Textsplit extends BaseFunction { @@ -27,147 +27,134 @@ export class Textsplit extends BaseFunction { override maxParams = 6; override calculate(text: BaseValueObject, colDelimiter: BaseValueObject, rowDelimiter?: BaseValueObject, ignoreEmpty?: BaseValueObject, matchMode?: BaseValueObject, padWith?: BaseValueObject) { - rowDelimiter = rowDelimiter ?? StringValueObject.create('\\s'); - ignoreEmpty = ignoreEmpty ?? NumberValueObject.create(0); - matchMode = matchMode ?? NumberValueObject.create(0); - padWith = padWith ?? StringValueObject.create(ErrorType.NA); + let _rowDelimiter = rowDelimiter ?? StringValueObject.create('\\s'); + const _ignoreEmpty = ignoreEmpty ?? NumberValueObject.create(0); + const _matchMode = matchMode ?? NumberValueObject.create(0); + const _padWith = padWith ?? StringValueObject.create(ErrorType.NA); - const colDelimiterValue: string[] = []; + const { _variant: _colDelimiter, values: colDelimiterValue } = this._getStringValues(colDelimiter); - if (colDelimiter.isArray()) { - (colDelimiter as ArrayValueObject).iterator((colDelimiterObject) => { - if (colDelimiterObject?.isError()) { - colDelimiter = colDelimiterObject; - return false; - } + const { _variant, values: rowDelimiterValue } = this._getStringValues(_rowDelimiter); + _rowDelimiter = _variant; - if (colDelimiterObject?.isNull()) { - colDelimiter = ErrorValueObject.create(ErrorType.VALUE); - return false; - } + const maxRowLength = Math.max( + text.isArray() ? (text as ArrayValueObject).getRowCount() : 1, + _ignoreEmpty.isArray() ? (_ignoreEmpty as ArrayValueObject).getRowCount() : 1, + _matchMode.isArray() ? (_matchMode as ArrayValueObject).getRowCount() : 1 + ); - const delimiterValue = this._getRegExpStringValue(colDelimiterObject as BaseValueObject); + const maxColumnLength = Math.max( + text.isArray() ? (text as ArrayValueObject).getColumnCount() : 1, + _ignoreEmpty.isArray() ? (_ignoreEmpty as ArrayValueObject).getColumnCount() : 1, + _matchMode.isArray() ? (_matchMode as ArrayValueObject).getColumnCount() : 1 + ); - if (delimiterValue === '') { - colDelimiter = ErrorValueObject.create(ErrorType.VALUE); - return false; - } + const textArray = expandArrayValueObject(maxRowLength, maxColumnLength, text, ErrorValueObject.create(ErrorType.NA)); + const ignoreEmptyArray = expandArrayValueObject(maxRowLength, maxColumnLength, _ignoreEmpty, ErrorValueObject.create(ErrorType.NA)); + const matchModeArray = expandArrayValueObject(maxRowLength, maxColumnLength, _matchMode, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = this._getResultArray( + textArray, + _colDelimiter, + _rowDelimiter, + ignoreEmptyArray, + matchModeArray, + _padWith, + colDelimiterValue, + rowDelimiterValue + ); - colDelimiterValue.push(delimiterValue); - }); + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as ArrayValueObject; } else { - const delimiterValue = this._getRegExpStringValue(colDelimiter); - - if (delimiterValue === '') { - colDelimiter = ErrorValueObject.create(ErrorType.VALUE); - } - - colDelimiterValue.push(delimiterValue); + return resultArray.map((item) => (item as ArrayValueObject).get(0, 0) as BaseValueObject); } + } - const rowDelimiterValue: string[] = []; + private _getStringValues(variant: BaseValueObject) { + let _variant = variant; + const values: string[] = []; - if (rowDelimiter.isArray()) { - (rowDelimiter as ArrayValueObject).iterator((rowDelimiterObject) => { - if (rowDelimiterObject?.isError()) { - rowDelimiter = rowDelimiterObject; + if (_variant.isArray()) { + (_variant as ArrayValueObject).iterator((variantObject) => { + if (variantObject?.isError()) { + _variant = variantObject; return false; } - if (rowDelimiterObject?.isNull()) { - rowDelimiter = ErrorValueObject.create(ErrorType.VALUE); + if (variantObject?.isNull()) { + _variant = ErrorValueObject.create(ErrorType.VALUE); return false; } - const delimiterValue = this._getRegExpStringValue(rowDelimiterObject as BaseValueObject); + const value = this._getRegExpStringValue(variantObject as BaseValueObject); - if (delimiterValue === '') { - rowDelimiter = ErrorValueObject.create(ErrorType.VALUE); + if (value === '') { + _variant = ErrorValueObject.create(ErrorType.VALUE); return false; } - rowDelimiterValue.push(delimiterValue); + values.push(value); }); } else { - const delimiterValue = this._getRegExpStringValue(rowDelimiter); + const value = this._getRegExpStringValue(_variant); - if (delimiterValue === '') { - rowDelimiter = ErrorValueObject.create(ErrorType.VALUE); + if (value === '') { + _variant = ErrorValueObject.create(ErrorType.VALUE); } - rowDelimiterValue.push(delimiterValue); + values.push(value); } - let padWithRowCount = 1; - let padWithColumnCount = 1; - - if (padWith.isArray()) { - padWithRowCount = (padWith as ArrayValueObject).getRowCount(); - padWithColumnCount = (padWith as ArrayValueObject).getColumnCount(); - - if (padWithRowCount === 1 && padWithColumnCount === 1) { - padWith = (padWith as ArrayValueObject).get(0, 0) as BaseValueObject; - } - } - - // get max row length - const maxRowLength = Math.max( - text.isArray() ? (text as ArrayValueObject).getRowCount() : 1, - ignoreEmpty.isArray() ? (ignoreEmpty as ArrayValueObject).getRowCount() : 1, - matchMode.isArray() ? (matchMode as ArrayValueObject).getRowCount() : 1 - ); - - // get max column length - const maxColumnLength = Math.max( - text.isArray() ? (text as ArrayValueObject).getColumnCount() : 1, - ignoreEmpty.isArray() ? (ignoreEmpty as ArrayValueObject).getColumnCount() : 1, - matchMode.isArray() ? (matchMode as ArrayValueObject).getColumnCount() : 1 - ); - - const textArray = expandArrayValueObject(maxRowLength, maxColumnLength, text, ErrorValueObject.create(ErrorType.NA)); - const ignoreEmptyArray = expandArrayValueObject(maxRowLength, maxColumnLength, ignoreEmpty, ErrorValueObject.create(ErrorType.NA)); - const matchModeArray = expandArrayValueObject(maxRowLength, maxColumnLength, matchMode, ErrorValueObject.create(ErrorType.NA)); + return { + _variant, + values, + }; + } + private _getResultArray( + textArray: ArrayValueObject, + colDelimiter: BaseValueObject, + rowDelimiter: BaseValueObject, + ignoreEmptyArray: ArrayValueObject, + matchModeArray: ArrayValueObject, + padWith: BaseValueObject, + colDelimiterValue: string[], + rowDelimiterValue: string[] + ) { const resultArray = textArray.map((textObject, rowIndex, columnIndex) => { let ignoreEmptyObject = ignoreEmptyArray.get(rowIndex, columnIndex) as BaseValueObject; let matchModeObject = matchModeArray.get(rowIndex, columnIndex) as BaseValueObject; - if (textObject.isError()) { - return textObject; - } + const _variantsError = this._checkVariantsError(textObject, colDelimiter, rowDelimiter, ignoreEmptyObject, matchModeObject); - if (colDelimiter.isError()) { - return colDelimiter; + if (_variantsError.isError()) { + return _variantsError; } - if ((rowDelimiter as BaseValueObject).isError()) { - return rowDelimiter as ErrorValueObject; + if (textObject.isNull()) { + return ErrorValueObject.create(ErrorType.VALUE); } - if (ignoreEmptyObject.isError()) { - return ignoreEmptyObject; - } + let _padWith = padWith; - if (matchModeObject.isError()) { - return matchModeObject; - } + if (_padWith.isArray()) { + const padWithRowCount = (_padWith as ArrayValueObject).getRowCount(); + const padWithColumnCount = (_padWith as ArrayValueObject).getColumnCount(); - if (textObject.isNull()) { - return ErrorValueObject.create(ErrorType.VALUE); - } + if (padWithRowCount > 1 || padWithColumnCount > 1) { + return ErrorValueObject.create(ErrorType.VALUE); + } - if (padWithRowCount > 1 || padWithColumnCount > 1) { - return ErrorValueObject.create(ErrorType.VALUE); + _padWith = (_padWith as ArrayValueObject).get(0, 0) as BaseValueObject; } - let textValue = textObject.getValue() as string; + let textValue = `${textObject.getValue()}`; if (textObject.isBoolean()) { - textValue = textValue ? 'TRUE' : 'FALSE'; + textValue = textValue.toLocaleUpperCase(); } - textValue += ''; - if (ignoreEmptyObject.isString()) { ignoreEmptyObject = ignoreEmptyObject.convertToNumberObjectValue(); @@ -192,49 +179,68 @@ export class Textsplit extends BaseFunction { return ErrorValueObject.create(ErrorType.VALUE); } - let padWithValue = padWith!.getValue() as string; + let padWithValue = `${_padWith.getValue()}`; - if (padWith!.isBoolean()) { - padWithValue = padWithValue ? 'TRUE' : 'FALSE'; + if (_padWith.isBoolean()) { + padWithValue = padWithValue.toLocaleUpperCase(); } - padWithValue += ''; + return this._getResult(textValue, colDelimiterValue, rowDelimiterValue, ignoreEmptyValue, matchModeValue, padWithValue); + }); - const rowDelimiterRegExp = new RegExp(rowDelimiterValue.join('|'), `g${!matchModeValue ? '' : 'i'}`); - const colDelimiterRegExp = new RegExp(colDelimiterValue.join('|'), `g${!matchModeValue ? '' : 'i'}`); + return resultArray; + } - const resultRows = textValue.split(rowDelimiterRegExp); + private _getResult( + textValue: string, + colDelimiterValue: string[], + rowDelimiterValue: string[], + ignoreEmptyValue: number, + matchModeValue: number, + padWithValue: string + ) { + const rowDelimiterRegExp = new RegExp(rowDelimiterValue.join('|'), `g${!matchModeValue ? '' : 'i'}`); + const colDelimiterRegExp = new RegExp(colDelimiterValue.join('|'), `g${!matchModeValue ? '' : 'i'}`); - let resultColsMaxCount = 1; + const resultRows = textValue.split(rowDelimiterRegExp); - let result = resultRows.map((row) => { - let cols = row.split(colDelimiterRegExp); + let resultColsMaxCount = 1; - if (ignoreEmptyValue) { - cols = cols.filter((col) => col !== ''); - } + let result = resultRows.map((row) => { + let cols = row.split(colDelimiterRegExp); - resultColsMaxCount = Math.max(resultColsMaxCount, cols.length); + if (ignoreEmptyValue) { + cols = cols.filter((col) => col !== ''); + } - return cols; - }); + resultColsMaxCount = Math.max(resultColsMaxCount, cols.length); - result = result.map((row) => { - if (row.length < resultColsMaxCount) { - row = row.concat(new Array(resultColsMaxCount - row.length).fill(padWithValue)); - } + return cols; + }); - return row; - }); + result = result.map((row) => { + let _row = row; + + if (_row.length < resultColsMaxCount) { + _row = _row.concat(new Array(resultColsMaxCount - _row.length).fill(padWithValue)); + } - return ArrayValueObject.createByArray(result); + return _row; }); - if (maxRowLength === 1 && maxColumnLength === 1) { - return (resultArray as ArrayValueObject).get(0, 0) as ArrayValueObject; - } else { - return resultArray.map((item) => (item as ArrayValueObject).get(0, 0) as BaseValueObject); + return ArrayValueObject.createByArray(result); + } + + private _checkVariantsError(...variantas: BaseValueObject[]) { + for (let i = 0; i < variantas.length; i++) { + const variant = variantas[i]; + + if (variant.isError()) { + return variant; + } } + + return BooleanValueObject.create(true); } private _getRegExpStringValue(valueObject: BaseValueObject): string {