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;