UNPKG

@syncfusion/ej2-spreadsheet

Version:

Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel

998 lines 276 kB
import { FormulasErrorsStrings, CommonErrors, getSkeletonVal } from '../common/index'; import { getAlphalabel } from '../base/index'; import { isNullOrUndefined, getValue, Internationalization } from '@syncfusion/ej2-base'; import { DataUtil } from '@syncfusion/ej2-data'; import { checkDateFormat, dateToInt, isNumber, isCellReference, isValidCellReference, getCellIndexes, isHiddenRow, isHiddenCol } from '../../workbook/index'; /** * Represents the basic formulas module. */ var BasicFormulas = /** @class */ (function () { function BasicFormulas(parent) { this.formulas = [ { formulaName: 'SUM', category: 'Math & Trig', description: 'Sums individual values, cell references or ranges.' }, { formulaName: 'SUMIFS', category: 'Math & Trig', description: 'Sums the cells specified by a given set of conditionsor criteria.' }, { formulaName: 'SUMPRODUCT', category: 'Math & Trig', description: 'Returns sum of the product of given ranges of arrays.' }, { formulaName: 'ABS', category: 'Math & Trig', description: 'Returns the absolute value of a number.' }, { formulaName: 'RAND', category: 'Math & Trig', description: 'Return a random number between 0 and 1.' }, { formulaName: 'FLOOR', category: 'Math & Trig', description: 'Returns the round a number down to the nearest integer.' }, { formulaName: 'CEILING', category: 'Math & Trig', description: 'Returns a number rounded up to a multiple of another number.' }, { formulaName: 'SUMIF', category: 'Math & Trig', description: 'It will sum up cells that meet the given criteria.' }, { formulaName: 'PRODUCT', category: 'Math & Trig', description: 'Multiplies all the numbers given as arguments and returns the product.' }, { formulaName: 'AVERAGE', category: 'Statistical', description: 'The sum of the numbers divided by how many numbers are being averaged.' }, { formulaName: 'AVERAGEIF', category: 'Statistical', description: 'Computes the average of the numbers in a range that meet the supplied criteria.' }, { formulaName: 'COUNT', category: 'Statistical', description: 'Counts the numbers in the list of arguments, exclude text entries.' }, { formulaName: 'COUNTA', category: 'Statistical', description: 'Counts the non-empty values in the list of arguments.' }, { formulaName: 'COUNTIF', category: 'Statistical', description: 'Counts the number of cells in a range that meet a specified condition.' }, { formulaName: 'COUNTIFS', category: 'Statistical', description: 'Counts the number of times each cells in all the ranges that meet the specific conditions.' }, { formulaName: 'AVERAGEA', category: 'Statistical', description: 'Calculates the average of values in the list of arguments.Arguments can be numbers, names, arrays or references.' }, { formulaName: 'AVERAGEIFS', category: 'Statistical', description: 'Conditionally returns the average of the contents of cells for the set of ranges.' }, { formulaName: 'MIN', category: 'Statistical', description: 'Returns the smaller number in set of arguments.' }, { formulaName: 'MAX', category: 'Statistical', description: 'Returns the largest number in set of arguments.' }, { formulaName: 'DATE', category: 'Date', description: 'Returns the date, given the year, month and day of the month.' }, { formulaName: 'DAY', category: 'Date', description: 'Returns the day of a given date.' }, { formulaName: 'TODAY', category: 'Date', description: 'Returns the current date as date value.' }, { formulaName: 'DAYS', category: 'Date', description: 'Returns the number of days between two dates.' }, { formulaName: 'WEEKDAY', category: 'Date', description: 'Returns the day of the week corresponding to a date.' }, { formulaName: 'IF', category: 'Logical', description: 'Returns one value if a logical expression is TRUE and another if it is FALSE' }, { formulaName: 'AND', category: 'Logical', description: 'Returns TRUE if all the arguments are considered TRUE, and FALSE otherwise.' }, { formulaName: 'IFS', category: 'Logical', description: 'Checks multiple conditions and returns a value corresponding to the first TRUE result.' }, { formulaName: 'IFERROR', category: 'Logical', description: 'Returns a value you specify if a formula evaluates to an error; otherwise, it returns the result of the formula.' }, { formulaName: 'CHOOSE', category: 'Lookup & Reference', description: 'Returns a value from a list, given an index number.' }, { formulaName: 'INDEX', category: 'Lookup & Reference', description: 'Returns a value from a table, given a row and column number.' }, { formulaName: 'FIND', category: 'Text', description: 'Returns the position of a string of text within another string.' }, { formulaName: 'CONCATENATE', category: 'Text', description: ' Used to join two or more strings together.' }, { formulaName: 'CONCAT', category: 'Text', description: 'Concatenates a list or range of text strings.' }, { formulaName: 'SUBTOTAL', category: 'Lookup & Reference', description: 'Returns a subtotal in a list or database.' }, { formulaName: 'RADIANS', category: 'Math & Trig', description: 'Converts degrees to radians.' }, { formulaName: 'OR', category: 'Logical', description: 'Returns TRUE if any arguments considered TRUE, and all the arguments are FALSE it will return FALSE.' }, { formulaName: 'NOT', category: 'Logical', description: 'Returns the inverse of a given logical expression.' }, { formulaName: 'MATCH', category: 'Lookup & Reference', description: 'Returns the relative position of an checked item in range that matches a specified value in a specified order' }, { formulaName: 'RANDBETWEEN', category: 'Math & Trig', description: 'Returns an integer random number in a specified range.' }, { formulaName: 'SLOPE', category: 'Statistical', description: 'Returns the slope of the line from linear regression of the data points.' }, { formulaName: 'INTERCEPT', category: 'Statistical', description: 'Calculates the point of the Y-intercept line via linear regression.' }, { formulaName: 'RSQ', category: 'Statistical', description: 'Returns the square of the Pearson product moment correlation coefficient based on data points in known_ys and known_xs' }, { formulaName: 'UNIQUE', category: 'Lookup & Reference', description: 'Returns a unique values from a range or array.' }, { formulaName: 'ROUNDUP', category: 'Math & Trig', description: 'Rounds a number away from zero.' }, { formulaName: 'ROUNDDOWN', category: 'Math & Trig', description: 'Rounds a number down, toward zero.' }, { formulaName: 'INT', category: 'Math & Trig', description: 'Returns a number to the nearest integer.' }, { formulaName: 'LN', category: 'Math & Trig', description: 'Returns the natural logarithm of a number.' }, { formulaName: 'ISNUMBER', category: 'Information', description: 'Returns TRUE, if the argument is number and FALSE otherwise.' }, { formulaName: 'ROUND', category: 'Math & Trig', description: 'Rounds a number to a specified number of digits.' }, { formulaName: 'LOG', category: 'Math & Trig', description: 'Returns the logarithm of a number to the base that you specify.' }, { formulaName: 'POWER', category: 'Math & Trig', description: 'Returns the result of a number raised to power.' }, { formulaName: 'SQRT', category: 'Math & Trig', description: 'Returns the square root of a positive number.' }, { formulaName: 'TRUNC', category: 'Math & Trig', description: 'Returns the truncated value of a number to a specified number of decimal places.' }, { formulaName: 'EXP', category: 'Math & Trig', description: 'Returns e raised to the power of the given number.' }, { formulaName: 'GEOMEAN', category: 'Statistical', description: 'Returns the geometric mean of an array or range of positive data.' }, { formulaName: 'TEXT', category: 'Lookup & Reference', description: 'Converts a value to text in specified number format.' }, { formulaName: 'SORT', category: 'Lookup & Reference', description: 'Sorts a range of an array.' }, { formulaName: 'LOOKUP', category: 'Lookup & Reference', description: 'Looks for a value in a one-row or one-column range, then returns a value from the same position in a second one-row or one-column range.' }, { formulaName: 'VLOOKUP', category: 'Lookup & Reference', description: 'Looks for a specific value in the first column of a lookup range and returns a corresponding value from a different column within the same row.' }, { formulaName: 'HLOOKUP', category: 'Lookup & Reference', description: 'Looks for a value in the top row of the array of values and then returns a value in the same column from a row in the array that you specify.' }, { formulaName: 'T', category: 'Text', description: 'Checks whether a value is text or not and returns the text.' }, { formulaName: 'EXACT', category: 'Text', description: 'Checks whether a two text strings are exactly same and returns TRUE or FALSE.' }, { formulaName: 'LEN', category: 'Text', description: 'Returns a number of characters in a given string.' }, { formulaName: 'MOD', category: 'Math & Trig', description: 'Returns a remainder after a number is divided by divisor.' }, { formulaName: 'ODD', category: 'Math & Trig', description: 'Rounds a positive number up and negative number down to the nearest odd integer.' }, { formulaName: 'PI', category: 'Math & Trig', description: 'Returns the value of pi.' }, { formulaName: 'COUNTBLANK', category: 'Statistical', description: 'Returns the number of empty cells in a specified range of cells.' }, { formulaName: 'EVEN', category: 'Math & Trig', description: 'Rounds a positive number up and negative number down to the nearest even integer.' }, { formulaName: 'FACT', category: 'Math & Trig', description: 'Returns the factorial of a number.' }, { formulaName: 'DECIMAL', category: 'Math & Trig', description: 'Converts a text representation of a number in a given base into a decimal number.' }, { formulaName: 'DEGREES', category: 'Math & Trig', description: 'Converts radians to degrees.' }, { formulaName: 'ADDRESS', category: 'Lookup & Reference', description: 'Returns a cell reference as text, given specified row and column numbers.' }, { formulaName: 'TIME', category: 'Date & Time', description: 'Converts hours, minutes, seconds to the time formatted text.' }, { formulaName: 'CHAR', category: 'Text', description: 'Returns the character from the specified number.' }, { formulaName: 'CODE', category: 'Text', description: 'Returns the numeric code for the first character in a given string.' }, { formulaName: 'DOLLAR', category: 'Text', description: 'Converts the number to currency formatted text.' }, { formulaName: 'SMALL', category: 'Statistical', description: 'Returns the k-th smallest value in a given array.' }, { formulaName: 'LARGE', category: 'Statistical', description: 'Returns the k-th largest value in a given array.' }, { formulaName: 'MEDIAN', category: 'Statistical', description: 'Returns the median of the given set of numbers.' }, { formulaName: 'EDATE', category: 'Date & Time', description: 'Returns a date with given number of months before or after the specified date.' }, { formulaName: 'EOMONTH', category: 'Date & Time', description: 'Returns the last day of the month that is a specified number of months before or after an initially supplied start date.' }, { formulaName: 'DATEVALUE', category: 'Date & Time', description: 'Converts a date string into date value.' }, { formulaName: 'HOUR', category: 'Date & Time', description: 'Returns the number of hours in a specified time string.' }, { formulaName: 'MINUTE', category: 'Date & Time', description: 'Returns the number of minutes in a specified time string.' }, { formulaName: 'SECOND', category: 'Date & Time', description: 'Returns the number of seconds in a specified time string.' }, { formulaName: 'NOW', category: 'Date & Time', description: 'Returns the current date and time.' }, { formulaName: 'MONTH', category: 'Date & Time', description: 'Returns the number of months in a specified date string.' }, { formulaName: 'PROPER', category: 'Text', description: 'Converts a text to proper case; first letter to uppercase and other letters to lowercase.' } ]; this.isConcat = false; this.parent = parent; this.init(); } BasicFormulas.prototype.init = function () { var fn; for (var i = 0; i < this.formulas.length; i++) { fn = getValue('Compute' + this.formulas[i].formulaName, this).bind(this); this.addFormulaCollection(this.formulas[i].formulaName.toUpperCase(), fn, this.formulas[i].category, this.formulas[i].description); } }; BasicFormulas.prototype.addFormulaCollection = function (formulaName, functionName, formulaCategory, description) { this.parent.libraryFormulas = { fName: formulaName, handler: functionName, category: formulaCategory, description: description }; }; /** * @hidden * @param {string[]} args - specify the args * @returns {string | number} - Comput sum value */ BasicFormulas.prototype.ComputeSUM = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var isSubtotalFormula = false; var isAggregateComputation; var sheet; if (args.length) { var lastArgument = args[args.length - 1]; if (lastArgument === 'isSubtotal') { isSubtotalFormula = true; args.pop(); } else if (lastArgument === 'isAggregate') { sheet = this.parent.parentObject.getActiveSheet(); isAggregateComputation = true; args.pop(); } } if (isNullOrUndefined(args) || (args.length === 1 && args[0] === '')) { return this.parent.formulaErrorStrings[FormulasErrorsStrings.InvalidArguments]; } var sum = 0; var val; var orgValue; var maxDecimalLength = 0; var indexes; if (!isNullOrUndefined(args)) { var argArr = args; var setMaxDecimalLength = function (val) { if (val.toString().indexOf('.') > -1) { maxDecimalLength = Math.max(maxDecimalLength, val.split('.')[1].length); } }; for (var i = 0; i < argArr.length; i++) { var argValue = argArr[i].toString(); if (argValue.indexOf(':') > -1 && this.parent.isCellReference(argValue)) { var cellCollection = this.parent.getCellCollection(argValue.split(this.parent.tic).join('')); for (var j = 0; j < cellCollection.length; j++) { if (isAggregateComputation) { indexes = getCellIndexes(cellCollection[j]); if (isHiddenRow(sheet, indexes[0]) || isHiddenCol(sheet, indexes[1])) { continue; } } val = !isSubtotalFormula ? this.parent.getValueFromArg(cellCollection[j]) : this.parent.getValueFromArg(cellCollection[j], null, null, true); if (isSubtotalFormula && val.includes('SUBTOTAL(')) { continue; } if (this.parent.getErrorStrings().indexOf(val) > -1) { return val; } if (isNullOrUndefined(val[0]) || isNaN(this.parent.parseFloat(val))) { continue; } setMaxDecimalLength(val); sum = sum + this.parent.parseFloat(val); } } else { if (argArr[i].indexOf(this.parent.tic) > -1) { if (isNaN(this.parent.parseFloat(argArr[i].split(this.parent.tic).join(''))) || argArr[i].split(this.parent.tic).join('').trim() === '') { return this.parent.getErrorStrings()[CommonErrors.Value]; } } if (argArr[i].split(this.parent.tic).join('') === this.parent.trueValue) { argArr[i] = '1'; } if (argArr[i].split(this.parent.tic).join('') === this.parent.falseValue) { argArr[i] = '0'; } orgValue = !isSubtotalFormula ? this.parent.getValueFromArg(argArr[i].split(this.parent.tic).join('')) : this.parent.getValueFromArg(argArr[i].split(this.parent.tic).join(''), null, null, true); if (isSubtotalFormula && orgValue.includes('SUBTOTAL(')) { continue; } if (this.parent.getErrorStrings().indexOf(orgValue) > -1) { return orgValue; } if (isNullOrUndefined(orgValue) || isNaN(this.parent.parseFloat(orgValue))) { continue; } if (orgValue.length > 0) { setMaxDecimalLength(orgValue); sum = sum + this.parent.parseFloat(orgValue + ''); } } } } return sum.toString().indexOf('.') > -1 ? sum.toFixed(maxDecimalLength) : sum; }; /** * @hidden * @param {string[]} args - specify the args. * @returns {string | number} - Compute the Integer. */ BasicFormulas.prototype.ComputeINT = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var argsValue; var errCollection = this.parent.getErrorStrings(); if (args[0] === '' && args.length === 1) { return this.parent.formulaErrorStrings[FormulasErrorsStrings.InvalidArguments]; } else if (args.length > 1) { return this.parent.formulaErrorStrings[FormulasErrorsStrings.WrongNumberArguments]; } argsValue = this.parent.getValueFromArg(args[0]); if (errCollection.indexOf(argsValue) > -1) { return argsValue; } if (argsValue.toUpperCase() === this.parent.trueValue) { argsValue = '1'; } else if (argsValue.toUpperCase() === this.parent.falseValue) { argsValue = '0'; } if (!this.parent.isCellReference(args[0])) { if (args[0].indexOf(this.parent.tic + this.parent.tic) === -1) { argsValue = argsValue.split(this.parent.tic).join(''); } if (argsValue.trim() === '') { return errCollection[CommonErrors.Value]; } } if (argsValue.indexOf('%') > -1) { argsValue = (Number(argsValue.split('%')[0]) * 0.01).toString(); } if (isNaN(this.parent.parseFloat(argsValue))) { return errCollection[CommonErrors.Value]; } argsValue = this.parent.parseFloat(argsValue); argsValue = Math.floor(argsValue); return argsValue; }; /** * @hidden * @param {string[]} args - specify the args. * @returns {Date | string} - Compute the Today. */ BasicFormulas.prototype.ComputeTODAY = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var str; if (args.length !== 1 || args[0] !== '') { str = this.parent.formulaErrorStrings[FormulasErrorsStrings.InvalidArguments]; } else { var dt = new Date(Date.now()); if (this.parent.parentObject.getModuleName() === 'spreadsheet') { str = this.parent.parentObject.dateToInt(dt); if (this.parent.parser.storedStringText.toUpperCase().indexOf('TODAY') === 0 && this.parent.cell !== '') { this.parent.parentObject.setDateFormat(this.parent.getSheetId(this.parent.grid), this.parent.rowIndex(this.parent.cell) - 1, this.parent.colIndex(this.parent.cell) - 1); } } else { str = dt.getFullYear() + '/' + this.parent.calculateDate((dt.getMonth() + 1).toString()) + '/' + this.parent.calculateDate(dt.getDate().toString()); } } return str; }; /** * @hidden * @param {string[]} args - specify the args. * @returns {number} - Compute the day from the date. */ BasicFormulas.prototype.ComputeWEEKDAY = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if ((args[0] === '' && isNullOrUndefined(args[1])) || args.length > 2) { return this.parent.formulaErrorStrings[FormulasErrorsStrings.InvalidArguments]; } if ((args[0] === '' && args[1] === '') || args[1] === '') { return this.parent.getErrorStrings()[CommonErrors.Num].toString(); } if (args.length === 1) { args.push('1'); } if ((args[0].indexOf(this.parent.tic) > -1 && args[0].split(this.parent.tic).join('').trim() === '') || (args[1].split(this.parent.tic).join('').trim() === '') || (args[1].indexOf(this.parent.tic) > -1 && isNaN(this.parent.parseFloat(args[1].split(this.parent.tic).join(''))))) { return this.parent.getErrorStrings()[CommonErrors.Value]; } var date; var value; var day; if (this.parent.isCellReference(args[0])) { date = this.parent.getValueFromArg(args[0].split(this.parent.tic).join('')) || '0'; if (date.indexOf(this.parent.tic) > -1) { return this.parent.getErrorStrings()[CommonErrors.Value]; } } else { if ((args[0].indexOf(this.parent.tic) > -1 && isNaN(this.parent.parseFloat(args[0].split(this.parent.tic).join(''))))) { date = this.parent.getValueFromArg(args[0]); } else { date = this.parent.getValueFromArg(args[0].split(this.parent.tic).join('')) || '0'; } } if (this.parent.isCellReference(args[1])) { value = this.parent.getValueFromArg(args[1].split(this.parent.tic).join('')) || '0'; } else { value = this.parent.getValueFromArg(args[1].split(this.parent.tic).join('')); } if (this.parent.getErrorStrings().indexOf(date) > -1) { return date; } if (this.parent.getErrorStrings().indexOf(value) > -1) { return value; } date = date === this.parent.trueValue ? '1' : (date === this.parent.falseValue ? '0' : date); value = value === this.parent.trueValue ? '1' : (value === this.parent.falseValue ? '0' : value); day = this.parent.parseFloat(date); value = this.parent.parseFloat(value); if (isNaN(value) || isNaN(day)) { return this.parent.getErrorStrings()[CommonErrors.Value]; } if (day < 0 || day > 2958465) { return this.parent.getErrorStrings()[CommonErrors.Num].toString(); } value = parseInt(value.toString(), 10); day = day < 1 ? 0 : Math.floor(day) % 7; switch (value) { case 1: case 17: day = day <= 0 ? day + 7 : day; break; case 2: case 11: day = day - 1; day = day <= 0 ? day + 7 : day; break; case 3: day = day - 2; day = day < 0 ? day + 7 : day; break; case 12: day = day + 5; day = day > 7 ? day - 7 : day; break; case 13: day = day + 4; day = day > 7 ? day - 7 : day; break; case 14: day = day + 3; day = day > 7 ? day - 7 : day; break; case 15: day = day + 2; day = day > 7 ? day - 7 : day; break; case 16: day = day + 1; day = day > 7 ? day - 7 : day; break; default: day = this.parent.getErrorStrings()[CommonErrors.Num].toString(); break; } return day; }; /** * @hidden * @param {string[]} args - specify the args. * @returns {string} - Compute to the Proper casing. */ BasicFormulas.prototype.ComputePROPER = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var str; var nestedFormula; var errCollection = this.parent.getErrorStrings(); if (args.length && args[args.length - 1] === 'nestedFormulaTrue') { nestedFormula = true; args.pop(); } if (isNullOrUndefined(args) || (args[0].trim() === '' && args.length === 1)) { return this.parent.formulaErrorStrings[FormulasErrorsStrings.InvalidArguments]; } else if (args.length > 1) { return this.parent.formulaErrorStrings[FormulasErrorsStrings.WrongNumberArguments]; } str = this.parent.getValueFromArg(args[0]).trim(); if (errCollection.indexOf(str) > -1) { return str; } if (args[0].indexOf(this.parent.tic) > -1) { if (args[0] !== str && args[0].startsWith('n')) { str = this.parent.removeTics(str.trim()); } else { str = this.parent.removeTics(args[0].trim()); if (str.indexOf(this.parent.tic + this.parent.tic) > -1) { str = str.replace(/""/g, this.parent.tic); } } } else if (!args[0].startsWith('n') && str.split('%').length === 2 && this.parent.isNumber(str.split('%')[0])) { str = (Number(str.split('%')[0]) / 100).toString(); } str = str.toLowerCase().replace(/\b\w/g, function (char) { return char.toUpperCase(); }).replace(/(\d)([a-z])/g, function (match, number, char) { return number + char.toUpperCase(); }); if (nestedFormula) { str = this.parent.tic + str + this.parent.tic; } return str; }; /** * @hidden * @param {string[]} args - specify the args. * @returns {string | number} - Compute the Sum product. */ BasicFormulas.prototype.ComputeSUMPRODUCT = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var _a, _b; if (isNullOrUndefined(args) || (args.length === 1 && args[0] === '')) { return this.parent.formulaErrorStrings[FormulasErrorsStrings.InvalidArguments]; } var sum = 0; var count = 0; var index; var mulValues = null; var ranges = args; var len = []; for (var i = 0; i < ranges.length; i++) { var cells = this.parent.getCellCollection(ranges[i]); if (cells[0] === '#REF!') { return this.parent.getErrorStrings()[CommonErrors.Name]; } len.push(cells.length); } for (var j = 0; j < len.length; j++) { if (len[j] && len[j + 1] && len[j] !== len[j + 1]) { return this.parent.getErrorStrings()[CommonErrors.Value]; } } for (var k = 0; k < ranges.length; ++k) { var range = ranges[k]; if (!range.startsWith(this.parent.tic) && this.parent.isCellReference(range)) { var i = range.indexOf(':'); var startRow = this.parent.rowIndex(range.substr(0, i)); var endRow = this.parent.rowIndex(range.substr(i + 1)); if (!(startRow !== -1 || endRow === -1) === (startRow === -1 || endRow !== -1)) { return this.parent.getErrorStrings()[CommonErrors.Name]; } if (startRow > endRow) { _a = [endRow, startRow], startRow = _a[0], endRow = _a[1]; } var col1 = this.parent.colIndex(range.substr(0, i)); var col2 = this.parent.colIndex(range.substr(i + 1)); if (col1 > col2) { _b = [col2, col1], col1 = _b[0], col2 = _b[1]; } if (mulValues === null) { count = (endRow - startRow + 1) * (col2 - col1 + 1); mulValues = []; for (i = 0; i < count; ++i) { mulValues[i] = 1; //To create required index. } } i = 0; for (var row = startRow; row <= endRow; ++row) { for (var col = col1; col <= col2; ++col) { var cellRef = this.getSheetReference(range) + this.parent.convertAlpha(col) + (row); var result = this.parent.getValueFromArg(cellRef); if (this.parent.getErrorStrings().indexOf(result) > -1) { return result; } if (!isNaN(this.parent.parseFloat(result))) { //To return #VALUE! error when array dimensions are mismatched. if (isNaN(mulValues[i])) { return this.parent.getErrorStrings()[CommonErrors.Name]; } mulValues[i] = mulValues[i] * this.parent.parseFloat(result); } else { mulValues[i] = 0; } i++; } } } else { var s1 = this.parent.getValueFromArg(range); index = s1.indexOf('"'); if (this.parent.getErrorStrings().indexOf(s1) > -1) { return s1; } else if (index > -1) { return 0; } else { return this.parent.getErrorStrings()[CommonErrors.Value]; } } } for (var i = 0; i < count; ++i) { sum += mulValues[i]; } return sum; }; /** * @hidden * @param {string[]} args - specify the args. * @returns {string | number} - Compute the Roundup. */ BasicFormulas.prototype.ComputeROUNDUP = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var str; var arg1; var arg2; var index; var num; var len = args.length; if (!isNullOrUndefined(args) && len > 2) { str = this.parent.formulaErrorStrings[FormulasErrorsStrings.InvalidArguments]; } if (len === 1 && args[0] !== '') { index = args[0].indexOf('"'); arg1 = args[0].indexOf('"') > -1 ? args[0].replace('"', '') : args[0]; arg1 = arg1.indexOf('"') > -1 ? arg1.replace('"', '') : arg1; arg1 = arg1.toUpperCase() === 'TRUE' ? '1' : (arg1 === 'FALSE' ? '0' : arg1); arg1 = this.parent.getValueFromArg(arg1); num = this.parent.parseFloat(arg1); if (num > 0) { num += .4999999999; // To round the number, we using this value. } else if (num < 0) { num -= .4999999999; } num = this.parent.parseFloat(num.toFixed(0)); str = num.toString(); } else if (len === 2) { index = args[0].indexOf('"') > -1 ? args[0].indexOf('"') : (args[1].indexOf('"') > -1 ? args[1].indexOf('"') : -1); if (this.parent.isCellReference(args[0])) { arg1 = this.parent.getValueFromArg(args[0]) || '0'; } else { if (args[0].indexOf(this.parent.tic) > -1 && (args[0].split(this.parent.tic).join('') === this.parent.trueValue || args[0].split(this.parent.tic).join('') === this.parent.falseValue)) { return this.parent.getErrorStrings()[CommonErrors.Value]; } arg1 = this.parent.getValueFromArg(args[0]).split(this.parent.tic).join(''); } if (this.parent.getErrorStrings().indexOf(arg1) > -1) { return arg1; } if (this.parent.isCellReference(args[1])) { arg2 = this.parent.getValueFromArg(args[1]) || '0'; } else { if (args[1].indexOf(this.parent.tic) > -1 && (args[1].split(this.parent.tic).join('') === this.parent.trueValue || args[1].split(this.parent.tic).join('') === this.parent.falseValue)) { return this.parent.getErrorStrings()[CommonErrors.Value]; } arg2 = this.parent.getValueFromArg(args[1]).split(this.parent.tic).join(''); } if (this.parent.getErrorStrings().indexOf(arg2) > -1) { return arg2; } arg1 = arg1.toUpperCase() === 'TRUE' ? '1' : (arg1 === 'FALSE' ? '0' : arg1); arg2 = arg2.toUpperCase() === 'TRUE' ? '1' : (arg2 === 'FALSE' ? '0' : arg2); var isInvalidNumStr = isNaN(Number(arg1)) || arg1.trim() === ''; var isInvalidDigStr = isNaN(Number(arg2)) || arg2.trim() === ''; if (((args[0].indexOf('"') > -1 || this.parent.isCellReference(args[0])) && isInvalidNumStr) || ((args[1].indexOf('"') > -1 || this.parent.isCellReference(args[1])) && isInvalidDigStr)) { return this.parent.getErrorStrings()[CommonErrors.Value]; } var digits = Math.ceil(this.parent.parseFloat(arg2)); num = this.parent.parseFloat(arg1); if (digits > 0) { var decimalArr = arg1.split('.'); var decimalCount = decimalArr.length === 2 ? (decimalArr[1].length >= digits ? digits : decimalArr[1].length) : 0; num = this.parent.parseFloat(this.preciseRound(num, decimalCount, 'ROUNDUP')); str = num.toString(); if (isNaN(num)) { if (digits.toString().indexOf('"') > -1) { str = this.parent.getErrorStrings()[CommonErrors.Value]; } else { str = this.parent.getErrorStrings()[CommonErrors.Name]; } } } else { if (num > 0) { num = (num / Math.pow(10, -digits)) + .49999; } else if (num < 0) { num = (num / Math.pow(10, -digits)) - .49999; } if (num > 0 && digits < -9) { num = 1 * Math.pow(10, -digits); } else { num = this.parent.parseFloat(num.toFixed(0)) * Math.pow(10, -digits); } str = num.toString(); if (isNaN(num)) { str = (digits.toString().indexOf('"') > -1) ? this.parent.getErrorStrings()[CommonErrors.Value] : str = this.parent.getErrorStrings()[CommonErrors.Name]; } } } else { str = index > -1 ? this.parent.getErrorStrings()[CommonErrors.Value] : this.parent.formulaErrorStrings[FormulasErrorsStrings.InvalidArguments]; } return str; }; /** * @hidden * @param {string[]} args - specify the args. * @returns {string | number} - Compute the Rounddown. */ BasicFormulas.prototype.ComputeROUNDDOWN = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var result; var arg1; var arg2; var index; var num; var len = args.length; if (!isNullOrUndefined(args) && len > 2) { result = this.parent.formulaErrorStrings[FormulasErrorsStrings.InvalidArguments]; } if (len === 1 && args[0] !== '') { index = args[0].indexOf('"'); arg1 = args[0].indexOf('"') > -1 ? args[0].replace('"', '') : args[0]; arg1 = arg1.indexOf('"') > -1 ? arg1.replace('"', '') : arg1; arg1 = arg1.toUpperCase() === 'TRUE' ? '1' : (arg1 === 'FALSE' ? '0' : arg1); arg1 = this.parent.getValueFromArg(arg1); num = this.parent.parseFloat(arg1); if (num > 0) { num -= .4999999999; // To round the number, we are using this value. } else if (num < 0) { num += .4999999999; } num = this.parent.parseFloat(num.toFixed(0)); result = num.toString(); } else if (len === 2) { index = args[0].indexOf('"') > -1 ? args[0].indexOf('"') : (args[1].indexOf('"') > -1 ? args[1].indexOf('"') : -1); if (this.parent.isCellReference(args[0])) { arg1 = this.parent.getValueFromArg(args[0]) || '0'; } else { if (args[0].indexOf(this.parent.tic) > -1 && (args[0].split(this.parent.tic).join('') === this.parent.trueValue || args[0].split(this.parent.tic).join('') === this.parent.falseValue)) { return this.parent.getErrorStrings()[CommonErrors.Value]; } arg1 = this.parent.getValueFromArg(args[0]).split(this.parent.tic).join(''); } if (this.parent.getErrorStrings().indexOf(arg1) > -1) { return arg1; } if (this.parent.isCellReference(args[1])) { arg2 = this.parent.getValueFromArg(args[1]) || '0'; } else { if (args[1].indexOf(this.parent.tic) > -1 && (args[1].split(this.parent.tic).join('') === this.parent.trueValue || args[1].split(this.parent.tic).join('') === this.parent.falseValue)) { return this.parent.getErrorStrings()[CommonErrors.Value]; } arg2 = this.parent.getValueFromArg(args[1]).split(this.parent.tic).join(''); } if (this.parent.getErrorStrings().indexOf(arg2) > -1) { return arg2; } arg1 = arg1.toUpperCase() === 'TRUE' ? '1' : (arg1 === 'FALSE' ? '0' : arg1); arg2 = arg2.toUpperCase() === 'TRUE' ? '1' : (arg2 === 'FALSE' ? '0' : arg2); var isInvalidNumStr = isNaN(Number(arg1)) || arg1.trim() === ''; var isInvalidDigStr = isNaN(Number(arg2)) || arg2.trim() === ''; if (((args[0].indexOf('"') > -1 || this.parent.isCellReference(args[0])) && isInvalidNumStr) || ((args[1].indexOf('"') > -1 || this.parent.isCellReference(args[1])) && isInvalidDigStr)) { return this.parent.getErrorStrings()[CommonErrors.Value]; } var digits = Math.ceil(this.parent.parseFloat(arg2)); num = this.parent.parseFloat(arg1); if (digits > 0) { var decimalIndex = arg1.indexOf('.'); var decimalCount = 0; if (decimalIndex !== -1) { decimalCount = arg1.length - decimalIndex - 1; decimalCount = decimalCount >= digits ? digits : decimalCount; } num = this.parent.parseFloat(this.preciseRound(num, decimalCount, 'ROUNDDOWN')); result = num.toString(); if (isNaN(num)) { if (digits.toString().indexOf('"') > -1) { result = this.parent.getErrorStrings()[CommonErrors.Value]; } else { result = this.parent.getErrorStrings()[CommonErrors.Name]; } } } else { if (num > 0) { num = (num / Math.pow(10, -digits)) - .49999; } else if (num < 0) { num = (num / Math.pow(10, -digits)) + .49999; } if (num > 0 && digits < -9) { num = 1 * Math.pow(10, -digits); } else { num = this.parent.parseFloat(num.toFixed(0)) * Math.pow(10, -digits); } result = num.toString(); if (isNaN(num)) { result = (digits.toString().indexOf('"') > -1) ? this.parent.getErrorStrings()[CommonErrors.Value] : result = this.parent.getErrorStrings()[CommonErrors.Name]; } } } else { result = index > -1 ? this.parent.getErrorStrings()[CommonErrors.Value] : this.parent.formulaErrorStrings[FormulasErrorsStrings.InvalidArguments]; } return result; }; /** * @hidden * @param {string[]} args - specify the args. * @returns {number | string} - Compute the count. */ BasicFormulas.prototype.ComputeCOUNT = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var isSubtotalFormula = false; if (args.length && args[args.length - 1] === 'isSubtotal') { isSubtotalFormula = true; args.pop(); } if (isNullOrUndefined(args) || (args.length === 1 && args[0] === '')) { return this.parent.formulaErrorStrings[FormulasErrorsStrings.WrongNumberArguments]; } var argArr = args; var argVal; var cellColl; var result = 0; var cellValue; var value; for (var i = 0; i < argArr.length; i++) { argVal = argArr[i]; if (this.parent.isCellReference(argVal)) { if (argVal.indexOf(':') > -1) { cellColl = this.parent.getCellCollection(argVal.split(this.parent.tic).join('')); for (var j = 0; j < cellColl.length; j++) { cellValue = !isSubtotalFormula ? this.parent.getValueFromArg(cellColl[j]) : this.parent.getValueFromArg(cellColl[j], null, null, true); if (isSubtotalFormula && cellValue.includes('SUBTOTAL(')) { continue; } if (!isNaN(this.parent.parseFloat(cellValue))) { if (argVal.length > 0 && cellValue.trim() !== '') { result++; } } } } else { cellValue = !isSubtotalFormula ? this.parent.getValueFromArg(argVal) : this.parent.getValueFromArg(argVal, null, null, true); if (isSubtotalFormula && cellValue.includes('SUBTOTAL(')) { continue; } if (!isNaN(this.parent.parseFloat(cellValue))) { if (argVal.length > 0 && cellValue.trim() !== '') { result++; } } } } else { value = this.parent.getValueFromArg(argVal).split(this.parent.tic).join(''); if (argVal.length === 0 && value.trim() === '') { result++; } else if (!isNaN(this.parent.parseFloat(value)) || argVal === this.parent.trueValue || argVal === this.parent.falseValue) { if (argVal.length > 0 && argVal.trim() !== '' && value.trim() !== '') { result++; } } } } return result; }; /** * @hidden * @param {string[]} args - specify the args. * @returns {Date | string} - Compute the Date. */ BasicFormulas.prototype.ComputeDATE = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var nestedFormula; if (args.length && args[args.length - 1] === 'nestedFormulaTrue') { nestedFormula = true; args.pop(); } if (isNullOrUndefined(args) || (args.length === 1 && args[0] === '')) { return this.parent.formulaErrorStrings[FormulasErrorsStrings.WrongNumberArguments]; } if (args.length !== 3) { return this.parent.formulaErrorStrings[FormulasErrorsStrings.WrongNumberArguments]; } var argArr = []; for (var i = 0; i < args.length; ++i) { argArr[i] = this.parent.getValueFromArg(args[i]); } argArr[0] = (argArr[0] === this.parent.trueValue) ? '1' : (argArr[0] === this.parent.falseValue) ? '0' : argArr[0]; argArr[1] = (argArr[1] === this.parent.trueValue) ? '1' : (argArr[1] === this.parent.falseValue) ? '0' : argArr[1]; argArr[2] = (argArr[2] === this.parent.trueValue) ? '1' : (argArr[2] === this.parent.falseValue) ? '0' : argArr[2]; for (var idx = 0; idx < argArr.length; idx++) { var argsValue = argArr[idx]; if (this.parent.getErrorStrings().indexOf(argsValue) > -1) { return argsValue; } else if ((argsValue === '""') || (argsValue === '"0"' && args[idx] !== '"0"') || (argsValue === '"TRUE"' || argsValue === '"FALSE"')) { return this.parent.getErrorStrings()[CommonErrors.Value].toString(); } } var year = Math.floor(this.parent.parseFloat(argArr[0].split(this.parent.tic).join(''))); var month = Math.floor(this.parent.parseFloat(argArr[1].split(this.parent.tic).join(''))); var day = Math.floor(this.parent.parseFloat(argArr[2].split(this.parent.tic).join(''))); var days = 0; if (!isNaN(year) && !isNaN(month) && !isNaN(day)) { if ((year < 0 && month <= 12) || (year >= 10000 && month > 0)) { return this.parent.getErrorStrings()[CommonErrors.Num].toString(); } while (month > 12) { month -= 12; year++; } days = this.parent.getSerialDateFromDate(year, month, day); } else { return this.parent.getErrorStrings()[CommonErrors.Value].toString(); } if (days === 0) { return this.parent.getErrorStrin