From ee704b386842901b68ce7b84504045c4d2bd30d8 Mon Sep 17 00:00:00 2001 From: GoshaZotov Date: Fri, 13 Dec 2024 10:38:38 +0300 Subject: [PATCH] [se] Fix bug 71925 --- .../model/FormulaObjects/databaseFunctions.js | 80 +++++++-- cell/model/FormulaObjects/parserFormula.js | 4 +- .../spreadsheet-calculation/FormulaTests.js | 158 ++++++++++++++++++ 3 files changed, 227 insertions(+), 15 deletions(-) diff --git a/cell/model/FormulaObjects/databaseFunctions.js b/cell/model/FormulaObjects/databaseFunctions.js index 91f7857293..0ef639cc26 100644 --- a/cell/model/FormulaObjects/databaseFunctions.js +++ b/cell/model/FormulaObjects/databaseFunctions.js @@ -321,6 +321,7 @@ function (window, undefined) { var previousWinArray; var winElems = []; + let isContainsHeader = false; for (var i = 1; i < conditionData.length; i++) { previousWinArray = null; for (var j = 0; j < conditionData[0].length; j++) { @@ -334,6 +335,8 @@ function (window, undefined) { continue; } + isContainsHeader = true; + var winColumnArray = []; for (var n = 0; n < databaseData.length; n++) { if (previousWinArray && previousWinArray[n]) { @@ -349,6 +352,9 @@ function (window, undefined) { winElems[i - 1] = previousWinArray; } + if ((!winElems.length || (winElems.length && winElems[0] && !winElems[0].length)) && isContainsHeader) { + return null; + } var resArr = []; var usuallyAddElems = []; @@ -363,24 +369,36 @@ function (window, undefined) { return new cError(cErrorType.wrong_value_type); } - for (var i = 0; i < winElems.length; i++) { - for (var j in winElems[i]) { - if (winElems[i].hasOwnProperty(j)) { - if (true === usuallyAddElems[j] || cElementType.empty === needDataColumn[j].type) { - continue; - } + if (!isContainsHeader) { + //ms wins all + for (let i = 0; i < needDataColumn.length; i++) { + if (bIsGetObjArray) { + resArr.push(needDataColumn[i]); + } else { + resArr.push(needDataColumn[i].getValue()); + } + } + } else { + for (let i = 0; i < winElems.length; i++) { + for (let j in winElems[i]) { + if (winElems[i].hasOwnProperty(j)) { + if (true === usuallyAddElems[j] || cElementType.empty === needDataColumn[j].type) { + continue; + } - if (bIsGetObjArray) { - resArr.push(needDataColumn[j]); - } else { - resArr.push(needDataColumn[j].getValue()); - } + if (bIsGetObjArray) { + resArr.push(needDataColumn[j]); + } else { + resArr.push(needDataColumn[j].getValue()); + } - usuallyAddElems[j] = true; + usuallyAddElems[j] = true; + } } } } + return resArr.length ? resArr : new cError(cErrorType.division_by_zero); } @@ -416,6 +434,9 @@ function (window, undefined) { } var resArr = getNeedValuesFromDataBase(argClone[0], argClone[1], argClone[2]); + if (resArr === null) { + return new cError(cErrorType.division_by_zero); + } if (cElementType.error === resArr.type) { return resArr; } @@ -467,6 +488,9 @@ function (window, undefined) { } var resArr = getNeedValuesFromDataBase(argClone[0], argClone[1], argClone[2], null, true); + if (resArr === null) { + return new cNumber(0); + } if (cElementType.error === resArr.type) { return resArr; } @@ -517,6 +541,9 @@ function (window, undefined) { } var resArr = getNeedValuesFromDataBase(argClone[0], argClone[1], argClone[2], true, true); + if (resArr === null) { + return new cNumber(0); + } if (cElementType.error === resArr.type) { return resArr; } @@ -559,6 +586,9 @@ function (window, undefined) { } var resArr = getNeedValuesFromDataBase(argClone[0], argClone[1], argClone[2]); + if (resArr === null) { + return new cError(cErrorType.wrong_value_type); + } if (cElementType.error === resArr.type) { return resArr; } @@ -598,6 +628,9 @@ function (window, undefined) { } var resArr = getNeedValuesFromDataBase(argClone[0], argClone[1], argClone[2]); + if (resArr === null) { + return new cNumber(0); + } if (cElementType.error === resArr.type) { return resArr; } @@ -638,6 +671,9 @@ function (window, undefined) { } var resArr = getNeedValuesFromDataBase(argClone[0], argClone[1], argClone[2]); + if (resArr === null) { + return new cNumber(0); + } if (cElementType.error === resArr.type) { return resArr; } @@ -679,6 +715,9 @@ function (window, undefined) { } var resArr = getNeedValuesFromDataBase(argClone[0], argClone[1], argClone[2]); + if (resArr === null) { + return new cNumber(0); + } if (cElementType.error === resArr.type) { return resArr; } @@ -727,6 +766,9 @@ function (window, undefined) { } var resArr = getNeedValuesFromDataBase(argClone[0], argClone[1], argClone[2]); + if (resArr === null) { + return new cError(cErrorType.division_by_zero); + } if (cElementType.error === resArr.type) { return resArr; } @@ -783,6 +825,9 @@ function (window, undefined) { } var resArr = getNeedValuesFromDataBase(argClone[0], argClone[1], argClone[2], true); + if (resArr === null) { + return new cError(cErrorType.division_by_zero); + } if (cElementType.error === resArr.type) { return resArr; } @@ -831,7 +876,7 @@ function (window, undefined) { cDSUM.prototype.argumentsType = [argType.reference, argType.number, argType.text]; cDSUM.prototype.Calculate = function (arg) { - var oArguments = this._prepareArguments(arg, arguments[1], true, [cElementType.array, null, cElementType.array]); + var oArguments = this._prepareArguments(arg, arguments[1], true, [cElementType.array, null, cElementType.array], null, cErrorType.wrong_value_type); var argClone = oArguments.args; var argError; @@ -840,6 +885,9 @@ function (window, undefined) { } var resArr = getNeedValuesFromDataBase(argClone[0], argClone[1], argClone[2]); + if (resArr === null) { + return new cNumber(0); + } if (cElementType.error === resArr.type) { return resArr; } @@ -884,6 +932,9 @@ function (window, undefined) { } var resArr = getNeedValuesFromDataBase(argClone[0], argClone[1], argClone[2], true); + if (resArr === null) { + return new cError(cErrorType.division_by_zero); + } if (cElementType.error === resArr.type) { return resArr; } @@ -947,6 +998,9 @@ function (window, undefined) { } var resArr = getNeedValuesFromDataBase(argClone[0], argClone[1], argClone[2], true); + if (resArr === null) { + return new cError(cErrorType.division_by_zero); + } if (cElementType.error === resArr.type) { return resArr; } diff --git a/cell/model/FormulaObjects/parserFormula.js b/cell/model/FormulaObjects/parserFormula.js index 0c966a1b27..f123854f43 100644 --- a/cell/model/FormulaObjects/parserFormula.js +++ b/cell/model/FormulaObjects/parserFormula.js @@ -3537,7 +3537,7 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara return calculateFunc(argsArray); }; - cBaseFunction.prototype._prepareArguments = function (args, arg1, bAddFirstArrElem, typeArray, bFirstRangeElem) { + cBaseFunction.prototype._prepareArguments = function (args, arg1, bAddFirstArrElem, typeArray, bFirstRangeElem, notArrayError) { var newArgs = []; var indexArr = null; @@ -3556,7 +3556,7 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara } else if (cElementType.error === arg.type) { newArgs[i] = arg; } else { - newArgs[i] = new cError(cErrorType.division_by_zero); + newArgs[i] = new cError(notArrayError ? notArrayError : cErrorType.division_by_zero); } } else if (cElementType.cellsRange === arg.type || cElementType.cellsRange3D === arg.type) { newArgs[i] = bFirstRangeElem ? arg.getValueByRowCol(0,0) : arg.cross(arg1); diff --git a/tests/cell/spreadsheet-calculation/FormulaTests.js b/tests/cell/spreadsheet-calculation/FormulaTests.js index 9547a1a8f0..2da121a97d 100644 --- a/tests/cell/spreadsheet-calculation/FormulaTests.js +++ b/tests/cell/spreadsheet-calculation/FormulaTests.js @@ -29380,6 +29380,18 @@ $(function () { assert.ok(oParser.parse()); assert.strictEqual(oParser.calculate().getValue(), 13); + ws.getRange2("G1").setValue("Profit"); + ws.getRange2("G2").setValue("555"); + + oParser = new parserFormula('DAVERAGE(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), "#DIV/0!"); + + ws.getRange2("G1").setValue("noname"); + + oParser = new parserFormula('DAVERAGE(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 13); }); QUnit.test("Test: \"DCOUNT\"", function (assert) { @@ -29398,6 +29410,18 @@ $(function () { assert.ok(oParser.parse()); assert.strictEqual(oParser.calculate().getValue(), "#VALUE!"); + ws.getRange2("G1").setValue("Profit"); + ws.getRange2("G2").setValue("555"); + + oParser = new parserFormula('DCOUNT(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 0); + + ws.getRange2("G1").setValue("noname"); + + oParser = new parserFormula('DCOUNT(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 6); }); QUnit.test("Test: \"DCOUNTA\"", function (assert) { @@ -29416,6 +29440,18 @@ $(function () { assert.ok(oParser.parse()); assert.strictEqual(oParser.calculate().getValue(), "#VALUE!"); + ws.getRange2("G1").setValue("Profit"); + ws.getRange2("G2").setValue("555"); + + oParser = new parserFormula('DCOUNTA(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 0); + + ws.getRange2("G1").setValue("noname"); + + oParser = new parserFormula('DCOUNTA(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 6); }); QUnit.test("Test: \"DGET\"", function (assert) { @@ -29430,6 +29466,18 @@ $(function () { assert.ok(oParser.parse(), 'DGET(A4:E10, "Yield", A1:F2)'); assert.strictEqual(oParser.calculate().getValue(), 10, 'DGET(A4:E10, "Yield", A1:F2)'); + ws.getRange2("G1").setValue("Profit"); + ws.getRange2("G2").setValue("555"); + + oParser = new parserFormula('DGET(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), "#VALUE!"); + + ws.getRange2("G1").setValue("noname"); + + oParser = new parserFormula('DGET(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), "#NUM!"); }); QUnit.test("Test: \"DMAX\"", function (assert) { @@ -29440,6 +29488,18 @@ $(function () { assert.ok(oParser.parse()); assert.strictEqual(oParser.calculate().getValue(), 96); + ws.getRange2("G1").setValue("Profit"); + ws.getRange2("G2").setValue("555"); + + oParser = new parserFormula('DMAX(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 0); + + ws.getRange2("G1").setValue("noname"); + + oParser = new parserFormula('DMAX(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 20); }); QUnit.test("Test: \"DMIN\"", function (assert) { @@ -29450,6 +29510,18 @@ $(function () { assert.ok(oParser.parse()); assert.strictEqual(oParser.calculate().getValue(), 75); + ws.getRange2("G1").setValue("Profit"); + ws.getRange2("G2").setValue("555"); + + oParser = new parserFormula('DMIN(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 0); + + ws.getRange2("G1").setValue("noname"); + + oParser = new parserFormula('DMIN(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 8); }); QUnit.test("Test: \"DPRODUCT\"", function (assert) { @@ -29460,6 +29532,18 @@ $(function () { assert.ok(oParser.parse()); assert.strictEqual(oParser.calculate().getValue(), 800); + ws.getRange2("G1").setValue("Profit"); + ws.getRange2("G2").setValue("555"); + + oParser = new parserFormula('DPRODUCT(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 0); + + ws.getRange2("G1").setValue("noname"); + + oParser = new parserFormula('DPRODUCT(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 3628800); }); QUnit.test("Test: \"DSTDEV\"", function (assert) { @@ -29470,6 +29554,19 @@ $(function () { assert.ok(oParser.parse()); assert.strictEqual(oParser.calculate().getValue().toFixed(4) - 0, 1.1547); + + ws.getRange2("G1").setValue("Profit"); + ws.getRange2("G2").setValue("555"); + + oParser = new parserFormula('DSTDEV(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), "#DIV/0!"); + + ws.getRange2("G1").setValue("noname"); + + oParser = new parserFormula('DSTDEV(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 4.381780460041329); }); QUnit.test("Test: \"DSTDEVP\"", function (assert) { @@ -29480,6 +29577,18 @@ $(function () { assert.ok(oParser.parse()); assert.strictEqual(oParser.calculate().getValue().toFixed(6) - 0, 0.942809); + ws.getRange2("G1").setValue("Profit"); + ws.getRange2("G2").setValue("555"); + + oParser = new parserFormula('DSTDEVP(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), "#DIV/0!"); + + ws.getRange2("G1").setValue("noname"); + + oParser = new parserFormula('DSTDEV(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 4.381780460041329); }); QUnit.test("Test: \"STDEVPA\"", function (assert) { @@ -29564,6 +29673,30 @@ $(function () { assert.ok(oParser.parse()); assert.strictEqual(oParser.calculate().getValue(), 247.8); + oParser = new parserFormula('DSUM(A4:E10, "Age",A1:F2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 15); + + oParser = new parserFormula('DSUM(A4:E10, "Age","test")', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), "#VALUE!"); + + oParser = new parserFormula('DSUM(A4:E10, "Age",E2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), "#VALUE!"); + + ws.getRange2("G1").setValue("Profit"); + ws.getRange2("G2").setValue("555"); + + oParser = new parserFormula('DSUM(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 0); + + ws.getRange2("G1").setValue("noname"); + + oParser = new parserFormula('DSUM(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 78); }); QUnit.test("Test: \"DVAR\"", function (assert) { @@ -29574,6 +29707,18 @@ $(function () { assert.ok(oParser.parse()); assert.strictEqual(oParser.calculate().getValue().toFixed(1) - 0, 8.8); + ws.getRange2("G1").setValue("Profit"); + ws.getRange2("G2").setValue("555"); + + oParser = new parserFormula('DSTDEVP(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), "#DIV/0!"); + + ws.getRange2("G1").setValue("noname"); + + oParser = new parserFormula('DVAR(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 19.2); }); QUnit.test("Test: \"DVARP\"", function (assert) { @@ -29584,6 +29729,19 @@ $(function () { assert.ok(oParser.parse()); assert.strictEqual(oParser.calculate().getValue().toFixed(2) - 0, 7.04); + ws.getRange2("G1").setValue("Profit"); + ws.getRange2("G2").setValue("555"); + + oParser = new parserFormula('DSTDEVP(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), "#DIV/0!"); + + ws.getRange2("G1").setValue("noname"); + + oParser = new parserFormula('DVARP(A4:E10, "Age",G1:G2)', "AA2", ws); + assert.ok(oParser.parse()); + assert.strictEqual(oParser.calculate().getValue(), 16); + }); QUnit.test("Test: \"UNICODE\"", function (assert) {