使用脚本的条件格式 - 根据自定义公式突出显示行

Conditional Formatting with Script - Highlight Rows based on Custom Formula

我有一个 Google Sheet 可以使用滚动日历跟踪出席情况。它有多个 sheet,我希望每个 sheet 具有相同的条件格式。起初这看起来很简单,我写了一些脚本,让它遍历所有 sheet 以将一个单元格中的格式复制到整个 sheet。它运行良好,直到它以某种方式删除了除一个 =A=TODAY() 之外的所有条件格式。我一直在试图确定它为什么这样做以及如何解决它。我尝试在非移动单元格 (A1) 中设置条件格式,但公式无法正常工作。他们最终突出了错误的行。我也一直在查看 Google Sheets API Sheets,但在实施时遇到了麻烦。有没有一种方法可以编写脚本来设置这些条件格式设置规则以及如何设置?感谢任何帮助。

我已经提供了一张我正在尝试完成的图片以及我一直在使用的脚本和参考资料,所有这些都在下面。

sheet的基本布局如图所示。该图片还描述了我尝试使用条件格式完成的任务。

格式规则如下(并按顺序排列):

  1. 适用范围:A1:NH(整sheet)
    自定义公式为:=A$1=TODAY()
    背景颜色:默认绿色背景 (#b7e1cd)

  2. 应用于范围:C2:NH(除第 1 行和 A 和 B 列之外的所有内容)
    自定义公式为:=$B2>=10
    背景颜色:深红色 1 (#cc0000)

  3. 适用范围:C2:NH
    自定义公式为:=$B2>=8
    背景颜色:浅红色 2 (#ea9999)

  4. 适用范围:C2:NH
    自定义公式为:=$B2>=5
    背景颜色:浅橙色 1 (#f6b26b)

  5. 适用范围:C2:NH
    自定义公式为:=$B2>=2
    背景颜色:淡黄色 2 (#ffe599)

B 列中的公式是 =SUM($C2:2) 自动填充到每一行。

我当前的脚本是

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sh = ss.getSheets();
  var sheetNames = [ 'Screening','Maint - PrePress','Vulcan','Sullivan','Packing','Materials','Shipping','Labels','Embroidery','PadPrint','Quality'];
  
  sh.forEach(sheet=> {
    if(sheetNames.includes(sheet.getName())) {
        var rng = sheet.getRange('F2');
        
        rng.copyFormatToRange(sheet, 3, sheet.getLastColumn(), 2, sheet.getLastRow());
  }
});
}

参考文献:

  1. https://developers.google.com/apps-script/reference/spreadsheet/gradient-condition
  2. https://developers.google.com/apps-script/reference/spreadsheet/conditional-format-rule
  3. https://developers.google.com/sheets/api/guides/conditional-format#apps-script

试试这个代码,它有效:

function myFunction() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sh = ss.getSheets();

  // The sheet from which we take a sample of the rules
  var sheetS = ss.getSheetByName('Screening'); 
  var rng = sheetS.getRange('F2');

  var sheetNames = ['Screening','Maint - PrePress','Vulcan','Sullivan','Packing','Materials','Shipping','Labels','Embroidery','PadPrint','Quality'];
  
  sh.forEach(sheet=> {
             if(sheetNames.includes(sheet.getName())) {    
    rng.copyFormatToRange(sheet, 3, sheet.getLastColumn(), 2, sheet.getLastRow());
  }
});
}

为了以编程方式应用条件格式,您可以执行以下操作:

代码片段:

function applyConditionalFormat() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheets = ss.getSheets(); // Remove if not all sheets
  //var sheetNames = ['Screening','Quality', ...]; // Uncomment if not all sheets
  //var sheets = sheetNames.map(sheetName => ss.getSheetByName(sheetName)); // Uncomment if not all sheets
  sheets.forEach(sheet => {
    //sheet.clearConditionalFormatRules(); // Uncomment if want to remove previous rules
    var rules = [];
    rules.push(createRule(sheet, "A1:NH", "=A=TODAY()", "#b7e1cd"));
    rules.push(createRule(sheet, "C2:NH", "=$B2>=10", "#cc0000"));
    rules.push(createRule(sheet, "C2:NH", "=$B2>=8", "#ea9999"));
    rules.push(createRule(sheet, "C2:NH", "=$B2>=5", "#f6b26b"));
    rules.push(createRule(sheet, "C2:NH", "=$B2>=2", "#ffe599"));
    sheet.setConditionalFormatRules(rules);
  });
}

function createRule(sheet, rangeNotation, formula, color) {
  var range = sheet.getRange(rangeNotation);
  var rule = SpreadsheetApp.newConditionalFormatRule()
    .whenFormulaSatisfied(formula)
    .setBackground(color)
    .setRanges([range])
    .build();
  return rule;
}

注:

  • 我假设您希望将此应用于传播sheet 中的所有 sheet。如果不是这种情况,请取消注释代码片段的第 4 行和第 5 行,删除第 3 行,并将所有需要的 sheet 名称写入第 4 行中的数组。
  • 如果您不希望每次运行这个条件都堆积起来,请取消注释行sheet.clearConditionalFormatRules();