使用 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 表格中的边框进行条件格式设置的主要内容,如果未能解决你的问题,请参考以下文章