【问题标题】:Conditional borders in Google SheetsGoogle 表格中的条件边框
【发布时间】:2018-10-29 20:42:06
【问题描述】:

我正在尝试完全按照Add border format to row if condition met in Google Sheets 的要求去做,但接受的答案根本不起作用。原帖说的很清楚了,这里再放一遍:

Excel 显然具有这种类型的条件格式 built-in.

我想通过Google Apps Script 在 Google 表格中完成相同的操作。下面应该演示之前和之后 条件:

示例数据集

        A           B           C
  1   apple     Macintosh
  2   apple     Granny Smith
  3   orange    Florida
  4   orange    Valencia
  5   pear      Garden
  6   banana    Chiquita

生成的示例数据集

        A           B           C
  1   apple     Macintosh
  2   apple     Granny Smith
  -----------------------------------
  3   orange    Florida
  4   orange    Valencia
  -----------------------------------
  5   pear      Garden
  -----------------------------------
  6   banana    Chiquita
  -----------------------------------  

此问题的脚本/答案应显示底部边框 在整行(列“A”、“B”和“C”)下,第 2、4、5 和 6 行。

这个原始帖子的接受答案提供了以下脚本:

function onOpen() {
   GroupMyData(); // trigger this function on sheet opening
}

function GroupMyData() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('Sheet 1'); // apply to sheet name only
  var rows = sheet.getRange('a1:g'); // 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('a1:a').getValues(); // array of values to be tested (1st column of the range named above)

  rows.setBorder(false, false, false, false, false, false, "red", SpreadsheetApp.BorderStyle.SOLID_MEDIUM); // 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 + ':g' + n).setBorder(null, null, true, null, null, null, "red", SpreadsheetApp.BorderStyle.SOLID_MEDIUM); // format if true
      }
  }
};

该脚本的功能如下: 每一行的底部都会出现一个边框,其中 A 列的单元格中有一个数字(并且没有字母),无论该数字是否与其上方单元格中的数字相同或不同。

但是,A 的目标是要有文本,并且当 A 列下的连续文本从重复字符串变为不同字符串时,不同字符串之间应该有一个边框。

【问题讨论】:

    标签: google-apps-script google-sheets google-sheets-api


    【解决方案1】:

    提问者指的是之前基于评估数字的问答。在提问者的情况下,评估是基于一个字符串。

    我提到了提问者提到的问题。我还提到了How to compare strings in google apps script,其中包含Harold 提出的一种非常优雅和有效的方法,我在这个答案中已经采用了这种方法。这使用indexof 来检测新值,因此下划线可以与每个新值相关联。

    function so53053492() {
    
        //setup spreadsheet
        var ss = SpreadsheetApp.getActiveSpreadsheet();
        var sheet = ss.getSheetByName("Sheet1");
    
        // get key variables
        var LastRow = sheet.getLastRow();
        var LastColumn = sheet.getLastColumn();
    
        //erase any current formatting 
        var ClearRange = sheet.getRange(1, 1, LastRow, LastColumn).setBorder(false, false, false, false, false, false); // clear all formatting
    
        // get the data
        var data = sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();
    
        // setup new array  
        var ListofFruits = new Array();
    
        // Loop through the fruits (Column A)
        for (var i in data) {
            var row = data[i][0].toString();
    
    
            // search for unqiue values
            if (ListofFruits.indexOf(row) == -1) { // if value =-1, then the variable is unique
    
                // Logger.log(row+" is not referenced. Adding it");//DEBUG
                // underline the previous row
                var range = sheet.getRange((+i + 1), 1, 1, 2).setBorder(true, false, false, false, false, false, "red", SpreadsheetApp.BorderStyle.SOLID_MEDIUM); // format if true
    
                // continue to build array
                ListofFruits.push(row);
            }
    
        }
        // underline the last row of the fruits column
        var range = sheet.getRange(LastRow, 1, 1, LastColumn).setBorder(null, null, true, null, false, false, "red", SpreadsheetApp.BorderStyle.SOLID_MEDIUM); // format if true
        // Logger.log(ListofFruits);// DEBUG
    }
    


    更新 - 标题会计


    以前的版本假定没有标题。这个版本考虑了标题。有几行代码受到影响,但关键变量是headerRows,它允许用户指定标题的深度。

    function so53053492_01() {
    
        //setup spreadsheet
        var ss = SpreadsheetApp.getActiveSpreadsheet();
        var sheet = ss.getSheetByName("Sheet3");
    
        // get key variables
        var LastRow = sheet.getLastRow();
        var LastColumn = sheet.getLastColumn();
        var NumColumns = sheet.getMaxColumns();
    
        // allow for headers
        var headerRows = 2;
    
        //erase any current formatting 
        var ClearRange = sheet.getRange(1, 1, LastRow, NumColumns).setBorder(false, false, false, false, false, false); // clear all formatting
    
        // get the data
        var data = sheet.getRange((+1 + headerRows), 1, (LastRow - headerRows), LastColumn).getValues();
    
        // setup new array  
        var ListofFruits = new Array();
    
        // Loop through the fruits (Column A)
        for (var i in data) {
    
            var row = data[i][0].toString();
            // Logger.log("Inside LOOP: i = "+i+", value = "+ row);// DEBUG
    
            // search for unqiue values
            if (ListofFruits.indexOf(row) == -1) { // if value =-1, then the variable is unique
    
                // Logger.log("Inside IF#1: i = "+i+", "+row+" is not referenced. Adding it");//DEBUG
                // underline the previous row
    
                if (i != 0) {
                    // This IF statement to avoid underlining the Header row
                    var range = sheet.getRange((+i + 1 + headerRows), 1, 1, NumColumns).setBorder(true, false, false, false, false, false, "red", SpreadsheetApp.BorderStyle.SOLID_MEDIUM); // format if true
                }
                // continue to build array
                ListofFruits.push(row);
            }
    
        }
        // underline the last row of the fruits column
        var range = sheet.getRange(LastRow, 1, 1, NumColumns).setBorder(null, null, true, null, false, false, "red", SpreadsheetApp.BorderStyle.SOLID_MEDIUM); // format if true
        //Logger.log(ListofFruits);// DEBUG
    }
    

    显示标题的屏幕截图:


    【讨论】:

    • 这已经接近完美了。我非常欣赏这段代码的清晰性。我正在尝试调整的两件小事:(1)如何让它在某个行号之后开始添加边框? IE。忽略前两行,它们是我实际文档中的标题。并且(2)我希望边框跨越行的整个长度,无论可能存在多少列。我看到我的原始帖子没有正确可视化,将修复。我在第 30 行找到了会改变它跨越多少列的数字,但理想情况下,它不会是存在的静态列数,这可能会改变。谢谢!
    • 我为自己更改了此脚本以运行 onOpen,这样我就不必每次都手动触发它。如何更改它以使其在 onEdit 上运行但仅适用于 A 列中的编辑? (我已经搜索过这个,但我似乎无法将我在其他地方找到的脚本用到这个脚本中)
    • 这是一个很好的指南 [stackoverflow.com/a/27112175/1330560].在您的情况下:添加var activeSheet = e.source.getActiveSheet();if (activeSheet.getName() !== "Sheet3" &amp;&amp; e.value.getColumn() !== 1) return;。把它放在// get key variables 上面的行中。如果活动工作表不是“Sheet3”并且编辑的单元格不在 A 列 (Col=1) 中,则脚本应该退出。 -所有未经测试;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    • 2014-11-27
    相关资源
    最近更新 更多