diff --git a/docs/zh/guide/api.md b/docs/zh/guide/api.md
index 10bed91..58117f8 100644
--- a/docs/zh/guide/api.md
+++ b/docs/zh/guide/api.md
@@ -1444,9 +1444,6 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
 
 ### deleteRangeConditionalFormat(itemIndex [,setting])
 
-[todo]
-
-
 - **参数**:
 
 	- {Number} [itemIndex]: 条件格式规则索引
@@ -1469,9 +1466,6 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
 
 ### clearRange([setting])
 
-[todo]
-
-
 - **参数**:
 
 	- {PlainObject} [setting]: 可选参数
@@ -1481,7 +1475,7 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
 
 - **说明**:
 	
-	清除指定工作表指定单元格区域的内容,返回清除掉的数据,不同于删除选区的功能,不需要设定单元格移动情况
+	清除指定工作表指定单元格区域的内容,不同于删除选区的功能,不需要设定单元格移动情况
 
 - **示例**:
 
@@ -1492,9 +1486,6 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
 
 ### deleteRange(move [,setting])
 
-[todo]
-
-
 - **参数**:
 	
 	- {String} [move]: 删除后,右侧还是下方的单元格移动
@@ -1505,13 +1496,13 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
 		+ `"up"`: 下方单元格上移
 		
 	- {PlainObject} [setting]: 可选参数
-		+ {Array | Object | String} [range]: 要删除的选区范围,支持选区的格式为`"A1:B2"`、`"sheetName!A1:B2"`或者`{row:[0,1],column:[0,1]}`,允许多个选区组成的数组;默认为当前选区
+		+ {Object | String} [range]: 要删除的选区范围,支持选区的格式为`"A1:B2"`、`"sheetName!A1:B2"`或者`{row:[0,1],column:[0,1]}`;默认为当前选区
 		+ {Number} [order]: 工作表下标;默认值为当前工作表下标
 		+ {Function} [success]: 操作结束的回调函数
 
 - **说明**:
 	
-	删除指定工作表指定单元格区域,返回删除掉的数据,同时,指定是右侧单元格左移还是下方单元格上移
+	删除指定工作表指定单元格区域,同时,指定是右侧单元格左移还是下方单元格上移
 
 - **示例**:
 
@@ -1558,9 +1549,6 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
 
 ### matrixOperation(type [,setting])
 
-[todo]
-
-
 - **参数**:
 	
 	- {String} [type]: 矩阵操作的类型
@@ -1603,9 +1591,6 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
 
 ### matrixCalculation(type, number [,setting])
 
-[todo]
-
-
 - **参数**:
 	- {String} [type]: 计算方式
 	
@@ -1678,8 +1663,6 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
 
 ### getSheet([setting])
 
-[todo]
-
 - **参数**:
 
     - {PlainObject} [setting]: 可选参数
@@ -1695,9 +1678,6 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
 
 ### getSheetData([setting])
 
-[todo]
-
-
 - **参数**:
 
     - {PlainObject} [setting]: 可选参数
@@ -1711,9 +1691,6 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
 
 ### getConfig([setting])
 
-[todo]
-
-
 - **参数**:
 
     - {PlainObject} [setting]: 可选参数
@@ -1725,20 +1702,17 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
 
 ------------
 
-### setConfig([setting])
-
-[todo]
-
+### setConfig(cfg, [setting])
 
 - **参数**:
-
+	- {Object} [cfg]: config配置
     - {PlainObject} [setting]: 可选参数
     	+ {Number} [order]: 工作表下标;默认值为当前工作表下标
     	+ {Function} [success]: 操作结束的回调函数
 	
 - **说明**:
 
-	快捷设置当前工作表config配置
+	快捷设置指定工作表config配置
 
 ------------
 
diff --git a/src/controllers/constant.js b/src/controllers/constant.js
index f043532..d9f3c9b 100644
--- a/src/controllers/constant.js
+++ b/src/controllers/constant.js
@@ -287,24 +287,22 @@ function rightclickHTML(){
                 
                 
                     
-                    
                 
                 
                 
                 
                 
                 
                 
             
diff --git a/src/controllers/insertFormula.js b/src/controllers/insertFormula.js
index 532338d..4eceeb2 100644
--- a/src/controllers/insertFormula.js
+++ b/src/controllers/insertFormula.js
@@ -329,7 +329,7 @@ const insertFormula = {
                 }
             }
             else{ //参数是公式
-                $("#luckysheet-search-formula-parm .parmBox").eq(index).find(".val").text(" = {"+ eval($.trim(formula.functionParser("=" + parmtxt))) +"}");
+                $("#luckysheet-search-formula-parm .parmBox").eq(index).find(".val").text(" = {"+ eval($.trim(formula.functionParserExe("=" + parmtxt))) +"}");
             }
         })
 
