From 44cf72a1c7592ac5227a92c3e325e7f5088bca30 Mon Sep 17 00:00:00 2001 From: wpxp123456 <2677556700@qq.com> Date: Mon, 28 Sep 2020 17:20:29 +0800 Subject: [PATCH 1/4] feat(api add): deleteRangeConditionalFormat clearRange deleteRange --- docs/zh/guide/api.md | 38 +-- src/controllers/rowColumnOperation.js | 4 + src/global/api.js | 338 +++++++++++++++++++++++- src/global/extend.js | 353 ++++++++++++++++++++++++-- 4 files changed, 673 insertions(+), 60 deletions(-) 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/rowColumnOperation.js b/src/controllers/rowColumnOperation.js index 7dd6965..652d032 100644 --- a/src/controllers/rowColumnOperation.js +++ b/src/controllers/rowColumnOperation.js @@ -1574,6 +1574,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; 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/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, From cc3b16ad91f3703c3a0c118db4c77a29edd462b9 Mon Sep 17 00:00:00 2001 From: lrz <1414556676@qq.com> Date: Mon, 28 Sep 2020 17:36:14 +0800 Subject: [PATCH 2/4] style(style): style right click menu style --- src/controllers/constant.js | 13 +--- src/controllers/keyboard.js | 11 +++ src/controllers/rowColumnOperation.js | 98 +++++++++++++++++++++++---- src/css/luckysheet-core.css | 2 +- src/global/cursorPos.js | 9 ++- 5 files changed, 107 insertions(+), 26 deletions(-) diff --git a/src/controllers/constant.js b/src/controllers/constant.js index 7901821..2ff7939 100644 --- a/src/controllers/constant.js +++ b/src/controllers/constant.js @@ -287,24 +287,22 @@ function rightclickHTML(){
-
+
${rightclick.to} ${rightclick.left} ${rightclick.add} ${rightclick.column} -
-
+
${rightclick.to} ${rightclick.right} ${rightclick.add} ${rightclick.column} -
@@ -313,13 +311,12 @@ function rightclickHTML(){ ${rightclick.column}
-
+
${rightclick.column} ${rightclick.width} px -
@@ -409,7 +406,6 @@ function rightclickHTML(){ ${rightclick.to}${rightclick.top}${rightclick.add} ${rightclick.row} -
@@ -417,7 +413,6 @@ function rightclickHTML(){ ${rightclick.to}${rightclick.bottom}${rightclick.add} ${rightclick.row} -
@@ -425,7 +420,6 @@ function rightclickHTML(){ ${rightclick.to}${rightclick.left}${rightclick.add} ${rightclick.column} -
@@ -433,7 +427,6 @@ function rightclickHTML(){ ${rightclick.to}${rightclick.right}${rightclick.add} ${rightclick.column} -
diff --git a/src/controllers/keyboard.js b/src/controllers/keyboard.js index 80a5263..a7ad8e9 100644 --- a/src/controllers/keyboard.js +++ b/src/controllers/keyboard.js @@ -907,4 +907,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/rowColumnOperation.js b/src/controllers/rowColumnOperation.js index 7dd6965..1b2f34a 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(); + }); //删除选中行列 @@ -1587,11 +1649,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/css/luckysheet-core.css b/src/css/luckysheet-core.css index f9c6ba1..85325b6 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/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(); From 9c80c57f2c598d9f12785486a85a6a095f31f20e Mon Sep 17 00:00:00 2001 From: liuyang Date: Mon, 28 Sep 2020 22:14:18 +0800 Subject: [PATCH 3/4] 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: {}, From d8dfe50782108745e5f132c0bbb1438f7180d198 Mon Sep 17 00:00:00 2001 From: liuyang Date: Mon, 28 Sep 2020 23:40:43 +0800 Subject: [PATCH 4/4] fix(offset indirect formula fix): fix bug --- src/function/functionImplementation.js | 51 +++++++++++---- src/global/formula.js | 86 +++++++++++++++++++------- 2 files changed, 103 insertions(+), 34 deletions(-) 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/formula.js b/src/global/formula.js index b36d3aa..18898f9 100644 --- a/src/global/formula.js +++ b/src/global/formula.js @@ -4266,25 +4266,50 @@ const luckysheetformula = { if(dynamicArray_compute==null){ dynamicArray_compute = {}; } - + let _this = this; + let txt1 = txt.toUpperCase(); + let isOffsetFunc = txt1.indexOf("INDIRECT")>-1 || txt1.indexOf("OFFSET")>-1; if(txt in this.formulaContainCellList){ let cellList = this.formulaContainCellList[txt]; - for(let cellStr in cellList){ - this.isFunctionRangeSaveChange(cellStr, r, c, index, dynamicArray_compute); + 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; } - let txt1 = txt.toUpperCase(); - if(txt1.indexOf("INDIRECT")>-1 || txt1.indexOf("OFFSET")>-1){ + + if(isOffsetFunc){ this.isFunctionRange(txt, r, c, index,dynamicArray_compute); } else{ this.isFunctionRangeSimple(txt, r, c, index,dynamicArray_compute); } }, - isFunctionRange: function (txt, r, c, index,dynamicArray_compute) { + isFunctionRange: function (txt, r, c, index,dynamicArray_compute, cellRangeFunction) { let _this = this; if (_this.operatorjson == null) { @@ -4346,7 +4371,7 @@ const luckysheetformula = { let bt = bracket.pop(); if (bracket.length == 0) { - function_str += _this.isFunctionRange(str,r,c, index,dynamicArray_compute) + ")"; + function_str += _this.isFunctionRange(str,r,c, index,dynamicArray_compute,cellRangeFunction) + ")"; str = ""; } else { @@ -4373,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, index,dynamicArray_compute) + ","; + function_str += _this.isFunctionRange(str, r, c, index,dynamicArray_compute,cellRangeFunction) + ","; str = ""; } else { @@ -4391,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, index,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)); @@ -4420,7 +4445,7 @@ const luckysheetformula = { else { if (bracket.length == 0) { if ($.trim(str).length > 0) { - cal2.unshift(_this.isFunctionRange($.trim(str), r, c, index,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)); @@ -4517,8 +4542,8 @@ const luckysheetformula = { i++; } - //console.log(function_str); - _this.checkSpecialFunctionRange(function_str, r, c, index, dynamicArray_compute); + // console.log(function_str); + _this.checkSpecialFunctionRange(function_str, r, c, index, dynamicArray_compute,cellRangeFunction); return function_str; }, isFunctionRangeSaveChange: function (str, r, c, index, dynamicArray_compute) { @@ -4527,9 +4552,9 @@ const luckysheetformula = { 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++) { @@ -4548,7 +4573,7 @@ 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 { @@ -4569,7 +4594,7 @@ const luckysheetformula = { // } } }, - checkSpecialFunctionRange: function (function_str, r, c, index, 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) { @@ -4578,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{ @@ -4599,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); } }