首页 > 解决方案 > Google 应用程序脚本 - 基于不匹配的单元格设置边框格式以构建易于阅读的报告

问题描述

我需要在报告中添加边框(以便于阅读)。我发现了一些接近的代码并尝试对其进行调整,但我显然对数组和范围的理解不足以了解正在发生的事情。 我正在使用的 Google 表格. 我基本上想要一个边框来显示学生及其数据组何时发生变化(A 到 H)。因为每个学生的“健康访问”、“缺勤”、“出席百分比”和“缺课”累计为一个值;但是一个学生学习了不止一门课程并且每门课程都获得了分数,我将字体设置为白色(使用基于 K 列中的值的条件格式),因此如果每个课程超过一组数据,它就不会一遍又一遍地显示学生。我使用 VLOOKUP 来提取我需要的数据;然后是一个连接公式,将 K 列中的分组数据拉到一起(忽略类别和分数)。我想通读 K 列,当值更改(或不匹配)时,我想在该行上方添加一个边框显示学生之间的休息。可能有更好/更简单的方法来做到这一点 - 但它' s 什么我已经想出到目前为止。任何帮助表示赞赏。谢谢!

这里有两张屏幕截图——一张是没有边框的报告,一张是我希望它看起来像有边框的: 这是我正在使用的代码。我在我缺乏理解的评论中添加了:在此处输入图像描述 在此处输入图像描述

function applyBorders() {

    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = ss.getSheetByName("Report");

    // 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(2, 12, sheet.getLastRow(), sheet.getLastColumn()).getValues(); //This I don't understand. I want it to be column K so
                                                                                             // so it can read through and find the dupes.

    // setup new array  
    var ListofIdentifiers = new Array();  //I don't understand what this does . . . just hold a space for the new array values?

    // Loop through the Identifying Column (Column K?)
    for (var i in data) {
        var row = data[i][1].toString(); //Is this converting to a string because it is a formula? Should I cut and paste special to make it values vs. a formula?


        // search for Identifiers that don't match
        if (ListofIdentifiers.indexOf(row) !=-1) { // if value is not =-1, then the variable is not unique

            // underline the previous row -- not understanding exactly what the range below is looking at?
            var range = sheet.getRange((+i + 1), 9, 1, 1).setBorder(true, false, false, false, false, false, "blue", SpreadsheetApp.BorderStyle.SOLID_MEDIUM); // format if true

            // continue to build array
            ListofIdentifiers.push(row);
        }

    }
    // underline the last row  - this works!
    var range = sheet.getRange(LastRow, 1, 1, 10).setBorder(null, null, true, null, false, false, "blue", SpreadsheetApp.BorderStyle.SOLID_MEDIUM); // format if true
    // Logger.log(ListofFruits);// DEBUG
}

在此处输入图像描述

标签: google-apps-scriptgoogle-sheets

解决方案


我复制了您的代码,修改了一些部分并添加了一些注释。

尝试这个:

function applyBorders() {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = ss.getSheetByName("Report");
    
    var LastRow = sheet.getLastRow();
    var LastColumn = sheet.getLastColumn();
    var StartRow = 2;
    var StartCol = 11;
    
    //erase any current formatting 
    sheet.getRange(1, 1, LastRow, LastColumn).setBorder(false, false, false, false, false, false); // clear all formatting
    
    // get the data from column K
    var range = sheet.getRange(StartRow, StartCol, sheet.getLastRow()-1, 1);
    var data = range.getValues();
    //The data we collect are rows of data, each row represent sub array in 2d array.
    //merge 2d array into 1d
    var merged = [].concat.apply([], data);
    //loop through each element of merged array.
    for( var i in merged){
      var id = merged[i];
      var id_prev = merged[parseInt(i)-1];
      
      //check if the current id is not equal to the previous id
      //added id_prev != undefined to prevent true if i == 0
      if(id != id_prev && id_prev != undefined){
        //set top border
        var borderRange = sheet.getRange((StartRow + parseInt(i)), 1, 1, 10);
        borderRange.setBorder(true, false, false, false, false, false, "blue", SpreadsheetApp.BorderStyle.SOLID_MEDIUM);        
      }
    }
    sheet.getRange(LastRow, 1, 1, 10).setBorder(null, null, true, null, null, null, "blue", SpreadsheetApp.BorderStyle.SOLID_MEDIUM);
}

输出:

输出

参考:


推荐阅读