使用 Apps 脚本对 Google 表格中的边框进行条件格式设置

Posted

技术标签:

【中文标题】使用 Apps 脚本对 Google 表格中的边框进行条件格式设置【英文标题】:Conditional formatting of borders in Google Sheets using Apps Script 【发布时间】:2021-05-18 15:27:33 【问题描述】:

我想使用条件格式为 Google 表格中的单元格添加边框。我知道您无法使用 Google 表格中的标准条件格式化过程来执行此操作,因此我正在尝试掌握如何使用脚本来执行此操作。

我从以下解决方案中复制了一个脚本,并尝试根据需要对其进行编辑:(Add border format to row if condition met in Google Sheets)

但是,我仍然对这些脚本的工作方式有所了解,并且还无法按预期进行。

想要的效果是,对于所有第 5 行及更高的行,其中 A 不为空,边框应应用于 A 到 M 列中的所有单元格。工作表称为“套件检查列表”,脚本应为每当对工作表进行编辑时触发。

这是我目前的尝试

function onEdit() 
   GroupMyData(); // trigger this function when edits are made


function GroupMyData() 
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('Kit check list'); // apply to sheet name only
  var rows = sheet.getRange('A5:M'); // range to apply formatting to
  var numRows = rows.getNumRows(); // no. of rows in the range named above
  var values = rows.getValues(); // array of values in the range named above
  var testvalues = sheet.getRange('a5:a').getValues(); // array of values to be tested (1st column of the range named above)

  rows.setBorder(false, false, false, false, false, false, "black", SpreadsheetApp.BorderStyle.SOLID); // remove existing borders before applying rule below
      //Logger.log(numRows);

  for (var i = 0; i <= numRows - 1; i++) 
      var n = i + 1;
      //Logger.log(n);
      //Logger.log(testvalues[i] > 0);
      //Logger.log(testvalues[i]);
      if (testvalues[i] > 0)  // test applied to array of values
        sheet.getRange('a' + n + ':m' + n).setBorder(true, true, true, true, true, true, "black", SpreadsheetApp.BorderStyle.SOLID); // format if true
      
  
;

不幸的是,它只重置了指定区域的边框,并没有将边框应用于所需的行。

对此的任何帮助将不胜感激。

【问题讨论】:

我建议您考虑使用背景颜色而不是边框​​。如果可能的话,当然可以。使用 Google App Script,您可以比边框更轻松地处理背景。至少现在。 感谢颜色而不是边框​​的建议。在我制作的电子表格中,我不太使用边框,但是在这种情况下,电子表格用于生成可打印的表单,其中包含供人们写入的字段网格,因此边框更合适。 【参考方案1】:

试试这个:

function onEdit(e) 
  const sh = e.range.getSheet();
  if (sh.getName() == 'Kit check list') 
    const sr = 5;
    const rg = sh.getRange(sr, 1, sh.getLastRow() - sr + 1, sh.getLastColumn());
    const vs = rg.getValues();
    rg.setBorder(false, false, false, false, false, false, "black", SpreadsheetApp.BorderStyle.SOLID);
    const numcolumns = sh.getLastColumn();
    vs.forEach((r, i) => 
      if (r[0]) 
        sh.getRange(i + sr, 1, 1, numcolumns).setBorder(true, true, true, true, true, true, "black", SpreadsheetApp.BorderStyle.SOLID);
      
    );
  

演示:

注意:如果不提供填充 e 的事件对象,则无法运行此函数。测试它的唯一合理方法是设置它并保存它并编辑工作表。

你可能更喜欢这种方式:

function onEdit(e) 
  const sh = e.range.getSheet();
  if (sh.getName() == 'Kit check list') 
    const sr = 5;
    const rg = sh.getRange(sr, 1, sh.getLastRow() - sr + 1, sh.getLastColumn());
    const vs = rg.getValues();
    //rg.setBorder(false, false, false, false, false, false, "black", SpreadsheetApp.BorderStyle.SOLID);
    const numcolumns = sh.getLastColumn();
    vs.forEach((r, i) => 
      if (r[0]) 
        sh.getRange(i + sr, 1, 1, numcolumns).setBorder(true, true, true, true, true, true, "black", SpreadsheetApp.BorderStyle.SOLID);
       else 
        sh.getRange(i + sr, 1, 1, numcolumns).setBorder(false, false, false, false, false, false, "black", SpreadsheetApp.BorderStyle.SOLID);
      
    );
  

【讨论】:

你做得很好。但问题中的脚本运行速度明显更快。 感谢 MetaMan - 从您的演示来看,这看起来正是我正在寻找的功能。但是,当我尝试运行您的脚本时,我收到如下错误“TypeError: Cannot read property 'range' of undefined: onEdit @ Code.gs:2”,与第 2 行有关。我对该错误了解不够解决任何问题。 我刚刚发现为什么您的脚本运行如此缓慢。它在这里:sh.getRange(i + sr, 1, 1, sh.getLastColumn()).setBorder(...。您不应该为每一行调用getLastColumn()。最好只在forEach() 之外获取最后一列,然后将其用作常量。 如果有一个带有二维数组的 setBorders 就好了 哇,这是一个愚蠢的错误,哇,它现在确实运行得更快了。谢谢【参考方案2】:

您的脚本运行良好。我只修了一条线。

而不是这个:

var n = i + 1;

你需要:

var n = i + 5;

代码如下:

function onEdit() 
   GroupMyData(); // trigger this function when edits are made


function GroupMyData() 
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('Kit check list'); // apply to sheet name only
  var rows = sheet.getRange('A5:M'); // range to apply formatting to
  var numRows = rows.getNumRows(); // no. of rows in the range named above
  var values = rows.getValues(); // array of values in the range named above
  var testvalues = sheet.getRange('A5:A').getValues(); // array of values to be tested (1st column of the range named above)

  rows.setBorder(false, false, false, false, false, false, "black", SpreadsheetApp.BorderStyle.SOLID); // remove existing borders before applying rule below

  for (var i=0; i <= numRows-1; i++) 
      var n = i + 5;
      //Logger.log(n);
      //Logger.log(testvalues[i] > 0);
      //Logger.log(testvalues[i]);
      if (testvalues[i] > 0)  // test applied to array of values
        sheet.getRange('A' + n + ':M' + n).setBorder(true, true, true, true, true, true, "black", SpreadsheetApp.BorderStyle.SOLID); // format if true
      
  
;

【讨论】:

非常感谢您对此的帮助。但是,我没有意识到我的脚本接近工作的原因是因为它只适用于数字。当 A 列包含 any 文本时,有没有办法让脚本为行添加边框? 我想它在这里:if (testvalues[i] &gt; 0) // test applied to array of values。您只需以这种方式更改条件if (testvalues[i] !="") 【参考方案3】:

无需任何脚本,您可以先在 MS Excel 中使用条件格式,然后将工作簿导入 Google 表格!奇怪...

【讨论】:

以上是关于使用 Apps 脚本对 Google 表格中的边框进行条件格式设置的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Google Apps 脚本中使用服务帐户对 Google 表格进行身份验证

使用 Google Apps 脚本对范围启用数据过滤器

使用Google Apps脚本删除Google表格中的行

如何保护 Google 电子表格中的 Apps 脚本代码?

是否可以使用 Apps 脚本运行 Google 表格插件?

Google 表格中的 Google Apps 脚本是不是有类似悬停的触发器?