Google script change row color based on data change, sheet sorted

冷暖自知 提交于 2020-07-10 07:37:05

问题


Link to demo sheet

I have a sheet which is sorted by column E. Values in column E can be duplicate, which means that several rows can have the same value in column E. Now I want to color rows which signify a change in column E. Here's the code that I've built based on some great answers on StackOverflow:

function quicktest() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
  var rangeData = spreadsheet.getDataRange().getValues();
  var lastRow = spreadsheet.getLastRow();
  //  var searchRange = spreadsheet.getRange(1, 1, lastRow-1, 5);
//  var rangeValues = searchRange.getValues();
  var previousclient = rangeData[2][5];
  console.log(previousclient);
  for ( j = 1 ; j < lastRow - 1; j++){
    var currentclient = rangeData[j][5];
    console.log(previousclient," ",currentclient);
    if (previousclient != currentclient) {
      spreadsheet.getRange(j,1,1,5).setBackground("#cc4125");
      previousclient = currentclient;  
    }; 
}

The code runs, but the result is that it's "painting" the wrong cell and it's also not painting the entire row (columns A to H), it's painting just A to C. I've also read some answers here that recommend sending the values to rangeValues, but that didn't work me. That's why it's listed as a comment in the code. Perhaps I do need to use it. Here's how I'd like to demo sheet to look like after running this code:

Thanks


回答1:


Be careful with indices - arrays start with [0]

The respective confusion leads to several problems in your code:

  • rangeData[2][5] means cell F3 - not E, if you want to retrieve the column E - it corresponds to the array index 4 (both for previous and current client!)
  • Given that the initial previousclient is not suposed to be colored (only the following onew) you should set it to the header row, so rangeData[0][4]
  • When you use the method getRange() - the row indices start with 1 (unlike array elements!!!), so array element i corresponds to the rowi+1

To fix those issue modify your code as following:

function change_row_color() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
  var rangeData = spreadsheet.getDataRange().getValues();
  var lastRow = spreadsheet.getLastRow();
  var previousclient = rangeData[0][4];
  console.log(previousclient);
  for ( j = 1 ; j < lastRow - 1; j++){
    var currentclient = rangeData[j][4];
    console.log(previousclient," ",currentclient);
    if (previousclient != currentclient) {
      spreadsheet.getRange(j+1,1,1,5).setBackground("#cc4125");
      previousclient = currentclient;  
    };
  }}

UPDATE

Calls to external services including SpreadsheetApp methods should be minimized because they make your code slower.

So, for example calling setBackground within each loop will result in a longer execution time.
If you want to set the colors only once with setBackgrounds instead of setBackground, you can do it like this:

function change_row_color() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
  var range = spreadsheet.getDataRange();
  var rangeData = range.getValues();
  var lastRow = spreadsheet.getLastRow();
  var previousclient = rangeData[0][4];
  console.log(previousclient);
  var colors = [[0,0,0,0,0]];
  for ( j = 1 ; j < lastRow; j++){
    var currentclient = rangeData[j][4];
    console.log(previousclient," ",currentclient);
    if (previousclient != currentclient) {
      colors.push(["#cc4125","#cc4125","#cc4125","#cc4125","#cc4125"]);
      previousclient = currentclient;  
    } else{
      colors.push([0,0,0,0,0]);
    }
  }
range.setBackgrounds(colors);
}

Either this approach will be faster strongly depends on your data size and amount of duplicates.



来源:https://stackoverflow.com/questions/62590592/google-script-change-row-color-based-on-data-change-sheet-sorted

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!