@@ -419,7 +419,7 @@ const insertFormula = {
 
             luckysheet_count_show(col_pre, row_pre, col - col_pre - 1, row - row_pre - 1, cellrange.row, cellrange.column);
 
-            $("#luckysheet-search-formula-parm .parmBox").eq(formula.data_parm_index).find(".val").text(" = {"+ eval($.trim(formula.functionParser("=" + parmtxt))) +"}");
+            $("#luckysheet-search-formula-parm .parmBox").eq(formula.data_parm_index).find(".val").text(" = {"+ eval($.trim(formula.functionParserExe("=" + parmtxt))) +"}");
         }
     },
     functionStrCompute: function(){
@@ -471,7 +471,7 @@ const insertFormula = {
         $("#luckysheet-functionbox-cell").html($("#luckysheet-rich-text-editor").html());
         
         if(isVal){ //公式计算
-            let fp = $.trim(formula.functionParser($("#luckysheet-rich-text-editor").text()));
+            let fp = $.trim(formula.functionParserExe($("#luckysheet-rich-text-editor").text()));
             
             let result = null;
 
diff --git a/src/controllers/keyboard.js b/src/controllers/keyboard.js
index 05f1316..772fa40 100644
--- a/src/controllers/keyboard.js
+++ b/src/controllers/keyboard.js
@@ -909,4 +909,15 @@ export function keyboardInitial(){
     }).change(function(){
         server.saveParam("na", null, $(this).val());
     });
+
+
+    // 右击菜单的input输入框 敲击Enter一样生效
+    $("#" + Store.container).add("input.luckysheet-mousedown-cancel").keydown(function (event) {
+
+        const element =  event.target.closest('.luckysheet-cols-menuitem');
+        if (typeof(element) != 'undefined' && element != null && event.keyCode === 13){
+            $(element).trigger('click');
+        }
+
+    })
 }
\ No newline at end of file
diff --git a/src/controllers/postil.js b/src/controllers/postil.js
index 1206ea9..d274e54 100644
--- a/src/controllers/postil.js
+++ b/src/controllers/postil.js
@@ -799,7 +799,7 @@ const luckysheetPostil = {
         editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据
 
         Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].data = Store.flowdata;
-        formula.execFunctionGroupData = Store.flowdata;
+        // formula.execFunctionGroupData = Store.flowdata;
 
         //共享编辑模式
         if(server.allowUpdate){
diff --git a/src/controllers/rowColumnOperation.js b/src/controllers/rowColumnOperation.js
index 2c9f52a..1942399 100644
--- a/src/controllers/rowColumnOperation.js
+++ b/src/controllers/rowColumnOperation.js
@@ -929,7 +929,14 @@ export function rowColumnOperationInitial(){
     });
 
     //向左增加列,向上增加行
-    $("#luckysheet-add-lefttop, #luckysheet-add-lefttop_t").click(function (event) {
+    // $("#luckysheet-add-lefttop, #luckysheet-add-lefttop_t").click(function (event) {
+    $("#luckysheet-top-left-add-selected").click(function (event) {
+
+        // Click input element, don't comfirm 
+        if(event.target.nodeName === 'INPUT'){
+            return;
+        }
+
         $("#luckysheet-rightclick-menu").hide();
         luckysheetContainerFocus();
         
@@ -950,7 +957,7 @@ export function rowColumnOperationInitial(){
 
         
 
-        let $t = $(this), value = $t.parent().find("input").val();
+        let $t = $(this), value = $t.find("input").val();
         if (!isRealNum(value)) {
             if(isEditMode()){
                 alert(locale_info.tipInputNumber);
@@ -977,7 +984,16 @@ export function rowColumnOperationInitial(){
         let st_index = Store.luckysheet_select_save[0][Store.luckysheetRightHeadClickIs][0];
         luckysheetextendtable(Store.luckysheetRightHeadClickIs, st_index, value, "lefttop");
     });
-    $("#luckysheet-addTopRows").click(function (event) {
+
+    // Add the row up, and click the text area to trigger the confirmation instead of clicking the confirmation button to enhance the experience
+    // $("#luckysheet-addTopRows").click(function (event) {
+    $("#luckysheetColsRowsHandleAdd_sub .luckysheet-cols-menuitem:first-child").click(function (event) {
+
+        // Click input element, don't comfirm 
+        if(event.target.nodeName === 'INPUT'){
+            return;
+        }
+
         $("#luckysheet-rightclick-menu").hide();
         luckysheetContainerFocus();
 
@@ -996,7 +1012,7 @@ export function rowColumnOperationInitial(){
             return;
         }
 
-        let $t = $(this), value = $t.parent().find("input").val();
+        let $t = $(this), value = $t.find("input").val();
         if (!isRealNum(value)) {
             if(isEditMode()){
                 alert(locale_info.tipInputNumber);
@@ -1022,8 +1038,24 @@ export function rowColumnOperationInitial(){
 
         let st_index = Store.luckysheet_select_save[0].row[0];
         luckysheetextendtable('row', st_index, value, "lefttop");
+
+        $("#luckysheetColsRowsHandleAdd_sub").hide();
     })
-    $("#luckysheet-addLeftCols").click(function (event) {
+
+    // // input输入时阻止冒泡,禁止父级元素的确认事件触发
+    // $("input.luckysheet-mousedown-cancel").click(function(event) {
+    //     event.stopPropagation;
+    // })
+
+
+    // $("#luckysheet-addLeftCols").click(function (event) {
+    $("#luckysheetColsRowsHandleAdd_sub .luckysheet-cols-menuitem:nth-child(3)").click(function (event) {
+
+        // Click input element, don't comfirm 
+        if(event.target.nodeName === 'INPUT'){
+            return;
+        }
+
         $("#luckysheet-rightclick-menu").hide();
         luckysheetContainerFocus();
 
@@ -1042,7 +1074,7 @@ export function rowColumnOperationInitial(){
             return;
         }
 
-        let $t = $(this), value = $t.parent().find("input").val();
+        let $t = $(this), value = $t.find("input").val();
         if (!isRealNum(value)) {
             if(isEditMode()){
                 alert(locale_info.tipInputNumber);
@@ -1068,10 +1100,20 @@ export function rowColumnOperationInitial(){
 
         let st_index = Store.luckysheet_select_save[0].column[0];
         luckysheetextendtable('column', st_index, value, "lefttop");
+
+        $("#luckysheetColsRowsHandleAdd_sub").hide();
+        
     })
 
     //向右增加列,向下增加行
-    $("#luckysheet-add-rightbottom, #luckysheet-add-rightbottom_t").click(function (event) {
+    // $("#luckysheet-add-rightbottom, #luckysheet-add-rightbottom_t").click(function (event) {
+    $("#luckysheet-bottom-right-add-selected").click(function (event) {
+
+        // Click input element, don't comfirm 
+        if(event.target.nodeName === 'INPUT'){
+            return;
+        }
+
         $("#luckysheet-rightclick-menu").hide();
         luckysheetContainerFocus();
 
@@ -1090,7 +1132,7 @@ export function rowColumnOperationInitial(){
             return;
         }
 
-        let $t = $(this), value = $t.parent().find("input").val();
+        let $t = $(this), value = $t.find("input").val();
         if (!isRealNum(value)) {
             if(isEditMode()){
                 alert(locale_info.tipInputNumber);
@@ -1118,7 +1160,15 @@ export function rowColumnOperationInitial(){
         let st_index = Store.luckysheet_select_save[0][Store.luckysheetRightHeadClickIs][1];
         luckysheetextendtable(Store.luckysheetRightHeadClickIs, st_index, value, "rightbottom");
     });
-    $("#luckysheet-addBottomRows").click(function (event) {
+
+    // $("#luckysheet-addBottomRows").click(function (event) {
+    $("#luckysheetColsRowsHandleAdd_sub .luckysheet-cols-menuitem:nth-child(2)").click(function (event) {
+
+         // Click input element, don't comfirm 
+         if(event.target.nodeName === 'INPUT'){
+            return;
+        }
+
         $("#luckysheet-rightclick-menu").hide();
         luckysheetContainerFocus();
 
@@ -1137,7 +1187,7 @@ export function rowColumnOperationInitial(){
             return;
         }
 
-        let $t = $(this), value = $t.parent().find("input").val();
+        let $t = $(this), value = $t.find("input").val();
         if (!isRealNum(value)) {
             if(isEditMode()){
                 alert(locale_info.tipInputNumber);
@@ -1164,8 +1214,17 @@ export function rowColumnOperationInitial(){
 
         let st_index = Store.luckysheet_select_save[0].row[1];
         luckysheetextendtable('row', st_index, value, "rightbottom");
+
+        $("#luckysheetColsRowsHandleAdd_sub").hide();
+
     });
-    $("#luckysheet-addRightCols").click(function (event) {
+    // $("#luckysheet-addRightCols").click(function (event) {
+    $("#luckysheetColsRowsHandleAdd_sub .luckysheet-cols-menuitem:nth-child(4)").click(function (event) {
+
+        // Click input element, don't comfirm 
+        if(event.target.nodeName === 'INPUT'){
+            return;
+        }
         $("#luckysheet-rightclick-menu").hide();
         luckysheetContainerFocus();
 
@@ -1184,7 +1243,7 @@ export function rowColumnOperationInitial(){
             return;
         }
 
-        let $t = $(this), value = $t.parent().find("input").val();
+        let $t = $(this), value = $t.find("input").val();
         if (!isRealNum(value)) {
             if(isEditMode()){
                 alert(locale_info.tipInputNumber);
@@ -1211,6 +1270,9 @@ export function rowColumnOperationInitial(){
 
         let st_index = Store.luckysheet_select_save[0].column[1];
         luckysheetextendtable('column', st_index, value, "rightbottom");
+
+        $("#luckysheetColsRowsHandleAdd_sub").hide();
+
     });
     
     //删除选中行列
@@ -1577,6 +1639,10 @@ export function rowColumnOperationInitial(){
 
                                 delete d[r][c]["spl"];
                             }
+
+                            if(d[r][c]["ct"] != null && d[r][c]["ct"].t == 'inlineStr'){
+                                delete d[r][c]["ct"];
+                            }
                         }
                         else{
                             d[r][c] = null;
@@ -1590,11 +1656,19 @@ export function rowColumnOperationInitial(){
     });
 
     //行高列宽设置
-    $("#luckysheet-rows-cols-changesize").click(function(){
+    // $("#luckysheet-rows-cols-changesize").click(function(){
+    $("#luckysheet-column-row-width-selected").click(function (event) {
+
+        // Click input element, don't comfirm 
+        if(event.target.nodeName === 'INPUT'){
+            return;
+        }
+        
         $("#luckysheet-rightclick-menu").hide();
         luckysheetContainerFocus();
 
-        let size = parseInt($(this).siblings("input[type='number']").val().trim());
+        // let size = parseInt($(this).siblings("input[type='number']").val().trim());
+        let size = parseInt($(this).closest('.luckysheet-cols-menuitem').find("input[type='number']").val().trim());
 
         if(size < 0 || size > 255){
             const locale_info = locale().info;
diff --git a/src/controllers/selection.js b/src/controllers/selection.js
index 4e74ac8..df1d6e2 100644
--- a/src/controllers/selection.js
+++ b/src/controllers/selection.js
@@ -1451,7 +1451,7 @@ const selection = {
                                 func = "=" + formula.functionCopy(func, "left", Math.abs(offsetCol));
                             }
 
-                            let funcV = formula.execfunction(func, h, c, true);
+                            let funcV = formula.execfunction(func, h, c, undefined, true);
 
                             if(value.spl != null){
                                 value.f = funcV[2];
diff --git a/src/controllers/sheetmanage.js b/src/controllers/sheetmanage.js
index 5d943da..b6478cd 100644
--- a/src/controllers/sheetmanage.js
+++ b/src/controllers/sheetmanage.js
@@ -864,7 +864,8 @@ const sheetmanage = {
         Store.flowdata = file["data"];
         editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据
 
-        formula.execFunctionGroupData = null;
+        // formula.execFunctionGroupData = null;
+        formula.execFunctionGlobalData = null;
         window.luckysheet_getcelldata_cache = null;
 
         this.sheetParamRestore(file, Store.flowdata);
@@ -1152,7 +1153,7 @@ const sheetmanage = {
         _this.restoreselect();
     },
     checkLoadSheetIndex: function(file) {
-    	let calchain = file.calcChain; //index
+    	let calchain = formula.getAllFunctionGroup();//file.calcChain; //index
     	let chart = file.chart; //dataSheetIndex
     	let pivotTable = file.pivotTable; //pivotDataSheetIndex
 
@@ -1166,7 +1167,14 @@ const sheetmanage = {
                 let dataindex = f.index;
                 let formulaTxt = getcellFormula(f.r, f.c, dataindex);
 
+                if(formulaTxt==null){
+                    let file = Store.luckysheetfile[this.getSheetIndex(dataindex)];
+                    file.data = this.buildGridData(file);
+                    formulaTxt = getcellFormula(f.r, f.c, dataindex);
+                }
+
                 formula.functionParser(formulaTxt, (str)=>{
+                    formula.addToCellList(formulaTxt, str);
                     if(str.indexOf("!")>-1){
                         let name = str.substr(0, str.indexOf('!'));
                         dataNameList[name] = true;
@@ -1178,7 +1186,7 @@ const sheetmanage = {
                 }
                 
         		if(cache[dataindex.toString()] == null){
-        			ret.push(dataindex);
+        			// ret.push(dataindex);
         			cache[dataindex.toString()] = 1;
         		}
             }
diff --git a/src/css/luckysheet-core.css b/src/css/luckysheet-core.css
index 66d532c..cb31135 100644
--- a/src/css/luckysheet-core.css
+++ b/src/css/luckysheet-core.css
@@ -360,7 +360,7 @@
     background-color: #0081f9;
     height: 3px;
     width: 55%;
-    left: 25%;
+    left: 30%;
 }
 
 .luckysheet-toolbar-button-inner-box .luckysheet-icon,
diff --git a/src/function/func.js b/src/function/func.js
index d4d3f06..f988a4d 100644
--- a/src/function/func.js
+++ b/src/function/func.js
@@ -190,7 +190,7 @@ function luckysheet_compareWith() {
 
                             let value;
                             if(isRealNum(fp[m][n]) && isRealNum(tp[m][n])){
-                                value = luckysheet_calcADPMM(fp[m][n], sp, tp[p][n]);//parseFloat(fp[m][n]) * parseFloat(tp[m][n]);
+                                value = luckysheet_calcADPMM(fp[m][n], sp, tp[m][n]);//parseFloat(fp[m][n]) * parseFloat(tp[m][n]);
                             }
                             else{
                                 value = error.v;
@@ -1621,15 +1621,16 @@ function luckysheet_getcelldata(txt) {
         }
     } 
     else {
-        let index = getSheetIndex(Store.currentSheetIndex);
+        let index = getSheetIndex(Store.calculateSheetIndex);
         sheettxt = luckysheetfile[index].name;
         sheetIndex = luckysheetfile[index].index;
-        sheetdata = Store.flowdata;
+        // sheetdata = Store.flowdata;
+        sheetdata = luckysheetfile[index].data;
         rangetxt = val[0];
 
-        if (formula.execFunctionGroupData != null) {
-            sheetdata = formula.execFunctionGroupData;
-        }
+        // if (formula.execFunctionGroupData != null) {
+        //     sheetdata = formula.execFunctionGroupData;
+        // }
     }
 
     if (rangetxt.indexOf(":") == -1) {
@@ -1642,6 +1643,13 @@ function luckysheet_getcelldata(txt) {
                 "column": [col, col]
             })[0][0];
 
+            if (formula.execFunctionGlobalData != null) {
+                let ef = formula.execFunctionGlobalData[row+"_"+col+"_"+sheetIndex];
+                if(ef!=null){
+                    ret = ef;
+                }
+            }
+
             //范围的长宽
             let rowl = 1;
             let coll = 1;
@@ -1700,6 +1708,18 @@ function luckysheet_getcelldata(txt) {
             "row": row,
             "column": col
         });
+
+        if(formula.execFunctionGlobalData!=null){
+            for(let r=row[0];r<=row[1];r++){
+                for(let c=col[0];c<=col[1];c++){
+                    let ef = formula.execFunctionGlobalData[r+"_"+c+"_"+sheetIndex];
+                    if(ef!=null){
+                        ret[r-row[0]][c-col[0]] = ef;
+                    }
+                }
+            }
+        }
+
         
         //范围的长宽
         let rowl = row[1] - row[0] + 1;
@@ -1887,7 +1907,7 @@ function luckysheet_offset_check() {
         return formula.error.r;
     }
 
-    return getRangetxt(Store.currentSheetIndex, {
+    return getRangetxt(Store.calculateSheetIndex, {
         row: [cellRow0, cellRow1],
         column: [cellCol0, cellCol1]
     });
diff --git a/src/function/functionImplementation.js b/src/function/functionImplementation.js
index 8fad899..f95904a 100644
--- a/src/function/functionImplementation.js
+++ b/src/function/functionImplementation.js
@@ -10299,11 +10299,13 @@ const functionImplementation = {
                 }
             }
 
-            let sheetdata = null;
-            sheetdata = Store.flowdata;
-            if (formula.execFunctionGroupData != null) {
-                sheetdata = formula.execFunctionGroupData;
-            }
+            let luckysheetfile = getluckysheetfile();
+            let index = getSheetIndex(Store.calculateSheetIndex);
+            let sheetdata = luckysheetfile[index].data;
+            // sheetdata = Store.flowdata;
+            // if (formula.execFunctionGroupData != null) {
+            //     sheetdata = formula.execFunctionGroupData;
+            // }
 
             //计算
             if(A1){
@@ -10319,6 +10321,13 @@ const functionImplementation = {
                         return 0;
                     }
 
+                    if (formula.execFunctionGlobalData != null) {
+                        let ef = formula.execFunctionGlobalData[row+"_"+col+"_"+Store.calculateSheetIndex];
+                        if(ef!=null){
+                            return ef.v;
+                        }
+                    }
+
                     return sheetdata[row][col].v;
                 }
                 else{
@@ -10338,6 +10347,13 @@ const functionImplementation = {
                         return 0;
                     }
 
+                    if (formula.execFunctionGlobalData != null) {
+                        let ef = formula.execFunctionGlobalData[row+"_"+col+"_"+Store.calculateSheetIndex];
+                        if(ef!=null){
+                            return ef.v;
+                        }
+                    }
+
                     return sheetdata[row][col].v;
                 }
                 else{
@@ -10617,11 +10633,15 @@ const functionImplementation = {
             var cellRow1 = cellRow0 + height - 1;
             var cellCol1 = cellCol0 + width - 1;
 
-            let sheetdata = null;
-            sheetdata = Store.flowdata;
-            if (formula.execFunctionGroupData != null) {
-                sheetdata = formula.execFunctionGroupData;
-            }
+            // let sheetdata = null;
+            // sheetdata = Store.flowdata;
+            // if (formula.execFunctionGroupData != null) {
+            //     sheetdata = formula.execFunctionGroupData;
+            // }
+
+            let luckysheetfile = getluckysheetfile();
+            let index = getSheetIndex(Store.calculateSheetIndex);
+            let sheetdata = luckysheetfile[index].data;
 
             if (cellRow0 < 0 || cellRow1 >= sheetdata.length || cellCol0 < 0 || cellCol1 >= sheetdata[0].length){
                 return formula.error.r;
@@ -10633,7 +10653,16 @@ const functionImplementation = {
                 var rowArr = [];
 
                 for(var c = cellCol0; c <= cellCol1; c++){
-                    if (sheetdata[r][c] != null && !isRealNull(sheetdata[r][c].v)){
+                    if(formula.execFunctionGlobalData != null && formula.execFunctionGlobalData[r+"_"+c+"_"+Store.calculateSheetIndex]!=null){
+                        let ef = formula.execFunctionGlobalData[r+"_"+c+"_"+Store.calculateSheetIndex];
+                        if(ef!=null){
+                            rowArr.push(ef.v);
+                        }
+                        else{
+                            rowArr.push(0);
+                        }
+                    }
+                    else if (sheetdata[r][c] != null && !isRealNull(sheetdata[r][c].v)){
                         rowArr.push(sheetdata[r][c].v);
                     }
                     else{
diff --git a/src/global/api.js b/src/global/api.js
index 81d1631..9f97138 100644
--- a/src/global/api.js
+++ b/src/global/api.js
@@ -1136,6 +1136,10 @@ export function getRangeHtml(options = {}) {
         }];
     }
 
+    if(getObjType(range) != 'array'){
+        return tooltip.info("The range parameter is invalid.", ""); 
+    }
+
     let file = Store.luckysheetfile[order];
 
     if(file == null){
@@ -3040,6 +3044,10 @@ export function setRangeConditionalFormatDefault(conditionName, conditionValue,
         cellrange = [cellrange];
     }
 
+    if(getObjType(cellrange) != 'array'){
+        return tooltip.info('The cellrange parameter is invalid.', '');
+    }
+
     let rule = {
         "type": "default",
         "cellrange": cellrange,
@@ -3309,6 +3317,10 @@ export function setRangeConditionalFormat(type, options = {}) {
         cellrange = [cellrange];
     }
 
+    if(getObjType(cellrange) != 'array'){
+        return tooltip.info('The cellrange parameter is invalid.', '');
+    }
+
     let rule = {
         "type": type, 
         "cellrange": cellrange, 
@@ -3342,14 +3354,247 @@ export function setRangeConditionalFormat(type, options = {}) {
 
 
 /**
- * 
- * @param {String} move 删除后,右侧还是下方的单元格移动
+ * 为指定下标的工作表,删除条件格式规则,返回被删除的条件格式规则 
+ * @param {Number} itemIndex 条件格式规则索引
  * @param {Object} options 可选参数
+ * @param {Number} options.order 工作表下标;默认值为当前工作表下标
+ * @param {Function} options.success 操作结束的回调函数
  */
-function deleteRange(move, options = {}) {
+export function deleteRangeConditionalFormat(itemIndex, options = {}) {
+    if(!isRealNum(itemIndex)){
+        return tooltip.info('The itemIndex parameter is invalid.', ''); 
+    }
+
+    itemIndex = Number(itemIndex);
+
+    let {
+        order = getSheetIndex(Store.currentSheetIndex),
+        success
+    } = {...options}
+
+    let file = Store.luckysheetfile[order];
+
+    if(file == null){
+        return tooltip.info('The order parameter is invalid.', ''); 
+    }
+
+    let cdformat = $.extend(true, [], file.luckysheet_conditionformat_save);
+
+    if(cdformat.length == 0){
+        return tooltip.info('This worksheet has no conditional format to delete', '');
+    }
+    else if(cdformat[itemIndex] == null){
+        return tooltip.info('The conditional format of the index cannot be found', '');
+    }
+
+    let cdformatItem = cdformat.splice(itemIndex, 1);
+
+    //保存之前的规则
+    let fileH = $.extend(true, [], Store.luckysheetfile);
+    let historyRules = conditionformat.getHistoryRules(fileH);
 
+    //保存当前的规则
+    file["luckysheet_conditionformat_save"] = cdformat;
+
+    let fileC = $.extend(true, [], Store.luckysheetfile);
+    let currentRules = conditionformat.getCurrentRules(fileC);
+
+    //刷新一次表格
+    conditionformat.ref(historyRules, currentRules);
+
+    //发送给后台
+    if(server.allowUpdate){
+        server.saveParam("all", file.index, ruleArr, { "k": "luckysheet_conditionformat_save" });
+    }
+
+    setTimeout(() => {
+        if (success && typeof success === 'function') {
+            success();
+        }
+    }, 1);
+
+    return cdformatItem;
 }
 
+
+/**
+ * 清除指定工作表指定单元格区域的内容,不同于删除选区的功能,不需要设定单元格移动情况 
+ * @param {Object} options 可选参数
+ * @param {Array | Object | String} options.range 要清除的选区范围
+ * @param {Number} options.order 工作表下标;默认值为当前工作表下标
+ * @param {Function} options.success 操作结束的回调函数
+ */
+export function clearRange(options = {}) {
+    let {
+        range = Store.luckysheet_select_save,
+        order = getSheetIndex(Store.currentSheetIndex),
+        success
+    } = {...options}
+
+    if(getObjType(range) == 'string'){
+        if(!formula.iscelldata(range)){
+            return tooltip.info("The range parameter is invalid.", "");
+        }
+
+        let cellrange = formula.getcellrange(range);
+        range = [{
+            "row": cellrange.row,
+            "column": cellrange.column
+        }]
+    }
+    else if(getObjType(range) == 'object'){
+        if(range.row == null || range.column == null){
+            return tooltip.info("The range parameter is invalid.", "");
+        }
+
+        range = [{
+            "row": range.row,
+            "column": range.column
+        }];
+    }
+
+    if(getObjType(range) != 'array'){
+        return tooltip.info("The range parameter is invalid.", ""); 
+    }
+
+    let file = Store.luckysheetfile[order];
+
+    if(file == null){
+        return tooltip.info("The order parameter is invalid.", "");
+    }
+
+    let cfg = $.extend(true, {}, file.config);
+    let has_PartMC = false;
+
+    for(let s = 0; s < range.length; s++){
+        let r1 = range[s].row[0],
+            r2 = range[s].row[1];
+        let c1 = range[s].column[0],
+            c2 = range[s].column[1];
+
+        has_PartMC = hasPartMC(cfg, r1, r2, c1, c2);
+
+        if(has_PartMC){
+            break;
+        }
+    }
+
+    if(has_PartMC){
+        return tooltip.info('Cannot perform this operation on partially merged cells', '');
+    }
+
+    let d = $.extend(true, [], file.data);
+
+    if(d.length == 0){
+        d = $.extend(true, [], sheetmanage.buildGridData(file));
+    }
+
+    for(let s = 0; s < range.length; s++){
+        let r1 = range[s].row[0],
+            r2 = range[s].row[1];
+        let c1 = range[s].column[0],
+            c2 = range[s].column[1];
+
+        for(let r = r1; r <= r2; r++){
+            for(let c = c1; c <= c2; c++){
+                let cell = d[r][c];
+
+                if(getObjType(cell) == "object"){
+                    delete cell["m"];
+                    delete cell["v"];
+
+                    if(cell["f"] != null){
+                        delete cell["f"];
+                        formula.delFunctionGroup(r, c, file.index);
+
+                        delete cell["spl"];
+                    }
+
+                    if(cell["ct"] != null && cell["ct"].t == 'inlineStr'){
+                        delete cell["ct"];
+                    }
+                }
+                else{
+                    d[r][c] = null;
+                }
+            }
+        }
+    }
+
+    if(file.index == Store.currentSheetIndex){
+        jfrefreshgrid(d, range);
+    }
+    else{
+        file.data = d;
+    }
+
+    if (success && typeof success === 'function') {
+        success();
+    }
+}
+
+
+/**
+ * 删除指定工作表指定单元格区域,返回删除掉的数据,同时,指定是右侧单元格左移还是下方单元格上移 
+ * @param {String} move 删除后,单元格左移/上移
+ * @param {Object} options 可选参数
+ * @param {Object | String} options.range 要删除的选区范围
+ * @param {Number} options.order 工作表下标;默认值为当前工作表下标
+ * @param {Function} options.success 操作结束的回调函数
+ */
+export function deleteRange(move, options = {}) {
+    let moveList = ['left', 'up'];
+
+    if(!moveList.includes(move)){
+        return tooltip.info("The move parameter is invalid.", ""); 
+    }
+
+    let {
+        range = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1],
+        order = getSheetIndex(Store.currentSheetIndex),
+        success
+    } = {...options} 
+
+    if(getObjType(range) == 'string'){
+        if(!formula.iscelldata(range)){
+            return tooltip.info("The range parameter is invalid.", "");
+        }
+
+        let cellrange = formula.getcellrange(range);
+        range = {
+            "row": cellrange.row,
+            "column": cellrange.column
+        };
+    }
+
+    if(getObjType(range) != 'object' || range.row == null || range.column == null){
+        return tooltip.info("The range parameter is invalid.", "");
+    }
+
+    let file = Store.luckysheetfile[order];
+
+    if(file == null){
+        return tooltip.info("The order parameter is invalid.", "");
+    }
+
+    let str = range.row[0],
+        edr = range.row[1],
+        stc = range.column[0],
+        edc = range.column[1];
+
+    if(move == 'left'){
+        luckysheetDeleteCell('moveLeft', str, edr, stc, edc, order);
+    }
+    else if(move == 'up'){
+        luckysheetDeleteCell('moveUp', str, edr, stc, edc, order);
+    }
+    
+    if (success && typeof success === 'function') {
+        success();
+    }
+}
+
+
 /**
  * 指定工作表指定单元格区域的数据进行矩阵操作,返回操作成功后的结果数据
  * @param {String} type 矩阵操作的类型
@@ -4033,6 +4278,93 @@ export function getSheet(options = {}){
 
 }
 
+/**
+ * 快捷返回指定工作表的数据
+ * @param {Object} options 可选参数
+ * @param {Number} options.order 工作表下标;默认值为当前工作表下标
+ */
+export function getSheetData(options = {}) {
+    let {
+        order = getSheetIndex(Store.currentSheetIndex)
+    } = {...options}; 
+
+    let file = Store.luckysheetfile[order];
+
+    if(file == null){
+        return tooltip.info("The order parameter is invalid.", ""); 
+    }
+
+    let data = $.extend(true, [], file.data);
+
+    if(data == null || data.length == 0){
+        data = $.extend(true, [], sheetmanage.buildGridData(file));
+    }
+
+    return data;
+}
+
+/**
+ * 快捷返回指定工作表的config配置 
+ * @param {Object} options 可选参数
+ * @param {Number} options.order 工作表下标;默认值为当前工作表下标
+ */
+export function getConfig(options = {}) {
+    let {
+        order = getSheetIndex(Store.currentSheetIndex)
+    } = {...options}; 
+
+    let file = Store.luckysheetfile[order];
+
+    if(file == null){
+        return tooltip.info("The order parameter is invalid.", ""); 
+    }
+
+    let config = $.extend(true, {}, file.config);
+
+    return config;
+}
+
+/**
+ * 快捷设置指定工作表config配置
+ * @param {Object} options 可选参数
+ * @param {Number} options.order 工作表下标;默认值为当前工作表下标
+ * @param {Function} options.success 操作结束的回调函数
+ */
+export function setConfig(cfg, options = {}) {
+    if(getObjType(cfg) != 'object'){
+        return tooltip.info("The cfg parameter is invalid.", "");
+    }
+
+    let {
+        order = getSheetIndex(Store.currentSheetIndex),
+        success
+    } = {...options}; 
+
+    let file = Store.luckysheetfile[order];
+
+    if(file == null){
+        return tooltip.info("The order parameter is invalid.", ""); 
+    }
+
+    file.config = cfg;
+
+    if(file.index == Store.currentSheetIndex){
+        Store.config = cfg;
+        
+        if("rowhidden" in cfg || "colhidden" in cfg || "rowlen" in cfg || "columnlen" in cfg){
+            jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);
+        }
+
+        setTimeout(function () {
+            luckysheetrefreshgrid();
+        }, 1);
+    }
+
+    if (success && typeof success === 'function') {
+        success();
+    }
+}
+
 /**
  * 返回所有表格数据结构的一维数组luckysheetfile
  */
diff --git a/src/global/cursorPos.js b/src/global/cursorPos.js
index 29fd6a7..74dad30 100644
--- a/src/global/cursorPos.js
+++ b/src/global/cursorPos.js
@@ -48,11 +48,18 @@ function getCursortPosition(textDom){
 }
 
 function hideMenuByCancel(event){
+
+    // Right-click the menu in the title bar, and click on the elements whose class is luckysheet-cols-rows-shift-left and luckysheet-cols-rows-shift-right will trigger the hiding of the menu bar. It should be prohibited. Exclude these two elements. There may be more Other elements will also jump here for more testing
+
+    if(event.target.classList.contains('luckysheet-cols-rows-shift-left') || event.target.classList.contains('luckysheet-cols-rows-shift-right')){
+        return;
+    }
+
     if (!$(event.target).hasClass("luckysheet-mousedown-cancel") && $(event.target).filter("[class*='sp-palette']").length == 0 && $(event.target).filter("[class*='sp-thumb']").length == 0 && $(event.target).filter("[class*='sp-']").length == 0) {
         $("#luckysheet-rightclick-menu").hide();
         $("#luckysheet-cols-h-hover").hide();
         $("#luckysheet-cols-menu-btn").hide();
-        $("#luckysheet-rightclick-menu").hide();
+        // $("#luckysheet-rightclick-menu").hide();
         $("#luckysheet-sheet-list, #luckysheet-rightclick-sheet-menu, #luckysheet-user-menu").hide();
         $("body > .luckysheet-filter-menu, body > .luckysheet-filter-submenu, body > .luckysheet-cols-menu").hide();
         //$("body > luckysheet-menuButton").hide();
diff --git a/src/global/extend.js b/src/global/extend.js
index 960ea37..70b8aea 100644
--- a/src/global/extend.js
+++ b/src/global/extend.js
@@ -1612,6 +1612,13 @@ function luckysheetDeleteCell(type, str, edr, stc, edc, order) {
             else if(str <= r && edr >= r + rs - 1 && edc < c){
                 merge_new[r + "_" + (c - clen)] = { "r": r, "c": c - clen, "rs": rs, "cs": cs };
             }
+            else{
+                for(let r_i = r; r_i <= r + rs - 1; r_i++){
+                    for(let c_i = c; c_i <= c + cs - 1; c_i++){
+                        delete d[r_i][c_i].mc;
+                    }
+                }
+            }
         }
         else if(type == "moveUp"){
             if(stc > c + cs - 1 || edc < c || str > r + rs - 1){
@@ -1620,6 +1627,13 @@ function luckysheetDeleteCell(type, str, edr, stc, edc, order) {
             else if(stc <= c && edc >= c + cs - 1 && edr < r){
                 merge_new[(r - rlen) + "_" + c] = { "r": r - rlen, "c": c, "rs": rs, "cs": cs };
             }
+            else{
+                for(let r_i = r; r_i <= r + rs - 1; r_i++){
+                    for(let c_i = c; c_i <= c + cs - 1; c_i++){
+                        delete d[r_i][c_i].mc;
+                    }
+                }
+            }
         }
     }
     cfg["merge"] = merge_new;
@@ -1905,19 +1919,9 @@ function luckysheetDeleteCell(type, str, edr, stc, edc, order) {
                     CFr2 = cf_range[j].row[1],
                     CFc1 = cf_range[j].column[0],
                     CFc2 = cf_range[j].column[1];
-
-                if(!(str > CFr2 || edr < CFr1) || !(stc > CFc2 || edc < CFc1)){
-                    let range = conditionformat.CFSplitRange(
-                        cf_range[j], 
-                        { "row": [str, edr], "column": [stc, edc] }, 
-                        { "row": [str, edr], "column": [stc, edc] }, 
-                        "restPart"
-                    );
-
-                    cf_new_range.concat(range);
-                }
-                else{
-                    cf_new_range.push(cf_range[j]);
+                
+                if(!(str <= CFr1 && edr >= CFr2 && stc <= CFc1 && edc >= CFc2)){
+                    cf_new_range = getMoveRange(type, str, edr, stc, edc, CFr1, CFr2, CFc1, CFc2, rlen, clen);
                 }
             }
 
@@ -1978,18 +1982,8 @@ function luckysheetDeleteCell(type, str, edr, stc, edc, order) {
                         bd_c1 = borderRange[j].column[0],
                         bd_c2 = borderRange[j].column[1];
 
-                    if(!(str > bd_r2 || edr < bd_r1) || !(stc > bd_c2 || edc < bd_c1)){
-                        let range = conditionformat.CFSplitRange(
-                            borderRange[j], 
-                            { "row": [str, edr], "column": [stc, edc] }, 
-                            { "row": [str, edr], "column": [stc, edc] }, 
-                            "restPart"
-                        );
-    
-                        emptyRange.concat(range);
-                    }
-                    else{
-                        emptyRange.push(borderRange[j]);
+                    if(!(str <= bd_r1 && edr >= bd_r2 && stc <= bd_c1 && edc >= bd_c2)){
+                        emptyRange = getMoveRange(type, str, edr, stc, edc, bd_r1, bd_r2, bd_c1, bd_c2, rlen, clen);
                     }
                 }
 
@@ -2095,6 +2089,315 @@ function luckysheetDeleteCell(type, str, edr, stc, edc, order) {
     }
 }
 
+function getMoveRange(type, str, edr, stc, edc, r1, r2, c1, c2, rlen, clen) {
+    let newRange = [];
+
+    if(type == "moveLeft"){
+        if(str > r2 || edr < r1 || stc > c2){
+            newRange.push({
+                "row": [r1, r2],
+                "column": [c1, c2]
+            });
+        }
+        else if(edc < c1){
+            if(str <= r1 && edr >= r2){
+                newRange.push({
+                    "row": [r1, r2],
+                    "column": [c1 - clen, c2 - clen]
+                });
+            }
+            else if(str > r1 && edr < r2){
+                let range= [
+                    { "row": [r1, str - 1], "column": [c1, c2] },
+                    { "row": [edr + 1, r2], "column": [c1, c2] },
+                    { "row": [str, edr], "column": [c1 - clen, c2 - clen] }
+                ];
+                newRange = newRange.concat(range);
+            }
+            else if(str > r1){
+                let range= [
+                    { "row": [r1, str - 1], "column": [c1, c2] },
+                    { "row": [str, r2], "column": [c1 - clen, c2 - clen] },
+                ];
+                newRange = newRange.concat(range);
+            }
+            else if(edr < r2){
+                let range= [
+                    { "row": [r1, edr], "column": [c1 - clen, c2 - clen] },
+                    { "row": [edr + 1, r2], "column": [c1, c2] },
+                ];
+                newRange = newRange.concat(range);
+            }
+        }
+        else if(edc >= c1){
+            if(stc <= c1 && edc >= c2){
+                if(str > r1 && edr < r2){
+                    let range= [
+                        { "row": [r1, str - 1], "column": [c1, c2] },
+                        { "row": [edr + 1, r2], "column": [c1, c2] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(str > r1){
+                    let range= [
+                        { "row": [r1, str - 1], "column": [c1, c2] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(edr < r2){
+                    let range= [
+                        { "row": [edr + 1, r2], "column": [c1, c2] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+            }
+            else if(stc > c1 && edc < c2){
+                if(str <= r1 && edr >= r2){
+                    newRange.push({
+                        "row": [r1, r2],
+                        "column": [c1, c2 - clen]
+                    });
+                }
+                else if(str > r1 && edr < r2){
+                    let range= [
+                        { "row": [r1, str - 1], "column": [c1, c2] },
+                        { "row": [edr + 1, r2], "column": [c1, c2] },
+                        { "row": [str, edr], "column": [c1, c2 - clen] }
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(str > r1){
+                    let range= [
+                        { "row": [r1, str - 1], "column": [c1, c2] },
+                        { "row": [str, r2], "column": [c1, c2 - clen] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(edr < r2){
+                    let range= [
+                        { "row": [r1, edr], "column": [c1, c2 - clen] },
+                        { "row": [edr + 1, r2], "column": [c1, c2] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+            }
+            else if(stc > c1){
+                if(str <= r1 && edr >= r2){
+                    newRange.push({
+                        "row": [r1, r2],
+                        "column": [c1, stc - 1]
+                    });
+                }
+                else if(str > r1 && edr < r2){
+                    let range= [
+                        { "row": [r1, str - 1], "column": [c1, c2] },
+                        { "row": [edr + 1, r2], "column": [c1, c2] },
+                        { "row": [str, edr], "column": [c1, stc - 1] }
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(str > r1){
+                    let range= [
+                        { "row": [r1, str - 1], "column": [c1, c2] },
+                        { "row": [str, r2], "column": [c1, stc - 1] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(edr < r2){
+                    let range= [
+                        { "row": [r1, edr], "column": [c1, stc - 1] },
+                        { "row": [edr + 1, r2], "column": [c1, c2] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+            }
+            else if(edc < c2){
+                if(str <= r1 && edr >= r2){
+                    newRange.push({
+                        "row": [r1, r2],
+                        "column": [c1 - clen, c2 - clen]
+                    });
+                }
+                else if(str > r1 && edr < r2){
+                    let range= [
+                        { "row": [r1, str - 1], "column": [c1, c2] },
+                        { "row": [edr + 1, r2], "column": [c1, c2] },
+                        { "row": [str, edr], "column": [c1 - clen, c2 - clen] }
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(str > r1){
+                    let range= [
+                        { "row": [r1, str - 1], "column": [c1, c2] },
+                        { "row": [str, r2], "column": [c1 - clen, c2 - clen] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(edr < r2){
+                    let range= [
+                        { "row": [r1, edr], "column": [c1 - clen, c2 - clen] },
+                        { "row": [edr + 1, r2], "column": [c1, c2] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+            }
+        }
+    }
+    else if(type == "moveUp"){
+        if(stc > c2 || edc < c1 || str > r2){
+            newRange.push({
+                "row": [r1, r2],
+                "column": [c1, c2]
+            });
+        }
+        else if(edr < r1){
+            if(stc <= c1 && edc >= c2){
+                newRange.push({
+                    "row": [r1 - rlen, r2 - rlen],
+                    "column": [c1, c2]
+                });
+            }
+            else if(stc > c1 && edc < c2){
+                let range= [
+                    { "row": [r1, r2], "column": [c1, stc - 1] },
+                    { "row": [r1, r2], "column": [edc + 1, c2] },
+                    { "row": [r1 - rlen, r2 - rlen], "column": [stc, edc] }
+                ];
+                newRange = newRange.concat(range);
+            }
+            else if(stc > c1){
+                let range= [
+                    { "row": [r1, r2], "column": [c1, stc - 1] },
+                    { "row": [r1 - rlen, r2 - rlen], "column": [stc, c2] },
+                ];
+                newRange = newRange.concat(range);
+            }
+            else if(edc < c2){
+                let range= [
+                    { "row": [r1 - rlen, r2 - rlen], "column": [c1, edc] },
+                    { "row": [r1, r2], "column": [edc + 1, c2] },
+                ];
+                newRange = newRange.concat(range);
+            }
+        }
+        else if(edr >= r1){
+            if(str <= r1 && edr >= r2){
+                if(stc > c1 && edc < c2){
+                    let range= [
+                        { "row": [r1, r2], "column": [c1, stc - 1] },
+                        { "row": [r1, r2], "column": [edc + 1, c2] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(stc > c1){
+                    let range= [
+                        { "row": [r1, r2], "column": [c1, stc - 1] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(edc < c2){
+                    let range= [
+                        { "row": [r1, r2], "column": [edc + 1, c2] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+            }
+            else if(str > r1 && edr < r2){
+                if(stc <= c1 && edc >= c2){
+                    newRange.push({
+                        "row": [r1, r2 - rlen],
+                        "column": [c1, c2]
+                    });
+                }
+                else if(stc > c1 && edc < c2){
+                    let range= [
+                        { "row": [r1, r2], "column": [c1, stc - 1] },
+                        { "row": [r1, r2], "column": [edc + 1, c2] },
+                        { "row": [r1, r2 - rlen], "column": [stc, edc] }
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(stc > c1){
+                    let range= [
+                        { "row": [r1, r2], "column": [c1, stc - 1] },
+                        { "row": [r1, r2 - rlen], "column": [stc, c2] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(edc < c2){
+                    let range= [
+                        { "row": [r1, r2 - rlen], "column": [c1, edc] },
+                        { "row": [r1, r2], "column": [edc + 1, c2] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+            }
+            else if(str > r1){
+                if(stc <= c1 && edc >= c2){
+                    newRange.push({
+                        "row": [r1, str - 1],
+                        "column": [c1, c2]
+                    });
+                }
+                else if(stc > c1 && edc < c2){
+                    let range= [
+                        { "row": [r1, r2], "column": [c1, stc - 1] },
+                        { "row": [r1, r2], "column": [edc + 1, c2] },
+                        { "row": [r1, str - 1], "column": [stc, edc] }
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(stc > c1){
+                    let range= [
+                        { "row": [r1, r2], "column": [c1, stc - 1] },
+                        { "row": [r1, str - 1], "column": [stc, c2] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(edc < c2){
+                    let range= [
+                        { "row": [r1, str - 1], "column": [c1, edc] },
+                        { "row": [r1, r2], "column": [edc + 1, c2] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+            }
+            else if(edr < r2){
+                if(stc <= c1 && edc >= c2){
+                    newRange.push({
+                        "row": [r1 - rlen, r2 - rlen],
+                        "column": [c1, c2]
+                    });
+                }
+                else if(stc > c1 && edc < c2){
+                    let range= [
+                        { "row": [r1, r2], "column": [c1, stc - 1] },
+                        { "row": [r1, r2], "column": [edc + 1, c2] },
+                        { "row": [r1 - rlen, r2 - rlen], "column": [stc, edc] }
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(stc > c1){
+                    let range= [
+                        { "row": [r1, r2], "column": [c1, stc - 1] },
+                        { "row": [r1 - rlen, r2 - rlen], "column": [stc, c2] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+                else if(edc < c2){
+                    let range= [
+                        { "row": [r1 - rlen, r2 - rlen], "column": [c1, edc] },
+                        { "row": [r1, r2], "column": [edc + 1, c2] },
+                    ];
+                    newRange = newRange.concat(range);
+                }
+            }
+        }
+    }
+
+    return newRange;
+}
+
 export {
     luckysheetextendtable,
     luckysheetextendData,
diff --git a/src/global/formula.js b/src/global/formula.js
index b8fe635..18898f9 100644
--- a/src/global/formula.js
+++ b/src/global/formula.js
@@ -11,7 +11,7 @@ import { seletedHighlistByindex, luckysheet_count_show } from '../controllers/se
 import { isRealNum, isRealNull, valueIsError, isEditMode } from './validate';
 import { isdatetime, isdatatype } from './datecontroll';
 import { getCellTextSplitArr,getCellTextInfo } from '../global/getRowlen';
-import { getcellvalue,getcellFormula,getInlineStringNoStyle } from './getdata';
+import { getcellvalue,getcellFormula,getInlineStringNoStyle, getOrigincell } from './getdata';
 import { setcellvalue } from './setdata';
 import { genarate, valueShowEs } from './format';
 import editor from './editor';
@@ -677,6 +677,14 @@ const luckysheetformula = {
         return num;
     },
     getcellrange: function(txt) {
+        if(txt==null || txt.length==0){
+            return;
+        }
+
+        if(txt in this.addToCellIndexList){
+           return this.addToCellIndexList[txt];
+        }
+
         let val = txt.split("!");
 
         let sheettxt = "",
@@ -711,11 +719,13 @@ const luckysheetformula = {
             let col = ABCatNum(rangetxt.replace(/[^A-Za-z]/g, ""));
 
             if (!isNaN(row) && !isNaN(col)) {
-                return {
+                let item = {
                     "row": [row, row],
                     "column": [col, col],
                     "sheetIndex": sheetIndex
                 };
+                this.addToCellIndexList(txt,item);
+                return item;
             }
             else {
                 return null;
@@ -747,11 +757,13 @@ const luckysheetformula = {
                 return null;
             }
 
-            return {
+            let item = {
                 "row": row,
                 "column": col,
                 "sheetIndex": sheetIndex
             };
+            this.addToCellIndexList(txt,item);
+            return item;
         }
     },
     rangeHightlightHTML: '',
@@ -1289,9 +1301,10 @@ const luckysheetformula = {
             if(!isCurInline){
 
                 if(getObjType(value) == "string" && value.slice(0, 1) == "=" && value.length > 1){
-                    let v = _this.execfunction(value, r, c, true);
+                    let v = _this.execfunction(value, r, c, undefined, true);
                     isRunExecFunction = false;
-                    curv = _this.execFunctionGroupData[r][c];
+                    // curv = _this.execFunctionGroupData[r][c];
+                    curv.v = _this.execFunctionGlobalData[r+"_"+c+"_"+Store.currentSheetIndex].v;
                     curv.f = v[2];
 
                     //打进单元格的sparklines的配置串, 报错需要单独处理。
@@ -1317,11 +1330,12 @@ const luckysheetformula = {
                     let valueFunction = value.f;
 
                     if(getObjType(valueFunction) == "string" && valueFunction.slice(0, 1) == "=" && valueFunction.length > 1){
-                        let v = _this.execfunction(valueFunction, r, c, true);
+                        let v = _this.execfunction(valueFunction, r, c, undefined, true);
                         isRunExecFunction = false;
                         // get v/m/ct
 
-                        curv = _this.execFunctionGroupData[r][c];
+                        // curv = _this.execFunctionGroupData[r][c];
+                        curv.v = _this.execFunctionGlobalData[r+"_"+c+"_"+Store.currentSheetIndex].v;
                         curv.f = v[2];
         
                         //打进单元格的sparklines的配置串, 报错需要单独处理。
@@ -1347,10 +1361,11 @@ const luckysheetformula = {
                         let valueFunction = value.f;
         
                         if(getObjType(valueFunction) == "string" && valueFunction.slice(0, 1) == "=" && valueFunction.length > 1){
-                            let v = _this.execfunction(valueFunction, r, c, true);
+                            let v = _this.execfunction(valueFunction, r, c, undefined, true);
                             isRunExecFunction = false;
                             // get v/m/ct
-                            curv = _this.execFunctionGroupData[r][c];
+                            // curv = _this.execFunctionGroupData[r][c];
+                            curv.v = _this.execFunctionGlobalData[r+"_"+c+"_"+Store.currentSheetIndex].v;
         
                             // get f
                             curv.f = v[2];
@@ -1384,7 +1399,9 @@ const luckysheetformula = {
                     _this.delFunctionGroup(r, c);
                     _this.execFunctionGroup(r, c, value);
                     isRunExecFunction = false;
-                    curv = _this.execFunctionGroupData[r][c];
+                    // curv = _this.execFunctionGroupData[r][c];
+
+                    curv.v = _this.execFunctionGlobalData[r+"_"+c+"_"+Store.currentSheetIndex].v;
     
                     delete curv.f;
                     delete curv.spl;
@@ -1402,7 +1419,7 @@ const luckysheetformula = {
         } 
         else {
             if(getObjType(value) == "string" && value.slice(0, 1) == "=" && value.length > 1){
-                let v = _this.execfunction(value, r, c, true);
+                let v = _this.execfunction(value, r, c, undefined, true);
                 isRunExecFunction = false;
                 value = {
                     "v": v[1],
@@ -1429,7 +1446,7 @@ const luckysheetformula = {
                 let valueFunction = value.f;
 
                 if(getObjType(valueFunction) == "string" && valueFunction.slice(0, 1) == "=" && valueFunction.length > 1){
-                    let v = _this.execfunction(valueFunction, r, c, true);
+                    let v = _this.execfunction(valueFunction, r, c, undefined, true);
                     isRunExecFunction = false;
                     // value = {
                     //     "v": v[1],
@@ -1555,7 +1572,7 @@ const luckysheetformula = {
         jfrefreshgrid(d, [{ "row": [r, r], "column": [c, c] }], allParam, isRunExecFunction);
 
         // Store.luckysheetCellUpdate.length = 0; //clear array
-        _this.execFunctionGroupData = null; //销毁
+        _this.execFunctionGlobalData = null; //销毁
     },
     cancelNormalSelected: function() {
         let _this = this;
@@ -2514,7 +2531,7 @@ const luckysheetformula = {
                 
                 if(isVal){
                     //公式计算
-                    let fp = $.trim(_this.functionParser($("#luckysheet-rich-text-editor").text()));
+                    let fp = $.trim(_this.functionParserExe($("#luckysheet-rich-text-editor").text()));
                     let result = eval(fp);
                     $("#luckysheet-search-formula-parm .result span").text(result);
                 }
@@ -3239,7 +3256,7 @@ const luckysheetformula = {
             let value = $editer.text(),
                 valuetxt = value;
 
-            if (value.length > 0 && value1txt.substr(0, 1) == "=" && (kcode != 229 || value.length == 1)) {
+            if (value.length > 0 && value.substr(0, 1) == "=" && (kcode != 229 || value.length == 1)) {
                 value = _this.functionHTMLGenerate(value);
                 value1 = _this.functionHTMLGenerate(value1txt);
 
@@ -3630,138 +3647,6 @@ const luckysheetformula = {
 
         return {"fn": fn, "param": param};
     },
-    functionParser1: function(txt) {
-        let _this = this;
-
-        if (_this.operatorjson == null) {
-            let arr = _this.operator.split("|"),
-                op = {};
-
-            for (let i = 0; i < arr.length; i++) {
-                op[arr[i].toString()] = 1;
-            }
-
-            _this.operatorjson = op;
-        }
-
-        if (txt.substr(0, 1) == "=") {
-            txt = txt.substr(1);
-        }
-
-        let funcstack = txt.split("");
-        let i = 0,
-            str = "",
-            function_str = "",
-            ispassby = true;
-        let matchConfig = {
-            "bracket": 0,
-            "comma": 0,
-            "squote": 0,
-            "dquote": 0,
-            "compare":0
-        }
-
-        while (i < funcstack.length) {
-            let s = funcstack[i];
-
-            if (s == "(" && matchConfig.dquote == 0) {
-                matchConfig.bracket += 1;
-                
-                if (str.length > 0) {
-                    function_str += "luckysheet_function." + str.toUpperCase() + ".f(";
-                } 
-                else {
-                    function_str += "(";
-                }
-
-                str = "";
-            } 
-            else if (s == ")" && matchConfig.dquote == 0) {
-                matchConfig.bracket -= 1;
-                function_str += _this.functionParser(str);
-                
-                if(matchConfig.compare == 1){
-                    function_str += '))';
-                    matchConfig.compare = 0;
-                }
-                else{
-                    function_str += ')';
-                }
-
-                str = "";
-            }
-            else if (s == '"' && matchConfig.squote == 0) {
-                if (matchConfig.dquote > 0) {
-                    function_str += str + '"';
-                    matchConfig.dquote -= 1;
-                    str = "";
-                } 
-                else {
-                    matchConfig.dquote += 1;
-                    str += '"';
-                }
-            } 
-            else if (s == ',' && matchConfig.dquote == 0) {
-                //matchConfig.comma += 1;
-                function_str += _this.functionParser(str);
-                
-                if(matchConfig.compare == 1){
-                    function_str += '),';
-                    matchConfig.compare = 0;
-                }
-                else{
-                    function_str += ',';
-                }
-
-                str = "";
-            } 
-            else if (s in _this.operatorjson && matchConfig.dquote == 0) {
-                let s_next = "";
-                if ((i + 1) < funcstack.length) {
-                    s_next = funcstack[i + 1];
-                }
-
-                if ((s + s_next) in _this.operatorjson) {
-                    if (str.length > 0) {
-                        matchConfig.compare = 1;
-                        function_str += "luckysheet_compareWith(" + _this.functionParser(str) + ",'" + s + s_next + "', ";
-                        str = "";
-                    } 
-                    else {
-                        function_str += s + s_next;
-                    }
-
-                    i++;
-                } 
-                else {
-                    if (str.length > 0) {
-                        matchConfig.compare = 1;
-                        function_str += "luckysheet_compareWith(" + _this.functionParser(str) + ",'" + s + "', ";
-                        str = "";
-                    } 
-                    else {
-                        function_str += s;
-                    }
-                }
-            } 
-            else {
-                str += s;
-            }
-
-            if (i == funcstack.length - 1) {
-                if (_this.iscelldata($.trim(str))) {
-                    function_str += "luckysheet_getcelldata('" + $.trim(str) + "')";
-                } 
-                else {
-                    function_str += $.trim(str);
-                }
-            }
-
-            i++;
-        }
-
-        return function_str;
-    },
     calPostfixExpression: function(cal){
         if(cal.length == 0){
             return "";
@@ -3841,6 +3726,13 @@ const luckysheetformula = {
         "+": 2,
         "-": 2
     },
+    functionParserExe:function(txt){
+        let _this = this;
+        // let txt1 = txt.toUpperCase();
+        return this.functionParser(txt, function(c){
+            _this.addToCellList(txt, c);
+        });
+    },
     functionParser: function(txt, cellRangeFunction) {
         let _this = this;
 
@@ -4117,6 +4009,21 @@ const luckysheetformula = {
         });
         setluckysheetfile(luckysheetfile);
     },
+    getAllFunctionGroup: function() {
+        let luckysheetfile = getluckysheetfile();
+        let ret = [];
+        for(let i=0;i 0) {
-                        function_str += _this.isFunctionRangeSimple(str, r, c,dynamicArray_compute) + s + s_next;
+                        function_str += _this.isFunctionRangeSimple(str, r, c, index,dynamicArray_compute) + s + s_next;
                         str = "";
                     } 
                     else {
@@ -4279,7 +4186,7 @@ const luckysheetformula = {
                 } 
                 else {
                     if (str.length > 0) {
-                        function_str += _this.isFunctionRangeSimple(str, r, c,dynamicArray_compute) + s;
+                        function_str += _this.isFunctionRangeSimple(str, r, c, index,dynamicArray_compute) + s;
                         str = "";
                     } 
                     else {
@@ -4293,7 +4200,7 @@ const luckysheetformula = {
 
             if (i == funcstack.length - 1) {
                 if (_this.iscelldata($.trim(str))) {
-                    _this.isFunctionRangeSaveChange(str, r, c, dynamicArray_compute);
+                    _this.isFunctionRangeSaveChange(str, r, c, index, dynamicArray_compute);
                     // if (r != null && c != null) {
                         
                     //     let range = _this.getcellrange($.trim(str));
@@ -4348,19 +4255,61 @@ const luckysheetformula = {
         //console.log(function_str);
         return function_str;
     },
-    isFunctionRangeSelect:function(txt, r, c, dynamicArray_compute){
+    isFunctionRangeSelect:function(txt, r, c, index, dynamicArray_compute){
         if(txt==null || txt==""){
             return;
         }
+
+        if(index==null){
+            index = Store.currentSheetIndex;
+        }
+        if(dynamicArray_compute==null){
+            dynamicArray_compute = {};
+        }
+        let _this = this;
         let txt1 = txt.toUpperCase();
-        if(txt1.indexOf("INDIRECT")>-1 || txt1.indexOf("OFFSET")>-1){
-            this.isFunctionRange(txt, r, c, dynamicArray_compute);
+        let isOffsetFunc = txt1.indexOf("INDIRECT")>-1 || txt1.indexOf("OFFSET")>-1;
+        if(txt in this.formulaContainCellList){
+            let cellList = this.formulaContainCellList[txt];
+            if(isOffsetFunc){
+                let isoff = cellList["__LuckyisOff__"];
+                if(isoff==true){
+                    for(let cellStr in cellList){
+                        if(cellStr=="__LuckyisOff__"){
+                            continue;
+                        }
+                        this.isFunctionRangeSaveChange(cellStr, r, c, index, dynamicArray_compute);
+                    }
+                }
+                else{
+                    this.isFunctionRange(txt, r, c, index,dynamicArray_compute, function(str){
+                        _this.addToCellList(txt, str);
+                    });
+                    cellList["__LuckyisOff__"] = true;
+                }
+            }
+            else{
+                
+                for(let cellStr in cellList){
+                    if(cellStr=="__LuckyisOff__"){
+                        continue;
+                    }
+                    this.isFunctionRangeSaveChange(cellStr, r, c, index, dynamicArray_compute);
+                }
+            }
+            
+            return;
+        }
+
+
+        if(isOffsetFunc){
+            this.isFunctionRange(txt, r, c, index,dynamicArray_compute);
         }
         else{
-            this.isFunctionRangeSimple(txt, r, c, dynamicArray_compute);
+            this.isFunctionRangeSimple(txt, r, c, index,dynamicArray_compute);
         }
     },
-    isFunctionRange: function (txt, r, c, dynamicArray_compute) {
+    isFunctionRange: function (txt, r, c, index,dynamicArray_compute, cellRangeFunction) {
         let _this = this;
 
         if (_this.operatorjson == null) {
@@ -4422,7 +4371,7 @@ const luckysheetformula = {
                 let bt = bracket.pop();
 
                 if (bracket.length == 0) {
-                    function_str += _this.isFunctionRange(str,r,c,dynamicArray_compute) + ")";
+                    function_str += _this.isFunctionRange(str,r,c, index,dynamicArray_compute,cellRangeFunction) + ")";
                     str = "";
                 }
                 else {
@@ -4449,7 +4398,7 @@ const luckysheetformula = {
             }
             else if (s == ',' && matchConfig.dquote == 0 && matchConfig.braces == 0) {
                 if (bracket.length <= 1) {
-                    function_str += _this.isFunctionRange(str, r, c,dynamicArray_compute) + ",";
+                    function_str += _this.isFunctionRange(str, r, c, index,dynamicArray_compute,cellRangeFunction) + ",";
                     str = "";
                 }
                 else {
@@ -4467,7 +4416,7 @@ const luckysheetformula = {
                 if ((s + s_next) in _this.operatorjson) {
                     if (bracket.length == 0) {
                         if ($.trim(str).length > 0) {
-                            cal2.unshift(_this.isFunctionRange($.trim(str), r, c,dynamicArray_compute));
+                            cal2.unshift(_this.isFunctionRange($.trim(str), r, c, index,dynamicArray_compute,cellRangeFunction));
                         }
                         else if ($.trim(function_str).length > 0) {
                             cal2.unshift($.trim(function_str));
@@ -4496,7 +4445,7 @@ const luckysheetformula = {
                 else {
                     if (bracket.length == 0) {
                         if ($.trim(str).length > 0) {
-                            cal2.unshift(_this.isFunctionRange($.trim(str), r, c,dynamicArray_compute));
+                            cal2.unshift(_this.isFunctionRange($.trim(str), r, c, index,dynamicArray_compute,cellRangeFunction));
                         }
                         else if ($.trim(function_str).length > 0) {
                             cal2.unshift($.trim(function_str));
@@ -4542,7 +4491,7 @@ const luckysheetformula = {
                 if (_this.iscelldata($.trim(str))) {
                     endstr = "luckysheet_getcelldata('" + $.trim(str) + "')";
 
-                    _this.isFunctionRangeSaveChange(str, r, c, dynamicArray_compute);
+                    _this.isFunctionRangeSaveChange(str, r, c, index, dynamicArray_compute);
                 }
                 else {
                     str = $.trim(str);
@@ -4593,19 +4542,19 @@ const luckysheetformula = {
 
             i++;
         }
-        //console.log(function_str);
-        _this.checkSpecialFunctionRange(function_str, r, c, dynamicArray_compute);
+        // console.log(function_str);
+        _this.checkSpecialFunctionRange(function_str, r, c, index, dynamicArray_compute,cellRangeFunction);
         return function_str;
     },
-    isFunctionRangeSaveChange: function (str, r, c, dynamicArray_compute) {
+    isFunctionRangeSaveChange: function (str, r, c, index, dynamicArray_compute) {
         let _this = this;
         if (r != null && c != null) {
             let range = _this.getcellrange($.trim(str));
             let row = range.row,
                 col = range.column,
-                index = range.sheetIndex;
+                sheetIndex = range.sheetIndex;
 
-            if ((r + "_" + c) in dynamicArray_compute && (Store.currentSheetIndex==index || index==null)) {
+            if ((r + "_" + c) in dynamicArray_compute && (index==sheetIndex || index==null)) {
                 let isd_range = false;
 
                 for (let d_r = row[0]; d_r <= row[1]; d_r++) {
@@ -4624,26 +4573,28 @@ const luckysheetformula = {
                 }
             }
             else {
-                if (r >= row[0] && r <= row[1] && c >= col[0] && c <= col[1] && (Store.currentSheetIndex==index || index==null)) {
+                if (r >= row[0] && r <= row[1] && c >= col[0] && c <= col[1] && (index==sheetIndex || index==null)) {
                     _this.isFunctionRangeSave = _this.isFunctionRangeSave || true;
                 }
                 else {
                     _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;
                 }
             }
+
         }
         else {
-            let sheetlen = $.trim(str).split("!");
+            _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;
+            // let sheetlen = $.trim(str).split("!");
 
-            if (sheetlen.length > 1) {
-                _this.isFunctionRangeSave = _this.isFunctionRangeSave || true;//if change sheet, it must be true, but this is very slow
-            }
-            else {
-                _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;
-            }
+            // if (sheetlen.length > 1) {
+            //     _this.isFunctionRangeSave = _this.isFunctionRangeSave || true;//if change sheet, it must be true, but this is very slow
+            // }
+            // else {
+            //     _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;
+            // }
         }
     },
-    checkSpecialFunctionRange: function (function_str, r, c, dynamicArray_compute) {
+    checkSpecialFunctionRange: function (function_str, r, c, index, dynamicArray_compute,cellRangeFunction) {
         if (function_str.substr(0, 20) == "luckysheet_function.") {
             let funcName = function_str.split(".")[1];
             if (funcName != null) {
@@ -4652,15 +4603,22 @@ const luckysheetformula = {
                     let tempFunc = "luckysheet_indirect_check" + function_str.substr(30, function_str.length);
 
                     //tempFunc = tempFunc.replace(/luckysheet_getcelldata/g, "luckysheet_indirect_check_return");
-
+                    
                     try {
+                        Store.calculateSheetIndex = index;
                         let str = eval(tempFunc);
+                        
                         if(str instanceof Object && str.data!=null){
                             str = str.data.v;
                         }
-                        if (this.iscelldata($.trim(str))) {
-                            this.isFunctionRangeSaveChange(str, r, c, dynamicArray_compute);
-                            //console.log(function_str, str, this.isFunctionRangeSave,r,c);
+                        let str_nb = $.trim(str);
+                        // console.log(function_str, tempFunc,str, this.iscelldata(str_nb),this.isFunctionRangeSave,r,c);
+                        if (this.iscelldata(str_nb)) {
+                            if(typeof(cellRangeFunction)=="function"){
+                                cellRangeFunction(str_nb);
+                            }
+                            this.isFunctionRangeSaveChange(str, r, c, index, dynamicArray_compute);
+                            console.log(function_str, str, this.isFunctionRangeSave,r,c);
                         }
                     }
                     catch{
@@ -4673,9 +4631,17 @@ const luckysheetformula = {
                     let tempFunc = "luckysheet_offset_check" + function_str.substr(28, function_str.length);
 
                     try {
+                        Store.calculateSheetIndex = index;
                         let str = eval(tempFunc);
-                        if (this.iscelldata($.trim(str))) {
-                            this.isFunctionRangeSaveChange(str, r, c, dynamicArray_compute);
+                        if(str instanceof Object && str.data!=null){
+                            str = str.data.v;
+                        }
+                        let str_nb = $.trim(str);
+                        if (this.iscelldata(str_nb)) {
+                            if(typeof(cellRangeFunction)=="function"){
+                                cellRangeFunction(str_nb);
+                            }
+                            this.isFunctionRangeSaveChange(str, r, c, index,dynamicArray_compute);
                             //console.log(function_str, str, this.isFunctionRangeSave,r,c);
                         }
                     }
@@ -4693,6 +4659,34 @@ const luckysheetformula = {
     execvertex: {},
     execFunctionGroupData: null,
     execFunctionExist: null,
+    formulaContainCellList:{},
+    cellTextToIndexList:{},
+    addToCellList:function(formulaTxt, cellstring){
+        if(formulaTxt==null || formulaTxt.length==0|| cellstring==null || cellstring.length==0){
+            return;
+        }
+        if(this.formulaContainCellList==null){
+            this.formulaContainCellList = {};
+        }
+
+        // formulaTxt = formulaTxt.toUpperCase();
+        if(this.formulaContainCellList[formulaTxt]==null){
+            this.formulaContainCellList[formulaTxt] = {};
+        }
+
+        this.formulaContainCellList[formulaTxt][cellstring] = 1;
+    },
+    addToCellIndexList:function(txt, infoObj){
+        if(txt==null || txt.length==0|| infoObj==null){
+            return;
+        }
+        if(this.cellTextToIndexList==null){
+            this.cellTextToIndexList = {};
+        }
+
+        this.cellTextToIndexList[txt] = infoObj;
+    },
+    execFunctionGlobalData:{},
     execFunctionGroupForce:function(isForce){
         if(isForce){
             this.execFunctionGroup(undefined, undefined, undefined, undefined, undefined,true);
@@ -4721,21 +4715,29 @@ const luckysheetformula = {
             window.luckysheet_calcADPMM = luckysheet_calcADPMM;
         }
 
-        _this.execFunctionGroupData = $.extend(true, [], data);
+        if(_this.execFunctionGlobalData==null){
+            _this.execFunctionGlobalData = {};
+        }
         let luckysheetfile = getluckysheetfile();
         let dynamicArray_compute = luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dynamicArray_compute"] == null ? {} : luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dynamicArray_compute"];
         
+        if (index == null) {
+            index = Store.currentSheetIndex;
+        }
+
         if (value != null) {
             //此处setcellvalue 中this.execFunctionGroupData会保存想要更新的值,本函数结尾不要设为null,以备后续函数使用
-            setcellvalue(origin_r, origin_c, _this.execFunctionGroupData, value);
+            // setcellvalue(origin_r, origin_c, _this.execFunctionGroupData, value);
+            let cellCache = [[{v:null}]];
+            setcellvalue(0, 0, cellCache, value);
+            _this.execFunctionGlobalData[origin_r+"_"+origin_c+"_"+index] = cellCache[0][0];
+            
         }
 
-        if (index == null) {
-            index = Store.currentSheetIndex;
-        }
+
 
         //{ "r": r, "c": c, "index": index, "func": func}
-        let group = _this.getFunctionGroup(index),
+        let group = _this.getAllFunctionGroup(),
             vertex1 = {},
             stack = [],
             count = 0;
@@ -4749,7 +4751,7 @@ const luckysheetformula = {
                     continue;
                 }
                 let cell = file.data[item.r][item.c];
-                let calc_funcStr = getcellFormula(item.r, item.c, item.index, _this.execFunctionGroupData);
+                let calc_funcStr = getcellFormula(item.r, item.c, item.index);
                 if(cell != null && cell.f != null && cell.f == calc_funcStr){
                     if(!(item instanceof Object)){
                         item = eval('('+ item +')');
@@ -4760,22 +4762,22 @@ const luckysheetformula = {
                     item.chidren = {};
                     item.times = 0;
 
-                    vertex1["r" + item.r.toString() + "c" + item.c.toString()] = item;
+                    vertex1["r" + item.r + "c" + item.c + "i" + item.index] = item;
                     _this.isFunctionRangeSave = false;
 
                     if(isForce){
                         _this.isFunctionRangeSave = true;
                     }
                     else if (origin_r != null && origin_c != null) {
-                        _this.isFunctionRangeSelect(calc_funcStr, origin_r, origin_c, dynamicArray_compute);
+                        _this.isFunctionRangeSelect(calc_funcStr, origin_r, origin_c, index, dynamicArray_compute);
                     } 
-                    else {
-                        _this.isFunctionRangeSelect(calc_funcStr, undefined, undefined ,dynamicArray_compute);
-                    }
+                    // else {
+                    //     _this.isFunctionRangeSelect(calc_funcStr, undefined, undefined ,dynamicArray_compute);
+                    // }
 
                     if (_this.isFunctionRangeSave) {
                         stack.push(item);
-                        _this.execvertex["r" + item.r.toString() + "c" + item.c.toString()] = item;
+                        _this.execvertex["r" + item.r + "c" + item.c + "i" + item.index] = item;
                         count++;
                     }
                 }
@@ -4785,63 +4787,70 @@ const luckysheetformula = {
             for (let x = 0; x < _this.execFunctionExist.length; x++) {
                 let cell = _this.execFunctionExist[x];
 
-                if ("r" + cell.r.toString() + "c" + cell.c.toString() in vertex1) {
+                if ("r" + cell.r + "c" + cell.c + "i" + cell.i in vertex1) {
                     continue;
                 }
 
                 for (let i = 0; i < group.length; i++) {
                     let item = group[i];
-                    let calc_funcStr =  getcellFormula(item.r, item.c, item.index, _this.execFunctionGroupData);
+                    let calc_funcStr =  getcellFormula(item.r, item.c, item.index);
                     item.color = "w";
                     item.parent = null;
                     item.chidren = {};
                     item.times = 0;
 
-                    vertex1["r" + item.r.toString() + "c" + item.c.toString()] = item;
+                    vertex1["r" + item.r + "c" + item.c + "i"+ item.index] = item;
                     _this.isFunctionRangeSave = false;
                     if(isForce){
                         _this.isFunctionRangeSave = true;
                     }
                     else{
-                        _this.isFunctionRangeSelect(calc_funcStr, cell.r, cell.c, dynamicArray_compute);
+                        _this.isFunctionRangeSelect(calc_funcStr, cell.r, cell.c, cell.i, dynamicArray_compute);
                     }
                     
                     if (_this.isFunctionRangeSave) {
                         stack.push(item);
-                        _this.execvertex["r" + item.r.toString() + "c" + item.c.toString()] = item;
+                        _this.execvertex["r" + item.r + "c" + item.c + "i" + item.index] = item;
                         count++;
                     }
                 }
             }
         }
 
+        // console.time("1");
+        let iii =0;
         while (stack.length > 0) {
             let u = stack.shift();
 
             for (let name in vertex1) {
-                if (u.r == vertex1[name].r && u.c == vertex1[name].c) {
+                let item = vertex1[name];
+                if(item==null){
+                    continue;
+                }
+                if (u.r == item.r && u.c == item.c && u.index == item.index) {
                     continue;
                 }
 
                 _this.isFunctionRangeSave = false;
-                let item = vertex1[name];
-                let calc_funcStr =  getcellFormula(item.r, item.c, item.index, _this.execFunctionGroupData);
-                _this.isFunctionRangeSelect(calc_funcStr, u.r, u.c, dynamicArray_compute);
+                
+                let calc_funcStr =  getcellFormula(item.r, item.c, item.index);
+                _this.isFunctionRangeSelect(calc_funcStr, u.r, u.c, u.index, dynamicArray_compute);
 
                 if (_this.isFunctionRangeSave) {
-                    let v = vertex1[name];
-
                     if (!(name in _this.execvertex)) {
-                        stack.push(v);
-                        _this.execvertex[name] = v;
+                        stack.push(item);
+                        _this.execvertex[name] = item;
                     }
 
                     count++;
-                    _this.execvertex[name].chidren["r" + u.r.toString() + "c" + u.c.toString()] = 1;
+                    _this.execvertex[name].chidren["r" + u.r + "c" + u.c + "i" + u.index] = 1;
                 }
+                // console.log(iii++);
             }
         }
+        // console.timeEnd("1");
 
+        // console.time("2");
         _this.groupValuesRefreshData = [];
         let i = 0;
 
@@ -4857,7 +4866,8 @@ const luckysheetformula = {
                 }
             }
         }
-        
+        // console.timeEnd("2");
+        // console.log(this.formulaContainCellList);
         _this.execFunctionExist = null;
     },
     //深度优先算法,处理多级调用函数
@@ -4868,58 +4878,72 @@ const luckysheetformula = {
         for (let chd in u.chidren) {
             let v = _this.execvertex[chd];
             if (v.color == "w") {
-                v.parent = "r" + u.r.toString() + "c" + u.c.toString();
+                v.parent = "r" + u.r.toString() + "c" + u.c.toString() + "i" + u.index;
                 _this.functionDFS(v);
             }
         }
 
         u.color = "b";
         window.luckysheet_getcelldata_cache = null;
-        let calc_funcStr =  getcellFormula(u.r, u.c, u.index, _this.execFunctionGroupData);
+        let calc_funcStr =  getcellFormula(u.r, u.c, u.index);
 
-        let v = _this.execfunction(calc_funcStr, u.r, u.c);
+        let v = _this.execfunction(calc_funcStr, u.r, u.c, u.index);
 
-        let value = _this.execFunctionGroupData[u.r][u.c];
-        if(value == null){
-            value = {};
-        }
+        // let value = _this.execFunctionGroupData[u.r][u.c];
+        // if(value == null){
+        //     value = {};
+        // }
 
-        value.v = v[1];
-        value.f = v[2];
+        // value.v = v[1];
+        // value.f = v[2];
 
-        if(value.spl != null){
+        let cell = getOrigincell(u.r,u.c,u.index);
+
+        let spl;
+        if(cell.spl != null){
             window.luckysheetCurrentRow = u.r;
             window.luckysheetCurrentColumn = u.c;
-            window.luckysheetCurrentFunction = _this.execFunctionGroupData[u.r][u.c].f;
+            window.luckysheetCurrentIndex = u.index;
+            window.luckysheetCurrentFunction = calc_funcStr;
 
-            let fp = $.trim(_this.functionParser(_this.execFunctionGroupData[u.r][u.c].f));
+            let fp = $.trim(_this.functionParserExe(calc_funcStr));
             let sparklines = eval(fp);
-            value.spl = sparklines;
+            spl = sparklines;
         }
 
         _this.groupValuesRefreshData.push({
             "r": u.r,
             "c": u.c,
-            "v": value,
-            "i": Store.currentSheetIndex
+            "v": v[1],
+            "spl":spl,
+            "index": u.index
         });
 
-        _this.execFunctionGroupData[u.r][u.c] = value;
+        // _this.execFunctionGroupData[u.r][u.c] = value;
+        _this.execFunctionGlobalData[u.r+"_"+u.c+"_"+u.index] = {
+            v:v[1],
+            f:v[2]
+        };
     },
     groupValuesRefreshData: [],
     groupValuesRefresh: function() {
         let _this = this;
-
+        let luckysheetfile = getluckysheetfile();
         if(_this.groupValuesRefreshData.length > 0){
             for (let i = 0; i < _this.groupValuesRefreshData.length; i++) {
                 let item = _this.groupValuesRefreshData[i];
 
-                if(item.i != Store.currentSheetIndex){
+                // if(item.i != Store.currentSheetIndex){
+                //     continue;
+                // }
+
+                
+                let data = luckysheetfile[getSheetIndex(item.index)].data;
+                if(data==null){
                     continue;
                 }
-
-                setcellvalue(item.r, item.c, Store.flowdata, item.v);
-                server.saveParam("v", Store.currentSheetIndex, item.v, {
+                setcellvalue(item.r, item.c, data, item.v);
+                server.saveParam("v", item.index, item.v, {
                     "r": item.r,
                     "c": item.c
                 });
@@ -4954,109 +4978,7 @@ const luckysheetformula = {
 
         setluckysheetfile(luckysheetfile);
     },
-    execfunction1: function(txt, r, c, isrefresh) {
-        let _this = this;
-
-        let fp = $.trim(_this.functionParser(txt));
-        let funcf = fp.match(/luckysheet_function/g),
-            funcg = fp.match(/luckysheet_getcelldata/g),
-            funcc = fp.match(/luckysheet_compareWith/g),
-            funclen = 0;
-
-        if (isrefresh == null) {
-            isrefresh = false;
-        }
-
-        if (funcf != null) {
-            funclen += funcf.length;
-        }
-
-        if (funcg != null) {
-            funclen += funcg.length;
-        }
-
-        if (funcc != null) {
-            funclen += funcc.length;
-        }
-
-        let quota1 = fp.match(/\(/g),
-            quota2 = fp.match(/\)/g),
-            quotalen = 0;
-
-        if (quota1 != null) {
-            quotalen += quota1.length;
-        }
-
-        if (quota2 != null) {
-            quotalen += quota2.length;
-        }
-        
-        if ((fp.substr(0, 20) == "luckysheet_function." || fp.substr(0, 22) == "luckysheet_compareWith") && funclen != quotalen / 2) {
-            fp += ")";
-
-            if(fp.substr(0, 20) == "luckysheet_function."){
-                txt += ")";
-            }
-
-            _this.functionHTMLIndex = 0;
-            $("#luckysheet-functionbox-cell").html('=' + _this.functionHTML(txt));
-        }
-
-        if (!_this.testFunction(txt, fp)) {
-            tooltip.info("提示", "公式存在错误");
-            return [false, _this.error.n, txt];
-        }
-
-        let result = null;
-        window.luckysheetCurrentRow = r;
-        window.luckysheetCurrentColumn = c;
-        window.luckysheetCurrentFunction = txt;
-
-        try {
-            result = eval(fp);
-        } 
-        catch (e) {
-            let err = e;
-            //err错误提示处理
-            console.log(e);
-            err = _this.errorInfo(err);
-            result = [_this.error.n, err];
-        }
-
-        if (result instanceof Array) {
-            result = result[0];
-            //错误处理
-        }
-        else if(result instanceof Object){
-            result = result.data;
-            if (result instanceof Array) {
-                result = result[0];
-            }
-        }
-
-        window.luckysheetCurrentRow = null;
-        window.luckysheetCurrentColumn = null;
-        window.luckysheetCurrentFunction = null;
-
-        if (fp.substr(0, 19) == "luckysheet_getcelldata(") {
-            if (result instanceof Array) {
-                result = result.join(",");
-            } 
-            else if (result instanceof Object) {
-                result = result.v;
-            }
-        }
-
-        if (r != null && c != null) {
-            if (isrefresh) {
-                _this.execFunctionGroup(r, c, result);
-            }
-            _this.insertUpdateFunctionGroup(r, c);
-        }
-
-        return [true, result, txt];
-    },
-    execfunction: function(txt, r, c, isrefresh, notInsertFunc) {
+    execfunction: function(txt, r, c, index, isrefresh, notInsertFunc) {
         let _this = this;
 
         let _locale = locale();
@@ -5068,9 +4990,15 @@ const luckysheetformula = {
 
         if (!_this.checkBracketNum(txt)) {
             txt += ")";
+        }        
+        
+        if(index==null){
+            index = Store.currentSheetIndex;
         }
 
-        let fp = $.trim(_this.functionParser(txt));
+        Store.calculateSheetIndex = index;
+
+        let fp = $.trim(_this.functionParserExe(txt));
         
         if ((fp.substr(0, 20) == "luckysheet_function." || fp.substr(0, 22) == "luckysheet_compareWith") ) {
             _this.functionHTMLIndex = 0;
@@ -5081,9 +5009,12 @@ const luckysheetformula = {
             return [false, _this.error.n, txt];
         }
 
+
+
         let result = null;
         window.luckysheetCurrentRow = r;
         window.luckysheetCurrentColumn = c;
+        window.luckysheetCurrentIndex = index;
         window.luckysheetCurrentFunction = txt;
 
         let sparklines = null;
@@ -5100,7 +5031,7 @@ const luckysheetformula = {
                         return [true, _this.error.r, txt];
                     }
 
-                    if(funcgRange.sheetIndex == Store.currentSheetIndex && r >= funcgRange.row[0] && r <= funcgRange.row[1] && c >= funcgRange.column[0] && c <= funcgRange.column[1]){
+                    if(funcgRange.sheetIndex == Store.calculateSheetIndex && r >= funcgRange.row[0] && r <= funcgRange.row[1] && c >= funcgRange.column[0] && c <= funcgRange.column[1]){
                         if(isEditMode()){
                             alert(locale_formulaMore.execfunctionSelfError);
                         }
@@ -5171,15 +5102,16 @@ const luckysheetformula = {
 
         window.luckysheetCurrentRow = null;
         window.luckysheetCurrentColumn = null;
+        window.luckysheetCurrentIndex = null;
         window.luckysheetCurrentFunction = null;
 
         if (r != null && c != null) {
             if (isrefresh) {
-                _this.execFunctionGroup(r, c, result);
+                _this.execFunctionGroup(r, c, result, index);
             }
 
             if(!notInsertFunc){
-                _this.insertUpdateFunctionGroup(r, c);
+                _this.insertUpdateFunctionGroup(r, c, index);
             }
         }
 
diff --git a/src/global/getdata.js b/src/global/getdata.js
index 5308e21..dfb0c4e 100644
--- a/src/global/getdata.js
+++ b/src/global/getdata.js
@@ -61,6 +61,10 @@ export function getdatabyselectionD(d, range) {
     let dynamicArray_compute = dynamicArrayCompute(Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dynamicArray"]);
     let data = [];
 
+    if(d==null){
+        return data;
+    }
+
     for (let r = range["row"][0]; r <= range["row"][1]; r++) {
         if(d[r] == null){
             continue;
diff --git a/src/global/refresh.js b/src/global/refresh.js
index 53d831e..90ea6b5 100644
--- a/src/global/refresh.js
+++ b/src/global/refresh.js
@@ -40,7 +40,7 @@ function jfrefreshgrid(data, range, allParam, isRunExecFunction = true, isRefres
         }
         formula.execFunctionExist.reverse();
         formula.execFunctionGroup(null, null, null, null, data);
-        formula.execFunctionGroupData = null;
+        formula.execFunctionGlobalData = null;
     }
 
     //关联参数
@@ -157,7 +157,7 @@ function jfrefreshgrid(data, range, allParam, isRunExecFunction = true, isRefres
             window.luckysheetCurrentColumn = c1;
             window.luckysheetCurrentFunction = Store.flowdata[r1][c1].f;
 
-            let fp = $.trim(formula.functionParser(Store.flowdata[r1][c1].f));
+            let fp = $.trim(formula.functionParserExe(Store.flowdata[r1][c1].f));
             let sparklines = eval(fp);
             Store.flowdata[r1][c1].spl = sparklines;
         }
@@ -260,7 +260,7 @@ function jfrefreshgridall(colwidth, rowheight, data, cfg, range, ctrlType, ctrlV
         }
         formula.execFunctionExist.reverse();
         formula.execFunctionGroup(null, null, null, null, data);
-        formula.execFunctionGroupData = null;
+        formula.execFunctionGlobalData = null;
 
         redo["type"] = "datachangeAll";
 
@@ -341,7 +341,7 @@ function jfrefreshrange(data, range, cdformat) {
     }
     formula.execFunctionExist.reverse();
     formula.execFunctionGroup(null, null, null, null, data);
-    formula.execFunctionGroupData = null;
+    formula.execFunctionGlobalData = null;
 
     if (Store.clearjfundo) {
         Store.jfundo = [];
@@ -409,12 +409,12 @@ function jfrefreshgrid_adRC(data, cfg, ctrlType, ctrlValue, calc, filterObj, cf,
     //公式链中公式范围改变对应单元格值的改变
     let funcData = [];
     if(calc.length > 0){
-        formula.execFunctionGroupData = data;
+        // formula.execFunctionGroupData = data;
 
         for(let i = 0; i < calc.length; i++){
             let clc = calc[i];
             let clc_r = clc.r, clc_c = clc.c, clc_i = clc.index, clc_funcStr =  getcellFormula(clc_r, clc_c, clc_i, data);
-            let clc_result = formula.execfunction(clc_funcStr, clc_r, clc_c, null, true);
+            let clc_result = formula.execfunction(clc_funcStr, clc_r, clc_c, clc_i,null, true);
             clc.func = clc_result;
 
             if(data[clc_r][clc_c].f == clc_funcStr){
@@ -620,12 +620,12 @@ function jfrefreshgrid_deleteCell(data, cfg, ctrl, calc, filterObj, cf, dataVeri
     //公式链中公式范围改变对应单元格值的改变
     let funcData = [];
     if(calc.length > 0){
-        formula.execFunctionGroupData = data;
+        // formula.execFunctionGroupData = data;
 
         for(let i = 0; i < calc.length; i++){
             let clc = calc[i];
             let clc_r = clc.r, clc_c = clc.c, clc_i = clc.index, clc_funcStr =  getcellFormula(clc_r, clc_c, clc_i, data);
-            let clc_result = formula.execfunction(clc_funcStr, clc_r, clc_c, null, true);
+            let clc_result = formula.execfunction(clc_funcStr, clc_r, clc_c, clc_i,null, true);
             clc.func = clc_result;
 
             if(data[clc_r][clc_c].f == clc_funcStr){
@@ -769,7 +769,7 @@ function jfrefreshgrid_pastcut(source, target, RowlChange){
 
     formula.execFunctionExist.reverse();
     formula.execFunctionGroup(null, null, null, null, target["curData"]);
-    formula.execFunctionGroupData = null;
+    formula.execFunctionGlobalData = null;
 
     if(Store.clearjfundo){
         Store.jfundo = [];
@@ -922,7 +922,7 @@ function jfrefreshgrid_rhcw(rowheight, colwidth, isRefreshCanvas=true){
                 window.luckysheetCurrentColumn = c;
                 window.luckysheetCurrentFunction = Store.flowdata[r][c].f;
 
-                let fp = $.trim(formula.functionParser(Store.flowdata[r][c].f));
+                let fp = $.trim(formula.functionParserExe(Store.flowdata[r][c].f));
                 let sparklines = eval(fp);
                 Store.flowdata[r][c].spl = sparklines;
 
diff --git a/src/store/index.js b/src/store/index.js
index 624a193..a4cf1b2 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -6,7 +6,8 @@ const Store = {
     fullscreenmode: true,
     devicePixelRatio: 1,
 
-	currentSheetIndex: 0,
+    currentSheetIndex: 0,
+    calculateSheetIndex: 0,
 	flowdata: [],
     config: {},