Commit cd5b855a authored by Dmitry.Shahtanov's avatar Dmitry.Shahtanov Committed by Alexander.Trofimov

fixed:

Bug 24279 - Некорректная область определения аргументов при вычислении функций AMORDEGRC
Bug 24276 - Некорректная область определения аргументов при вычислении функций AMORLINC
Bug 25881 - Некорректный результат сравнивания больше двух значений в формуле

git-svn-id: svn://192.168.3.15/activex/AVS/Sources/TeamlabOffice/trunk/OfficeWeb@57709 954022d7-b5bf-4e40-9824-e11837661b57
parent 01b16273
...@@ -875,8 +875,11 @@ cAMORDEGRC.prototype.Calculate = function ( arg ) { ...@@ -875,8 +875,11 @@ cAMORDEGRC.prototype.Calculate = function ( arg ) {
salvage = salvage.getValue(); salvage = salvage.getValue();
period = period.getValue(); period = period.getValue();
basis = Math.floor( basis.getValue() ); basis = Math.floor( basis.getValue() );
datePurch = datePurch.getValue();
firstPer = firstPer.getValue();
if ( cost < 0 || salvage < 0 || period < 0 || rate <= 0 || basis == 2 || basis < 0 || basis > 4 ) { if ( cost < 0 || salvage < 0 || period < 0 || rate <= 0 || basis == 2 || basis < 0 || basis > 4 ||
firstPer < 0 || datePurch < 0 || datePurch > firstPer || cost < salvage ) {
return this.value = new cError( cErrorType.not_numeric ); return this.value = new cError( cErrorType.not_numeric );
} }
...@@ -886,19 +889,23 @@ cAMORDEGRC.prototype.Calculate = function ( arg ) { ...@@ -886,19 +889,23 @@ cAMORDEGRC.prototype.Calculate = function ( arg ) {
return this.value = new cNumber( 0 ); return this.value = new cNumber( 0 );
} }
if ( per < 3 ) if ( per >= 3 && per <= 4 ) {
coeff = 1;
else if ( per < 5 )
coeff = 1.5; coeff = 1.5;
else if ( per <= 6 ) }
else if ( per >= 5 && per <= 6 ) {
coeff = 2; coeff = 2;
else }
else if ( per > 6 ) {
coeff = 2.5; coeff = 2.5;
}
else {
return this.value = new cError( cErrorType.not_numeric );
}
rate *= coeff; rate *= coeff;
var val0 = Date.prototype.getDateFromExcel( datePurch.getValue() ), var val0 = Date.prototype.getDateFromExcel( datePurch ),
val1 = Date.prototype.getDateFromExcel( firstPer.getValue() ); val1 = Date.prototype.getDateFromExcel( firstPer );
var _rate = Math.round( yearFrac( val0, val1, basis ) * rate * cost ), rest; var _rate = Math.round( yearFrac( val0, val1, basis ) * rate * cost ), rest;
cost -= _rate; cost -= _rate;
...@@ -1030,31 +1037,40 @@ cAMORLINC.prototype.Calculate = function ( arg ) { ...@@ -1030,31 +1037,40 @@ cAMORLINC.prototype.Calculate = function ( arg ) {
period = period.getValue(); period = period.getValue();
rate = rate.getValue(); rate = rate.getValue();
basis = Math.floor( basis.getValue() ); basis = Math.floor( basis.getValue() );
var val0 = Date.prototype.getDateFromExcel( datePurch ),
if ( cost < 0 || salvage < 0 || period < 0 || rate <= 0 || basis == 2 || basis < 0 || basis > 4 ) { val1 = Date.prototype.getDateFromExcel( firstPer );
if ( cost < 0 || salvage < 0 || period < 0 || rate <= 0 || basis == 2 || basis < 0 || basis > 4 ||
datePurch < 0 || firstPer < 0 || datePurch > firstPer || cost < salvage ) {
return this.value = new cError( cErrorType.not_numeric ); return this.value = new cError( cErrorType.not_numeric );
} }
if ( cost == salvage || period > 1 / rate ) { var fDepTime = yearFrac( val0, val1, basis ).getValue() * rate * cost,
return this.value = new cNumber( 0 ); fDep, depr = rate * cost, availDepr, availDeprTemp,
} countedPeriod = 1, c = 0, maxIter = 10000;
var val0 = Date.prototype.getDateFromExcel( datePurch ), fDep = fDepTime == 0 ? cost * rate : fDepTime;
val1 = Date.prototype.getDateFromExcel( firstPer ); availDepr = (cost - salvage - fDep);
var costRate = cost * rate, rate = Math.ceil( 1 / rate );
costDelta = cost - salvage, if ( cost == salvage || period > rate ) {
_rate = yearFrac( val0, val1, basis ) * rate * cost, return new cNumber( 0 );
countFullPeriods = ( cost - salvage - _rate) / costRate; }
else {
if ( period == 0 ) if ( period == 0 ) {
return this.value = new cNumber( _rate ); return new cNumber( fDep );
else if ( period <= countFullPeriods ) }
return this.value = new cNumber( costRate ); else {
else if ( period == countFullPeriods + 1 )
return this.value = new cNumber( costDelta - costRate * countFullPeriods - _rate ); while ( countedPeriod <= period && c < maxIter ) {
else depr = depr > availDepr ? availDepr : depr;
return this.value = new cNumber( 0 ); availDeprTemp = availDepr - depr;
availDepr = availDeprTemp < 0 ? 0 : availDeprTemp;
countedPeriod++;
c++;
}
return new cNumber( Math.floor(depr) );
}
}
}; };
cAMORLINC.prototype.getInfo = function () { cAMORLINC.prototype.getInfo = function () {
......
...@@ -12,7 +12,9 @@ var cElementType = { ...@@ -12,7 +12,9 @@ var cElementType = {
func:8, func:8,
operator:9, operator:9,
name:10, name:10,
array:11 array:11,
cell3D:12,
cellsRange3D:13
}; };
/** @enum */ /** @enum */
var cErrorType = { var cErrorType = {
...@@ -225,13 +227,13 @@ String.prototype.repeat = function (s, n){ ...@@ -225,13 +227,13 @@ String.prototype.repeat = function (s, n){
} }
/** @constructor */ /** @constructor */
function cBaseType( val ) { function cBaseType( val, type ) {
this.needRecalc = false; this.needRecalc = false;
this.numFormat = null; this.numFormat = null;
this.type = null;
this.value = val;
this.ca = false; this.ca = false;
this.node = undefined; this.node = undefined;
this.type = type;
this.value = val;
} }
cBaseType.prototype = { cBaseType.prototype = {
constructor:cBaseType, constructor:cBaseType,
...@@ -260,15 +262,7 @@ cBaseType.prototype = { ...@@ -260,15 +262,7 @@ cBaseType.prototype = {
/*Basic types of an elements used into formulas*/ /*Basic types of an elements used into formulas*/
/** @constructor */ /** @constructor */
function cNumber( val ) { function cNumber( val ) {
// cBaseType.apply( this, arguments ); this.constructor.call( this, parseFloat( val ), cElementType.number );
// cBaseType.call( this, val );
this.needRecalc = false;
this.numFormat = null;
this.ca = false;
this.node = undefined;
this.type = cElementType.number;
this.value = parseFloat( val );
var res; var res;
if ( !isNaN( this.value ) && Math.abs( this.value ) !== Infinity ) { if ( !isNaN( this.value ) && Math.abs( this.value ) !== Infinity ) {
...@@ -284,9 +278,6 @@ function cNumber( val ) { ...@@ -284,9 +278,6 @@ function cNumber( val ) {
} }
cNumber.prototype = Object.create( cBaseType.prototype ); cNumber.prototype = Object.create( cBaseType.prototype );
cNumber.prototype.getValue = function () {
return this.value;//.toFixed( cExcelSignificantDigits ) - 0;
};
cNumber.prototype.tocString = function () { cNumber.prototype.tocString = function () {
return new cString( "" + this.value ); return new cString( "" + this.value );
}; };
...@@ -299,15 +290,7 @@ cNumber.prototype.tocBool = function () { ...@@ -299,15 +290,7 @@ cNumber.prototype.tocBool = function () {
/** @constructor */ /** @constructor */
function cString( val ) { function cString( val ) {
// cBaseType.call( this, val ); this.constructor.call( this, val, cElementType.string );
this.needRecalc = false;
this.numFormat = null;
this.value = val;
this.ca = false;
this.node = undefined;
this.type = cElementType.string;
} }
cString.prototype = Object.create( cBaseType.prototype ); cString.prototype = Object.create( cBaseType.prototype );
...@@ -356,10 +339,7 @@ cString.prototype.tryConvert = function () { ...@@ -356,10 +339,7 @@ cString.prototype.tryConvert = function () {
/** @constructor */ /** @constructor */
function cBool( val ) { function cBool( val ) {
cBaseType.call( this, val ); this.constructor.call( this, val.toString().toUpperCase() === "TRUE", cElementType.bool );
this.type = cElementType.bool;
this.value = val.toString().toUpperCase() === "TRUE";
} }
cBool.prototype = Object.create( cBaseType.prototype ); cBool.prototype = Object.create( cBaseType.prototype );
...@@ -384,15 +364,8 @@ cBool.prototype.toBool = function () { ...@@ -384,15 +364,8 @@ cBool.prototype.toBool = function () {
/** @constructor */ /** @constructor */
function cError( val ) { function cError( val ) {
// cBaseType.call( this, val ); this.constructor.call( this, val, cElementType.error );
this.needRecalc = false;
this.numFormat = null;
this.value = val;
this.ca = false;
this.node = undefined;
this.type = cElementType.error;
this.errorType = -1; this.errorType = -1;
switch ( val ) { switch ( val ) {
...@@ -472,19 +445,12 @@ cError.prototype.tocNumber = cError.prototype.tocString = cError.prototype.tocBo ...@@ -472,19 +445,12 @@ cError.prototype.tocNumber = cError.prototype.tocString = cError.prototype.tocBo
/** @constructor */ /** @constructor */
function cArea( val, ws ) {/*Area means "A1:E5" for example*/ function cArea( val, ws ) {/*Area means "A1:E5" for example*/
// cBaseType.call( this, val, _ws ); this.constructor.call( this, val, cElementType.cellsRange );
this.needRecalc = false;
this.numFormat = null;
this.value = val;
this.ca = false;
this.node = undefined;
this.ws = ws; this.ws = ws;
this.wb = ws.workbook; this.wb = ws.workbook;
this._cells = val; this._cells = val;
this.isAbsolute = false; this.isAbsolute = false;
this.type = cElementType.cellsRange;
this.range = null; this.range = null;
// this._valid = this.range ? true : false; // this._valid = this.range ? true : false;
} }
...@@ -752,18 +718,11 @@ cArea.prototype.index = function ( r, c, n ) { ...@@ -752,18 +718,11 @@ cArea.prototype.index = function ( r, c, n ) {
/** @constructor */ /** @constructor */
function cArea3D( val, wsFrom, wsTo, wb ) {/*Area3D means "Sheat1!A1:E5" for example*/ function cArea3D( val, wsFrom, wsTo, wb ) {/*Area3D means "Sheat1!A1:E5" for example*/
// cBaseType.call( this, val, _wsFrom, _wsTo, wb ); this.constructor.call( this, val, cElementType.cellsRange );
this.needRecalc = false;
this.numFormat = null;
this.value = val;
this.ca = false;
this.node = undefined;
this._wb = wb; this._wb = wb;
this._cells = val; this._cells = val;
this.isAbsolute = false; this.isAbsolute = false;
this.type = cElementType.cellsRange;
this.wsFrom = this._wb.getWorksheetByName( wsFrom ).getId(); this.wsFrom = this._wb.getWorksheetByName( wsFrom ).getId();
this.wsTo = this._wb.getWorksheetByName( wsTo ).getId(); this.wsTo = this._wb.getWorksheetByName( wsTo ).getId();
} }
...@@ -1109,20 +1068,12 @@ cArea3D.prototype.foreach2 = function ( action ) { ...@@ -1109,20 +1068,12 @@ cArea3D.prototype.foreach2 = function ( action ) {
/** @constructor */ /** @constructor */
function cRef( val, ws ) {/*Ref means A1 for example*/ function cRef( val, ws ) {/*Ref means A1 for example*/
// cBaseType.apply( this, arguments ); this.constructor.call( this, val, cElementType.cell );
// cBaseType.call( this, val, _ws );
this.needRecalc = false;
this.numFormat = null;
this.value = val;
this.ca = false;
this.node = undefined;
this._cells = val; this._cells = val;
this.ws = ws; this.ws = ws;
this.wb = this._wb = ws.workbook; this.wb = this._wb = ws.workbook;
this.isAbsolute = false; this.isAbsolute = false;
this.type = cElementType.cell;
var ca = g_oCellAddressUtils.getCellAddress( val.replace( rx_space_g, "" ) ); var ca = g_oCellAddressUtils.getCellAddress( val.replace( rx_space_g, "" ) );
this.range = null; this.range = null;
this._valid = ca.isValid(); this._valid = ca.isValid();
...@@ -1204,18 +1155,10 @@ cRef.prototype.isValid = function () { ...@@ -1204,18 +1155,10 @@ cRef.prototype.isValid = function () {
/** @constructor */ /** @constructor */
function cRef3D( val, _wsFrom, wb ) {/*Ref means Sheat1!A1 for example*/ function cRef3D( val, _wsFrom, wb ) {/*Ref means Sheat1!A1 for example*/
// cBaseType.call( this, val, _wsFrom, wb ); this.constructor.call( this, val, cElementType.cell );
this.needRecalc = false;
this.numFormat = null;
this.value = val;
this.ca = false;
this.node = undefined;
this.wb = this._wb = wb; this.wb = this._wb = wb;
this._cells = val; this._cells = val;
this.isAbsolute = false; this.isAbsolute = false;
this.type = cElementType.cell;
this.ws = this._wb.getWorksheetByName( _wsFrom ); this.ws = this._wb.getWorksheetByName( _wsFrom );
this.range = null; this.range = null;
} }
...@@ -1299,15 +1242,7 @@ cRef3D.prototype.getWS = function () { ...@@ -1299,15 +1242,7 @@ cRef3D.prototype.getWS = function () {
/** @constructor */ /** @constructor */
function cEmpty() { function cEmpty() {
// cBaseType.call( this ); this.constructor.call( this, "", cElementType.empty );
this.needRecalc = false;
this.numFormat = null;
this.value = "";
this.ca = false;
this.node = undefined;
this.type = cElementType.empty;
} }
cEmpty.prototype = Object.create( cBaseType.prototype ); cEmpty.prototype = Object.create( cBaseType.prototype );
...@@ -1326,16 +1261,8 @@ cEmpty.prototype.toString = function () { ...@@ -1326,16 +1261,8 @@ cEmpty.prototype.toString = function () {
/** @constructor */ /** @constructor */
function cName( val, wb ) { function cName( val, wb ) {
// cBaseType.call( this, val, wb ); this.constructor.call( this, val, cElementType.name );
this.needRecalc = false;
this.numFormat = null;
this.value = val;
this.ca = false;
this.node = undefined;
this.wb = wb; this.wb = wb;
this.type = cElementType.name;
} }
cName.prototype = Object.create( cBaseType.prototype ); cName.prototype = Object.create( cBaseType.prototype );
...@@ -1363,19 +1290,11 @@ cName.prototype.toRef = function ( wsID ) { ...@@ -1363,19 +1290,11 @@ cName.prototype.toRef = function ( wsID ) {
/** @constructor */ /** @constructor */
function cArray() { function cArray() {
// cBaseType.call( this ); this.constructor.call( this, undefined,cElementType.array );
this.needRecalc = false;
this.numFormat = null;
this.value = undefined;
this.ca = false;
this.node = undefined;
this.array = []; this.array = [];
this.rowCount = 0; this.rowCount = 0;
this.countElementInRow = []; this.countElementInRow = [];
this.countElement = 0; this.countElement = 0;
this.type = cElementType.array;
} }
cArray.prototype = Object.create( cBaseType.prototype ); cArray.prototype = Object.create( cBaseType.prototype );
...@@ -1527,7 +1446,6 @@ cArray.prototype.fillFromArray = function ( arr ) { ...@@ -1527,7 +1446,6 @@ cArray.prototype.fillFromArray = function ( arr ) {
function cUndefined(){this.value = undefined;} function cUndefined(){this.value = undefined;}
cUndefined.prototype = Object.create( cBaseType.prototype ); cUndefined.prototype = Object.create( cBaseType.prototype );
//функция для определения к какому типу относится значение val. //функция для определения к какому типу относится значение val.
function checkTypeCell( val ) { function checkTypeCell( val ) {
if ( val === "" ) { if ( val === "" ) {
...@@ -2394,7 +2312,7 @@ _func[cElementType.string][cElementType.bool] = function ( arg0, arg1, what ) { ...@@ -2394,7 +2312,7 @@ _func[cElementType.string][cElementType.bool] = function ( arg0, arg1, what ) {
return new cBool( false ); return new cBool( false );
} }
else if ( what === "<>" ) { else if ( what === "<>" ) {
return new cBool( false ); return new cBool( true );
} }
else if ( what === "-" ) { else if ( what === "-" ) {
_arg0 = arg0.tocNumber(); _arg0 = arg0.tocNumber();
...@@ -2485,10 +2403,10 @@ _func[cElementType.bool][cElementType.number] = function ( arg0, arg1, what ) { ...@@ -2485,10 +2403,10 @@ _func[cElementType.bool][cElementType.number] = function ( arg0, arg1, what ) {
return new cBool( false ); return new cBool( false );
} }
else if ( what === "=" ) { else if ( what === "=" ) {
return new cBool( true ); return new cBool( false );
} }
else if ( what === "<>" ) { else if ( what === "<>" ) {
return new cBool( false ); return new cBool( true );
} }
else if ( what === "-" ) { else if ( what === "-" ) {
_arg = arg0.tocNumber(); _arg = arg0.tocNumber();
...@@ -2535,7 +2453,7 @@ _func[cElementType.bool][cElementType.string] = function ( arg0, arg1, what ) { ...@@ -2535,7 +2453,7 @@ _func[cElementType.bool][cElementType.string] = function ( arg0, arg1, what ) {
return new cBool( false ); return new cBool( false );
} }
else if ( what === "=" ) { else if ( what === "=" ) {
return new cBool( true ); return new cBool( false );
} }
else if ( what === "<>" ) { else if ( what === "<>" ) {
return new cBool( true ); return new cBool( true );
...@@ -3374,6 +3292,8 @@ parserFormula.prototype = { ...@@ -3374,6 +3292,8 @@ parserFormula.prototype = {
this.outStack = []; this.outStack = [];
this.elemArr = []; this.elemArr = [];
return false; return false;
// this.outStack = [new cError(cErrorType.unsupported_function)];
// return this.isParsed = true;
} }
/* Booleans */ /* Booleans */
...@@ -3842,7 +3762,6 @@ parserFormula.prototype = { ...@@ -3842,7 +3762,6 @@ parserFormula.prototype = {
} }
} }
if ( res != undefined && res != null ){ if ( res != undefined && res != null ){
// console.log( this.Formula + " === " + res.toString() );
return res.toString(); return res.toString();
} }
else{ else{
...@@ -4044,10 +3963,11 @@ parserFormula.prototype = { ...@@ -4044,10 +3963,11 @@ parserFormula.prototype = {
buildDependencies:function () { buildDependencies:function () {
var node = this.wb.dependencyFormulas.addNode( this.ws.Id, this.cellId ); var node = this.wb.dependencyFormulas.addNode( this.ws.Id, this.cellId ),
ref, nTo, wsR;
for ( var i = 0; i < this.outStack.length; i++ ) { for ( var i = 0; i < this.outStack.length; i++ ) {
var ref = this.outStack[i]; ref = this.outStack[i];
if ( ref instanceof cName ) { if ( ref instanceof cName ) {
ref = ref.toRef( this.ws.getId() ); ref = ref.toRef( this.ws.getId() );
...@@ -4055,23 +3975,26 @@ parserFormula.prototype = { ...@@ -4055,23 +3975,26 @@ parserFormula.prototype = {
continue; continue;
} }
if ( (ref instanceof cRef || ref instanceof cRef3D || ref instanceof cArea || ref instanceof cArea3D) && ref.isValid() && if ( (ref instanceof cRef || ref instanceof cRef3D || ref instanceof cArea || ref instanceof cArea3D) &&
this.outStack[i + 1] && this.outStack[i + 1] instanceof cBaseFunction && ( this.outStack[i + 1].name == "ROWS" || this.outStack[i + 1].name == "COLUMNS" ) ) { ref.isValid() && this.outStack[i + 1] &&
this.outStack[i + 1] instanceof cBaseFunction &&
( this.outStack[i + 1].name == "ROWS" || this.outStack[i + 1].name == "COLUMNS" ) ) {
continue; continue;
} }
if ( (ref instanceof cRef || ref instanceof cRef3D || ref instanceof cArea) && ref.isValid() ) { if ( (ref instanceof cRef || ref instanceof cRef3D || ref instanceof cArea) && ref.isValid() ) {
var nTo = this.wb.dependencyFormulas.addNode( ref.getWsId(), ref._cells.replace( /\$/g, "" ) ); nTo = this.wb.dependencyFormulas.addNode( ref.getWsId(), ref._cells.replace( /\$/g, "" ) );
ref.setNode( nTo ); // ref.setNode( nTo );
this.wb.dependencyFormulas.addEdge2( node, nTo ); this.wb.dependencyFormulas.addEdge2( node, nTo );
} }
else if ( ref instanceof cArea3D && ref.isValid() ) { else if ( ref instanceof cArea3D && ref.isValid() ) {
var wsR = ref.wsRange(); wsR = ref.wsRange();
for ( var j = 0; j < wsR.length; j++ ) for ( var j = 0; j < wsR.length; j++ ){
this.wb.dependencyFormulas.addEdge( this.ws.Id, this.cellId.replace( /\$/g, "" ), wsR[j].Id, ref._cells.replace( /\$/g, "" ) ); this.wb.dependencyFormulas.addEdge( this.ws.Id, this.cellId.replace( /\$/g, "" ), wsR[j].Id, ref._cells.replace( /\$/g, "" ) );
}
} }
} }
}, },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment