From 9c80c57f2c598d9f12785486a85a6a095f31f20e Mon Sep 17 00:00:00 2001 From: liuyang Date: Mon, 28 Sep 2020 22:14:18 +0800 Subject: [PATCH] perf(rewrite formula refresh): formula calculation speed up and fix one equal label bug --- src/controllers/insertFormula.js | 6 +- src/controllers/postil.js | 2 +- src/controllers/selection.js | 2 +- src/controllers/sheetmanage.js | 14 +- src/function/func.js | 34 +- src/global/formula.js | 548 +++++++++++++------------------ src/global/getdata.js | 4 + src/global/refresh.js | 20 +- src/store/index.js | 3 +- 9 files changed, 279 insertions(+), 354 deletions(-) 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/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/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/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/global/formula.js b/src/global/formula.js index b8fe635..b36d3aa 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,36 @@ 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 = {}; + } + + if(txt in this.formulaContainCellList){ + let cellList = this.formulaContainCellList[txt]; + for(let cellStr in cellList){ + this.isFunctionRangeSaveChange(cellStr, r, c, index, dynamicArray_compute); + } + + return; + } + let txt1 = txt.toUpperCase(); if(txt1.indexOf("INDIRECT")>-1 || txt1.indexOf("OFFSET")>-1){ - this.isFunctionRange(txt, r, c, dynamicArray_compute); + 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) { let _this = this; if (_this.operatorjson == null) { @@ -4422,7 +4346,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) + ")"; str = ""; } else { @@ -4449,7 +4373,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) + ","; str = ""; } else { @@ -4467,7 +4391,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)); } else if ($.trim(function_str).length > 0) { cal2.unshift($.trim(function_str)); @@ -4496,7 +4420,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)); } else if ($.trim(function_str).length > 0) { cal2.unshift($.trim(function_str)); @@ -4542,7 +4466,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); @@ -4594,10 +4518,10 @@ const luckysheetformula = { i++; } //console.log(function_str); - _this.checkSpecialFunctionRange(function_str, r, c, dynamicArray_compute); + _this.checkSpecialFunctionRange(function_str, r, c, index, dynamicArray_compute); 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)); @@ -4631,19 +4555,21 @@ const luckysheetformula = { _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) { if (function_str.substr(0, 20) == "luckysheet_function.") { let funcName = function_str.split(".")[1]; if (funcName != null) { @@ -4693,6 +4619,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 +4675,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 +4711,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 +4722,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 +4747,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 +4826,8 @@ const luckysheetformula = { } } } - + // console.timeEnd("2"); + // console.log(this.formulaContainCellList); _this.execFunctionExist = null; }, //深度优先算法,处理多级调用函数 @@ -4868,58 +4838,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 +4938,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 +4950,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 +4969,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 +4991,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 +5062,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: {},