Browse Source

perf(rewrite formula refresh): formula calculation speed up and fix one equal label bug

master
liuyang 5 years ago
parent
commit
9c80c57f2c
  1. 6
      src/controllers/insertFormula.js
  2. 2
      src/controllers/postil.js
  3. 2
      src/controllers/selection.js
  4. 14
      src/controllers/sheetmanage.js
  5. 34
      src/function/func.js
  6. 548
      src/global/formula.js
  7. 4
      src/global/getdata.js
  8. 20
      src/global/refresh.js
  9. 3
      src/store/index.js

6
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;

2
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){

2
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];

14
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;
}
}

34
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;
@ -1701,6 +1709,18 @@ function luckysheet_getcelldata(txt) {
"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;
let coll = col[1] - col[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]
});

548
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: '<div id="luckysheet-formula-functionrange-highlight-${id}" rangeindex="${id}" class="luckysheet-selection-highlight luckysheet-formula-functionrange-highlight"><div data-type="top" class="luckysheet-selection-copy-top luckysheet-copy"></div><div data-type="right" class="luckysheet-selection-copy-right luckysheet-copy"></div><div data-type="bottom" class="luckysheet-selection-copy-bottom luckysheet-copy"></div><div data-type="left" class="luckysheet-selection-copy-left luckysheet-copy"></div><div class="luckysheet-selection-copy-hc"></div><div data-type="lt" class="luckysheet-selection-highlight-topleft luckysheet-highlight"></div><div data-type="rt" class="luckysheet-selection-highlight-topright luckysheet-highlight"></div><div data-type="lb" class="luckysheet-selection-highlight-bottomleft luckysheet-highlight"></div><div data-type="rb" class="luckysheet-selection-highlight-bottomright luckysheet-highlight"></div></div>',
@ -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<luckysheetfile.length;i++){
let file = luckysheetfile[i];
let calcChain = file.calcChain;
if(calcChain==null){
calcChain = [];
}
ret = ret.concat(calcChain);
}
return ret;
},
getFunctionGroup: function(index) {
if (index == null) {
index = Store.currentSheetIndex;
@ -4200,7 +4107,7 @@ const luckysheetformula = {
setluckysheetfile(luckysheetfile);
},
isFunctionRangeSave: false,
isFunctionRangeSimple: function(txt, r, c,dynamicArray_compute) {
isFunctionRangeSimple: function(txt, r, c, index,dynamicArray_compute) {
let _this = this;
if (_this.operatorjson == null) {
@ -4251,12 +4158,12 @@ const luckysheetformula = {
}
else if (s == ")" && matchConfig.dquote == 0) {
matchConfig.bracket -= 1;
function_str += _this.isFunctionRangeSimple(str, r, c,dynamicArray_compute) + ")";
function_str += _this.isFunctionRangeSimple(str, r, c, index,dynamicArray_compute) + ")";
str = "";
}
else if (s == ',' && matchConfig.dquote == 0) {
//matchConfig.comma += 1;
function_str += _this.isFunctionRangeSimple(str, r, c,dynamicArray_compute) + ',';
function_str += _this.isFunctionRangeSimple(str, r, c, index,dynamicArray_compute) + ',';
str = "";
}
else if (s in _this.operatorjson && matchConfig.dquote == 0) {
@ -4268,7 +4175,7 @@ const luckysheetformula = {
if ((s + s_next) in _this.operatorjson) {
if (str.length > 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);
}
else {
_this.isFunctionRangeSelect(calc_funcStr, undefined, undefined ,dynamicArray_compute);
_this.isFunctionRangeSelect(calc_funcStr, origin_r, origin_c, index, 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);
if (_this.isFunctionRangeSave) {
let v = vertex1[name];
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) {
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];
let cell = getOrigincell(u.r,u.c,u.index);
if(value.spl != null){
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('<span dir="auto" class="luckysheet-formula-text-color">=</span>' + _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();
@ -5070,7 +4952,13 @@ const luckysheetformula = {
txt += ")";
}
let fp = $.trim(_this.functionParser(txt));
if(index==null){
index = Store.currentSheetIndex;
}
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);
}
}

4
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;

20
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;

3
src/store/index.js

@ -6,7 +6,8 @@ const Store = {
fullscreenmode: true,
devicePixelRatio: 1,
currentSheetIndex: 0,
currentSheetIndex: 0,
calculateSheetIndex: 0,
flowdata: [],
config: {},

Loading…
Cancel
Save