@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
JavaScript
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