mirror of
https://github.com/ONLYOFFICE/sdkjs.git
synced 2026-04-07 14:09:12 +08:00
LOGINV, LOGNORMDIST, NEGBINOMDIST, NORMDIST, NORMINV, NORMSDIST, NORMSINV, PEARSON, PERCENTILE, PERCENTRANK, PERMUT, POISSON, PROB, QUARTILE, RSQ, SKEW, SLOPE, STANDARDIZE, STDEVA, VAR поправлены функции AVEDEV, AVERAGE, CORREL, FESHER, FISHERINV git-svn-id: svn://192.168.3.15/activex/AVS/Sources/TeamlabOffice/trunk/OfficeWeb@48959 954022d7-b5bf-4e40-9824-e11837661b57
3739 lines
144 KiB
JavaScript
3739 lines
144 KiB
JavaScript
/** @enum */
|
||
var cElementType = {
|
||
number:0,
|
||
string:1,
|
||
bool:2,
|
||
error:3,
|
||
empty:4,
|
||
cellsRange:5,
|
||
cell:6,
|
||
date:7,
|
||
func:8,
|
||
operator:9,
|
||
name:10,
|
||
array:11
|
||
};
|
||
/** @enum */
|
||
var cErrorType = {
|
||
division_by_zero:0,
|
||
not_available:1,
|
||
wrong_name:2,
|
||
null_value:3,
|
||
not_numeric:4,
|
||
bad_reference:5,
|
||
wrong_value_type:6,
|
||
unsupported_function:7,
|
||
getting_data:8
|
||
};
|
||
var cExcelSignificantDigits = 15;//количество цифр в числе после запятой
|
||
var cExcelMaxExponent = 308, cExcelMinExponent = -308;
|
||
var cExcelDateTimeDigits = 8;//количество цифр после запятой в числах отвечающих за время специализация $18.17.4.2
|
||
|
||
var c_Date1904Const = 24107; //разница в днях между 01.01.1970 и 01.01.1904 годами
|
||
var c_Date1900Const = 25568; //разница в днях между 01.01.1970 и 01.01.1900 годами
|
||
var c_DateCorrectConst = c_Date1900Const;
|
||
var c_sPerDay = 86400;
|
||
var c_msPerDay = c_sPerDay * 1000;
|
||
|
||
function extend( Child, Parent ) {
|
||
var F = function () {
|
||
};
|
||
F.prototype = Parent.prototype;
|
||
Child.prototype = new F();
|
||
Child.prototype.constructor = Child;
|
||
Child.superclass = Parent.prototype;
|
||
}
|
||
|
||
Date.prototype.isLeapYear = function () {
|
||
var y = this.getFullYear();
|
||
return y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
|
||
};
|
||
|
||
Date.prototype.getDaysInMonth = function () {
|
||
return arguments.callee[this.isLeapYear() ? 'L' : 'R'][this.getMonth()];
|
||
};
|
||
|
||
// durations of months for the regular year
|
||
Date.prototype.getDaysInMonth.R = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
||
// durations of months for the leap year
|
||
Date.prototype.getDaysInMonth.L = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
||
|
||
Date.prototype.getExcelDate = function () {
|
||
return Math.floor( ( this.getTime() / 1000 - this.getTimezoneOffset() * 60 ) / c_sPerDay + ( c_DateCorrectConst + (g_bDate1904 ? 0 : 1) ) )
|
||
}
|
||
|
||
Date.prototype.getDateFromExcel = function ( val ) {
|
||
if ( !g_bDate1904 ) {
|
||
if ( val < 60 )
|
||
return new Date( (val - c_DateCorrectConst) * c_msPerDay );
|
||
else if ( val == 60 )
|
||
return new Date( (val - c_DateCorrectConst - 1) * c_msPerDay );
|
||
else
|
||
return new Date( (val - c_DateCorrectConst - 1) * c_msPerDay );
|
||
}
|
||
else
|
||
return new Date( (val - c_DateCorrectConst) * c_msPerDay );
|
||
}
|
||
|
||
Date.prototype.addYears = function ( counts ) {
|
||
this.setYear( this.getFullYear() + counts );
|
||
}
|
||
|
||
Date.prototype.addMonths = function ( counts ) {
|
||
this.setMonth( this.getMonth() + counts );
|
||
}
|
||
|
||
Date.prototype.addDays = function ( counts ) {
|
||
this.setDate( this.getDate() + counts );
|
||
}
|
||
|
||
Math.sinh = function ( arg ) {
|
||
return (this.pow( this.E, arg ) - this.pow( this.E, -arg )) / 2;
|
||
}
|
||
|
||
Math.cosh = function ( arg ) {
|
||
return (this.pow( this.E, arg ) + this.pow( this.E, -arg )) / 2;
|
||
}
|
||
|
||
Math.tanh = function ( arg ) {
|
||
return this.sinh( arg ) / this.cosh( arg );
|
||
}
|
||
|
||
Math.asinh = function ( arg ) {
|
||
return this.log( arg + this.sqrt( arg * arg + 1 ) );
|
||
}
|
||
|
||
Math.acosh = function ( arg ) {
|
||
return this.log( arg + this.sqrt( arg + 1 ) * this.sqrt( arg - 1 ) )
|
||
}
|
||
|
||
Math.atanh = function ( arg ) {
|
||
return 0.5 * this.log( (1 + arg) / (1 - arg) );
|
||
}
|
||
|
||
Math.fact = function ( n ) {
|
||
var res = 1;
|
||
n = Math.floor( n );
|
||
if ( n < 0 ) return Number.NaN;
|
||
else if ( n > 170 ) return Number.Infinity;
|
||
while ( n != 0 ) {
|
||
res *= n--
|
||
}
|
||
;
|
||
return res;
|
||
}
|
||
|
||
Math.ln = function( x ){
|
||
return Math.log( x ) / Math.log( Math.E );
|
||
}
|
||
|
||
Math.binomCoeff = function ( n, k ) {
|
||
return this.fact( n ) / (this.fact( k ) * this.fact( n - k ));
|
||
}
|
||
|
||
Math.permut = function ( n, k ) {
|
||
return this.fact( n ) / this.fact( n - k );
|
||
}
|
||
var _func = [];//для велосипеда а-ля перегрузка функций.
|
||
_func[cElementType.number] = [];
|
||
_func[cElementType.string] = [];
|
||
_func[cElementType.bool] = [];
|
||
_func[cElementType.error] = [];
|
||
_func[cElementType.cellsRange] = [];
|
||
_func[cElementType.empty] = [];
|
||
_func[cElementType.array] = [];
|
||
|
||
|
||
_func[cElementType.number][cElementType.number] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
return new cBool( arg0.getValue() > arg1.getValue() );
|
||
case ">=":
|
||
return new cBool( arg0.getValue() >= arg1.getValue() );
|
||
case "<":
|
||
return new cBool( arg0.getValue() < arg1.getValue() );
|
||
case "<=":
|
||
return new cBool( arg0.getValue() <= arg1.getValue() );
|
||
case "=":
|
||
return new cBool( arg0.getValue() == arg1.getValue() );
|
||
case "<>":
|
||
return new cBool( arg0.getValue() != arg1.getValue() );
|
||
case "-":
|
||
return new cNumber( arg0.getValue() - arg1.getValue() );
|
||
case "+":
|
||
return new cNumber( arg0.getValue() + arg1.getValue() );
|
||
case "/":
|
||
if ( arg1.getValue() != 0 )
|
||
return new cNumber( arg0.getValue() / arg1.getValue() );
|
||
else
|
||
return new cError( cErrorType.division_by_zero );
|
||
case "*":
|
||
return new cNumber( arg0.getValue() * arg1.getValue() );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
_func[cElementType.number][cElementType.string] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
case ">=":
|
||
return new cBool( false );
|
||
case "<":
|
||
case "<=":
|
||
return new cBool( true );
|
||
case "=":
|
||
return new cBool( false );
|
||
case "<>":
|
||
return new cBool( true );
|
||
case "-":
|
||
case "+":
|
||
case "/":
|
||
case "*":
|
||
return new cError( cErrorType.wrong_value_type );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
_func[cElementType.number][cElementType.bool] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
case ">=":
|
||
return new cBool( false );
|
||
case "<":
|
||
case "<=":
|
||
return new cBool( true );
|
||
case "=":
|
||
return new cBool( false );
|
||
case "<>":
|
||
return new cBool( true );
|
||
case "-":
|
||
var _arg = arg1.tocNumber();
|
||
if ( _arg instanceof cError ) return _arg;
|
||
return new cNumber( arg0.getValue() - _arg.getValue() );
|
||
case "+":
|
||
var _arg = arg1.tocNumber();
|
||
if ( _arg instanceof cError ) return _arg;
|
||
return new cNumber( arg0.getValue() + _arg.getValue() );
|
||
case "/":
|
||
var _arg = arg1.tocNumber();
|
||
if ( _arg instanceof cError ) return _arg;
|
||
if ( _arg.getValue() != 0 )
|
||
return new cNumber( arg0.getValue() / _arg.getValue() );
|
||
else
|
||
return new cError( cErrorType.division_by_zero );
|
||
case "*":
|
||
var _arg = arg1.tocNumber();
|
||
if ( _arg instanceof cError ) return _arg;
|
||
return new cNumber( arg0.getValue() * _arg.getValue() );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
_func[cElementType.number][cElementType.error] = function ( arg0, arg1, what ) {
|
||
return arg1;
|
||
};
|
||
|
||
_func[cElementType.number][cElementType.empty] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
return new cBool( arg0.getValue() > 0 );
|
||
case ">=":
|
||
return new cBool( arg0.getValue() >= 0 );
|
||
case "<":
|
||
return new cBool( arg0.getValue() < 0 );
|
||
case "<=":
|
||
return new cBool( arg0.getValue() <= 0 );
|
||
case "=":
|
||
return new cBool( arg0.getValue() == 0 );
|
||
case "<>":
|
||
return new cBool( arg0.getValue() != 0 );
|
||
case "-":
|
||
return new cNumber( arg0.getValue() - 0 );
|
||
case "+":
|
||
return new cNumber( arg0.getValue() + 0 );
|
||
case "/":
|
||
return new cError( cErrorType.division_by_zero );
|
||
case "*":
|
||
return new cNumber( 0 );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
|
||
_func[cElementType.string][cElementType.number] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
case ">=":
|
||
return new cBool( true );
|
||
case "<":
|
||
case "<=":
|
||
case "=":
|
||
return new cBool( false );
|
||
case "<>":
|
||
return new cBool( true );
|
||
case "-":
|
||
case "+":
|
||
case "/":
|
||
case "*":
|
||
return new cError( cErrorType.wrong_value_type );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
_func[cElementType.string][cElementType.string] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
return new cBool( arg0.getValue() > arg1.getValue() );
|
||
case ">=":
|
||
return new cBool( arg0.getValue() >= arg1.getValue() );
|
||
case "<":
|
||
return new cBool( arg0.getValue() < arg1.getValue() );
|
||
case "<=":
|
||
return new cBool( arg0.getValue() <= arg1.getValue() );
|
||
case "=":
|
||
return new cBool( arg0.getValue() === arg1.getValue() );
|
||
case "<>":
|
||
return new cBool( arg0.getValue() !== arg1.getValue() );
|
||
case "-":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
if ( _arg0 instanceof cError ) return _arg0;
|
||
if ( _arg1 instanceof cError ) return _arg1;
|
||
return new cNumber( _arg0.getValue() - _arg1.getValue() );
|
||
case "+":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
if ( _arg0 instanceof cError ) return _arg0;
|
||
if ( _arg1 instanceof cError ) return _arg1;
|
||
return new cNumber( _arg0.getValue() + _arg1.getValue() );
|
||
case "/":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
if ( _arg0 instanceof cError ) return _arg0;
|
||
if ( _arg1 instanceof cError ) return _arg1;
|
||
if ( _arg1.getValue() != 0 )
|
||
return new cNumber( _arg0.getValue() / _arg1.getValue() );
|
||
return new cError( cErrorType.division_by_zero );
|
||
case "*":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
if ( _arg0 instanceof cError ) return _arg0;
|
||
if ( _arg1 instanceof cError ) return _arg1;
|
||
return new cNumber( _arg0.getValue() * _arg1.getValue() );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
_func[cElementType.string][cElementType.bool] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
case ">=":
|
||
return new cBool( false );
|
||
case "<":
|
||
case "<=":
|
||
return new cBool( true );
|
||
case "=":
|
||
return new cBool( false );
|
||
case "<>":
|
||
return new cBool( false );
|
||
case "-":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
if ( _arg0 instanceof cError ) return _arg0;
|
||
if ( _arg1 instanceof cError ) return _arg1;
|
||
return new cNumber( _arg0.getValue() - _arg1.getValue() );
|
||
case "+":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
if ( _arg0 instanceof cError ) return _arg0;
|
||
if ( _arg1 instanceof cError ) return _arg1;
|
||
return new cNumber( _arg0.getValue() + _arg1.getValue() );
|
||
case "/":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
if ( _arg0 instanceof cError ) return _arg0;
|
||
if ( _arg1 instanceof cError ) return _arg1;
|
||
if ( _arg1.getValue() != 0 )
|
||
return new cNumber( _arg0.getValue() / _arg1.getValue() );
|
||
return new cError( cErrorType.division_by_zero );
|
||
case "*":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
if ( _arg0 instanceof cError ) return _arg0;
|
||
if ( _arg1 instanceof cError ) return _arg1;
|
||
return new cNumber( _arg0.getValue() * _arg1.getValue() );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
_func[cElementType.string][cElementType.error] = function ( arg0, arg1, what ) {
|
||
return arg1;
|
||
};
|
||
|
||
_func[cElementType.string][cElementType.empty] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
return new cBool( arg0.getValue().length != 0 );
|
||
case ">=":
|
||
return new cBool( arg0.getValue().length >= 0 );
|
||
case "<":
|
||
return new cBool( false );
|
||
case "<=":
|
||
return new cBool( arg0.getValue().length <= 0 );
|
||
case "=":
|
||
return new cBool( arg0.getValue().length === 0 );
|
||
case "<>":
|
||
return new cBool( arg0.getValue().length != 0 );
|
||
case "-":
|
||
case "+":
|
||
case "/":
|
||
case "*":
|
||
return new cError( cErrorType.wrong_value_type );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
|
||
_func[cElementType.bool][cElementType.number] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
case ">=":
|
||
return new cBool( true );
|
||
case "<":
|
||
case "<=":
|
||
return new cBool( false );
|
||
case "=":
|
||
return new cBool( true );
|
||
case "<>":
|
||
return new cBool( false );
|
||
case "-":
|
||
var _arg = arg0.tocNumber();
|
||
if ( _arg instanceof cError ) return _arg;
|
||
return new cNumber( _arg.getValue() - arg1.getValue() );
|
||
case "+":
|
||
var _arg = arg1.tocNumber();
|
||
if ( _arg instanceof cError ) return _arg;
|
||
return new cNumber( _arg.getValue() + arg1.getValue() );
|
||
case "/":
|
||
var _arg = arg1.tocNumber();
|
||
if ( _arg instanceof cError ) return _arg;
|
||
if ( arg1.getValue() != 0 )
|
||
return new cNumber( _arg.getValue() / arg1.getValue() );
|
||
else
|
||
return new cError( cErrorType.division_by_zero );
|
||
case "*":
|
||
var _arg = arg1.tocNumber();
|
||
if ( _arg instanceof cError ) return _arg;
|
||
return new cNumber( _arg.getValue() * arg1.getValue() );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
_func[cElementType.bool][cElementType.string] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
case ">=":
|
||
return new cBool( true );
|
||
case "<":
|
||
case "<=":
|
||
return new cBool( false );
|
||
case "=":
|
||
return new cBool( true );
|
||
case "<>":
|
||
return new cBool( true );
|
||
case "-":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
if ( _arg1 instanceof cError ) return _arg1;
|
||
return new cNumber( _arg0.getValue() - _arg1.getValue() );
|
||
case "+":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
if ( _arg1 instanceof cError ) return _arg1;
|
||
return new cNumber( _arg0.getValue() + _arg1.getValue() );
|
||
case "/":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
if ( _arg1 instanceof cError ) return _arg1;
|
||
if ( _arg1.getValue() != 0 )
|
||
return new cNumber( _arg0.getValue() / _arg1.getValue() );
|
||
return new cError( cErrorType.division_by_zero );
|
||
case "*":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
if ( _arg1 instanceof cError ) return _arg1;
|
||
return new cNumber( _arg0.getValue() * _arg1.getValue() );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
_func[cElementType.bool][cElementType.bool] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
return new cBool( arg0.value > arg1.value );
|
||
case ">=":
|
||
return new cBool( arg0.value >= arg1.value );
|
||
case "<":
|
||
return new cBool( arg0.value < arg1.value );
|
||
case "<=":
|
||
return new cBool( arg0.value <= arg1.value );
|
||
case "=":
|
||
return new cBool( arg0.value === arg1.value );
|
||
case "<>":
|
||
return new cBool( arg0.value !== arg1.value );
|
||
case "-":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
return new cNumber( _arg0.getValue() - _arg1.getValue() );
|
||
case "+":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
return new cNumber( _arg0.getValue() + _arg1.getValue() );
|
||
case "/":
|
||
if ( !arg1.value )
|
||
return new cError( cErrorType.division_by_zero );
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
return new cNumber( _arg0.getValue() / _arg1.getValue() );
|
||
case "*":
|
||
var _arg0 = arg0.tocNumber(),
|
||
_arg1 = arg1.tocNumber();
|
||
return new cNumber( _arg0.getValue() * _arg1.getValue() );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
_func[cElementType.bool][cElementType.error] = function ( arg0, arg1, what ) {
|
||
return arg1;
|
||
};
|
||
|
||
_func[cElementType.bool][cElementType.empty] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
return new cBool( arg0.value > false );
|
||
case ">=":
|
||
return new cBool( arg0.value >= false );
|
||
case "<":
|
||
return new cBool( arg0.value < false );
|
||
case "<=":
|
||
return new cBool( arg0.value <= false );
|
||
case "=":
|
||
return new cBool( arg0.value === false );
|
||
case "<>":
|
||
return new cBool( arg0.value !== false );
|
||
case "-":
|
||
return new cNumber( arg0.value ? 1.0 : 0.0 - 0 );
|
||
case "+":
|
||
return new cNumber( arg0.value ? 1.0 : 0.0 + 0 );
|
||
case "/":
|
||
return new cError( cErrorType.division_by_zero );
|
||
case "*":
|
||
return new cNumber( 0 );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
|
||
_func[cElementType.error][cElementType.number] = _func[cElementType.error][cElementType.string] =
|
||
_func[cElementType.error][cElementType.bool] = _func[cElementType.error][cElementType.error] =
|
||
_func[cElementType.error][cElementType.empty] = function ( arg0, arg1, what ) {
|
||
return arg0;
|
||
};
|
||
|
||
|
||
_func[cElementType.empty][cElementType.number] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
return new cBool( 0 > arg1.getValue() );
|
||
case ">=":
|
||
return new cBool( 0 >= arg1.getValue() );
|
||
case "<":
|
||
return new cBool( 0 < arg1.getValue() );
|
||
case "<=":
|
||
return new cBool( 0 <= arg1.getValue() );
|
||
case "=":
|
||
return new cBool( 0 == arg1.getValue() );
|
||
case "<>":
|
||
return new cBool( 0 != arg1.getValue() );
|
||
case "-":
|
||
return new cNumber( 0 - arg1.getValue() );
|
||
case "+":
|
||
return new cNumber( 0 + arg1.getValue() );
|
||
case "/":
|
||
if ( arg1.getValue() == 0 )
|
||
return new cError( cErrorType.not_numeric );
|
||
return new cNumber( 0 );
|
||
case "*":
|
||
return new cNumber( 0 );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
_func[cElementType.empty][cElementType.string] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
return new cBool( 0 > arg1.getValue().length );
|
||
case ">=":
|
||
return new cBool( 0 >= arg1.getValue().length );
|
||
case "<":
|
||
return new cBool( 0 < arg1.getValue().length );
|
||
case "<=":
|
||
return new cBool( 0 <= arg1.getValue().length );
|
||
case "=":
|
||
return new cBool( 0 === arg1.getValue().length );
|
||
case "<>":
|
||
return new cBool( 0 != arg1.getValue().length );
|
||
case "-":
|
||
case "+":
|
||
case "/":
|
||
case "*":
|
||
return new cError( cErrorType.wrong_value_type );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
_func[cElementType.empty][cElementType.bool] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
return new cBool( false > arg1.value );
|
||
case ">=":
|
||
return new cBool( false >= arg1.value );
|
||
case "<":
|
||
return new cBool( false < arg1.value );
|
||
case "<=":
|
||
return new cBool( false <= arg1.value );
|
||
case "=":
|
||
return new cBool( arg1.value === false );
|
||
case "<>":
|
||
return new cBool( arg1.value !== false );
|
||
case "-":
|
||
return new cNumber( 0 - arg1.value ? 1.0 : 0.0 );
|
||
case "+":
|
||
return new cNumber( arg1.value ? 1.0 : 0.0 );
|
||
case "/":
|
||
if ( arg1.value )
|
||
return new cNumber( 0 );
|
||
return new cError( cErrorType.not_numeric );
|
||
case "*":
|
||
return new cNumber( 0 );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
_func[cElementType.empty][cElementType.error] = function ( arg0, arg1, what ) {
|
||
return arg1;
|
||
};
|
||
|
||
_func[cElementType.empty][cElementType.empty] = function ( arg0, arg1, what ) {
|
||
switch ( what ) {
|
||
case ">":
|
||
case "<":
|
||
case "<>":
|
||
return new cBool( false );
|
||
case ">=":
|
||
case "<=":
|
||
case "=":
|
||
return new cBool( true );
|
||
case "-":
|
||
case "+":
|
||
return new cNumber( 0 );
|
||
case "/":
|
||
return new cError( cErrorType.not_numeric );
|
||
case "*":
|
||
return new cNumber( 0 );
|
||
}
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
|
||
|
||
_func[cElementType.cellsRange][cElementType.number] = _func[cElementType.cellsRange][cElementType.string] =
|
||
_func[cElementType.cellsRange][cElementType.bool] = _func[cElementType.cellsRange][cElementType.error] =
|
||
_func[cElementType.cellsRange][cElementType.array] = _func[cElementType.cellsRange][cElementType.empty] = function ( arg0, arg1, what, cellAddress ) {
|
||
var cross = arg0.cross( cellAddress );
|
||
return _func[cross.type][arg1.type]( cross, arg1, what )
|
||
};
|
||
|
||
|
||
_func[cElementType.number][cElementType.cellsRange] = _func[cElementType.string][cElementType.cellsRange] =
|
||
_func[cElementType.bool][cElementType.cellsRange] = _func[cElementType.error][cElementType.cellsRange] =
|
||
_func[cElementType.array][cElementType.cellsRange] = _func[cElementType.empty][cElementType.cellsRange] = function ( arg0, arg1, what, cellAddress ) {
|
||
var cross = arg1.cross( cellAddress );
|
||
return _func[arg0.type][cross.type]( arg0, cross, what )
|
||
};
|
||
|
||
|
||
_func[cElementType.cellsRange][cElementType.cellsRange] = function ( arg0, arg1, what, cellAddress ) {
|
||
var cross1 = arg0.cross( cellAddress ),
|
||
cross2 = arg1.cross( cellAddress );
|
||
return _func[cross1.type][cross2.type]( cross1, cross2, what )
|
||
};
|
||
|
||
_func[cElementType.array][cElementType.array] = function ( arg0, arg1, what, cellAddress ) {
|
||
if ( arg0.getRowCount() != arg1.getRowCount() || arg0.getCountElementInRow() != arg1.getCountElementInRow() )return new cError( cErrorType.wrong_value_type );
|
||
var retArr = new cArray(), _arg0, _arg1;
|
||
for ( var iRow = 0; iRow < arg0.getRowCount(); iRow++, iRow < arg0.getRowCount() ? retArr.addRow() : true ) {
|
||
for ( var iCol = 0; iCol < arg0.getCountElementInRow(); iCol++ ) {
|
||
_arg0 = arg0.getElementRowCol( iRow, iCol );
|
||
_arg1 = arg1.getElementRowCol( iRow, iCol );
|
||
retArr.addElement( _func[_arg0.type][_arg1.type]( _arg0, _arg1, what ) );
|
||
}
|
||
}
|
||
return retArr;
|
||
};
|
||
|
||
_func[cElementType.array][cElementType.number] = _func[cElementType.array][cElementType.string] =
|
||
_func[cElementType.array][cElementType.bool] = _func[cElementType.array][cElementType.error] =
|
||
_func[cElementType.array][cElementType.empty] = function ( arg0, arg1, what, cellAddress ) {
|
||
var res = new cArray();
|
||
arg0.foreach( function ( elem, r, c ) {
|
||
if ( !res.array[r] ) res.addRow();
|
||
res.addElement( _func[elem.type][arg1.type]( elem, arg1, what ) );
|
||
} )
|
||
return res;
|
||
};
|
||
|
||
|
||
_func[cElementType.number][cElementType.array] = _func[cElementType.string][cElementType.array] =
|
||
_func[cElementType.bool][cElementType.array] = _func[cElementType.error][cElementType.array] =
|
||
_func[cElementType.empty][cElementType.array] = function ( arg0, arg1, what, cellAddress ) {
|
||
var res = new cArray();
|
||
arg1.foreach( function ( elem, r, c ) {
|
||
if ( !res.array[r] ) res.addRow();
|
||
res.addElement( _func[arg0.type][elem.type]( arg0, elem, what ) );
|
||
} );
|
||
return res;
|
||
};
|
||
|
||
|
||
_func.binarySearch = function ( sElem, arrTagert, regExp ) {
|
||
var first = 0, /* Номер первого элемента в массиве */
|
||
last = arrTagert.length - 1, /* Номер элемента в массиве, СЛЕДУЮЩЕГО ЗА последним */
|
||
/* Если просматриваемый участок непустой, first<last */
|
||
mid, x;
|
||
|
||
var arrTagertOneType = [], isString = false;
|
||
|
||
for ( var i = 0; i < arrTagert.length; i++ ) {
|
||
if ( (arrTagert[i] instanceof cString || sElem instanceof cString) && !isString ) {
|
||
i = 0;
|
||
isString = true;
|
||
sElem = new cString( sElem.value.toLowerCase() );
|
||
}
|
||
if ( isString ) {
|
||
arrTagertOneType[i] = new cString( arrTagert[i].getValue().toLowerCase() );
|
||
}
|
||
else {
|
||
arrTagertOneType[i] = arrTagert[i].tocNumber();
|
||
}
|
||
}
|
||
|
||
if ( arrTagert.length == 0 ) {
|
||
return -1;
|
||
/* массив пуст */
|
||
}
|
||
else if ( arrTagert[0].value > sElem.value ) {
|
||
return -2;
|
||
}
|
||
else if ( arrTagert[arrTagert.length - 1].value < sElem.value ) {
|
||
return arrTagert.length - 1;
|
||
}
|
||
|
||
while ( first < last ) {
|
||
mid = Math.floor( first + (last - first) / 2 );
|
||
if ( sElem.value <= arrTagert[mid].value || ( regExp && regExp.test( arrTagert[mid].value ) ) ) {
|
||
last = mid;
|
||
}
|
||
else {
|
||
first = mid + 1;
|
||
}
|
||
}
|
||
|
||
/* Если условный оператор if(n==0) и т.д. в начале опущен - значит, тут раскомментировать! */
|
||
if ( /* last<n &&*/ arrTagert[last].value == sElem.value ) {
|
||
return last;
|
||
/* Искомый элемент найден. last - искомый индекс */
|
||
}
|
||
else {
|
||
return last - 1;
|
||
/* Искомый элемент не найден. Но если вам вдруг надо его вставить со сдвигом, то его место - last. */
|
||
}
|
||
|
||
};
|
||
|
||
/*Functions that checks of an element in formula*/
|
||
var rx_operators = new RegExp( "^ *[-+*/^&%<=>:] *" ),
|
||
rx_LG = new RegExp( "^ *[<=>]+ *" ),
|
||
rx_Lt = new RegExp( "^ *< *" ),
|
||
rx_Le = new RegExp( "^ *<= *" ),
|
||
rx_Gt = new RegExp( "^ *> *" ),
|
||
rx_Ge = new RegExp( "^ *>= *" ),
|
||
rx_Ne = new RegExp( "^ *<> *" ),
|
||
rg = new RegExp( "^([\\w\\d.]+)[-+*/^&%<=>:;\\(\\)]" ),
|
||
rgRange = new RegExp( "^\\$?[A-Za-z]+\\$?\\d+:\\$?[A-Za-z]+\\$?\\d+" ),
|
||
rgCols = new RegExp( "^\\$?[A-Za-z]+:\\$?[A-Za-z]+" ),
|
||
rgRows = new RegExp( "^\\$?\\d+:\\$?\\d+" ),
|
||
rx_ref = new RegExp( "^(\\$?[A-Za-z]{1,3}\\$?(\\d{1,7}))([-+*/^&%<=>: ;),]|$)" ),
|
||
rx_refAll = new RegExp( "^(\\$?[A-Za-z]+\\$?(\\d+))([-+*/^&%<=>: ;),]|$)" ),
|
||
rx_ref3D_non_quoted = new XRegExp( "^(?<name_from>[\\p{L}\\d.]+)(:(?<name_to>[\\p{L}\\d.]+))?!" ),
|
||
rx_ref3D_quoted = new XRegExp( "^'(?<name_from>(?:''|[^\\[\\]'\\/*?:])*)(?::(?<name_to>(?:''|[^\\[\\]'\\/*?:])*))?'!" ),
|
||
rx_ref3D = new RegExp( "^\\D*[\\D\\d]*\\!" ),
|
||
rx_before_operators = new RegExp( "^ *[,()]" ), rx_space = new RegExp( " " ),
|
||
rx_number = new RegExp( "^[+-]?\\d*(\\d|\\.)\\d*([eE][+-]?\\d+)?" ),
|
||
rx_LeftParentheses = new RegExp( "^ *\\( *" ),
|
||
rx_RightParentheses = new RegExp( "^ *\\)" ),
|
||
rx_Comma = new RegExp( "^ *[,;] *" ),
|
||
rx_error = new RegExp( "^(#NULL!|#DIV\\/0!|#VALUE!|#REF!|#NAME\\?|#NUM!|#UNSUPPORTED_FUNCTION!|#N\\/A|#GETTING_DATA)" ),
|
||
rx_bool = new RegExp( "^(TRUE|FALSE|true|false)([-+*/^&%<=>: ;),]|$)" ),
|
||
rx_string = new RegExp( "^\"((\"\"|[^\"])*)\"" ),
|
||
rx_name = new XRegExp( "^(?<name>\\w[\\w\\d.]*)([-+*/^&%<=>: ;),]|$)" ),
|
||
rx_test_ws_name = new XRegExp( "^\\p{L}[\\p{L}\\d.]*$" ),
|
||
rx_LeftBrace = new RegExp( "^ *\\{ *" ),
|
||
rx_RightBrace = new RegExp( "^ *\\}" ),
|
||
rx_array = new RegExp( "^\\{(([+-]?\\d*(\\d|\\.)\\d*([eE][+-]?\\d+)?)?(\"((\"\"|[^\"])*)\")?(#NULL!|#DIV\\/0!|#VALUE!|#REF!|#NAME\\?|#NUM!|#UNSUPPORTED_FUNCTION!|#N\\A|#GETTING_DATA|FALSE|TRUE|true|false)?[,;]?)*\\}" );
|
||
|
||
//вспомогательный объект для парсинга формул и проверки строки по регуляркам указанным выше.
|
||
function parserHelper() {
|
||
}
|
||
parserHelper.prototype = {
|
||
_reset:function () {
|
||
delete this.operand_str;
|
||
delete this.pCurrPos;
|
||
},
|
||
|
||
isOperator:function ( formula, start_pos ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var str = formula.substring( start_pos )
|
||
var match = str.match( rx_operators );
|
||
if ( match == null || match == undefined )
|
||
return false;
|
||
else {
|
||
var mt = str.match( rx_LG )
|
||
if ( mt ) match = mt;
|
||
this.operand_str = match[0].replace( /\s/g, "", "" );
|
||
this.pCurrPos += match[0].length;
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
|
||
isFunc:function ( formula, start_pos ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var frml = formula.substring( start_pos );
|
||
var match = (frml).match( rg );
|
||
|
||
if ( match != null && match != undefined ) {
|
||
if ( match.length == 2 ) {
|
||
this.pCurrPos += match[1].length;
|
||
this.operand_str = match[1];
|
||
return true;
|
||
}
|
||
}
|
||
this.operand_str = null;
|
||
return false;
|
||
},
|
||
|
||
isArea:function ( formula, start_pos ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var subSTR = formula.substring( start_pos );
|
||
var match = subSTR.match( rgRange ) || subSTR.match( rgCols ) || subSTR.match( rgRows );
|
||
if ( match != null || match != undefined ) {
|
||
this.pCurrPos += match[0].length;
|
||
this.operand_str = match[0];
|
||
return true;
|
||
}
|
||
this.operand_str = null;
|
||
return false;
|
||
},
|
||
|
||
isRef:function ( formula, start_pos, allRef ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var match = (formula.substring( start_pos )).match( rx_ref );
|
||
if ( match != null || match != undefined ) {
|
||
if ( match.length >= 3 &&
|
||
g_oCellAddressUtils.colstrToColnum( match[1].substr( 0, (match[1].length - match[2].length) ) ) <= g_oCellAddressUtils.colstrToColnum( "XFD" ) &&
|
||
parseInt( match[2] ) <= 1048576
|
||
) {
|
||
this.pCurrPos += match[1].length;
|
||
this.operand_str = match[1];
|
||
return true;
|
||
}
|
||
else if ( allRef ) {
|
||
match = (formula.substring( start_pos )).match( rx_refAll );
|
||
if ( (match != null || match != undefined) && match.length >= 3 ) {
|
||
this.pCurrPos += match[1].length;
|
||
this.operand_str = match[1];
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
this.operand_str = null;
|
||
return false;
|
||
},
|
||
|
||
is3DRef:function ( formula, start_pos ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var subSTR = formula.substring( start_pos );
|
||
var match = rx_ref3D_quoted.xexec( subSTR ) || rx_ref3D_non_quoted.xexec( subSTR );
|
||
|
||
if ( match != null || match != undefined ) {
|
||
this.pCurrPos += match[0].length;
|
||
this.operand_str = match[1];
|
||
return [ true, match["name_from"] ? match["name_from"].replace( /''/g, "'" ) : null, match["name_to"] ? match["name_to"].replace( /''/g, "'" ) : null ];
|
||
}
|
||
this.operand_str = null;
|
||
return [false, null, null];
|
||
},
|
||
|
||
isNextPtg:function ( formula, start_pos ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var subSTR = formula.substring( start_pos );
|
||
return (
|
||
( subSTR.match( rx_before_operators ) != null || subSTR.match( rx_before_operators ) != undefined ) &&
|
||
( subSTR.match( rx_space ) != null || subSTR.match( rx_space ) != undefined )
|
||
)
|
||
},
|
||
|
||
isNumber:function ( formula, start_pos ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var match = (formula.substring( start_pos )).match( rx_number );
|
||
if ( match == null || match == undefined )
|
||
return false;
|
||
else {
|
||
this.operand_str = match[0];
|
||
this.pCurrPos += match[0].length;
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
|
||
isLeftParentheses:function ( formula, start_pos ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var match = (formula.substring( start_pos )).match( rx_LeftParentheses );
|
||
if ( match == null || match == undefined )
|
||
return false;
|
||
else {
|
||
this.operand_str = match[0].replace( /\s/, "" );
|
||
this.pCurrPos += match[0].length;
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
|
||
isRightParentheses:function ( formula, start_pos ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var match = (formula.substring( start_pos )).match( rx_RightParentheses );
|
||
if ( match == null || match == undefined )
|
||
return false;
|
||
else {
|
||
this.operand_str = match[0].replace( /\s/, "" );
|
||
this.pCurrPos += match[0].length;
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
|
||
isComma:function ( formula, start_pos ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var match = (formula.substring( start_pos )).match( rx_Comma );
|
||
if ( match == null || match == undefined )
|
||
return false;
|
||
else {
|
||
this.operand_str = match[0];
|
||
this.pCurrPos += match[0].length;
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
|
||
isError:function ( formula, start_pos ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var match = (formula.substring( start_pos )).match( rx_error );
|
||
if ( match == null || match == undefined )
|
||
return false;
|
||
else {
|
||
this.operand_str = match[0];
|
||
this.pCurrPos += match[0].length;
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
|
||
isBoolean:function ( formula, start_pos ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var match = (formula.substring( start_pos )).match( rx_bool );
|
||
if ( match == null || match == undefined )
|
||
return false;
|
||
else {
|
||
this.operand_str = match[1];
|
||
this.pCurrPos += match[1].length;
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
|
||
isString:function ( formula, start_pos ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var match = (formula.substring( start_pos )).match( rx_string );
|
||
if ( match != null || match != undefined ) {
|
||
this.operand_str = match[1].replace( "\"\"", "\"" );
|
||
this.pCurrPos += match[0].length;
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
|
||
isName:function ( formula, start_pos, wb ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var subSTR = formula.substring( start_pos );
|
||
var match = rx_name.xexec( subSTR );
|
||
|
||
if ( match != null || match != undefined ) {
|
||
var name = match["name"];
|
||
if ( name && name.length != 0 && wb.DefinedNames && wb.isDefinedNamesExists( name ) ) {
|
||
this.pCurrPos += name.length;
|
||
this.operand_str = name;
|
||
return [ true, name ];
|
||
}
|
||
}
|
||
return [false];
|
||
},
|
||
|
||
isArray:function ( formula, start_pos, wb ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var subSTR = formula.substring( start_pos );
|
||
var match = (formula.substring( start_pos )).match( rx_array );
|
||
|
||
if ( match != null || match != undefined ) {
|
||
this.operand_str = match[0].substring( 1, match[0].length - 1 );
|
||
this.pCurrPos += match[0].length;
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
},
|
||
|
||
isLeftBrace:function ( formula, start_pos ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var match = (formula.substring( start_pos )).match( rx_LeftBrace );
|
||
if ( match == null || match == undefined )
|
||
return false;
|
||
else {
|
||
this.operand_str = match[0].replace( /\s/, "" );
|
||
this.pCurrPos += match[0].length;
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
|
||
isRightBrace:function ( formula, start_pos ) {
|
||
if ( this instanceof parserHelper ) {
|
||
this._reset();
|
||
}
|
||
|
||
var match = (formula.substring( start_pos )).match( rx_RightBrace );
|
||
if ( match == null || match == undefined )
|
||
return false;
|
||
else {
|
||
this.operand_str = match[0].replace( /\s/, "" );
|
||
this.pCurrPos += match[0].length;
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
|
||
// Парсим ссылку на диапазон в листе
|
||
parse3DRef:function ( formula ) {
|
||
// Сначала получаем лист
|
||
var is3DRefResult = this.is3DRef( formula, 0 );
|
||
if ( is3DRefResult && true === is3DRefResult[0] ) {
|
||
// Имя листа в ссылке
|
||
var sheetName = is3DRefResult[1];
|
||
// Ищем начало range
|
||
var indexStartRange = formula.indexOf( "!" ) + 1;
|
||
if ( this.isArea( formula, indexStartRange ) ) {
|
||
if ( this.operand_str.length == formula.substring( indexStartRange ).length )
|
||
return {sheet:sheetName, range:this.operand_str};
|
||
else
|
||
return null;
|
||
}
|
||
else if ( this.isRef( formula, indexStartRange ) ) {
|
||
if ( this.operand_str.length == formula.substring( indexStartRange ).length )
|
||
return {sheet:sheetName, range:this.operand_str};
|
||
else
|
||
return null;
|
||
|
||
}
|
||
}
|
||
// Возвращаем ошибку
|
||
return null;
|
||
}
|
||
}
|
||
var parserHelp = new parserHelper();
|
||
|
||
//функция для определения к какому типу относится значение val.
|
||
function checkTypeCell( val ) {
|
||
if ( val == "" )
|
||
return new cEmpty();
|
||
else if ( parserHelp.isNumber( val, 0 ) )
|
||
return new cNumber( parserHelp.operand_str );
|
||
else if ( parserHelp.isString( val, 0 ) )
|
||
return new cString( parserHelp.operand_str );
|
||
else if ( parserHelp.isBoolean( val, 0 ) )
|
||
return new cBool( parserHelp.operand_str );
|
||
else if ( parserHelp.isError( val, 0 ) )
|
||
return new cError( parserHelp.operand_str );
|
||
else return new cString( val );
|
||
}
|
||
/*--------------------------------------------------------------------------*/
|
||
/*Base classes for operators & functions */
|
||
/** @constructor */
|
||
function cBaseOperator( name, priority, argumentCount ) {
|
||
this.name = name ? name : "";
|
||
this.priority = priority ? priority : 10;
|
||
this.type = cElementType.operator;
|
||
this.isRightAssociative = false;
|
||
this.argumentsCurrent = argumentCount ? argumentCount : 2;
|
||
this.value = null;
|
||
this.formatType = {
|
||
def:-1, //подразумевается формат первой ячейки входящей в формулу.
|
||
noneFormat:-2
|
||
};
|
||
this.numFormat = this.formatType.noneFormat;
|
||
}
|
||
cBaseOperator.prototype = {
|
||
constructor:cBaseOperator,
|
||
getArguments:function () {
|
||
return this.argumentsCurrent;
|
||
},
|
||
toString:function () {
|
||
return this.name;
|
||
},
|
||
Calculate:function () {
|
||
return null;
|
||
},
|
||
Assemble:function ( arg ) {
|
||
var str = "";
|
||
if ( this.argumentsCurrent == 2 )
|
||
str = arg[0] + "" + this.name + "" + arg[1];
|
||
else str = this.name + "" + arg[0];
|
||
return new cString( str );
|
||
}
|
||
}
|
||
|
||
/** @constructor */
|
||
function cBaseFunction( name ) {
|
||
this.name = name;
|
||
this.type = cElementType.func;
|
||
this.value = null;
|
||
this.argumentsMin = 0;
|
||
this.argumentsCurrent = 0;
|
||
this.argumentsMax = 255;
|
||
this.formatType = {
|
||
def:-1, //подразумевается формат первой ячейки входящей в формулу.
|
||
noneFormat:-2
|
||
};
|
||
this.numFormat = this.formatType.def;
|
||
}
|
||
cBaseFunction.prototype = {
|
||
constructor:cBaseFunction,
|
||
Calculate:function () {
|
||
return this.value = new cError( cErrorType.wrong_name )
|
||
},
|
||
setArgumentsMin:function ( count ) {
|
||
this.argumentsMin = count;
|
||
},
|
||
setArgumentsMax:function ( count ) {
|
||
this.argumentsMax = count;
|
||
},
|
||
DecrementArguments:function () {
|
||
--this.argumentsCurrent;
|
||
},
|
||
IncrementArguments:function () {
|
||
++this.argumentsCurrent;
|
||
},
|
||
setName:function ( name ) {
|
||
this.name = name;
|
||
},
|
||
setArgumentsCount:function ( count ) {
|
||
this.argumentsCurrent = count;
|
||
},
|
||
getArguments:function () {
|
||
return this.argumentsCurrent;
|
||
},
|
||
getMaxArguments:function () {
|
||
return this.argumentsMax;
|
||
},
|
||
getMinArguments:function () {
|
||
return this.argumentsMin;
|
||
},
|
||
Assemble:function ( arg ) {
|
||
var str = "";
|
||
for ( var i = 0; i < arg.length; i++ ) {
|
||
str += arg[i].toString();
|
||
if ( i != arg.length - 1 )
|
||
str += ",";
|
||
}
|
||
return new cString( this.name + "(" + str + ")" );
|
||
},
|
||
toString:function () {
|
||
return this.name
|
||
},
|
||
setCA:function ( arg, ca, numFormat ) {
|
||
this.value = arg;
|
||
if ( ca )this.value.ca = true;
|
||
if ( numFormat !== null && numFormat !== undefined )this.value.numFormat = numFormat;
|
||
return this.value;
|
||
},
|
||
setFormat:function ( f ) {
|
||
this.numFormat = f;
|
||
}
|
||
}
|
||
|
||
/** @constructor */
|
||
function cBaseType( val ) {
|
||
this.needRecalc = false;
|
||
this.numFormat = null;
|
||
this.type = null;
|
||
this.value = val;
|
||
this.ca = false;
|
||
}
|
||
cBaseType.prototype = {
|
||
constructor:cBaseType,
|
||
tryConvert:function () {
|
||
return this;
|
||
},
|
||
getValue:function () {
|
||
return this.value;
|
||
},
|
||
toString:function () {
|
||
return this.value.toString();
|
||
}
|
||
}
|
||
|
||
/* cFormulaOperators is container for holding all ECMA-376 operators, see chapter $18.17.2.2 in "ECMA-376, Second Edition, Part 1 - Fundamentals And Markup Language Reference" */
|
||
var cFormulaOperators = {
|
||
'(':function () {
|
||
var r = {};
|
||
r.name = "(";
|
||
r.type = cElementType.operator;
|
||
r.argumentsCurrent = 1;
|
||
r.DecrementArguments = function () {
|
||
--this.argumentsCurrent;
|
||
}
|
||
r.IncrementArguments = function () {
|
||
++this.argumentsCurrent;
|
||
}
|
||
r.toString = function () {
|
||
return this.name;
|
||
}
|
||
r.getArguments = function () {
|
||
return this.argumentsCurrent;
|
||
}
|
||
r.Assemble = function ( arg ) {
|
||
return new cString( "(" + arg + ")" );
|
||
}
|
||
return r;
|
||
},
|
||
')':function () {
|
||
var r = {};
|
||
r.name = ')';
|
||
r.type = cElementType.operator;
|
||
r.toString = function () {
|
||
return ')';
|
||
}
|
||
return r;
|
||
},
|
||
'{':function () {
|
||
var r = {};
|
||
r.name = '{';
|
||
r.toString = function () {
|
||
return this.name;
|
||
}
|
||
return r;
|
||
},
|
||
'}':function () {
|
||
var r = {};
|
||
r.name = '}';
|
||
r.toString = function () {
|
||
return this.name;
|
||
}
|
||
return r;
|
||
},
|
||
/* 50 is highest priority */
|
||
'un_minus':function () {
|
||
var r = new cBaseOperator( 'un_minus'/**name operator*/, 50/**priority of operator*/, 1/**count arguments*/ );
|
||
r.Calculate = function ( arg ) { //calculate operator
|
||
var arg0 = arg[0];
|
||
if ( arg0 instanceof cArea ) {
|
||
arg0 = arg0.cross( arguments[1].first );
|
||
}
|
||
else if ( arg0 instanceof cArray ) {
|
||
arg0.foreach(
|
||
function ( arrElem, r, c ) {
|
||
arrElem = arrElem.tocNumber();
|
||
arg0.array[r][c] = arrElem instanceof cError ? arrElem : new cNumber( -arrElem.getValue() );
|
||
}
|
||
)
|
||
return this.value = arg0;
|
||
}
|
||
arg0 = arg0.tocNumber();
|
||
return this.value = arg0 instanceof cError ? arg0 : new cNumber( -arg0.getValue() )
|
||
},
|
||
r.toString = function () { // toString function
|
||
return '-';
|
||
}
|
||
r.Assemble = function ( arg ) {
|
||
return new cString( "-" + arg[0] );
|
||
}
|
||
r.isRightAssociative = true;
|
||
return r;
|
||
},
|
||
'un_plus':function () {
|
||
var r = new cBaseOperator( 'un_plus', 50, 1 );
|
||
r.Calculate = function ( arg ) {
|
||
var arg0 = arg[0];
|
||
if ( arg0 instanceof cArea ) {
|
||
arg0 = arg0.cross( arguments[1].first );
|
||
}
|
||
arg0 = arg[0].tryConvert();
|
||
return this.value = arg0;
|
||
}
|
||
r.toString = function () {
|
||
return '+';
|
||
}
|
||
r.isRightAssociative = true;
|
||
r.Assemble = function ( arg ) {
|
||
return new cString( "+" + arg[0] );
|
||
}
|
||
return r;
|
||
},
|
||
'%':function () {
|
||
var r = new cBaseOperator( '%', 45, 1 );
|
||
r.Calculate = function ( arg ) {
|
||
var arg0 = arg[0];
|
||
if ( arg0 instanceof cArea ) {
|
||
arg0 = arg0.cross( arguments[1].first );
|
||
}
|
||
else if ( arg0 instanceof cArray ) {
|
||
arg0.foreach(
|
||
function ( arrElem, r, c ) {
|
||
arrElem = arrElem.tocNumber();
|
||
arg0.array[r][c] = arrElem instanceof cError ? arrElem : new cNumber( arrElem.getValue() / 100 );
|
||
}
|
||
)
|
||
return this.value = arg0;
|
||
}
|
||
arg0 = arg0.tocNumber();
|
||
this.value = arg0 instanceof cError ? arg0 : new cNumber( arg0.getValue() / 100 );
|
||
this.value.numFormat = 9;
|
||
return this.value;
|
||
}
|
||
r.isRightAssociative = true;
|
||
r.Assemble = function ( arg ) {
|
||
return new cString( arg[0] + this.name );
|
||
}
|
||
return r;
|
||
},
|
||
'^':function () {
|
||
var r = new cBaseOperator( '^', 40 );
|
||
r.Calculate = function ( arg ) {
|
||
var arg0 = arg[0], arg1 = arg[1];
|
||
if ( arg0 instanceof cArea ) {
|
||
arg0 = arg0.cross( arguments[1].first );
|
||
}
|
||
arg0 = arg0.tocNumber();
|
||
if ( arg1 instanceof cArea ) {
|
||
arg1 = arg1.cross( arguments[1].first );
|
||
}
|
||
arg1 = arg1.tocNumber();
|
||
if ( arg0 instanceof cError ) return this.value = arg0;
|
||
if ( arg1 instanceof cError ) return this.value = arg1;
|
||
|
||
var _v = Math.pow( arg0.getValue(), arg1.getValue() );
|
||
if ( isNaN( _v ) )
|
||
return this.value = new cError( cErrorType.not_numeric );
|
||
else if ( _v === Number.POSITIVE_INFINITY )
|
||
return this.value = new cError( cErrorType.division_by_zero );
|
||
return this.value = new cNumber( _v );
|
||
}
|
||
return r;
|
||
},
|
||
'*':function () {
|
||
var r = new cBaseOperator( '*', 30 );
|
||
r.Calculate = function ( arg ) {
|
||
var arg0 = arg[0].tryConvert(), arg1 = arg[1].tryConvert();
|
||
return this.value = _func[arg0.type][arg1.type]( arg0, arg1, "*", arguments[1].first );
|
||
}
|
||
return r;
|
||
},
|
||
'/':function () {
|
||
var r = new cBaseOperator( '/', 30 );
|
||
r.Calculate = function ( arg ) {
|
||
var arg0 = arg[0].tryConvert(), arg1 = arg[1].tryConvert();
|
||
return this.value = _func[arg0.type][arg1.type]( arg0, arg1, "/", arguments[1].first );
|
||
}
|
||
return r;
|
||
},
|
||
'+':function () {
|
||
var r = new cBaseOperator( '+', 20 );
|
||
r.Calculate = function ( arg ) {
|
||
var arg0 = arg[0].tryConvert(), arg1 = arg[1].tryConvert();
|
||
return this.value = _func[arg0.type][arg1.type]( arg0, arg1, "+", arguments[1].first );
|
||
}
|
||
return r;
|
||
},
|
||
'-':function () {
|
||
var r = new cBaseOperator( '-', 20 );
|
||
r.Calculate = function ( arg ) {
|
||
var arg0 = arg[0].tryConvert(), arg1 = arg[1].tryConvert();
|
||
return this.value = _func[arg0.type][arg1.type]( arg0, arg1, "-", arguments[1].first );
|
||
}
|
||
return r;
|
||
},
|
||
'&':function () {//concat str
|
||
var r = new cBaseOperator( '&', 15 );
|
||
r.Calculate = function ( arg ) {
|
||
var arg0 = arg[0], arg1 = arg[1];
|
||
if ( arg0 instanceof cArea ) {
|
||
arg0 = arg0.cross( arguments[1].first );
|
||
}
|
||
arg0 = arg0.tocString();
|
||
if ( arg1 instanceof cArea ) {
|
||
arg1 = arg1.cross( arguments[1].first );
|
||
}
|
||
arg1 = arg1.tocString();
|
||
|
||
return this.value = arg0 instanceof cError ? arg0 :
|
||
arg1 instanceof cError ? arg1 :
|
||
new cString( arg0.toString().concat( arg1.toString() ) )
|
||
}
|
||
return r;
|
||
},
|
||
'=':function () {// equals
|
||
var r = new cBaseOperator( '=', 10 );
|
||
r.Calculate = function ( arg ) {
|
||
var arg0 = arg[0].tryConvert(), arg1 = arg[1].tryConvert();
|
||
return this.value = _func[arg0.type][arg1.type]( arg0, arg1, "=", arguments[1].first );
|
||
}
|
||
return r;
|
||
},
|
||
'<>':function () {
|
||
var r = new cBaseOperator( '<>', 10 );
|
||
r.Calculate = function ( arg ) {
|
||
var arg0 = arg[0].tryConvert(), arg1 = arg[1].tryConvert();
|
||
return this.value = _func[arg0.type][arg1.type]( arg0, arg1, "<>", arguments[1].first );
|
||
}
|
||
return r;
|
||
},
|
||
'<':function () {
|
||
var r = new cBaseOperator( '<', 10 );
|
||
r.Calculate = function ( arg ) {
|
||
var arg0 = arg[0].tryConvert(), arg1 = arg[1].tryConvert();
|
||
return this.value = _func[arg0.type][arg1.type]( arg0, arg1, "<", arguments[1].first );
|
||
}
|
||
return r;
|
||
},
|
||
'<=':function () {
|
||
var r = new cBaseOperator( '<=', 10 );
|
||
r.Calculate = function ( arg ) {
|
||
var arg0 = arg[0].tryConvert(), arg1 = arg[1].tryConvert();
|
||
return this.value = _func[arg0.type][arg1.type]( arg0, arg1, "<=", arguments[1].first );
|
||
};
|
||
return r;
|
||
},
|
||
'>':function () {
|
||
var r = new cBaseOperator( '>', 10 );
|
||
r.Calculate = function ( arg ) {
|
||
var arg0 = arg[0].tryConvert(), arg1 = arg[1].tryConvert();
|
||
return this.value = _func[arg0.type][arg1.type]( arg0, arg1, ">", arguments[1].first );
|
||
};
|
||
return r;
|
||
},
|
||
'>=':function () {
|
||
var r = new cBaseOperator( '>=', 10 );
|
||
r.Calculate = function ( arg ) {
|
||
var arg0 = arg[0].tryConvert(), arg1 = arg[1].tryConvert();
|
||
return this.value = _func[arg0.type][arg1.type]( arg0, arg1, ">=", arguments[1].first );
|
||
};
|
||
return r;
|
||
}
|
||
/* 10 is lowest priopity */
|
||
};
|
||
|
||
/* cFormulaFunction is container for holding all ECMA-376 function, see chapter $18.17.7 in "ECMA-376, Second Edition, Part 1 - Fundamentals And Markup Language Reference" */
|
||
/*
|
||
Каждая формула представляет собой копию функции cBaseFunction.
|
||
Для реализации очередной функции необходимо указать количество (минимальное и максимальное) принимаемых аргументов. Берем в спецификации.
|
||
Также необходино написать реализацию методов Calculate и getInfo(возвращает название функции и вид/количетво аргументов).
|
||
В методе Calculate необходимо отслеживать тип принимаемых аргументов. Для примера, если мы обращаемся к ячейке A1, в которой лежит 123, то этот аргумент будет числом. Если же там лежит "123", то это уже строка. Для более подробной информации смотреть спецификацию.
|
||
Метод getInfo является обязательным, ибо через этот метод в интерфейс передается информация о реализованных функциях.
|
||
*/
|
||
var cFormulaFunction = {};
|
||
|
||
function getFormulasInfo() {
|
||
var list = [], a, b;
|
||
for ( var type in cFormulaFunction ) {
|
||
b = new Asc.asc_CFormulaGroup( cFormulaFunction[type]["groupName"] );
|
||
for ( var f in cFormulaFunction[type] ) {
|
||
if ( f != "groupName" ) {
|
||
a = cFormulaFunction[type][f]();
|
||
if ( a.getInfo )
|
||
b.asc_addFormulaElement( new Asc.asc_CFormula( a.getInfo() ) );
|
||
delete a;
|
||
}
|
||
}
|
||
list.push( b )
|
||
}
|
||
return list;
|
||
}
|
||
/*--------------------------------------------------------------------------*/
|
||
/*Basic types of an elements used into formulas*/
|
||
/** @constructor */
|
||
function cNumber( val ) {
|
||
cNumber.superclass.constructor.call( this, val );
|
||
this.type = cElementType.number;
|
||
this.value = parseFloat( val );
|
||
if( !isNaN( this.value ) && Math.abs(this.value)!=Infinity )
|
||
return this;
|
||
else
|
||
return new cError( cErrorType.not_numeric );
|
||
}
|
||
extend( cNumber, cBaseType );
|
||
cNumber.prototype.getValue = function () {
|
||
return this.value.toFixed( cExcelSignificantDigits ) - 0;
|
||
};
|
||
cNumber.prototype.tocString = function () {
|
||
return new cString( "" + this.value );
|
||
};
|
||
cNumber.prototype.tocNumber = function () {
|
||
return this;
|
||
};
|
||
cNumber.prototype.tocBool = function () {
|
||
return new cBool( this.value != 0 );
|
||
};
|
||
|
||
/** @constructor */
|
||
function cString( val ) {
|
||
cString.superclass.constructor.call( this, val );
|
||
this.type = cElementType.string;
|
||
}
|
||
extend( cString, cBaseType );
|
||
cString.prototype.tocNumber = function () {
|
||
if ( this.value == "" )
|
||
return new cEmpty();
|
||
|
||
var m = this.value;
|
||
if ( this.value[0] == '"' && this.value[this.value.length - 1] == '"' )
|
||
m = this.value.substring( 1, this.value.length - 1 );
|
||
if ( !parseNum( m ) )
|
||
return new cError( cErrorType.wrong_value_type );
|
||
else {
|
||
var _numberValue = parseFloat( m );
|
||
if ( !isNaN( _numberValue ) )
|
||
return new cNumber( _numberValue );
|
||
}
|
||
};
|
||
cString.prototype.tocBool = function () {
|
||
if ( parserHelp.isBoolean( this.value, 0 ) ) {
|
||
if ( parserHelp.operand_str == "TRUE" )
|
||
return new cBool( true );
|
||
else
|
||
return new cBool( false );
|
||
}
|
||
else
|
||
return this;
|
||
};
|
||
cString.prototype.tocString = function () {
|
||
return this;
|
||
};
|
||
|
||
/** @constructor */
|
||
function cBool( val ) {
|
||
cBool.superclass.constructor.call( this, val );
|
||
this.type = cElementType.bool;
|
||
var that = this;
|
||
switch ( val.toString().toUpperCase() ) {
|
||
case "TRUE":
|
||
this.value = true;
|
||
break;
|
||
case "FALSE":
|
||
this.value = false;
|
||
break;
|
||
}
|
||
}
|
||
extend( cBool, cBaseType );
|
||
cBool.prototype.toString = function () {
|
||
return this.value.toString().toUpperCase();
|
||
};
|
||
cBool.prototype.getValue = function () {
|
||
return this.toString();
|
||
};
|
||
cBool.prototype.tocNumber = function () {
|
||
return new cNumber( this.value ? 1.0 : 0.0 );
|
||
};
|
||
cBool.prototype.tocString = function () {
|
||
return new cString( this.value ? "TRUE" : "FALSE" );
|
||
};
|
||
cBool.prototype.tocBool = function () {
|
||
return this;
|
||
};
|
||
cBool.prototype.toBool = function () {
|
||
return this.value;
|
||
};
|
||
|
||
/** @constructor */
|
||
function cError( val ) {
|
||
cError.superclass.constructor.call( this, val );
|
||
this.type = cElementType.error;
|
||
this.errorType = -1;
|
||
|
||
if ( isNaN( parseInt( val ) ) ) {
|
||
switch ( val ) {
|
||
case "#VALUE!":
|
||
this.errorType = cErrorType.wrong_value_type;
|
||
break;
|
||
case "#NULL!":
|
||
this.errorType = cErrorType.null_value;
|
||
break;
|
||
case "#DIV/0!":
|
||
this.errorType = cErrorType.division_by_zero;
|
||
break;
|
||
case "#REF!":
|
||
this.errorType = cErrorType.bad_reference;
|
||
break;
|
||
case "#NAME?":
|
||
this.errorType = cErrorType.wrong_name;
|
||
break;
|
||
case "#NUM!":
|
||
this.errorType = cErrorType.not_numeric;
|
||
break;
|
||
case "#N/A":
|
||
this.errorType = cErrorType.not_available;
|
||
break;
|
||
case "#UNSUPPORTED_FUNCTION!":
|
||
this.errorType = cErrorType.unsupported_function;
|
||
break;
|
||
case "#GETTING_DATA":
|
||
this.errorType = cErrorType.getting_data;
|
||
break;
|
||
}
|
||
return this;
|
||
}
|
||
switch ( val ) {
|
||
case cErrorType.null_value:
|
||
this.value = "#NULL!";
|
||
this.errorType = cErrorType.null_value;
|
||
break;
|
||
case cErrorType.division_by_zero:
|
||
this.value = "#DIV/0!";
|
||
this.errorType = cErrorType.division_by_zero;
|
||
break;
|
||
case cErrorType.wrong_value_type:
|
||
this.value = "#VALUE!";
|
||
this.errorType = cErrorType.wrong_value_type;
|
||
break;
|
||
case cErrorType.bad_reference:
|
||
this.value = "#REF!";
|
||
this.errorType = cErrorType.bad_reference;
|
||
break;
|
||
case cErrorType.wrong_name:
|
||
this.value = "#NAME?";
|
||
this.errorType = cErrorType.wrong_name;
|
||
break;
|
||
case cErrorType.not_numeric:
|
||
this.value = "#NUM!";
|
||
this.errorType = cErrorType.not_numeric;
|
||
break;
|
||
case cErrorType.not_available:
|
||
this.value = "#N/A";
|
||
this.errorType = cErrorType.not_available;
|
||
break;
|
||
case cErrorType.unsupported_function:
|
||
this.value = "#UNSUPPORTED_FUNCTION!";
|
||
this.errorType = cErrorType.unsupported_function;
|
||
break;
|
||
case cErrorType.getting_data:
|
||
this.value = "#GETTING_DATA";
|
||
this.errorType = cErrorType.getting_data;
|
||
break;
|
||
}
|
||
}
|
||
extend( cError, cBaseType );
|
||
cError.prototype.tocNumber = cError.prototype.tocString = cError.prototype.tocBool = cError.prototype.tocEmpty = function () {
|
||
return this;
|
||
};
|
||
|
||
/** @constructor */
|
||
function cArea( val, _ws ) {/*Area means "A1:E5" for example*/
|
||
cArea.superclass.constructor.call( this, val );
|
||
this.ws = _ws;
|
||
this.wb = _ws.workbook;
|
||
this._cells = val;
|
||
this.isAbsolute = false;
|
||
this.type = cElementType.cellsRange;
|
||
// this.range = this.wb.getWorksheetById(this.ws).getRange2(val);
|
||
// this._valid = this.range ? true : false;
|
||
}
|
||
extend( cArea, cBaseType );
|
||
cArea.prototype.getWsId = function () {
|
||
return this.ws.Id;
|
||
};
|
||
cArea.prototype.getValue = function () {
|
||
var _val = [], r = this.getRange();
|
||
if ( !r ) {
|
||
_val.push( new cError( cErrorType.bad_reference ) )
|
||
}
|
||
else
|
||
r._foreachNoEmpty( function ( _cell ) {
|
||
switch ( _cell.getType() ) {
|
||
case CellValueType.Number:
|
||
_cell.getValueWithoutFormat() == "" ? _val.push( new cEmpty() ) : _val.push( new cNumber( _cell.getValueWithoutFormat() ) )
|
||
break;
|
||
case CellValueType.Bool:
|
||
_val.push( new cBool( _cell.getValueWithoutFormat() ) );
|
||
break;
|
||
case CellValueType.Error:
|
||
_val.push( new cError( _cell.getValueWithoutFormat() ) );
|
||
break;
|
||
case CellValueType.String:
|
||
_val.push( new cString( _cell.getValueWithoutFormat() ) );
|
||
break;
|
||
default:
|
||
if ( _cell.getValueWithoutFormat() && _cell.getValueWithoutFormat() != "" ) {
|
||
_val.push( new cNumber( _cell.getValueWithoutFormat() ) )
|
||
}
|
||
else
|
||
_val.push( checkTypeCell( "" + _cell.getValueWithoutFormat() ) );
|
||
}
|
||
} );
|
||
return _val;
|
||
};
|
||
cArea.prototype.getValue2 = function ( cell ) {
|
||
var _val = [], r = this.getRange();
|
||
if ( !r ) {
|
||
_val.push( new cError( cErrorType.bad_reference ) )
|
||
}
|
||
else
|
||
r._foreachNoEmpty( function ( _cell ) {
|
||
if ( cell.getID() == _cell.getName() )
|
||
switch ( _cell.getType() ) {
|
||
case CellValueType.Number:
|
||
_cell.getValueWithoutFormat() == "" ? _val.push( new cEmpty() ) : _val.push( new cNumber( _cell.getValueWithoutFormat() ) )
|
||
break;
|
||
case CellValueType.Bool:
|
||
_val.push( new cBool( _cell.getValueWithoutFormat() ) );
|
||
break;
|
||
case CellValueType.Error:
|
||
_val.push( new cError( _cell.getValueWithoutFormat() ) );
|
||
break;
|
||
case CellValueType.String:
|
||
_val.push( new cString( _cell.getValueWithoutFormat() ) );
|
||
break;
|
||
default:
|
||
if ( _cell.getValueWithoutFormat() && _cell.getValueWithoutFormat() != "" ) {
|
||
_val.push( new cNumber( _cell.getValueWithoutFormat() ) )
|
||
}
|
||
else
|
||
_val.push( checkTypeCell( "" + _cell.getValueWithoutFormat() ) );
|
||
}
|
||
} );
|
||
return _val[0];
|
||
};
|
||
cArea.prototype.getRange = function () {
|
||
return this.ws.getRange2( this._cells );
|
||
};
|
||
cArea.prototype.tocNumber = function () {
|
||
return this.getValue()[0].tocNumber();
|
||
};
|
||
cArea.prototype.tocString = function () {
|
||
return this.getValue()[0].tocString();
|
||
};
|
||
cArea.prototype.tocBool = function () {
|
||
return this.getValue()[0].tocBool();
|
||
};
|
||
cArea.prototype.toString = function () {
|
||
return this._cells;
|
||
};
|
||
cArea.prototype.setRange = function ( cell ) {
|
||
this._cells = this.value = cell;
|
||
this.range = this.ws.getRange2( cell );
|
||
this._valid = this.range ? true : false;
|
||
};
|
||
cArea.prototype.getWS = function () {
|
||
return this.ws;
|
||
};
|
||
cArea.prototype.getBBox = function () {
|
||
return this.getRange().getBBox();
|
||
};
|
||
cArea.prototype.cross = function ( arg ) {
|
||
var r = this.getRange();
|
||
if ( !r )
|
||
return new cError( cErrorType.wrong_name );
|
||
var cross = r.cross( arg );
|
||
if ( cross ) {
|
||
if ( cross.r != undefined ) {
|
||
return this.getValue2( new CellAddress( cross.r, this.getBBox().c1 ) )
|
||
}
|
||
else if ( cross.c != undefined ) {
|
||
return this.getValue2( new CellAddress( this.getBBox().r1, cross.c ) )
|
||
}
|
||
else
|
||
return new cError( cErrorType.wrong_value_type );
|
||
}
|
||
else
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
cArea.prototype.isValid = function () {
|
||
var r = this.getRange();
|
||
if ( !r )
|
||
return false;
|
||
return true;
|
||
};
|
||
cArea.prototype.countCells = function () {
|
||
var r = this.getRange(), bbox = r.bbox,
|
||
count = (Math.abs( bbox.c1 - bbox.c2 ) + 1) * (Math.abs( bbox.r1 - bbox.r2 ) + 1);
|
||
r._foreachNoEmpty( function ( _cell ) {
|
||
count--;
|
||
} )
|
||
return new cNumber( count );
|
||
};
|
||
cArea.prototype.foreach = function ( action ) {
|
||
var r = this.getRange();
|
||
if ( r ) {
|
||
r._foreach2( action )
|
||
}
|
||
}
|
||
cArea.prototype.foreach2 = function ( action ) {
|
||
var r = this.getRange();
|
||
if ( r ) {
|
||
r._foreach2( function ( _cell ) {
|
||
var val;
|
||
switch ( _cell.getType() ) {
|
||
case CellValueType.Number:
|
||
_cell.getValueWithoutFormat() == "" ? val = new cEmpty() : val = new cNumber( _cell.getValueWithoutFormat() )
|
||
break;
|
||
case CellValueType.Bool:
|
||
val = new cBool( _cell.getValueWithoutFormat() );
|
||
break;
|
||
case CellValueType.Error:
|
||
val = new cError( _cell.getValueWithoutFormat() );
|
||
break;
|
||
case CellValueType.String:
|
||
val = new cString( _cell.getValueWithoutFormat() );
|
||
break;
|
||
default:
|
||
if ( _cell.getValueWithoutFormat() && _cell.getValueWithoutFormat() != "" ) {
|
||
val = new cNumber( _cell.getValueWithoutFormat() )
|
||
}
|
||
else
|
||
val = checkTypeCell( "" + _cell.getValueWithoutFormat() );
|
||
}
|
||
action(val);
|
||
} );
|
||
}
|
||
}
|
||
cArea.prototype.getMatrix = function () {
|
||
var arr = [],
|
||
r = this.getRange();
|
||
r._foreach2( function ( cell, i, j, r1, c1 ) {
|
||
if ( !arr[i - r1] )
|
||
arr[i - r1] = [];
|
||
if ( cell ) {
|
||
switch ( cell.getType() ) {
|
||
case CellValueType.Number:
|
||
arr[i - r1][j - c1] = cell.getValueWithoutFormat() == "" ? new cEmpty() : new cNumber( cell.getValueWithoutFormat() )
|
||
break;
|
||
case CellValueType.Bool:
|
||
arr[i - r1][j - c1] = new cBool( cell.getValueWithoutFormat() );
|
||
break;
|
||
case CellValueType.Error:
|
||
arr[i - r1][j - c1] = new cError( cell.getValueWithoutFormat() );
|
||
break;
|
||
case CellValueType.String:
|
||
arr[i - r1][j - c1] = new cString( cell.getValueWithoutFormat() );
|
||
break;
|
||
default:
|
||
if ( cell.getValueWithoutFormat() && cell.getValueWithoutFormat() != "" ) {
|
||
arr[i - r1][j - c1] = new cNumber( cell.getValueWithoutFormat() )
|
||
}
|
||
else
|
||
arr[i - r1][j - c1] = checkTypeCell( "" + cell.getValueWithoutFormat() );
|
||
}
|
||
}
|
||
else
|
||
arr[i - r1][j - c1] = new cEmpty();
|
||
} )
|
||
return arr;
|
||
}
|
||
|
||
/** @constructor */
|
||
function cRef( val, _ws ) {/*Ref means A1 for example*/
|
||
cRef.superclass.constructor.call( this, val );
|
||
this._cells = val;
|
||
this.ws = _ws;
|
||
this.wb = _ws.workbook;
|
||
this.isAbsolute = false;
|
||
this.type = cElementType.cell;
|
||
this.range = _ws.getRange2( val );
|
||
this._valid = new CellAddress( val.replace( /\$/g, "" ) ).isValid();
|
||
}
|
||
extend( cRef, cBaseType );
|
||
cRef.prototype.getWsId = function () {
|
||
return this.ws.Id;
|
||
};
|
||
cRef.prototype.getValue = function () {
|
||
if ( !this._valid ) {
|
||
return new cError( cErrorType.bad_reference )
|
||
}
|
||
switch ( this.range.getType() ) {
|
||
case CellValueType.Number:
|
||
{
|
||
var v = this.range.getValueWithoutFormat();
|
||
if ( v == "" )
|
||
return new cEmpty( "" + v )
|
||
else
|
||
return new cNumber( "" + v );
|
||
}
|
||
case CellValueType.String:
|
||
return new cString( "" + this.range.getValueWithoutFormat() );
|
||
case CellValueType.Bool:
|
||
return new cBool( "" + this.range.getValueWithoutFormat() )
|
||
case CellValueType.Error:
|
||
return new cError( "" + this.range.getValueWithoutFormat() )
|
||
default:
|
||
var _val = "" + this.range.getValueWithoutFormat();
|
||
if ( _val == "" || _val == null )
|
||
return new cEmpty();
|
||
else if ( parserHelp.isNumber( _val ) )
|
||
return new cNumber( parserHelp.operand_str )
|
||
else if ( parserHelp.isBoolean( _val ) )
|
||
return new cBool( parserHelp.operand_str )
|
||
else if ( parserHelp.isError( _val ) )
|
||
return new cError( parserHelp.operand_str )
|
||
else return new cString( _val );
|
||
}
|
||
};
|
||
cRef.prototype.tocNumber = function () {
|
||
return this.getValue().tocNumber();
|
||
};
|
||
cRef.prototype.tocString = function () {
|
||
return this.getValue().tocString();
|
||
/* new cString(""+this.range.getValueWithFormat()); */
|
||
};
|
||
cRef.prototype.tocBool = function () {
|
||
return this.getValue().tocBool();
|
||
};
|
||
cRef.prototype.tryConvert = function () {
|
||
return this.getValue();
|
||
};
|
||
cRef.prototype.toString = function () {
|
||
return this._cells;
|
||
};
|
||
cRef.prototype.getRange = function () {
|
||
return this.range;
|
||
};
|
||
cRef.prototype.getWS = function () {
|
||
return this.ws;
|
||
};
|
||
cRef.prototype.isValid = function () {
|
||
return this._valid;
|
||
};
|
||
|
||
/** @constructor */
|
||
function cArea3D( val, _wsFrom, _wsTo, wb ) {/*Area3D means "Sheat1!A1:E5" for example*/
|
||
cArea3D.superclass.constructor.call( this, val );
|
||
this._wb = wb;
|
||
this._cells = val;
|
||
this.isAbsolute = false;
|
||
this.type = cElementType.cellsRange;
|
||
this.wsFrom = this._wb.getWorksheetByName( _wsFrom ).getId();
|
||
this.wsTo = this._wb.getWorksheetByName( _wsTo ).getId();
|
||
}
|
||
extend( cArea3D, cBaseType );
|
||
cArea3D.prototype.wsRange = function () {
|
||
var r = [];
|
||
if ( !this.wsTo ) this.wsTo = this.wsFrom;
|
||
var wsF = this._wb.getWorksheetById( this.wsFrom ).getIndex(), wsL = this._wb.getWorksheetById( this.wsTo ).getIndex(), r = [];
|
||
for ( var i = wsF; i <= wsL; i++ ) {
|
||
r.push( this._wb.getWorksheet( i ) );
|
||
}
|
||
return r;
|
||
};
|
||
cArea3D.prototype.range = function ( wsRange ) {
|
||
if ( !wsRange ) return [null];
|
||
var r = [];
|
||
for ( var i = 0; i < wsRange.length; i++ ) {
|
||
if ( !wsRange[i] )
|
||
r.push( null );
|
||
else
|
||
r.push( wsRange[i].getRange2( this._cells ) );
|
||
}
|
||
return r;
|
||
};
|
||
cArea3D.prototype.getRange = function () {
|
||
return this.range( this.wsRange() );
|
||
};
|
||
cArea3D.prototype.getValue = function () {
|
||
var _wsA = this.wsRange();
|
||
var _val = [];
|
||
if ( _wsA.length < 1 ) {
|
||
_val.push( new cError( cErrorType.bad_reference ) );
|
||
return _val;
|
||
}
|
||
for ( var i = 0; i < _wsA.length; i++ ) {
|
||
if ( !_wsA[i] ) {
|
||
_val.push( new cError( cErrorType.bad_reference ) );
|
||
return _val;
|
||
}
|
||
|
||
}
|
||
var _r = this.range( _wsA );
|
||
for ( var i = 0; i < _r.length; i++ ) {
|
||
if ( !_r[i] ) {
|
||
_val.push( new cError( cErrorType.bad_reference ) );
|
||
return _val;
|
||
}
|
||
_r[i]._foreachNoEmpty( function ( _cell ) {
|
||
switch ( _cell.getType() ) {
|
||
case CellValueType.Number:
|
||
_cell.getValueWithoutFormat() == "" ? _val.push( new cEmpty() ) : _val.push( new cNumber( _cell.getValueWithoutFormat() ) )
|
||
break;
|
||
case CellValueType.Bool:
|
||
_val.push( new cBool( _cell.getValueWithoutFormat() ) );
|
||
break;
|
||
case CellValueType.Error:
|
||
_val.push( new cError( _cell.getValueWithoutFormat() ) );
|
||
break;
|
||
case CellValueType.String:
|
||
_val.push( new cString( _cell.getValueWithoutFormat() ) );
|
||
break;
|
||
default:
|
||
if ( _cell.getValueWithoutFormat() && _cell.getValueWithoutFormat() != "" ) {
|
||
_val.push( new cNumber( _cell.getValueWithoutFormat() ) )
|
||
}
|
||
else
|
||
_val.push( checkTypeCell( "" + _cell.getValueWithoutFormat() ) );
|
||
}
|
||
} )
|
||
}
|
||
return _val;
|
||
};
|
||
cArea3D.prototype.getValue2 = function ( cell ) {
|
||
var _wsA = this.wsRange();
|
||
var _val = [];
|
||
if ( _wsA.length < 1 ) {
|
||
_val.push( new cError( cErrorType.bad_reference ) );
|
||
return _val;
|
||
}
|
||
for ( var i = 0; i < _wsA.length; i++ ) {
|
||
if ( !_wsA[i] ) {
|
||
_val.push( new cError( cErrorType.bad_reference ) );
|
||
return _val;
|
||
}
|
||
|
||
}
|
||
var _r = this.range( _wsA );
|
||
if ( !_r[0] ) {
|
||
_val.push( new cError( cErrorType.bad_reference ) );
|
||
return _val;
|
||
}
|
||
_r[0]._foreachNoEmpty( function ( _cell ) {
|
||
if ( cell.getID() == _cell.getName() )
|
||
switch ( _cell.getType() ) {
|
||
case CellValueType.Number:
|
||
_cell.getValueWithoutFormat() == "" ? _val.push( new cEmpty() ) : _val.push( new cNumber( _cell.getValueWithoutFormat() ) )
|
||
break;
|
||
case CellValueType.Bool:
|
||
_val.push( new cBool( _cell.getValueWithoutFormat() ) );
|
||
break;
|
||
case CellValueType.Error:
|
||
_val.push( new cError( _cell.getValueWithoutFormat() ) );
|
||
break;
|
||
case CellValueType.String:
|
||
_val.push( new cString( _cell.getValueWithoutFormat() ) );
|
||
break;
|
||
default:
|
||
if ( _cell.getValueWithoutFormat() && _cell.getValueWithoutFormat() != "" ) {
|
||
_val.push( new cNumber( _cell.getValueWithoutFormat() ) )
|
||
}
|
||
else
|
||
_val.push( checkTypeCell( "" + _cell.getValueWithoutFormat() ) );
|
||
}
|
||
} )
|
||
return _val[0];
|
||
};
|
||
cArea3D.prototype.changeSheet = function ( lastName, newName ) {
|
||
if ( this.wsFrom == this._wb.getWorksheetByName( lastName ).getId() && this.wsTo == this._wb.getWorksheetByName( lastName ).getId() ) {
|
||
this.wsFrom = this.wsTo = this._wb.getWorksheetByName( newName ).getId();
|
||
}
|
||
else if ( this.wsFrom == this._wb.getWorksheetByName( lastName ).getId() ) {
|
||
this.wsFrom = this._wb.getWorksheetByName( newName ).getId();
|
||
}
|
||
else if ( this.wsTo == this._wb.getWorksheetByName( lastName ).getId() ) {
|
||
this.wsTo = this._wb.getWorksheetByName( newName ).getId();
|
||
}
|
||
};
|
||
cArea3D.prototype.moveSheet = function ( tempW ) {
|
||
if ( this.wsFrom == this.wsTo ) {
|
||
return;
|
||
}
|
||
else if ( this.wsFrom == tempW.wFId ) {
|
||
var newWsFromIndex = this._wb.getWorksheetById( this.wsFrom ).getIndex(),
|
||
wsToIndex = this._wb.getWorksheetById( this.wsTo ).getIndex();
|
||
if ( newWsFromIndex > wsToIndex ) {
|
||
this.wsFrom = this._wb.getWorksheet( tempW.wFI ).getId();
|
||
}
|
||
}
|
||
else if ( this.wsTo == tempW.wFId ) {
|
||
var newWsToIndex = this._wb.getWorksheetById( this.wsTo ).getIndex(),
|
||
wsFromIndex = this._wb.getWorksheetById( this.wsFrom ).getIndex();
|
||
if ( newWsToIndex < wsFromIndex ) {
|
||
this.wsTo = this._wb.getWorksheet( tempW.wFI ).getId();
|
||
}
|
||
}
|
||
};
|
||
cArea3D.prototype.toString = function () {
|
||
var wsFrom = this._wb.getWorksheetById( this.wsFrom ).getName();
|
||
var wsTo = this._wb.getWorksheetById( this.wsTo ).getName();
|
||
if ( !rx_test_ws_name.test( wsFrom ) || !rx_test_ws_name.test( wsTo ) ) {
|
||
wsFrom = wsFrom.replace( /'/g, "''" );
|
||
wsTo = wsTo.replace( /'/g, "''" )
|
||
return "'" + (wsFrom != wsTo ?
|
||
wsFrom + ":" + wsTo :
|
||
wsFrom)
|
||
+ "'!" + this._cells;
|
||
}
|
||
return (wsFrom != wsTo ?
|
||
wsFrom + ":" + wsTo :
|
||
wsFrom)
|
||
+ "!" + this._cells;
|
||
};
|
||
cArea3D.prototype.tocNumber = function () {
|
||
return this.getValue()[0].tocNumber();
|
||
};
|
||
cArea3D.prototype.tocString = function () {
|
||
return this.getValue()[0].tocString();
|
||
};
|
||
cArea3D.prototype.tocBool = function () {
|
||
return this.getValue()[0].tocBool();
|
||
};
|
||
cArea3D.prototype.getWS = function () {
|
||
return this.wsRange()[0];
|
||
};
|
||
cArea3D.prototype.cross = function ( arg ) {
|
||
if ( this.wsFrom != this.wsTo )
|
||
return new cError( cErrorType.wrong_value_type );
|
||
var r = this.getRange();
|
||
if ( !r )
|
||
return new cError( cErrorType.wrong_name );
|
||
var cross = r[0].cross( arg );
|
||
if ( cross ) {
|
||
if ( cross.r != undefined ) {
|
||
return this.getValue2( new CellAddress( cross.r, this.getBBox().c1 ) )
|
||
}
|
||
else if ( cross.c != undefined ) {
|
||
return this.getValue2( new CellAddress( this.getBBox().r1, cross.c ) )
|
||
}
|
||
else
|
||
return new cError( cErrorType.wrong_value_type );
|
||
}
|
||
else
|
||
return new cError( cErrorType.wrong_value_type );
|
||
};
|
||
cArea3D.prototype.getBBox = function () {
|
||
return this.getRange()[0].getBBox();
|
||
};
|
||
cArea3D.prototype.isValid = function () {
|
||
var r = this.getRange();
|
||
for ( var i = 0; i < r.length; i++ ) {
|
||
if ( !r[i] )
|
||
return false;
|
||
}
|
||
return true;
|
||
};
|
||
cArea3D.prototype.countCells = function () {
|
||
var _wsA = this.wsRange();
|
||
var _val = [];
|
||
if ( _wsA.length < 1 ) {
|
||
_val.push( new cError( cErrorType.bad_reference ) );
|
||
return _val;
|
||
}
|
||
for ( var i = 0; i < _wsA.length; i++ ) {
|
||
if ( !_wsA[i] ) {
|
||
_val.push( new cError( cErrorType.bad_reference ) );
|
||
return _val;
|
||
}
|
||
|
||
}
|
||
var _r = this.range( _wsA ),
|
||
bbox = _r[0].bbox,
|
||
count = (Math.abs( bbox.c1 - bbox.c2 ) + 1) * (Math.abs( bbox.r1 - bbox.r2 ) + 1);
|
||
count = _r.length * count;
|
||
for ( var i = 0; i < _r.length; i++ ) {
|
||
_r[i]._foreachNoEmpty( function ( _cell ) {
|
||
|
||
if ( _cell.getType() == CellValueType.Number && _cell.getValueWithoutFormat() == "" )
|
||
return null;
|
||
|
||
count--;
|
||
} )
|
||
}
|
||
return new cNumber( count );
|
||
};
|
||
cArea3D.prototype.getMatrix = function () {
|
||
var arr = [],
|
||
r = this.getRange();
|
||
for ( var k = 0; k < r.length; k++ ) {
|
||
arr[k] = [];
|
||
r[k]._foreach2( function ( cell, i, j, r1, c1 ) {
|
||
if ( !arr[k][i - r1] )
|
||
arr[k][i - r1] = [];
|
||
if ( cell ) {
|
||
switch ( cell.getType() ) {
|
||
case CellValueType.Number:
|
||
arr[k][i - r1][j - c1] = cell.getValueWithoutFormat() == "" ? new cEmpty() : new cNumber( cell.getValueWithoutFormat() )
|
||
break;
|
||
case CellValueType.Bool:
|
||
arr[k][i - r1][j - c1] = new cBool( cell.getValueWithoutFormat() );
|
||
break;
|
||
case CellValueType.Error:
|
||
arr[k][i - r1][j - c1] = new cError( cell.getValueWithoutFormat() );
|
||
break;
|
||
case CellValueType.String:
|
||
arr[k][i - r1][j - c1] = new cString( cell.getValueWithoutFormat() );
|
||
break;
|
||
default:
|
||
if ( cell.getValueWithoutFormat() && cell.getValueWithoutFormat() != "" ) {
|
||
arr[k][i - r1][j - c1] = new cNumber( cell.getValueWithoutFormat() )
|
||
}
|
||
else
|
||
arr[k][i - r1][j - c1] = checkTypeCell( "" + cell.getValueWithoutFormat() );
|
||
}
|
||
}
|
||
else
|
||
arr[k][i - r1][j - c1] = new cEmpty();
|
||
} )
|
||
}
|
||
return arr;
|
||
}
|
||
cArea3D.prototype.foreach2 = function ( action ) {
|
||
var _wsA = this.wsRange();
|
||
if ( _wsA.length >= 1 ) {
|
||
var _r = this.range( _wsA );
|
||
for ( var i = 0; i < _r.length; i++ ) {
|
||
if ( _r[i] )
|
||
_r[i]._foreach2( function ( _cell ) {
|
||
var val;
|
||
switch ( _cell.getType() ) {
|
||
case CellValueType.Number:
|
||
_cell.getValueWithoutFormat() == "" ? val = new cEmpty() : val = new cNumber( _cell.getValueWithoutFormat() )
|
||
break;
|
||
case CellValueType.Bool:
|
||
val = new cBool( _cell.getValueWithoutFormat() );
|
||
break;
|
||
case CellValueType.Error:
|
||
val = new cError( _cell.getValueWithoutFormat() );
|
||
break;
|
||
case CellValueType.String:
|
||
val = new cString( _cell.getValueWithoutFormat() );
|
||
break;
|
||
default:
|
||
if ( _cell.getValueWithoutFormat() && _cell.getValueWithoutFormat() != "" ) {
|
||
val = new cNumber( _cell.getValueWithoutFormat() )
|
||
}
|
||
else
|
||
val = checkTypeCell( "" + _cell.getValueWithoutFormat() );
|
||
}
|
||
action(val);
|
||
} );
|
||
}
|
||
}
|
||
}
|
||
|
||
/** @constructor */
|
||
function cRef3D( val, _wsFrom, wb ) {/*Ref means Sheat1!A1 for example*/
|
||
cRef3D.superclass.constructor.call( this, val );
|
||
this._wb = wb;
|
||
this._cells = val;
|
||
this.isAbsolute = false;
|
||
this.type = cElementType.cell;
|
||
this.ws = this._wb.getWorksheetByName( _wsFrom );
|
||
}
|
||
extend( cRef3D, cBaseType );
|
||
cRef3D.prototype.getWsId = function () {
|
||
return this.ws.Id;
|
||
};
|
||
cRef3D.prototype.getRange = function () {
|
||
if ( this.ws )
|
||
return this.ws.getRange2( this._cells );
|
||
else
|
||
return null;
|
||
};
|
||
cRef3D.prototype.isValid = function () {
|
||
if ( this.getRange() )
|
||
return true;
|
||
else return false;
|
||
};
|
||
cRef3D.prototype.getValue = function () {
|
||
var _r = this.getRange();
|
||
if ( !_r ) {
|
||
return new cError( cErrorType.bad_reference );
|
||
}
|
||
switch ( _r.getType() ) {
|
||
case CellValueType.Number:
|
||
{
|
||
var v = _r.getValueWithoutFormat();
|
||
if ( v == "" )
|
||
return new cEmpty( "" + v );
|
||
else
|
||
return new cNumber( "" + v );
|
||
}
|
||
case CellValueType.String:
|
||
return new cString( "" + _r.getValueWithoutFormat() );
|
||
case CellValueType.Bool:
|
||
return new cBool( "" + _r.getValueWithoutFormat() )
|
||
case CellValueType.Error:
|
||
return new cError( "" + _r.getValueWithoutFormat() )
|
||
default:
|
||
var _val = "" + _r.getValueWithoutFormat();
|
||
if ( _val == "" || _val == null )
|
||
return new cEmpty();
|
||
else if ( parserHelp.isNumber( _val ) )
|
||
return new cNumber( parserHelp.operand_str )
|
||
else if ( parserHelp.isBoolean( _val ) )
|
||
return new cBool( parserHelp.operand_str )
|
||
else if ( parserHelp.isError( _val ) )
|
||
return new cError( parserHelp.operand_str )
|
||
else return new cString( _val );
|
||
}
|
||
};
|
||
cRef3D.prototype.tocBool = function () {
|
||
return this.getValue().tocBool();
|
||
};
|
||
cRef3D.prototype.tocNumber = function () {
|
||
return this.getValue().tocNumber();
|
||
};
|
||
cRef3D.prototype.tocString = function () {
|
||
return this.getValue().tocString();
|
||
};
|
||
cRef3D.prototype.tryConvert = function () {
|
||
return this.getValue();
|
||
};
|
||
cRef3D.prototype.changeSheet = function ( lastName, newName ) {
|
||
if ( this.ws.getName() == lastName ) {
|
||
this.ws = this._wb.getWorksheetByName( newName );
|
||
}
|
||
};
|
||
cRef3D.prototype.toString = function () {
|
||
var wsName = this.ws.getName();
|
||
if ( !rx_test_ws_name.test( wsName ) ) {
|
||
return "'" + wsName.replace( /'/g, "''" ) + "'" + "!" + this._cells;
|
||
}
|
||
else {
|
||
return wsName + "!" + this._cells;
|
||
}
|
||
};
|
||
cRef3D.prototype.getWS = function () {
|
||
return this.ws;
|
||
};
|
||
|
||
/** @constructor */
|
||
function cEmpty() {
|
||
cEmpty.superclass.constructor.call( this, "" );
|
||
this.type = cElementType.empty;
|
||
}
|
||
extend( cEmpty, cBaseType );
|
||
cEmpty.prototype.tocNumber = function () {
|
||
return new cNumber( 0 );
|
||
};
|
||
cEmpty.prototype.tocBool = function () {
|
||
return new cBool( false );
|
||
};
|
||
cEmpty.prototype.tocString = function () {
|
||
return new cString( "" );
|
||
};
|
||
cEmpty.prototype.toString = function () {
|
||
return "";
|
||
};
|
||
|
||
/** @constructor */
|
||
function cName( val, wb ) {
|
||
cName.superclass.constructor.call( this, val );
|
||
this.wb = wb;
|
||
this.type = cElementType.name;
|
||
}
|
||
extend( cName, cBaseType );
|
||
cName.prototype.toRef = function ( wsID ) {
|
||
var _3DRefTmp,
|
||
ref = this.wb.getDefinesNames( this.value, wsID ).Ref;
|
||
if ( (_3DRefTmp = parserHelp.is3DRef( ref, 0 ))[0] ) {
|
||
var _wsFrom, _wsTo;
|
||
_wsFrom = _3DRefTmp[1];
|
||
_wsTo = ( (_3DRefTmp[2] !== null) && (_3DRefTmp[2] !== undefined) ) ? _3DRefTmp[2] : _wsFrom;
|
||
if ( parserHelp.isArea( ref, ref.indexOf( "!" ) + 1 ) ) {
|
||
return new cArea3D( parserHelp.operand_str, _wsFrom, _wsTo, this.wb );
|
||
}
|
||
else if ( parserHelp.isRef( ref, ref.indexOf( "!" ) + 1 ) ) {
|
||
return new cRef3D( parserHelp.operand_str, _wsFrom, this.wb );
|
||
}
|
||
}
|
||
return new cError( "#REF!" );
|
||
};
|
||
|
||
/** @constructor */
|
||
function cArray() {
|
||
cArray.superclass.constructor.call( this );
|
||
this.array = [];
|
||
this.rowCount = 0;
|
||
this.countElementInRow = [];
|
||
this.countElement = 0;
|
||
this.type = cElementType.array;
|
||
}
|
||
extend( cArray, cBaseType );
|
||
cArray.prototype.addRow = function () {
|
||
this.array[this.array.length] = [];
|
||
this.countElementInRow[this.rowCount++] = 0;
|
||
};
|
||
cArray.prototype.addElement = function ( element ) {
|
||
if ( this.array.length == 0 ) {
|
||
this.addRow();
|
||
}
|
||
var arr = this.array,
|
||
subArr = arr[this.rowCount - 1];
|
||
subArr[subArr.length] = element;
|
||
this.countElementInRow[this.rowCount - 1]++;
|
||
this.countElement++;
|
||
};
|
||
cArray.prototype.getRow = function ( rowIndex ) {
|
||
if ( rowIndex < 0 || rowIndex > this.array.length - 1 )
|
||
return null;
|
||
return this.array[rowIndex];
|
||
};
|
||
cArray.prototype.getCol = function ( colIndex ) {
|
||
var col = [];
|
||
for ( var i = 0; i < this.rowCount; i++ ) {
|
||
col.push( this.array[i][colIndex] )
|
||
}
|
||
return col;
|
||
};
|
||
cArray.prototype.getElementRowCol = function ( row, col ) {
|
||
if ( row > this.rowCount || col > this.getCountElementInRow() )
|
||
return new cError( cErrorType.not_available );
|
||
return this.array[row][col];
|
||
};
|
||
cArray.prototype.getElement = function ( index ) {
|
||
for ( var i = 0; i < this.rowCount; i++ ) {
|
||
if ( index > this.countElementInRow[i].length )
|
||
index -= this.countElementInRow[i].length;
|
||
else
|
||
return this.array[i][index];
|
||
}
|
||
return null;
|
||
};
|
||
cArray.prototype.foreach = function ( action ) {
|
||
if ( typeof (action) != 'function' ) {
|
||
return true;
|
||
}
|
||
for ( var ir = 0; ir < this.rowCount; ir++ ) {
|
||
for ( var ic = 0; ic < this.countElementInRow[ir]; ic++ ) {
|
||
if ( action.call( this, this.array[ir][ic], ir, ic ) )
|
||
return true;
|
||
}
|
||
}
|
||
return undefined;
|
||
};
|
||
cArray.prototype.getCountElement = function () {
|
||
return this.countElement;
|
||
};
|
||
cArray.prototype.getCountElementInRow = function () {
|
||
return this.countElementInRow[0];
|
||
};
|
||
cArray.prototype.getRowCount = function () {
|
||
return this.rowCount;
|
||
};
|
||
cArray.prototype.tocNumber = function () {
|
||
var retArr = new cArray();
|
||
for ( var ir = 0; ir < this.rowCount; ir++, retArr.addRow() ) {
|
||
for ( var ic = 0; ic < this.countElementInRow[ir]; ic++ ) {
|
||
retArr.addElement( this.array[ir][ic].tocNumber() );
|
||
}
|
||
if ( ir == this.rowCount - 1 )
|
||
break;
|
||
}
|
||
return retArr;
|
||
};
|
||
cArray.prototype.tocString = function () {
|
||
var retArr = new cArray();
|
||
for ( var ir = 0; ir < this.rowCount; ir++, retArr.addRow() ) {
|
||
for ( var ic = 0; ic < this.countElementInRow[ir]; ic++ ) {
|
||
retArr.addElement( this.array[ir][ic].tocString() );
|
||
}
|
||
if ( ir == this.rowCount - 1 )
|
||
break;
|
||
}
|
||
return retArr;
|
||
};
|
||
cArray.prototype.tocBool = function () {
|
||
var retArr = new cArray();
|
||
for ( var ir = 0; ir < this.rowCount; ir++, retArr.addRow() ) {
|
||
for ( var ic = 0; ic < this.countElementInRow[ir]; ic++ ) {
|
||
retArr.addElement( this.array[ir][ic].tocBool() );
|
||
}
|
||
if ( ir == this.rowCount - 1 )
|
||
break;
|
||
}
|
||
return retArr;
|
||
};
|
||
cArray.prototype.toString = function () {
|
||
var ret = "";
|
||
for ( var ir = 0; ir < this.rowCount; ir++, ret += ";" ) {
|
||
for ( var ic = 0; ic < this.countElementInRow[ir]; ic++, ret += "," ) {
|
||
if ( this.array[ir][ic] instanceof cString ) {
|
||
ret += '"' + this.array[ir][ic].toString() + '"';
|
||
}
|
||
else
|
||
ret += this.array[ir][ic].toString() + "";
|
||
}
|
||
if ( ret[ret.length - 1] == "," )
|
||
ret = ret.substring( 0, ret.length - 1 )
|
||
}
|
||
if ( ret[ret.length - 1] == ";" )
|
||
ret = ret.substring( 0, ret.length - 1 );
|
||
return "{" + ret + "}";
|
||
};
|
||
cArray.prototype.isValidArray = function () {
|
||
for ( var i = 0; i < this.rowCount - 1; i++ ) {
|
||
if ( this.countElementInRow[i] - this.countElementInRow[i + 1] == 0 )
|
||
continue;
|
||
else
|
||
return false;
|
||
}
|
||
return true;
|
||
};
|
||
cArray.prototype.getMatrix = function () {
|
||
return this.array;
|
||
}
|
||
cArray.prototype.fillFromArray = function ( arr ) {
|
||
this.array = arr;
|
||
this.rowCount = arr.length;
|
||
for ( var i = 0; i < arr.length; i++ ) {
|
||
this.countElementInRow[i] = arr[i].length;
|
||
this.countElement += arr[i].length;
|
||
}
|
||
}
|
||
/** класс отвечающий за парсинг строки с формулой, подсчета формулы, перестройки формулы при манипуляции с ячейкой*/
|
||
/** @constructor */
|
||
function parserFormula( formula, _cellId, _ws ) {
|
||
var that = this;
|
||
this.is3D = false;
|
||
this.cellId = _cellId;
|
||
this.cellAddress = new CellAddress( this.cellId );
|
||
this.ws = _ws;
|
||
this.wb = this.ws.workbook
|
||
this.value = null;
|
||
this.Formula = "";
|
||
this.pCurrPos = 0;
|
||
this.elemArr = [];
|
||
this.outStack = [];
|
||
this.operand_str = null;
|
||
this.error = [];
|
||
this.Formula = formula;
|
||
}
|
||
parserFormula.prototype = {
|
||
|
||
/** @type parserFormula */
|
||
constructor:parserFormula,
|
||
|
||
setFormula:function ( formula ) {
|
||
this.Formula = formula;
|
||
this.cellId = _cellId;
|
||
this.ws = _ws;
|
||
this.value = null;
|
||
this.pCurrPos = 0;
|
||
this.elemArr = [];
|
||
this.outStack = [];
|
||
this.operand_str = null;
|
||
|
||
},
|
||
|
||
setCellId:function ( cellId ) {
|
||
this.cellId = cellId;
|
||
this.cellAddress = new CellAddress( cellId );
|
||
},
|
||
|
||
parse:function () {
|
||
|
||
if ( this.isParsed )
|
||
return this.isParsed;
|
||
/*
|
||
Парсер формулы реализует алгоритм перевода инфиксной формы записи выражения в постфиксную или Обратную Польскую Нотацию. Что упрощает вычисление результата формулы.
|
||
При разборе формулы важен порядок проверки очередной части выражения на принадлежность тому или иному типу.
|
||
*/
|
||
var operand_expected = true;
|
||
while ( this.pCurrPos < this.Formula.length ) {
|
||
/* Operators*/
|
||
if ( parserHelp.isOperator.call( this, this.Formula, this.pCurrPos )/* || isNextPtg(this.formula,this.pCurrPos) */ ) {
|
||
var found_operator = null;
|
||
|
||
if ( operand_expected ) {
|
||
if ( this.operand_str == "-" ) {
|
||
operand_expected = true;
|
||
found_operator = cFormulaOperators['un_minus']();
|
||
}
|
||
else if ( this.operand_str == "+" ) {
|
||
operand_expected = true;
|
||
found_operator = cFormulaOperators['un_plus']();
|
||
}
|
||
else {
|
||
this.error.push( c_oAscError.ID.FrmlWrongOperator );
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
return false;
|
||
}
|
||
}
|
||
else if ( !operand_expected ) {
|
||
if ( this.operand_str == "-" ) {
|
||
operand_expected = true;
|
||
found_operator = cFormulaOperators['-']();
|
||
}
|
||
else if ( this.operand_str == "+" ) {
|
||
operand_expected = true;
|
||
found_operator = cFormulaOperators['+']();
|
||
}
|
||
else if ( this.operand_str == "%" ) {
|
||
operand_expected = false;
|
||
found_operator = cFormulaOperators['%']();
|
||
}
|
||
else {
|
||
if ( this.operand_str in cFormulaOperators ) {
|
||
found_operator = cFormulaOperators[this.operand_str]();
|
||
operand_expected = true;
|
||
}
|
||
else {
|
||
this.error.push( c_oAscError.ID.FrmlWrongOperator );
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
this.error.push( c_oAscError.ID.FrmlWrongOperator );
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
return false;
|
||
}
|
||
|
||
while ( this.elemArr.length != 0 && (
|
||
found_operator.isRightAssociative ?
|
||
( found_operator.priority < this.elemArr[this.elemArr.length - 1].priority ) :
|
||
( found_operator.priority <= this.elemArr[this.elemArr.length - 1].priority )
|
||
)
|
||
) {
|
||
this.outStack.push( this.elemArr.pop() );
|
||
}
|
||
this.elemArr.push( found_operator );
|
||
}
|
||
|
||
/* Left & Right Parentheses */
|
||
else if ( parserHelp.isLeftParentheses.call( this, this.Formula, this.pCurrPos ) ) {
|
||
operand_expected = true;
|
||
this.elemArr.push( cFormulaOperators[this.operand_str]() );
|
||
}
|
||
|
||
else if ( parserHelp.isRightParentheses.call( this, this.Formula, this.pCurrPos ) ) {
|
||
var wasLeftParentheses = false;
|
||
var top_elem = null;
|
||
if ( this.elemArr.length != 0 && ( (top_elem = this.elemArr[this.elemArr.length - 1]).name == "(" ) && operand_expected ) {
|
||
if ( top_elem.getArguments() > 1 ) {
|
||
this.outStack.push( new cEmpty() );
|
||
}
|
||
else {
|
||
top_elem.DecrementArguments();
|
||
}
|
||
}
|
||
else {
|
||
while ( this.elemArr.length != 0 && !((top_elem = this.elemArr[this.elemArr.length - 1]).name == "(" ) ) {
|
||
if ( top_elem.name in cFormulaOperators && operand_expected ) {
|
||
this.error.push( c_oAscError.ID.FrmlOperandExpected );
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
return false;
|
||
}
|
||
this.outStack.push( this.elemArr.pop() );
|
||
}
|
||
}
|
||
if ( this.elemArr.length == 0 || top_elem == null/* && !wasLeftParentheses */ ) {
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
this.error.push( c_oAscError.ID.FrmlWrongCountParentheses );
|
||
return false;
|
||
}
|
||
|
||
var p = top_elem, func;
|
||
this.elemArr.pop();
|
||
if ( this.elemArr.length != 0 && ( func = this.elemArr[this.elemArr.length - 1] ).type == cElementType.func ) {
|
||
p = this.elemArr.pop();
|
||
if ( top_elem.getArguments() > func.getMaxArguments() ) {
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
this.error.push( c_oAscError.ID.FrmlWrongMaxArgument );
|
||
return false;
|
||
}
|
||
else {
|
||
if ( top_elem.getArguments() >= func.getMinArguments() ) {
|
||
func.setArgumentsCount( top_elem.getArguments() );
|
||
}
|
||
else {
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
this.error.push( c_oAscError.ID.FrmlWrongCountArgument );
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
// for (int i = 0; i < left_p.ParametersNum - 1; ++i)
|
||
// {
|
||
// ptgs_list.AddFirst(new PtgUnion()); // чета нужно добавить для Union.....
|
||
// }
|
||
}
|
||
this.outStack.push( p );
|
||
operand_expected = false;
|
||
}
|
||
|
||
/*Comma & arguments union*/
|
||
else if ( parserHelp.isComma.call( this, this.Formula, this.pCurrPos ) ) {
|
||
/* if( operand_expected ){
|
||
this.error.push(c_oAscError.ID.FrmlAnotherParsingError);
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
return false;
|
||
} */
|
||
var wasLeftParentheses = false;
|
||
var stackLength = this.elemArr.length;
|
||
var top_elem = null;
|
||
if ( this.elemArr.length != 0 && this.elemArr[stackLength - 1].name == "(" && operand_expected ) {
|
||
this.outStack.push( new cEmpty() );
|
||
top_elem = this.elemArr[stackLength - 1];
|
||
wasLeftParentheses = true;
|
||
}
|
||
else {
|
||
while ( stackLength != 0 ) {
|
||
top_elem = this.elemArr[stackLength - 1];
|
||
if ( top_elem.name == "(" ) {
|
||
wasLeftParentheses = true;
|
||
break;
|
||
}
|
||
else {
|
||
this.outStack.push( this.elemArr.pop() );
|
||
stackLength = this.elemArr.length;
|
||
}
|
||
}
|
||
}
|
||
if ( !wasLeftParentheses ) {
|
||
this.error.push( c_oAscError.ID.FrmlWrongCountParentheses );
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
return false;
|
||
}
|
||
top_elem.IncrementArguments();
|
||
operand_expected = true;
|
||
}
|
||
|
||
/* Array */
|
||
else if ( parserHelp.isArray.call( this, this.Formula, this.pCurrPos ) ) {
|
||
var pH = new parserHelper(), tO = {pCurrPos:0, Formula:this.operand_str};
|
||
var pos = 0, arr = new cArray();
|
||
while ( tO.pCurrPos < tO.Formula.length ) {
|
||
|
||
if ( pH.isComma.call( tO, tO.Formula, tO.pCurrPos ) ) {
|
||
if ( tO.operand_str == ";" ) {
|
||
arr.addRow();
|
||
}
|
||
}
|
||
else if ( pH.isBoolean.call( tO, tO.Formula, tO.pCurrPos ) ) {
|
||
arr.addElement( new cBool( tO.operand_str ) );
|
||
}
|
||
else if ( pH.isString.call( tO, tO.Formula, tO.pCurrPos ) ) {
|
||
arr.addElement( new cString( tO.operand_str ) );
|
||
}
|
||
else if ( pH.isError.call( tO, tO.Formula, tO.pCurrPos ) ) {
|
||
arr.addElement( new cError( tO.operand_str ) );
|
||
}
|
||
else if ( pH.isNumber.call( tO, tO.Formula, tO.pCurrPos ) ) {
|
||
arr.addElement( new cNumber( parseFloat( tO.operand_str ) ) );
|
||
}
|
||
}
|
||
if ( !arr.isValidArray() ) {
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
this.error.push( c_oAscError.ID.FrmlAnotherParsingError );
|
||
return false;
|
||
}
|
||
this.outStack.push( arr );
|
||
operand_expected = false;
|
||
}
|
||
/* Operands*/
|
||
else {
|
||
var found_operand = null, _3DRefTmp = null;
|
||
|
||
if ( !operand_expected ) {
|
||
this.error.push( c_oAscError.ID.FrmlWrongOperator );
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
return false;
|
||
}
|
||
|
||
/* Booleans */
|
||
if ( parserHelp.isBoolean.call( this, this.Formula, this.pCurrPos ) ) {
|
||
found_operand = new cBool( this.operand_str );
|
||
}
|
||
|
||
/* Strings */
|
||
else if ( parserHelp.isString.call( this, this.Formula, this.pCurrPos ) ) {
|
||
found_operand = new cString( this.operand_str );
|
||
}
|
||
|
||
/* Errors */
|
||
else if ( parserHelp.isError.call( this, this.Formula, this.pCurrPos ) ) {
|
||
found_operand = new cError( this.operand_str );
|
||
}
|
||
|
||
/* Referens to 3D area: Sheet1:Sheet3!A1:B3, Sheet1:Sheet3!B3, Sheet1!B3*/
|
||
else if ( (_3DRefTmp = parserHelp.is3DRef.call( this, this.Formula, this.pCurrPos ))[0] ) {
|
||
this.is3D = true;
|
||
var _wsFrom = _3DRefTmp[1],
|
||
_wsTo = ( (_3DRefTmp[2] !== null) && (_3DRefTmp[2] !== undefined) ) ? _3DRefTmp[2] : _wsFrom;
|
||
if ( !(this.wb.getWorksheetByName( _wsFrom ) && this.wb.getWorksheetByName( _wsTo )) ) {
|
||
this.error.push( c_oAscError.ID.FrmlAnotherParsingError );
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
return false;
|
||
}
|
||
if ( parserHelp.isArea.call( this, this.Formula, this.pCurrPos ) ) {
|
||
found_operand = new cArea3D( this.operand_str.toUpperCase(), _wsFrom, _wsTo, this.wb );
|
||
if ( this.operand_str.indexOf( "$" ) > -1 )
|
||
found_operand.isAbsolute = true;
|
||
}
|
||
else if ( parserHelp.isRef.call( this, this.Formula, this.pCurrPos ) ) {
|
||
if ( _wsTo != _wsFrom ) {
|
||
found_operand = new cArea3D( this.operand_str.toUpperCase(), _wsFrom, _wsTo, this.wb );
|
||
}
|
||
else {
|
||
found_operand = new cRef3D( this.operand_str.toUpperCase(), _wsFrom, this.wb );
|
||
}
|
||
if ( this.operand_str.indexOf( "$" ) > -1 )
|
||
found_operand.isAbsolute = true;
|
||
}
|
||
}
|
||
/* Referens to DefinesNames */
|
||
else if ( parserHelp.isName.call( this, this.Formula, this.pCurrPos, this.wb )[0] ) { // Shall be placed strongly before Area and Ref
|
||
found_operand = new cName( this.operand_str, this.wb );
|
||
}
|
||
/* Referens to cells area A1:A10 */
|
||
else if ( parserHelp.isArea.call( this, this.Formula, this.pCurrPos ) ) {
|
||
found_operand = new cArea( this.operand_str.toUpperCase(), this.ws );
|
||
if ( this.operand_str.indexOf( "$" ) > -1 )
|
||
found_operand.isAbsolute = true;
|
||
}
|
||
/* Referens to cell A4 */
|
||
else if ( parserHelp.isRef.call( this, this.Formula, this.pCurrPos, true ) ) {
|
||
found_operand = new cRef( this.operand_str.toUpperCase(), this.ws );
|
||
if ( this.operand_str.indexOf( "$" ) > -1 )
|
||
found_operand.isAbsolute = true;
|
||
}
|
||
|
||
/* Numbers*/
|
||
else if ( parserHelp.isNumber.call( this, this.Formula, this.pCurrPos ) ) {
|
||
found_operand = new cNumber( parseFloat( this.operand_str ) );
|
||
}
|
||
|
||
/* Function*/
|
||
else if ( parserHelp.isFunc.call( this, this.Formula, this.pCurrPos ) ) {
|
||
|
||
var found_operator = null;
|
||
if ( this.operand_str.toUpperCase() in cFormulaFunction.Mathematic )//mathematic
|
||
found_operator = cFormulaFunction.Mathematic[this.operand_str.toUpperCase()]();
|
||
|
||
else if ( this.operand_str.toUpperCase() in cFormulaFunction.Logical )//logical
|
||
found_operator = cFormulaFunction.Logical[this.operand_str.toUpperCase()]();
|
||
|
||
else if ( this.operand_str.toUpperCase() in cFormulaFunction.Information )//information
|
||
found_operator = cFormulaFunction.Information[this.operand_str.toUpperCase()]();
|
||
|
||
else if ( this.operand_str.toUpperCase() in cFormulaFunction.Statistical )//statistical
|
||
found_operator = cFormulaFunction.Statistical[this.operand_str.toUpperCase()]();
|
||
|
||
else if ( this.operand_str.toUpperCase() in cFormulaFunction.TextAndData )//text and data
|
||
found_operator = cFormulaFunction.TextAndData[this.operand_str.toUpperCase()]();
|
||
|
||
else if ( this.operand_str.toUpperCase() in cFormulaFunction.Cube )//cube
|
||
found_operator = cFormulaFunction.Cube[this.operand_str.toUpperCase()]();
|
||
|
||
else if ( this.operand_str.toUpperCase() in cFormulaFunction.Database )//Database
|
||
found_operator = cFormulaFunction.Database[this.operand_str.toUpperCase()]();
|
||
|
||
else if ( this.operand_str.toUpperCase() in cFormulaFunction.DateAndTime )//Date and time
|
||
found_operator = cFormulaFunction.DateAndTime[this.operand_str.toUpperCase()]();
|
||
|
||
else if ( this.operand_str.toUpperCase() in cFormulaFunction.Engineering )//Engineering
|
||
found_operator = cFormulaFunction.Engineering[this.operand_str.toUpperCase()]();
|
||
|
||
else if ( this.operand_str.toUpperCase() in cFormulaFunction.Financial )//Financial
|
||
found_operator = cFormulaFunction.Financial[this.operand_str.toUpperCase()]();
|
||
|
||
else if ( this.operand_str.toUpperCase() in cFormulaFunction.LookupAndReference )//Lookup and reference
|
||
found_operator = cFormulaFunction.LookupAndReference[this.operand_str.toUpperCase()]();
|
||
|
||
if ( found_operator != null && found_operator != undefined )
|
||
this.elemArr.push( found_operator );
|
||
else {
|
||
this.error.push( c_oAscError.ID.FrmlWrongFunctionName );
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
return false;
|
||
}
|
||
operand_expected = false;
|
||
continue;
|
||
}
|
||
|
||
if ( found_operand != null && found_operand != undefined ) {
|
||
this.outStack.push( found_operand );
|
||
operand_expected = false;
|
||
}
|
||
else {
|
||
this.error.push( c_oAscError.ID.FrmlAnotherParsingError );
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
return false;
|
||
}
|
||
}
|
||
|
||
}
|
||
if ( operand_expected ) {
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
this.error.push( c_oAscError.ID.FrmlOperandExpected );
|
||
return false;
|
||
}
|
||
var parentCount = 0, operand;
|
||
while ( this.elemArr.length != 0 ) {
|
||
operand = this.elemArr.pop()
|
||
if ( operand.name == "(" || operand.name == ")" ) {
|
||
this.outStack = [];
|
||
this.elemArr = [];
|
||
this.error.push( c_oAscError.ID.FrmlWrongCountParentheses );
|
||
return false;
|
||
}
|
||
else
|
||
this.outStack.push( operand );
|
||
}
|
||
if ( this.outStack.length != 0 )
|
||
return this.isParsed = true;
|
||
else
|
||
return this.isParsed = false;
|
||
},
|
||
|
||
calculate:function () {
|
||
if ( this.outStack.length < 1 ) {
|
||
return this.value = new cError( cErrorType.wrong_name );
|
||
}
|
||
var elemArr = [], stack = [], _tmp, numFormat = -1;
|
||
for ( var i = 0; i < this.outStack.length; i++ ) {
|
||
_tmp = this.outStack[i];
|
||
if ( _tmp instanceof cName ) {
|
||
_tmp = _tmp.toRef( this.ws.getId() );
|
||
}
|
||
stack[i] = _tmp;
|
||
}
|
||
var currentElement = null;
|
||
while ( stack.length != 0 ) {
|
||
currentElement = stack.shift();
|
||
if ( currentElement.name == "(" ) {
|
||
continue;
|
||
}
|
||
if ( currentElement.type == cElementType.operator || currentElement.type == cElementType.func ) {
|
||
if ( elemArr.length < currentElement.getArguments() ) {
|
||
elemArr = [];
|
||
return this.value = new cError( cErrorType.unsupported_function );
|
||
}
|
||
else {
|
||
var arg = [];
|
||
for ( var ind = 0; ind < currentElement.getArguments(); ind++ ) {
|
||
arg.unshift( elemArr.pop() );
|
||
}
|
||
_tmp = currentElement.Calculate( arg, this.ws.getCell( this.cellAddress ) );
|
||
if ( _tmp.numFormat !== undefined && _tmp.numFormat !== null ) {
|
||
numFormat = _tmp.numFormat; //> numFormat ? _tmp.numFormat : numFormat;
|
||
}
|
||
else if ( numFormat < 0 || currentElement.numFormat < currentElement.formatType.def ) {
|
||
numFormat = currentElement.numFormat;
|
||
}
|
||
elemArr.push( _tmp );
|
||
}
|
||
}
|
||
else {
|
||
elemArr.push( currentElement );
|
||
}
|
||
}
|
||
this.value = elemArr.pop();
|
||
this.value.numFormat = numFormat;
|
||
return this.value;
|
||
},
|
||
|
||
/* Метод возвращает все ссылки на ячейки которые учавствуют в формуле*/
|
||
getRef:function () {
|
||
var aOutRef = [];
|
||
for ( var i = 0; i < this.outStack.length; i++ ) {
|
||
var ref = this.outStack[i];
|
||
if ( ref instanceof cName ) {
|
||
ref = ref.toRef( this.ws.getId() );
|
||
if ( ref instanceof cError )
|
||
continue;
|
||
}
|
||
|
||
if ( ref instanceof cRef || ref instanceof cRef3D || ref instanceof cArea ) {
|
||
aOutRef.push( {wsId:ref.ws.getWsId(), cell:ref._cells} );
|
||
continue;
|
||
}
|
||
else if ( ref instanceof cArea3D ) {
|
||
var wsR = ref.wsRange();
|
||
for ( var j = 0; j < wsR.length; j++ )
|
||
aOutRef.push( {wsId:wsR[a].Id, cell:ref._cells} );
|
||
}
|
||
}
|
||
return aOutRef;
|
||
},
|
||
|
||
/* Для обратной сборки функции иногда необходимо поменять ссылки на ячейки */
|
||
changeOffset:function ( offset ) {//offset = {offsetCol:intNumber, offsetRow:intNumber}
|
||
for ( var i = 0; i < this.outStack.length; i++ ) {
|
||
if ( this.outStack[i] instanceof cRef || this.outStack[i] instanceof cRef3D || this.outStack[i] instanceof cArea ) {
|
||
|
||
var r = this.outStack[i].getRange();
|
||
if ( !r ) break;
|
||
|
||
if ( this.outStack[i].isAbsolute ) {
|
||
this._changeOffsetHelper( this.outStack[i], offset );
|
||
}
|
||
else {
|
||
var a, b;
|
||
if ( this.outStack[i] instanceof cArea && (r.isColumn() && offset.offsetRow != 0 || r.isRow() && offset.offsetCol != 0) ) {
|
||
continue;
|
||
}
|
||
r.setOffset( offset );
|
||
if ( r.isColumn() ) {
|
||
a = r.first.getColLetter();
|
||
b = r.last.getColLetter();
|
||
}
|
||
else if ( r.isRow() ) {
|
||
a = r.first.getRow();
|
||
b = r.last.getRow();
|
||
}
|
||
else {
|
||
a = r.first.getID(),
|
||
b = r.last.getID();
|
||
}
|
||
|
||
|
||
if ( a != b || this.outStack[i] instanceof cArea )
|
||
this.outStack[i].value = this.outStack[i]._cells = a + ":" + b;
|
||
else this.outStack[i].value = this.outStack[i]._cells = a;
|
||
}
|
||
continue;
|
||
}
|
||
if ( this.outStack[i] instanceof cArea3D ) {
|
||
var r = this.outStack[i]._cells.indexOf( ":" ) > -1 ? (new cArea( this.outStack[i]._cells, this.ws )) : (new cRef( this.outStack[i]._cells, this.ws ));
|
||
var _r = r.getRange();
|
||
|
||
if ( !_r ) break;
|
||
|
||
if ( this.outStack[i].isAbsolute ) {
|
||
this._changeOffsetHelper( r, offset );
|
||
}
|
||
else {
|
||
_r.setOffset( offset );
|
||
var a = _r.first.getID(),
|
||
b = _r.last.getID();
|
||
if ( a != b )
|
||
r.value = r._cells = a + ":" + b;
|
||
else r.value = r._cells = a;
|
||
}
|
||
this.outStack[i]._cells = r._cells;
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
|
||
/*
|
||
Для изменения ссылок на конкретную ячейку.
|
||
offset - на сколько сдвигаем ячейку (offset = {offsetCol:intNumber, offsetRow:intNumber})
|
||
cellId - какую ячейку сдвигаем
|
||
*/
|
||
shiftCells:function ( offset, oBBox, node, wsId, toDelete ) {
|
||
|
||
for ( var i = 0; i < this.outStack.length; i++ ) {
|
||
if ( this.outStack[i] instanceof cRef ) {
|
||
if ( this.ws.Id != wsId ) {
|
||
continue;
|
||
}
|
||
if ( toDelete ) {
|
||
this.outStack[i] = new cError( cErrorType.bad_reference )
|
||
continue;
|
||
}
|
||
if ( node.cellId == this.outStack[i]._cells.replace( /\$/ig, "" ) ) {
|
||
if ( this.outStack[i].isAbsolute ) {
|
||
this._changeOffsetHelper( this.outStack[i], offset );
|
||
}
|
||
else {
|
||
var r = this.outStack[i].getRange();
|
||
r.setOffset( offset );
|
||
var a = r.first.getID(),
|
||
b = r.last.getID();
|
||
if ( a != b )
|
||
this.outStack[i].value = this.outStack[i]._cells = a + ":" + b;
|
||
else this.outStack[i].value = this.outStack[i]._cells = a;
|
||
node.newCellId = this.outStack[i].value;
|
||
}
|
||
}
|
||
}
|
||
else if ( this.outStack[i] instanceof cRef3D ) {
|
||
if ( node.cellId == this.outStack[i]._cells.replace( /\$/ig, "" ) && this.outStack[i].ws == node.sheetId ) {
|
||
if ( this.outStack[i].isAbsolute ) {
|
||
this._changeOffsetHelper( this.outStack[i], offset );
|
||
}
|
||
else {
|
||
var r = this.outStack[i].getRange();
|
||
r.setOffset( offset );
|
||
var a = r.first.getID(),
|
||
b = r.last.getID();
|
||
if ( a != b )
|
||
this.outStack[i].value = this.outStack[i]._cells = a + ":" + b;
|
||
else this.outStack[i].value = this.outStack[i]._cells = a;
|
||
node.newCellId = this.outStack[i].value;
|
||
}
|
||
}
|
||
}
|
||
else if ( this.outStack[i] instanceof cArea3D ) {
|
||
|
||
if ( this.outStack[i].wsFrom.Id == this.outStack[i].wsTo.Id == node.sheetId && node.cellId == this.outStack[i]._cells.replace( /\$/ig, "" ) ) {
|
||
|
||
if ( this.outStack[i].isAbsolute ) {
|
||
this._changeOffsetHelper( this.outStack[i], offset );
|
||
}
|
||
else {
|
||
var r = this.outStack[i].getRange();
|
||
r[0].setOffset( offset );
|
||
this.outStack[i].value = this.outStack[i]._cells = r[0].getName();
|
||
node.newCellId = this.outStack[i].value;
|
||
}
|
||
|
||
}
|
||
}
|
||
else if ( this.outStack[i] instanceof cArea ) {
|
||
|
||
if ( this.ws.Id != wsId ) {
|
||
continue;
|
||
}
|
||
|
||
if ( toDelete ) {
|
||
this.outStack[i] = new cError( cErrorType.bad_reference )
|
||
continue;
|
||
}
|
||
|
||
if ( node.cellId == this.outStack[i]._cells.replace( /\$/ig, "" ) ) {
|
||
|
||
if ( this.outStack[i].isAbsolute ) {
|
||
this._changeOffsetHelper( this.outStack[i], offset );
|
||
}
|
||
else {
|
||
var r = this.outStack[i].getRange();
|
||
r.setOffset( offset );
|
||
this.outStack[i].value = this.outStack[i]._cells = r.getName();
|
||
}
|
||
node.newCellId = this.outStack[i].value;
|
||
}
|
||
|
||
}
|
||
}
|
||
},
|
||
|
||
stretchArea:function ( offset, oBBox, node, wsId ) {
|
||
for ( var i = 0; i < this.outStack.length; i++ ) {
|
||
if ( this.outStack[i] instanceof cArea ) {
|
||
if ( this.outStack[i]._cells.replace( /\$/ig, "" ) == node.cellId || this.outStack[i]._cells.replace( /\$/ig, "" ) == node.newCellId ) {
|
||
if ( this.outStack[i].isAbsolute ) {
|
||
this._changeOffsetHelper( this.outStack[i], offset );
|
||
}
|
||
else {
|
||
var r = this.outStack[i].getRange();
|
||
r.setOffsetLast( offset );
|
||
var a = r.first.getID(),
|
||
b = r.last.getID();
|
||
if ( a != b )
|
||
this.outStack[i].value = this.outStack[i]._cells = a + ":" + b;
|
||
else this.outStack[i].value = this.outStack[i]._cells = a;
|
||
node.newCellId = this.outStack[i].value;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
/* При переименовывании листа необходимо поменять название листа в соответствующих ссылках */
|
||
changeSheet:function ( lastName, newName ) {
|
||
if ( this.is3D )
|
||
for ( var i = 0; i < this.outStack.length; i++ ) {
|
||
if ( this.outStack[i] instanceof cRef3D && this.outStack[i].ws.getName() == lastName ) {
|
||
this.outStack[i].changeSheet( lastName, newName );
|
||
}
|
||
if ( this.outStack[i] instanceof cArea3D ) {
|
||
this.outStack[i].changeSheet( lastName, newName );
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
|
||
/* Сборка функции в инфиксную форму */
|
||
assemble:function () {/*При сборке формул вида A1+A2+A3 формула получает вид (A1+A2)+A3. Добавить проверку приоритета операций.*/
|
||
var str = "";
|
||
var elemArr = [];
|
||
var stack = [];
|
||
for ( var i = 0; i < this.outStack.length; i++ )
|
||
stack[i] = this.outStack[i];
|
||
var currentElement = null;
|
||
while ( stack.length != 0 ) {
|
||
currentElement = stack.shift();
|
||
if ( currentElement.type == cElementType.operator || currentElement.type == cElementType.func ) {
|
||
var arg = [];
|
||
for ( var ind = 0; ind < currentElement.getArguments(); ind++ ) {
|
||
arg.unshift( elemArr.pop() );
|
||
}
|
||
elemArr.push( currentElement.Assemble( arg ) );
|
||
}
|
||
else {
|
||
if ( currentElement instanceof cString )
|
||
currentElement = new cString( "\"" + currentElement.toString() + "\"" );
|
||
elemArr.push( currentElement );
|
||
}
|
||
}
|
||
return elemArr.pop().toString();
|
||
},
|
||
|
||
_changeOffsetHelper:function ( ref, offset ) {
|
||
var m = ref._cells.match( /\$/g );
|
||
if ( m.length == 1 ) {//для cRef, cRef3D, cArea. $A2, A$2, Sheet1!$A2, Sheet1!A$2, $A2:C4, A$2:C4, A2:$C4, A2:C$4.
|
||
if ( !(ref instanceof cArea) ) {
|
||
if ( ref._cells.indexOf( "$" ) == 0 ) {
|
||
r = ref.getRange();
|
||
r.setOffset( {offsetCol:0, offsetRow:offset.offsetRow} );
|
||
ref.value = ref._cells = "$" + r.first.getID();
|
||
}
|
||
else {
|
||
r = ref.getRange();
|
||
r.setOffset( {offsetCol:offset.offsetCol, offsetRow:0} );
|
||
ref.value = ref._cells = r.first.getColLetter() + "$" + r.first.getRow();
|
||
}
|
||
}
|
||
else {
|
||
var r = ref.getRange();
|
||
var c = ref._cells.split( ":" );// так как ссылка вида A1:A4, делим на первую и последнюю ячейку.
|
||
// проверяем в какой ячеейке находится абсолютная ссылка.
|
||
if ( c[0].indexOf( "$" ) > -1 ) {// если в первой ячейке
|
||
if ( c[0].indexOf( "$" ) == 0 ) {// абсолютна ли ссылка на столбец...
|
||
r.first.moveRow( offset.offsetRow );
|
||
r.last.moveCol( offset.offsetCol );
|
||
r.last.moveRow( offset.offsetRow );
|
||
ref.setRange( "$" + r.first.getColLetter() + r.first.getRow() + ":" + r.last.getColLetter() + r.last.getRow() );
|
||
}
|
||
else {// ... или абсолютна ссылка на строку
|
||
r.first.moveCol( offset.offsetCol );
|
||
r.last.moveCol( offset.offsetCol );
|
||
r.last.moveRow( offset.offsetRow );
|
||
ref.setRange( r.first.getColLetter() + "$" + r.first.getRow() + ":" + r.last.getColLetter() + r.last.getRow() );
|
||
}
|
||
}
|
||
else {// если в последней ячейке
|
||
if ( c[1].indexOf( "$" ) == 0 ) {// абсолютна ли ссылка на столбец...
|
||
r.first.moveCol( offset.offsetCol );
|
||
r.first.moveRow( offset.offsetRow );
|
||
r.last.moveRow( offset.offsetRow );
|
||
ref.setRange( r.first.getColLetter() + r.first.getRow() + ":" + "$" + r.last.getColLetter() + r.last.getRow() );
|
||
}
|
||
else {// ... или абсолютна ссылка на строку
|
||
r.first.moveCol( offset.offsetCol );
|
||
r.first.moveRow( offset.offsetRow );
|
||
r.last.moveCol( offset.offsetCol );
|
||
ref.setRange( r.first.getColLetter() + r.first.getRow() + ":" + r.last.getColLetter() + "$" + r.last.getRow() );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if ( m.length == 2 ) {//для cArea. $A$2:C4, A2:$C$4, $A2:$C4, $A2:C$4, A$2:$C4, A$2:C$4.
|
||
if ( ref instanceof cArea ) {
|
||
var r = ref.getRange();
|
||
var c = ref._cells.split( ":" );
|
||
if ( c[1].indexOf( "$" ) < 0 ) {
|
||
r.last.moveCol( offset.offsetCol );
|
||
r.last.moveRow( offset.offsetRow );
|
||
ref.setRange( "$" + r.first.getColLetter() + "$" + r.first.getRow() + ":" + r.last.getColLetter() + r.last.getRow() );
|
||
}
|
||
else if ( c[0].indexOf( "$" ) < 0 ) {
|
||
r.first.moveCol( offset.offsetCol );
|
||
r.first.moveRow( offset.offsetRow );
|
||
ref.setRange( r.first.getColLetter() + r.first.getRow() + ":" + "$" + r.last.getColLetter() + "$" + r.last.getRow() );
|
||
}
|
||
else {
|
||
if ( c[0].indexOf( "$" ) == 0 && c[1].indexOf( "$" ) == 0 ) {
|
||
r.first.moveRow( offset.offsetRow );
|
||
r.last.moveRow( offset.offsetRow );
|
||
ref.setRange( "$" + r.first.getColLetter() + r.first.getRow() + ":" + "$" + r.last.getColLetter() + r.last.getRow() );
|
||
}
|
||
else if ( c[0].indexOf( "$" ) == 0 && c[1].indexOf( "$" ) > 0 ) {
|
||
r.first.moveRow( offset.offsetRow );
|
||
r.last.moveCol( offset.offsetCol );
|
||
ref.setRange( "$" + r.first.getColLetter() + r.first.getRow() + ":" + r.last.getColLetter() + "$" + r.last.getRow() );
|
||
}
|
||
else if ( c[0].indexOf( "$" ) > 0 && c[1].indexOf( "$" ) == 0 ) {
|
||
r.first.moveCol( offset.offsetCol );
|
||
r.last.moveRow( offset.offsetRow );
|
||
ref.setRange( r.first.getColLetter() + "$" + r.first.getRow() + ":" + "$" + r.last.getColLetter() + r.last.getRow() );
|
||
}
|
||
else {
|
||
r.first.moveCol( offset.offsetCol );
|
||
r.last.moveCol( offset.offsetCol );
|
||
ref.setRange( r.first.getColLetter() + "$" + r.first.getRow() + ":" + r.last.getColLetter() + "$" + r.last.getRow() );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if ( m.length == 3 ) {//для cArea. $A$2:$C4, $A$2:C$4, $A2:$C$4, A$2:$C$4,
|
||
if ( ref instanceof cArea ) {
|
||
var r = ref.getRange();
|
||
var c = ref._cells.split( ":" );
|
||
if ( c[0].match( /\$/g ).length == 2 && c[1].indexOf( "$" ) == 0 ) {
|
||
r.last.moveRow( offset.offsetRow );
|
||
ref.setRange( "$" + r.first.getColLetter() + "$" + r.first.getRow() + ":" + "$" + r.last.getColLetter() + r.last.getRow() );
|
||
}
|
||
else if ( c[0].match( /\$/g ).length == 2 && c[1].indexOf( "$" ) > 0 ) {
|
||
r.last.moveCol( offset.offsetCol );
|
||
ref.setRange( "$" + r.first.getColLetter() + "$" + r.first.getRow() + ":" + r.last.getColLetter() + "$" + r.last.getRow() );
|
||
}
|
||
else if ( c[1].match( /\$/g ).length == 2 && c[0].indexOf( "$" ) == 0 ) {
|
||
r.first.moveRow( offset.offsetRow );
|
||
ref.setRange( "$" + r.first.getColLetter() + r.first.getRow() + ":" + "$" + r.last.getColLetter() + "$" + r.last.getRow() );
|
||
}
|
||
else if ( c[1].match( /\$/g ).length == 2 && c[0].indexOf( "$" ) > 0 ) {
|
||
r.first.moveCol( offset.offsetCol );
|
||
ref.setRange( r.first.getColLetter() + "$" + r.first.getRow() + ":" + "$" + r.last.getColLetter() + "$" + r.last.getRow() );
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
moveSheet:function ( tempW ) {
|
||
for ( var i = 0; i < this.outStack.length; i++ ) {
|
||
if ( this.outStack[i] instanceof cArea3D ) {
|
||
this.outStack[i].moveSheet( tempW );
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
|
||
buildDependencies:function () {
|
||
|
||
var node = new Vertex( this.ws.Id, this.cellId, this.wb );
|
||
|
||
this.wb.dependencyFormulas.addNode2( node );
|
||
this.wb.dependencyFormulas.addN( this.ws.Id, this.cellId );
|
||
|
||
for ( var i = 0; i < this.outStack.length; i++ ) {
|
||
var ref = this.outStack[i];
|
||
if ( ref instanceof cName ) {
|
||
ref = ref.toRef( this.ws.getId() );
|
||
if ( ref instanceof cError )
|
||
continue;
|
||
}
|
||
|
||
if ( (ref instanceof cRef || ref instanceof cRef3D || ref instanceof cArea) && ref.isValid() ) {
|
||
this.wb.dependencyFormulas.addEdge( this.ws.Id, this.cellId.replace( /\$/g, "" ), ref.getWsId(), ref._cells.replace( /\$/g, "" ) );
|
||
}
|
||
else if ( ref instanceof cArea3D && ref.isValid() ) {
|
||
var wsR = ref.wsRange();
|
||
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, "" ) );
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
function parseNum( str ) {
|
||
if ( str.indexOf( "x" ) > -1 )//исключаем запись числа в 16-ричной форме из числа.
|
||
return false;
|
||
return !isNaN( str );
|
||
}
|
||
|
||
|
||
function phi( x ) {
|
||
return 0.39894228040143268 * Math.exp( -(x * x) / 2.0 );
|
||
}
|
||
|
||
function taylor( pPolynom, nMax, x ) {
|
||
var nVal = pPolynom[nMax];
|
||
for ( var i = nMax - 1; i >= 0; i-- ) {
|
||
nVal = pPolynom[i] + (nVal * x);
|
||
}
|
||
return nVal;
|
||
}
|
||
|
||
function gauss( x ) {
|
||
var t0 =
|
||
[ 0.39894228040143268, -0.06649038006690545, 0.00997355701003582,
|
||
-0.00118732821548045, 0.00011543468761616, -0.00000944465625950,
|
||
0.00000066596935163, -0.00000004122667415, 0.00000000227352982,
|
||
0.00000000011301172, 0.00000000000511243, -0.00000000000021218 ],
|
||
t2 =
|
||
[ 0.47724986805182079, 0.05399096651318805, -0.05399096651318805,
|
||
0.02699548325659403, -0.00449924720943234, -0.00224962360471617,
|
||
0.00134977416282970, -0.00011783742691370, -0.00011515930357476,
|
||
0.00003704737285544, 0.00000282690796889, -0.00000354513195524,
|
||
0.00000037669563126, 0.00000019202407921, -0.00000005226908590,
|
||
-0.00000000491799345, 0.00000000366377919, -0.00000000015981997,
|
||
-0.00000000017381238, 0.00000000002624031, 0.00000000000560919,
|
||
-0.00000000000172127, -0.00000000000008634, 0.00000000000007894 ],
|
||
t4 =
|
||
[ 0.49996832875816688, 0.00013383022576489, -0.00026766045152977,
|
||
0.00033457556441221, -0.00028996548915725, 0.00018178605666397,
|
||
-0.00008252863922168, 0.00002551802519049, -0.00000391665839292,
|
||
-0.00000074018205222, 0.00000064422023359, -0.00000017370155340,
|
||
0.00000000909595465, 0.00000000944943118, -0.00000000329957075,
|
||
0.00000000029492075, 0.00000000011874477, -0.00000000004420396,
|
||
0.00000000000361422, 0.00000000000143638, -0.00000000000045848 ];
|
||
var asympt = [ -1.0, 1.0, -3.0, 15.0, -105.0 ],
|
||
xabs = Math.abs( x ),
|
||
xshort = Math.floor( xabs ),
|
||
nval = 0.0;
|
||
if ( xshort == 0 )
|
||
nval = taylor( t0, 11, (xabs * xabs) ) * xabs;
|
||
else if ( (xshort >= 1) && (xshort <= 2) )
|
||
nval = taylor( t2, 23, (xabs - 2.0) );
|
||
else if ( (xshort >= 3) && (xshort <= 4) )
|
||
nval = taylor( t4, 20, (xabs - 4.0) );
|
||
else
|
||
nval = 0.5 + phi( xabs ) * taylor( asympt, 4, 1.0 / (xabs * xabs) ) / xabs;
|
||
if ( x < 0.0 )
|
||
return -nval;
|
||
else
|
||
return nval;
|
||
}
|
||
|
||
function gaussinv( x ) {
|
||
var q, t, z;
|
||
|
||
q = x - 0.5;
|
||
|
||
if ( Math.abs( q ) <= .425 ) {
|
||
t = 0.180625 - q * q;
|
||
z =
|
||
q *
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
t * 2509.0809287301226727 + 33430.575583588128105
|
||
)
|
||
* t + 67265.770927008700853
|
||
)
|
||
* t + 45921.953931549871457
|
||
)
|
||
* t + 13731.693765509461125
|
||
)
|
||
* t + 1971.5909503065514427
|
||
)
|
||
* t + 133.14166789178437745
|
||
)
|
||
* t + 3.387132872796366608
|
||
)
|
||
/
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
t * 5226.495278852854561 + 28729.085735721942674
|
||
)
|
||
* t + 39307.89580009271061
|
||
)
|
||
* t + 21213.794301586595867
|
||
)
|
||
* t + 5394.1960214247511077
|
||
)
|
||
* t + 687.1870074920579083
|
||
)
|
||
* t + 42.313330701600911252
|
||
)
|
||
* t + 1.0
|
||
);
|
||
}
|
||
else {
|
||
if ( q > 0 )
|
||
t = 1 - x;
|
||
else
|
||
t = x;
|
||
|
||
t = Math.sqrt( -Math.log( t ) );
|
||
|
||
if ( t <= 5.0 ) {
|
||
t += -1.6;
|
||
z =
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
t * 7.7454501427834140764e-4 + 0.0227238449892691845833
|
||
)
|
||
* t + 0.24178072517745061177
|
||
)
|
||
* t + 1.27045825245236838258
|
||
)
|
||
* t + 3.64784832476320460504
|
||
)
|
||
* t + 5.7694972214606914055
|
||
)
|
||
* t + 4.6303378461565452959
|
||
)
|
||
* t + 1.42343711074968357734
|
||
)
|
||
/
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
t * 1.05075007164441684324e-9 + 5.475938084995344946e-4
|
||
)
|
||
* t + 0.0151986665636164571966
|
||
)
|
||
* t + 0.14810397642748007459
|
||
)
|
||
* t + 0.68976733498510000455
|
||
)
|
||
* t + 1.6763848301838038494
|
||
)
|
||
* t + 2.05319162663775882187
|
||
)
|
||
* t + 1.0
|
||
);
|
||
}
|
||
else {
|
||
t += -5.0;
|
||
z =
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
t * 2.01033439929228813265e-7 + 2.71155556874348757815e-5
|
||
)
|
||
* t + 0.0012426609473880784386
|
||
)
|
||
* t + 0.026532189526576123093
|
||
)
|
||
* t + 0.29656057182850489123
|
||
)
|
||
* t + 1.7848265399172913358
|
||
)
|
||
* t + 5.4637849111641143699
|
||
)
|
||
* t + 6.6579046435011037772
|
||
)
|
||
/
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
(
|
||
t * 2.04426310338993978564e-15 + 1.4215117583164458887e-7
|
||
)
|
||
* t + 1.8463183175100546818e-5
|
||
)
|
||
* t + 7.868691311456132591e-4
|
||
)
|
||
* t + 0.0148753612908506148525
|
||
)
|
||
* t + 0.13692988092273580531
|
||
)
|
||
* t + 0.59983220655588793769
|
||
)
|
||
* t + 1.0
|
||
);
|
||
}
|
||
|
||
if ( q < 0.0 ) z = -z;
|
||
}
|
||
|
||
return z;
|
||
}
|
||
|
||
/*
|
||
from OpenOffice Source.
|
||
\sc\source\core\tool\interpr3.cxx
|
||
begin
|
||
*/
|
||
|
||
var maxGammaArgument = 171.624376956302;
|
||
|
||
function lcl_getLanczosSum( fZ ) {
|
||
var num = [
|
||
23531376880.41075968857200767445163675473,
|
||
42919803642.64909876895789904700198885093,
|
||
35711959237.35566804944018545154716670596,
|
||
17921034426.03720969991975575445893111267,
|
||
6039542586.35202800506429164430729792107,
|
||
1439720407.311721673663223072794912393972,
|
||
248874557.8620541565114603864132294232163,
|
||
31426415.58540019438061423162831820536287,
|
||
2876370.628935372441225409051620849613599,
|
||
186056.2653952234950402949897160456992822,
|
||
8071.672002365816210638002902272250613822,
|
||
210.8242777515793458725097339207133627117,
|
||
2.506628274631000270164908177133837338626
|
||
],
|
||
denom = [
|
||
0,
|
||
39916800,
|
||
120543840,
|
||
150917976,
|
||
105258076,
|
||
45995730,
|
||
13339535,
|
||
2637558,
|
||
357423,
|
||
32670,
|
||
1925,
|
||
66,
|
||
1
|
||
];
|
||
// Horner scheme
|
||
var sumNum, sumDenom, i, zInv;
|
||
if ( fZ <= 1.0 ) {
|
||
sumNum = num[12];
|
||
sumDenom = denom[12];
|
||
for ( i = 11; i >= 0; --i ) {
|
||
sumNum *= fZ;
|
||
sumNum += num[i];
|
||
sumDenom *= fZ;
|
||
sumDenom += denom[i];
|
||
}
|
||
}
|
||
else
|
||
// Cancel down with fZ^12; Horner scheme with reverse coefficients
|
||
{
|
||
zInv = 1 / fZ;
|
||
sumNum = num[0];
|
||
sumDenom = denom[0];
|
||
for ( i = 1; i <= 12; ++i ) {
|
||
sumNum *= zInv;
|
||
sumNum += num[i];
|
||
sumDenom *= zInv;
|
||
sumDenom += denom[i];
|
||
}
|
||
}
|
||
return sumNum / sumDenom;
|
||
}
|
||
|
||
/** You must ensure fZ>0; fZ>171.624376956302 will overflow. */
|
||
function lcl_GetGammaHelper( fZ ) {
|
||
var gamma = lcl_getLanczosSum( fZ ),
|
||
fg = 6.024680040776729583740234375,
|
||
zgHelp = fZ + fg - 0.5;
|
||
// avoid intermediate overflow
|
||
var halfpower = Math.pow( zgHelp, fZ / 2 - 0.25 );
|
||
gamma *= halfpower;
|
||
gamma /= Math.exp( zgHelp );
|
||
gamma *= halfpower;
|
||
if ( fZ <= 20 && fZ == Math.floor( fZ ) )
|
||
gamma = Math.round( gamma );
|
||
return gamma;
|
||
}
|
||
|
||
/** You must ensure fZ>0 */
|
||
function lcl_GetLogGammaHelper( fZ ) {
|
||
var _fg = 6.024680040776729583740234375, zgHelp = fZ + _fg - 0.5;
|
||
return Math.log( lcl_getLanczosSum( fZ ) ) + (fZ - 0.5) * Math.log( zgHelp ) - zgHelp;
|
||
}
|
||
|
||
function getLogGamma( fZ ) {
|
||
if ( fZ >= maxGammaArgument )
|
||
return lcl_GetLogGammaHelper( fZ );
|
||
if ( fZ >= 0 )
|
||
return Math.log( lcl_GetGammaHelper( fZ ) );
|
||
if ( fZ >= 0.5 )
|
||
return Math.log( lcl_GetGammaHelper( fZ + 1 ) / fZ );
|
||
return lcl_GetLogGammaHelper( fZ + 2 ) - Math.log( fZ + 1 ) - Math.log( fZ );
|
||
} |