【问题标题】:Script: How to copy and reapply conditional formatting rules to a range on edit?脚本:如何将条件格式规则复制并重新应用到编辑范围?
【发布时间】:2020-03-07 22:28:58
【问题描述】:

在 Google 表格中,当您粘贴新值时,应用条件格式的单元格范围可能会发生变化。我正在寻找一个脚本,该脚本将复制工作表中存在的条件格式,并在人们粘贴数据时将其重新应用于新单元格。

我实际上并没有编写太多脚本,但我会窃取其他人的脚本,然后将它们一起弗兰肯斯坦,直到它们具有模糊的功能。这是我到目前为止偷的东西:

function onEdit(e) {
  var range = e.range;
  var sheet = range.getSheet();
  range.clearFormat();
  //clears formatting just on data that is pasted into the sheet

  var rules = sheet.getConditionalFormatRules();
  var newRules = [];
  for(var r = 0; r < rules.length; r++) {
    var booleanCondition = rules[r].getBooleanCondition();
    if(booleanCondition != null) {
      var rule = SpreadsheetApp.newConditionalFormatRule()
      .withCriteria(booleanCondition.getCriteriaType(), booleanCondition.getCriteriaValues())
      .setBackground(booleanCondition.getBackground())
      .setRanges([sheet.getRange("A:A"),sheet.getRange("C:C")])
      .build();
      newRules.push(rule);
      sheet.setConditionalFormatRules(newRules);
    }
  }
}

当然,问题在于我正在获取该工作表的所有条件格式规则并将它们全部应用到两列(A:A 和 C:C)。无论它们曾经应用于哪些列,都会应用这些规则。

有人可以建议一种方法来复制预先存在的条件格式规则并将它们重新应用于我从中复制它们的列吗?

【问题讨论】:

    标签: google-apps-script google-sheets gs-conditional-formatting


    【解决方案1】:

    setRanges() 函数 [1] 是您需要设置要应用格式的范围的地方。在这种情况下,我使用了您从 onEdit 触发器 [2] 的事件对象中获得的编辑范围:

    function onEdit(e) {
      var range = e.range;
      var column = range.getColumn();
      var sheet = range.getSheet();
      range.clearFormat();
      //clears formatting just on data that is pasted into the sheet
    
      //Get all Sheet rules and iterate through them
      var rules = sheet.getConditionalFormatRules();
      var newRules = [];
      newRules = newRules.concat(rules);
    
      for(var r = 0; r < rules.length; r++) {
        var rule = rules[r];
        //Get condition for each rule
        var booleanCondition = rule.getBooleanCondition();
    
        //Get the ranges to which each rule applies and iterate through
        var ranges = rule.getRanges();
        for (var i = 0; i < ranges.length; i++) {
          var ruleColumn = ranges[i].getColumn();  
    
          //If condition isn't null and edited column is the same as the one in the range, add rule
          if((ruleColumn == column) && (booleanCondition != null)) {
            var newRule = SpreadsheetApp.newConditionalFormatRule()
            .withCriteria(booleanCondition.getCriteriaType(), booleanCondition.getCriteriaValues())
            .setBackground(booleanCondition.getBackground())
            .setRanges([range])
            .build();
            newRules.push(newRule);
          }
        }
      }
      sheet.setConditionalFormatRules(newRules);
    }
    

    我还将这一行放在 for 循环之外,因为只需要在工作表中插入所有格式规则:

    sheet.setConditionalFormatRules(newRules);
    

    [1]https://developers.google.com/apps-script/reference/spreadsheet/conditional-format-rule-builder#setRanges(Range)

    [2]https://developers.google.com/apps-script/guides/triggers/events

    【讨论】:

    • 谢谢你,安德烈斯!不幸的是,我仍然遇到同样的问题。无论我使用 setRanges() 函数指定什么范围,整个工作表的条件格式规则都会应用于该范围。我正在寻找一种解决方案,该解决方案从每列中获取条件格式规则,并在添加数据时将它们重新应用于同一列。你有什么见解......比如说,如何按列选择性地检索条件格式规则并按列重新应用它们?
    • 我刚刚使用getRanges 函数为每个规则编辑了答案,并基于此将规则设置为已编辑的单元格。如果您需要调整代码,请查看我提供给您的文档。如果它对您有帮助,请考虑接受正确的答案。
    • 这绝对有帮助。条件格式现在已正确应用于每一列,但它会为每个规则创建一个新的迭代,当有编辑时,脚本会获取并重新应用到下一个范围。每次激活脚本时,相同规则的迭代次数都会呈指数增长。有没有办法仅从“A2:Z2”等指定单元格中提取条件格式?那将是一个完美的解决方法。再次感谢!
    • 如果你想问一个新问题,我无法在评论中回答这个问题。
    • 啊,感谢您帮助我遵守 SO 的网站规则。我将您的答案标记为正确,posted a separate question about this. 您在编译此脚本并帮助我更有效地理解语言方面提供了极大的帮助。我很感激!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 2014-03-09
    • 1970-01-01
    相关资源
    最近更新 更多