Skip to content

Commit

Permalink
Feature/add choose functions (#3072)
Browse files Browse the repository at this point in the history
* [se] Support choosecols/chooserows functions
  • Loading branch information
GoshaZotov authored Oct 31, 2022
1 parent 6cff181 commit 994af87
Show file tree
Hide file tree
Showing 3 changed files with 422 additions and 8 deletions.
119 changes: 111 additions & 8 deletions cell/model/FormulaObjects/lookupandreferenceFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function (window, undefined) {
var _func = AscCommonExcel._func;

cFormulaFunctionGroup['LookupAndReference'] = cFormulaFunctionGroup['LookupAndReference'] || [];
cFormulaFunctionGroup['LookupAndReference'].push(cADDRESS, cAREAS, cCHOOSE, cCOLUMN, cCOLUMNS, cFORMULATEXT,
cFormulaFunctionGroup['LookupAndReference'].push(cADDRESS, cAREAS, cCHOOSE, cCHOOSECOLS, cCHOOSEROWS, cCOLUMN, cCOLUMNS, cFORMULATEXT,
cGETPIVOTDATA, cHLOOKUP, cHYPERLINK, cINDEX, cINDIRECT, cLOOKUP, cMATCH, cOFFSET, cROW, cROWS, cRTD, cTRANSPOSE,
cUNIQUE, cVLOOKUP, cXLOOKUP, cVSTACK, cHSTACK, cTOROW, cTOCOL, cWRAPROWS, cWRAPCOLS);

Expand Down Expand Up @@ -281,6 +281,109 @@ function (window, undefined) {
return new cError(cErrorType.wrong_value_type);
};

function chooseRowsCols(arg, argument1, byCol) {
var argError = cBaseFunction.prototype._checkErrorArg.call(this, arg);
if (argError) {
return argError;
}

let arg1 = arg[0];
let matrix;
if (arg1.type === cElementType.cellsRange || arg1.type === cElementType.array || arg1.type === cElementType.cell || arg1.type === cElementType.cell3D) {
matrix = arg1.getMatrix();
} else if (arg1.type === cElementType.cellsRange3D) {
if (arg1.isSingleSheet()) {
matrix = arg1.getMatrix()[0];
} else {
return new cError(cErrorType.bad_reference);
}
} else if (arg1.type === cElementType.error) {
return arg1;
} else if (arg1.type === cElementType.empty) {
return new cError(cErrorType.wrong_value_type);
} else {
matrix = [[arg1]];
}

var dimension = arg1.getDimensions();
let res;
for (let i = 1; i < arg.length; i++) {
let _arg = arg[i];

if (cElementType.cellsRange === _arg.type || cElementType.cellsRange3D === _arg.type) {
//_arg = _arg.getValue2(0,0);
return new cError(cErrorType.wrong_value_type);
} else if (cElementType.array === _arg.type) {
//_arg = _arg.getElementRowCol(0, 0);
return new cError(cErrorType.wrong_value_type);
}

_arg = _arg.tocNumber();
if (_arg.type === cElementType.error) {
return _arg;
}
_arg = _arg.toNumber();
let reverse = _arg < 0;
_arg = Math.abs(_arg);
_arg = parseInt(_arg);
if (_arg < 1 || (_arg > dimension.col && byCol) || (_arg > dimension.row && !byCol)) {
return new cError(cErrorType.wrong_value_type);
}

if (!res) {
res = new cArray();
}

if (byCol) {
res.pushCol(matrix, reverse ? dimension.col - (_arg - 1) - 1 : _arg - 1);
} else {
res.pushRow(matrix, reverse ? dimension.row - (_arg - 1) - 1 : _arg - 1);
}
}

return res ? res : new cError(cErrorType.wrong_value_type);
}

/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cCHOOSECOLS() {
}

//***array-formula***
cCHOOSECOLS.prototype = Object.create(cBaseFunction.prototype);
cCHOOSECOLS.prototype.constructor = cCHOOSECOLS;
cCHOOSECOLS.prototype.name = 'CHOOSECOLS';
cCHOOSECOLS.prototype.argumentsMin = 2;
cCHOOSECOLS.prototype.argumentsMax = 253;
cCHOOSECOLS.prototype.argumentsType = [argType.reference, [argType.number]];
cCHOOSECOLS.prototype.returnValueType = AscCommonExcel.cReturnFormulaType.array;
cCHOOSECOLS.prototype.isXLFN = true;
cCHOOSECOLS.prototype.Calculate = function (arg) {
return chooseRowsCols(arg, arguments[1], true);
};

/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cCHOOSEROWS() {
}

//***array-formula***
cCHOOSEROWS.prototype = Object.create(cBaseFunction.prototype);
cCHOOSEROWS.prototype.constructor = cCHOOSEROWS;
cCHOOSEROWS.prototype.name = 'CHOOSEROWS';
cCHOOSEROWS.prototype.argumentsMin = 2;
cCHOOSEROWS.prototype.argumentsMax = 253;
cCHOOSEROWS.prototype.argumentsType = [argType.reference, [argType.number]];
cCHOOSEROWS.prototype.returnValueType = AscCommonExcel.cReturnFormulaType.array;
cCHOOSEROWS.prototype.isXLFN = true;
cCHOOSEROWS.prototype.Calculate = function (arg) {
return chooseRowsCols(arg, arguments[1]);
};

/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
Expand Down Expand Up @@ -2502,7 +2605,7 @@ function (window, undefined) {
} else {
return new cError(cErrorType.wrong_value_type);
}
}
};

/**
* @constructor
Expand Down Expand Up @@ -2544,7 +2647,7 @@ function (window, undefined) {
let maxColCount = 0;
for (let j = 0; j < matrix.length; j++) {
if (matrix[j]) {
maxColCount = Math.max(maxColCount, matrix[j].length)
maxColCount = Math.max(maxColCount, matrix[j].length);
for (let k = 0; k < matrix[j].length; k++) {
if (matrix[j][k]) {
if (!unionArray) {
Expand All @@ -2569,7 +2672,7 @@ function (window, undefined) {
} else {
return new cError(cErrorType.wrong_value_type);
}
}
};

function toRowCol(arg, argument1, toCol) {
var argError = cBaseFunction.prototype._checkErrorArg.call(this, arg);
Expand Down Expand Up @@ -2680,7 +2783,7 @@ function (window, undefined) {
cTOROW.prototype.isXLFN = true;
cTOROW.prototype.Calculate = function (arg) {
return toRowCol(arg, arguments[1]);
}
};

/**
* @constructor
Expand All @@ -2701,7 +2804,7 @@ function (window, undefined) {
cTOCOL.prototype.isXLFN = true;
cTOCOL.prototype.Calculate = function (arg) {
return toRowCol(arg, arguments[1], true);
}
};

function wrapRowsCols(arg, argument1, toCol) {
var argError = cBaseFunction.prototype._checkErrorArg.call(this, arg);
Expand Down Expand Up @@ -2799,7 +2902,7 @@ function (window, undefined) {
cWRAPROWS.prototype.isXLFN = true;
cWRAPROWS.prototype.Calculate = function (arg) {
return wrapRowsCols(arg, arguments[1]);
}
};

/**
* @constructor
Expand All @@ -2820,7 +2923,7 @@ function (window, undefined) {
cWRAPCOLS.prototype.isXLFN = true;
cWRAPCOLS.prototype.Calculate = function (arg) {
return wrapRowsCols(arg, arguments[1], true);
}
};

var g_oVLOOKUPCache = new VHLOOKUPCache(false);
var g_oHLOOKUPCache = new VHLOOKUPCache(true);
Expand Down
18 changes: 18 additions & 0 deletions cell/model/FormulaObjects/parserFormula.js
Original file line number Diff line number Diff line change
Expand Up @@ -2711,6 +2711,24 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara
this.countElement += this.array[i].length;
}
};
cArray.prototype.pushCol = function (matrix, colNum) {
for (let i = 0; i < matrix.length; i++) {
if (matrix[i] && matrix[i][colNum]) {
if (!this.array[i]) {
this.array[i] = [];
}
this.array[i].push(matrix[i][colNum]);
}
}
this.recalculate();
};
cArray.prototype.pushRow = function (matrix, colNum) {
if (matrix && matrix[colNum]) {
this.array.push(matrix[colNum]);
this.recalculate();
}
};



/**
Expand Down
Loading

0 comments on commit 994af87

Please sign in to comment.