diff --git a/Excel/.unit-tests/FormulaTests.html b/Excel/.unit-tests/FormulaTests.html index cdfe80868dcffad7b61c1aa3a08777e83ebba222..0edc78446b3a80b6a14bce59a3b70838f1d0247c 100644 --- a/Excel/.unit-tests/FormulaTests.html +++ b/Excel/.unit-tests/FormulaTests.html @@ -41,18 +41,18 @@ <script type="text/javascript" src="../model/CollaborativeEditing.js"></script> <script type="text/javascript" src="../model/ConditionalFormatting.js"></script> - <script type="text/javascript" src="../model/parserFormula.js"></script> - <script type="text/javascript" src="../model/dateandtimeFunctions.js"></script> - <script type="text/javascript" src="../model/engineeringFunctions.js"></script> - <script type="text/javascript" src="../model/cubeFunctions.js"></script> - <script type="text/javascript" src="../model/databaseFunctions.js"></script> - <script type="text/javascript" src="../model/textanddataFunctions.js"></script> - <script type="text/javascript" src="../model/statisticalFunctions.js"></script> - <script type="text/javascript" src="../model/financialFunctions.js"></script> - <script type="text/javascript" src="../model/mathematicFunctions.js"></script> - <script type="text/javascript" src="../model/lookupandreferenceFunctions.js"></script> - <script type="text/javascript" src="../model/informationFunctions.js"></script> - <script type="text/javascript" src="../model/logicalFunctions.js"></script> + <script type="text/javascript" src="../model/FormulaObjects/parserFormula.js"></script> + <script type="text/javascript" src="../model/FormulaObjects/dateandtimeFunctions.js"></script> + <script type="text/javascript" src="../model/FormulaObjects/engineeringFunctions.js"></script> + <script type="text/javascript" src="../model/FormulaObjects/cubeFunctions.js"></script> + <script type="text/javascript" src="../model/FormulaObjects/databaseFunctions.js"></script> + <script type="text/javascript" src="../model/FormulaObjects/textanddataFunctions.js"></script> + <script type="text/javascript" src="../model/FormulaObjects/statisticalFunctions.js"></script> + <script type="text/javascript" src="../model/FormulaObjects/financialFunctions.js"></script> + <script type="text/javascript" src="../model/FormulaObjects/mathematicFunctions.js"></script> + <script type="text/javascript" src="../model/FormulaObjects/lookupandreferenceFunctions.js"></script> + <script type="text/javascript" src="../model/FormulaObjects/informationFunctions.js"></script> + <script type="text/javascript" src="../model/FormulaObjects/logicalFunctions.js"></script> <script type="text/javascript" src="../model/CellComment.js"></script> <script type="text/javascript" src="../../Common/NumFormat.js"></script> <script type="text/javascript" src="../model/Serialize.js"></script> diff --git a/Excel/model/FormulaObjects/lookupandreferenceFunctions.js b/Excel/model/FormulaObjects/lookupandreferenceFunctions.js index f4ef2eb8b07c3a51e1e48a0c258f40517d6308e6..3353ff57b929773a27f142071fe3f1e671b7504a 100644 --- a/Excel/model/FormulaObjects/lookupandreferenceFunctions.js +++ b/Excel/model/FormulaObjects/lookupandreferenceFunctions.js @@ -242,15 +242,16 @@ cFormulaFunction.LookupAndReference = { if ( arg0 instanceof cString ) { valueForSearching = arg0.getValue(); - valueForSearching = valueForSearching - .replace( /(~)?\*/g, function ( $0, $1 ) { + /*valueForSearching = valueForSearching + .replace( /(~)?\*//*g, function ( $0, $1 ) { return $1 ? $0 : '[\\w\\W]*'; } ) .replace( /(~)?\?/g, function ( $0, $1 ) { return $1 ? $0 : '[\\w\\W]{1,1}'; } ) .replace( /\~/g, "\\" ); - regexp = new XRegExp( valueForSearching + "$", "i" ); + regexp = new XRegExp( valueForSearching + "$", "i" );*/ + regexp = searchRegExp(valueForSearching); } else if ( arg0 instanceof cError ) return this.value = arg0; @@ -672,15 +673,16 @@ cFormulaFunction.LookupAndReference = { if ( arg0 instanceof cString ) { valueForSearching = arg0.getValue(); - valueForSearching = valueForSearching - .replace( /(~)?\*/g, function ( $0, $1 ) { + /*valueForSearching = valueForSearching + .replace( /(~)?\*//*g, function ( $0, $1 ) { return $1 ? $0 : '[\\w\\W]*'; } ) .replace( /(~)?\?/g, function ( $0, $1 ) { return $1 ? $0 : '[\\w\\W]{1,1}'; } ) .replace( /\~/g, "\\" ); - regexp = new XRegExp( valueForSearching + "$", "i" ); + regexp = new XRegExp( valueForSearching + "$", "i" );*/ + regexp = searchRegExp(valueForSearching); } else if ( arg0 instanceof cError ) return this.value = arg0; diff --git a/Excel/model/FormulaObjects/mathematicFunctions.js b/Excel/model/FormulaObjects/mathematicFunctions.js index 28599958cc8a1d2424438dbbb8333b93603aa900..c7b9cb5d47635a3c522ddb16d1338fecb42e0c24 100644 --- a/Excel/model/FormulaObjects/mathematicFunctions.js +++ b/Excel/model/FormulaObjects/mathematicFunctions.js @@ -3048,9 +3048,21 @@ cFormulaFunction.Mathematic = { return this.value = new cError( cErrorType.wrong_value_type ); } - function matching( x, y, oper, startCell, pos ) { - var res = false; - if ( typeof x === typeof y ) { + function matching( x, y, oper ) { + var res = false, rS; + if ( y instanceof cString ) { + rS = searchRegExp(y.toString()) + switch ( oper ) { + case "<>": + res = !rS.test( x.value ); + break; + case "=": + default: + res = rS.test( x.value ); + break; + } + } + else if ( typeof x === typeof y ) { switch ( oper ) { case "<>": res = (x.value != y.value); @@ -3077,37 +3089,22 @@ cFormulaFunction.Mathematic = { } arg1 = arg1.toString(); - var operators = new RegExp( "^ *[<=> ]+ *" ); - var match = arg1.match( operators ); - if ( match || parseNum( arg1 ) ) { - - var search, oper, val; - if ( match ) { - search = arg1.substr( match[0].length ); - oper = match[0].replace( /\s/g, "" ); - } - else { - search = arg1; - } - valueForSearching = parseNum( search ) ? new cNumber( search ) : new cString( search ); - if ( arg0 instanceof cArea ) { - val = arg0.getValue(); - for ( var i = 0; i < val.length; i++ ) { - if ( matching( val[i], valueForSearching, oper ) ) { - var r = arg0.getRange(), ws = arg0.getWS(), - r1 = r.first.getRow0() + i, c1 = arg2.getRange().first.getCol0(); - r = new cRef( ws.getRange3( r1, c1, r1, c1 ).getName(), ws ); - if ( r.getValue() instanceof cNumber ) { - _sum += r.getValue().getValue(); - } - } - } - } - else { - val = arg0.getValue(); - if ( matching( val, valueForSearching, oper ) ) { + var operators = new RegExp( "^ *[<=> ]+ *" ), match = arg1.match( operators ), + search, oper, val; + if ( match ) { + search = arg1.substr( match[0].length ); + oper = match[0].replace( /\s/g, "" ); + } + else { + search = arg1; + } + valueForSearching = parseNum( search ) ? new cNumber( search ) : new cString( search ); + if ( arg0 instanceof cArea ) { + val = arg0.getValue(); + for ( var i = 0; i < val.length; i++ ) { + if ( matching( val[i], valueForSearching, oper ) ) { var r = arg0.getRange(), ws = arg0.getWS(), - r1 = r.first.getRow0() + 0, c1 = arg2.getRange().first.getCol0(); + r1 = r.first.getRow0() + i, c1 = arg2.getRange().first.getCol0(); r = new cRef( ws.getRange3( r1, c1, r1, c1 ).getName(), ws ); if ( r.getValue() instanceof cNumber ) { _sum += r.getValue().getValue(); @@ -3116,37 +3113,13 @@ cFormulaFunction.Mathematic = { } } else { - valueForSearching = arg1 - .replace( /(~)?\*/g, function ( $0, $1 ) { - return $1 ? $0 : '[\\w\\W]*'; - } ) - .replace( /(~)?\?/g, function ( $0, $1 ) { - return $1 ? $0 : '[\\w\\W]{1,1}'; - } ) - .replace( /(~\*)/g, "\\*" ).replace( /(~\?)/g, "\\?" ); - regexpSearch = new RegExp( valueForSearching + "$", "i" ); - if ( arg0 instanceof cArea ) { - val = arg0.getValue(); - for ( var i = 0; i < val.length; i++ ) { - if ( regexpSearch.test( val[i].value ) ) { - var r = arg0.getRange(), ws = arg0.getWS(), - r1 = r.first.getRow0() + i, c1 = arg2.getRange().first.getCol0(); - r = new cRef( ws.getRange3( r1, c1, r1, c1 ).getName(), ws ); - if ( r.getValue() instanceof cNumber ) { - _sum += r.getValue().getValue(); - } - } - } - } - else { - val = arg0.getValue(); - if ( regexpSearch.test( val.value ) ) { - var r = arg0.getRange(), ws = arg0.getWS(), - r1 = r.first.getRow0() + 0, c1 = arg2.getRange().first.getCol0(); - r = new cRef( ws.getRange3( r1, c1, r1, c1 ).getName(), ws ); - if ( r.getValue() instanceof cNumber ) { - _sum += r.getValue().getValue(); - } + val = arg0.getValue(); + if ( matching( val, valueForSearching, oper ) ) { + var r = arg0.getRange(), ws = arg0.getWS(), + r1 = r.first.getRow0() + 0, c1 = arg2.getRange().first.getCol0(); + r = new cRef( ws.getRange3( r1, c1, r1, c1 ).getName(), ws ); + if ( r.getValue() instanceof cNumber ) { + _sum += r.getValue().getValue(); } } } diff --git a/Excel/model/FormulaObjects/statisticalFunctions.js b/Excel/model/FormulaObjects/statisticalFunctions.js index 73d555f58bc13c6bcfa71153e4360e420aba4496..994a40bfb58195807da3efd700720ec1d0c82a92 100644 --- a/Excel/model/FormulaObjects/statisticalFunctions.js +++ b/Excel/model/FormulaObjects/statisticalFunctions.js @@ -219,9 +219,21 @@ cFormulaFunction.Statistical = { return this.value = new cError( cErrorType.wrong_value_type ); } - function matching( x, y, oper, startCell, pos ) { - var res = false; - if ( typeof x === typeof y ) { + function matching( x, y, oper ) { + var res = false, rS; + if ( y instanceof cString ) { + rS = searchRegExp(y.toString()) + switch ( oper ) { + case "<>": + res = !rS.test( x.value ); + break; + case "=": + default: + res = rS.test( x.value ); + break; + } + } + else if ( typeof x === typeof y ) { switch ( oper ) { case "<>": res = (x.value != y.value); @@ -248,38 +260,22 @@ cFormulaFunction.Statistical = { } arg1 = arg1.toString(); - var operators = new RegExp( "^ *[<=> ]+ *" ); - var match = arg1.match( operators ); - if ( match || parseNum( arg1 ) ) { - - var search, oper, val; - if ( match ) { - search = arg1.substr( match[0].length ); - oper = match[0].replace( /\s/g, "" ); - } - else { - search = arg1; - } - valueForSearching = parseNum( search ) ? new cNumber( search ) : new cString( search ); - if ( arg0 instanceof cArea ) { - val = arg0.getValue(); - for ( var i = 0; i < val.length; i++ ) { - if ( matching( val[i], valueForSearching, oper ) ) { - var r = arg0.getRange(), ws = arg0.getWS(), - r1 = r.first.getRow0() + i, c1 = arg2.getRange().first.getCol0(); - r = new cRef( ws.getRange3( r1, c1, r1, c1 ).getName(), ws ); - if ( r.getValue() instanceof cNumber ) { - _sum += r.getValue().getValue(); - _count++; - } - } - } - } - else { - val = arg0.getValue(); - if ( matching( val, valueForSearching, oper ) ) { + var operators = new RegExp( "^ *[<=> ]+ *" ), match = arg1.match( operators ), + search, oper, val; + if ( match ) { + search = arg1.substr( match[0].length ); + oper = match[0].replace( /\s/g, "" ); + } + else { + search = arg1; + } + valueForSearching = parseNum( search ) ? new cNumber( search ) : new cString( search ); + if ( arg0 instanceof cArea ) { + val = arg0.getValue(); + for ( var i = 0; i < val.length; i++ ) { + if ( matching( val[i], valueForSearching, oper ) ) { var r = arg0.getRange(), ws = arg0.getWS(), - r1 = r.first.getRow0() + 0, c1 = arg2.getRange().first.getCol0(); + r1 = r.first.getRow0() + i, c1 = arg2.getRange().first.getCol0(); r = new cRef( ws.getRange3( r1, c1, r1, c1 ).getName(), ws ); if ( r.getValue() instanceof cNumber ) { _sum += r.getValue().getValue(); @@ -289,44 +285,24 @@ cFormulaFunction.Statistical = { } } else { - valueForSearching = arg1 - .replace( /(~)?\*/g, function ( $0, $1 ) { - return $1 ? $0 : '[\\w\\W]*'; - } ) - .replace( /(~)?\?/g, function ( $0, $1 ) { - return $1 ? $0 : '[\\w\\W]{1,1}'; - } ) - .replace( /(~\*)/g, "\\*" ).replace( /(~\?)/g, "\\?" ); - regexpSearch = new RegExp( valueForSearching + "$", "i" ); - if ( arg0 instanceof cArea ) { - val = arg0.getValue(); - for ( var i = 0; i < val.length; i++ ) { - if ( regexpSearch.test( val[i].value ) ) { - var r = arg0.getRange(), ws = arg0.getWS(), - r1 = r.first.getRow0() + i, c1 = arg2.getRange().first.getCol0(); - r = new cRef( ws.getRange3( r1, c1, r1, c1 ).getName(), ws ); - if ( r.getValue() instanceof cNumber ) { - _sum += r.getValue().getValue(); - _count++; - } - } - } - } - else { - val = arg0.getValue(); - if ( regexpSearch.test( val.value ) ) { - var r = arg0.getRange(), ws = arg0.getWS(), - r1 = r.first.getRow0() + 0, c1 = arg2.getRange().first.getCol0(); - r = new cRef( ws.getRange3( r1, c1, r1, c1 ).getName(), ws ); - if ( r.getValue() instanceof cNumber ) { - _sum += r.getValue().getValue(); - _count++; - } + val = arg0.getValue(); + if ( matching( val, valueForSearching, oper ) ) { + var r = arg0.getRange(), ws = arg0.getWS(), + r1 = r.first.getRow0() + 0, c1 = arg2.getRange().first.getCol0(); + r = new cRef( ws.getRange3( r1, c1, r1, c1 ).getName(), ws ); + if ( r.getValue() instanceof cNumber ) { + _sum += r.getValue().getValue(); + _count++; } } } - return this.value = new cNumber( _sum / _count ); + if( _count == 0 ){ + return new cError( cErrorType.division_by_zero ); + } + else{ + return this.value = new cNumber( _sum / _count ); + } } r.getInfo = function () { return { @@ -701,8 +677,20 @@ cFormulaFunction.Statistical = { } function matching( x, y, oper ) { - var res = 0; - if ( typeof x === typeof y ) { + var res = false, rS; + if ( y instanceof cString ) { + rS = searchRegExp(y.toString()) + switch ( oper ) { + case "<>": + res = !rS.test( x.value ); + break; + case "=": + default: + res = rS.test( x.value ); + break; + } + } + else if ( typeof x === typeof y ) { switch ( oper ) { case "<>": res = (x.value != y.value); @@ -723,74 +711,38 @@ cFormulaFunction.Statistical = { default: res = (x.value == y.value); break; - } } - _count += res; + return res; } arg1 = arg1.toString(); - var operators = new RegExp( "^ *[<=> ]+ *" ), searchOperators = new RegExp( "^ *[*?]" ) - var match = arg1.match( operators ); - if ( match || parseNum( arg1 ) ) { + var operators = new RegExp( "^ *[<=> ]+ *" ), searchOperators = new RegExp( "^ *[*?]" ), search, oper, val, + match = arg1.match( operators ); - var search, oper, val; - if ( match ) { - search = arg1.substr( match[0].length ); - oper = match[0].replace( /\s/g, "" ); - } - else { - search = arg1; - } - valueForSearching = parseNum( search ) ? new cNumber( search ) : new cString( search ); - if ( arg0 instanceof cArea ) { - val = arg0.getValue(); - for ( var i = 0; i < val.length; i++ ) { - matching( val[i], valueForSearching, oper ); - } - } - else if ( arg0 instanceof cArea3D ) { - val = arg0.getValue(); - for ( var i = 0; i < val.length; i++ ) { - matching( val[i], valueForSearching, oper ); - } + if ( match ) { + search = arg1.substr( match[0].length ); + oper = match[0].replace( /\s/g, "" ); + } + else { + search = arg1; + } + valueForSearching = parseNum( search ) ? new cNumber( search ) : new cString( search ); + if ( arg0 instanceof cArea ) { + val = arg0.getValue(); + for ( var i = 0; i < val.length; i++ ) { + _count += matching( val[i], valueForSearching, oper ); } - else { - val = arg0.getValue(); - matching( val, valueForSearching, oper ); + } + else if ( arg0 instanceof cArea3D ) { + val = arg0.getValue(); + for ( var i = 0; i < val.length; i++ ) { + _count += matching( val[i], valueForSearching, oper ); } } else { - match = arg1.match( searchOperators ) - if ( match ) { - valueForSearching = arg1 - .replace( /(~)?\*/g, function ( $0, $1 ) { - return $1 ? $0 : '[\\w\\W]*'; - } ) - .replace( /(~)?\?/g, function ( $0, $1 ) { - return $1 ? $0 : '[\\w\\W]{1,1}'; - } ) - .replace( /(~\*)/g, "\\*" ).replace( /(~\?)/g, "\\?" ) - regexpSearch = new RegExp( valueForSearching + "$", "i" ); - if ( arg0 instanceof cArea ) { - val = arg0.getValue(); - for ( var i = 0; i < val.length; i++ ) { - _count += regexpSearch.test( val[i].value ); - } - } - else if ( arg0 instanceof cArea3D ) { - val = arg0.getValue(); - for ( var i in val ) { - for ( var j in val[i] ) { - _count += regexpSearch.test( val[i][j].value ); - } - } - } - else { - val = arg0.getValue(); - _count += regexpSearch.test( val.value ); - } - } + val = arg0.getValue(); + _count += matching( val, valueForSearching, oper ); } return this.value = new cNumber( _count ); diff --git a/Excel/model/FormulaObjects/textanddataFunctions.js b/Excel/model/FormulaObjects/textanddataFunctions.js index 2baaf46dad1feb105b1dd21f508436520815f6d2..7300e52b62255242c06a765d4d55f194f7a38cd0 100644 --- a/Excel/model/FormulaObjects/textanddataFunctions.js +++ b/Excel/model/FormulaObjects/textanddataFunctions.js @@ -953,15 +953,24 @@ cFormulaFunction.TextAndData = { var string1 = arg0.getValue(), string2 = arg1.getValue(), valueForSearching = string1 + .replace( /(\\)/g, "\\" ) + .replace( /(\^)/g, "\\^" ) + .replace( /(\()/g, "\\(" ) + .replace( /(\))/g, "\\)" ) + .replace( /(\+)/g, "\\+" ) + .replace( /(\[)/g, "\\[" ) + .replace( /(\])/g, "\\]" ) + .replace( /(\{)/g, "\\{" ) + .replace( /(\})/g, "\\}" ) + .replace( /(\$)/g, "\\$" ) .replace( /(~)?\*/g, function ( $0, $1 ) { - return $1 ? $0 : '[\\w\\W]*'; + return $1 ? $0 : '(.*)'; } ) .replace( /(~)?\?/g, function ( $0, $1 ) { - return $1 ? $0 : '[\\w\\W]{1,1}'; + return $1 ? $0 : '.'; } ) .replace( /(~\*)/g, "\\*" ).replace( /(~\?)/g, "\\?" ); - - valueForSearching = new RegExp( valueForSearching, "ig" ) + valueForSearching = new RegExp( valueForSearching, "ig" ); if ( string1 == "" ) return this.value = arg2; diff --git a/Excel/view/WorksheetView.js b/Excel/view/WorksheetView.js index 263a440db08c8b6bfb768a1e1f0fa8f7490f7436..4111c3264d31e314908ac19e8b212f1ed2fd8029 100644 --- a/Excel/view/WorksheetView.js +++ b/Excel/view/WorksheetView.js @@ -8701,15 +8701,19 @@ findFlags += "i"; // Ðе чувÑтвителен к региÑтру var valueForSearching = options.findWhat - .replace(/(~)?\*/g, function($0, $1){ - return $1 ? $0 : '[\\w\\W]*'; - }) - .replace(/(~)?\?/g, function($0, $1){ - return $1 ? $0 : '[\\w\\W]{1,1}'; - }) - .replace(/(~\*)/g,"\\*").replace(/(~\?)/g, "\\?"); + .replace( /(\\)/g, "\\" ).replace( /(\^)/g, "\\^" ) + .replace( /(\()/g, "\\(" ).replace( /(\))/g, "\\)" ) + .replace( /(\+)/g, "\\+" ).replace( /(\[)/g, "\\[" ) + .replace( /(\])/g, "\\]" ).replace( /(\{)/g, "\\{" ) + .replace( /(\})/g, "\\}" ).replace( /(\$)/g, "\\$" ) + .replace( /(~)?\*/g, function ( $0, $1 ) { + return $1 ? $0 : '(.*)'; + } ) + .replace( /(~)?\?/g, function ( $0, $1 ) { + return $1 ? $0 : '.'; + } ) + .replace( /(~\*)/g, "\\*" ).replace( /(~\?)/g, "\\?" ); valueForSearching = new RegExp(valueForSearching, findFlags); - var t = this; var ar = this.activeRange.clone(); ar.startCol = this.activeRange.startCol;