代码之家  ›  专栏  ›  技术社区  ›  Dženis H.

如何调整此自定义函数,使其在工作表中的数据更改时更新?

  •  0
  • Dženis H.  · 技术社区  · 6 年前

    使用谷歌应用程序脚本,我可以选择所有工作表并排除我不需要的工作表,但当我更改数据时,它不会在我使用此功能的主工作表上更新。如何调整此脚本以实现这一点?

    我尝试添加 onEdit() 但我没有完全弄明白。

    function SUMALLSHEETS(range, excluded) {
        try {
            var sum = 0,
                ex = (excluded) ? Trim(excluded.split()) : false;
            SpreadsheetApp.getActive()
                .getSheets()
                .forEach(function (s) {
                    if (ex && ex.indexOf(s.getName()) === -1 || !ex) {
                        s.getRange(range)
                            .getValues()
                            .reduce(function (a, b) {
                                return a.concat(b);
                            })
                            .forEach(function (v) {
                                sum += (!isNaN(parseFloat(v) && isFinite(v))) ? v : 0;
                            });
                    };
                });
            return sum;
        } catch (e) {
            throw e.message;
        }
    }
    
    function Trim(v) {
        v = (v === null || typeof v == 'undefined') ? '' : v.toString();
        return v.replace(/^\s\s*/, "")
            .replace(/\s\s*$/, "");
    }
    
    2 回复  |  直到 6 年前
        1
  •  3
  •   tehhowch    6 年前

    自定义函数(如您的函数)基于输入参数缓存其输出,因为它们被假定为确定性的。只有当这些参数更改时,自定义函数才会重新计算。请参见 Apps Script documentation on custom functions ,以及其他 custom-function 此处提出的问题。

    您的问题的解决方案—在非排除工作表上更改特定范围内的值时更新求和—只有在您只使用了一次函数的情况下才是微不足道的。Diego的回答为您提供了一个提示,告诉您如何在编辑给定单元格后获取其值。

    但是,如果每次在多个位置使用具有不同参数的自定义函数,则单个 on edit 将无法维护。解决方案是更改数据存储体系结构,使相关的原始数据存储在中心位置,并在需要时使用和后处理该原始数据的视图。

    如果您不希望更改存储体系结构,那么可以完全放弃自定义功能概念。您可以使用带有硬编码范围+名称对的脚本,然后在完成数据更新后手动调用它来更新它们。您可以添加一个菜单选项来简化此手动操作,甚至可以编写一个侧栏,允许在不需要打开脚本编辑器的情况下操作这些对。

        2
  •  1
  •   Diego    6 年前

    很容易过度思考 onEdit() 作用这是一个特殊功能( a "simple" trigger )谷歌知道如何利用它的存在。只需复制、粘贴和保存此代码。下次编辑时,例如“H1”,所有H1值都将被求和并记录。

    function onEdit(event) {
      var cellA1Notation = event.range.getA1Notation();
      var excluded; // Define how you want
      Logger.log(SUMALLSHEETS(cellA1Notation, excluded));
    }