完善luckysheet的跨sheet公式引用

目前luckysheet存在的问题

问题1

        现有A、B两个sheet页,A页有个公式,公式表达式是将B页中的两个单元格相加。如图-1.

 图-1

 将A页的B列删除,发现公式竟然也跟着发生了变化,如图-2

 正确的效果应该是公式不会改变,还是"B!I5+B!J5"

问题2

        继续问题1的操作,来到B页,将B页的C列删除,回到A页,公式引用却没有改变。在excel中是会改变的。

        所以,luckysheet中对于跨sheet的公式引用更新是不准的。

原因

        查阅源码发现,luckysheet在处理时,只会更新本页面的公式,并且会将公式中其他sheet页的参数也跟着更新。所以需要解决跨sheet页的公式胡乱更新的问题。

解决

        更新原则:在“操作页”删除一列后,“操作页”中除本页外的所有公式的参数都不应该改变,除“操作页”以外的其他sheet页的公式只更新含“操作页”单元格的参数。

代码

        (extend.js)在原有的公式更新之前,完成对其他sheet的公式更新,主要更新和“操作页”有关的参数。

        更新的核心是formula.functionStrChange方法,还需要对这个方法进行改造。

        (formula.js)写个函数getFuncStr负责判断参数是否需要更新,如下:

        然后在functionStrChange中调用上面写的函数。 

 代码

extend.js

    // nby 多页面的公式引用
    // 先更新其他页面的公式
    Store.luckysheetfile = luckysheet.getAllSheets()    //这里需要更新Store.luckysheetfile
    let otherSheet = Store.luckysheetfile.filter((it)=>it.index !== file.index && it.calcChain?.length > 0)

    otherSheet?.forEach((sheetFile,sheetIndex)=>{
        let opeArr =  sheetFile.celldata?.filter(cell=>sheetFile.calcChain?.findIndex(calc=>calc.r===cell.r&&calc.c===cell.c)!=-1 )
        opeArr.forEach((cell,cellIndex)=>{
            if(cell.v?.f.includes(file.name)){
                let calc_r = cell.r
                let calc_c = cell.c
                let calc_funcStr = cell.v.f
                let functionStr = ''
                if(type == "row"){
                    // if(calc_r < st || calc_r > ed){
                        functionStr = "=" + formula.functionStrChange(calc_funcStr, "del", "row", null, st, slen,true);
                    // }
                }
                else if(type == "column"){
                        functionStr = "=" + formula.functionStrChange(calc_funcStr, "del", "col", null, st, slen,true);
                }
                // 更新公式
                let curCelldata = Store.luckysheetfile[sheetFile.order].celldata.find(ce=>ce.c==cell.c&&ce.r==cell.r)
                curCelldata.v.f = functionStr
                Store.luckysheetfile[sheetFile.order].data = []
            }
        })
    })
    // nby 多页面的公式引用 END

formula.js

    getFuncStr(str, rightStr,result){
        let function_str = ''
        let sheetStr = str.split('!')[0]
        let sheetFile = Store.luckysheetfile.find((it)=>it.name==sheetStr)
        if(sheetFile){
            if(sheetFile.index != Store.currentSheetIndex){
                    function_str += str + rightStr; //参数不更新
            }else{
                function_str += result + rightStr;
            }
        }else{
                function_str += result + rightStr
        }
        return function_str
    },

getFuncStr调用

在functionStrChange中需要的位置进行调用

            // ...
            else if (s == ',' && matchConfig.dquote == 0) {
                // 源码如下:
                // function_str += _this.functionStrChange(str, type, rc, orient, stindex, step) + ',';
                // str = "";

                // nby 多页面的公式引用 
                function_str += _this.getFuncStr(str,',',_this.functionStrChange(str, type, rc, orient, stindex, step))
                str = "";
                // nby 多页面的公式引用  END
            }
            // ...

思考

        实现的原理还是筛选数组后再循环更新,想着能不能用响应式来实现,看了看整体代码发现不好做。不知道excel中是如何做的?

github地址

表格编辑器的luckysheet: 工企表格编辑器的luckysheet (gitee.com)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值