应用脚本:根据行号数组构造行范围

时间:2015-07-01 14:39:02

标签: google-apps-script google-sheets

我在电子表格中有一个行号列表,我需要更改其背景颜色。由于电子表格非常大(10张以上,每张都有近5000行),我正在尝试构建一个范围,以便我可以批量设置背景,因为单独执行每行占用的最长时间为6分钟。

这是我的代码:

// highlight required rows
var first = -1, last = -1;
for(var j = 0; j < rowNumsToHighlight.length; j++) {
  if(first == -1) {
    first = rowNumsToHighlight[j];
    continue;
  }

  // if the current row number is one more than the previous, update last to be the current row number
  if(rowNumsToHighlight[j] - 1 == rowNumsToHighlight[j - 1]) {
    last = rowNumsToHighlight[j];
    continue;
  }
  // otherwise the last row should be the previous one
  else {
    last = rowNumsToHighlight[j - 1];
  }

  var numRows = (last - first) + 1;
  var range = sheet.getRange(first, 1, numRows, 4);
  if(range.getBackground().toUpperCase() != highlightColour.toUpperCase()) {
    range.setBackground(highlightColour);
  }

  first = -1; 
  last = -1;
}

rowNumsToHighlight只是一个类似于[205,270,271,272,278,279]的数组。因此,以此为例,setBackground应该在第205行,第270-272行和第278-279行上运行。

我很确定解决方案很简单,但却看不到它。谢谢你的帮助。

====更新了代码====

根据下面的Serge代码,我通过减少getRange()次呼叫的数量,再次提高了效率。时间从78秒减少到54秒。

function updateColours(sheet, array, colour){
  var columns = sheet.getLastColumn();
  var rows = sheet.getLastRow();
  var range = sheet.getRange(1, 1, rows, columns);

  Logger.log("Resetting highlight on all rows...");
  range.setBackground(null);

  var backgrounds = range.getBackgrounds();
  for(var n = 0; n < backgrounds.length; n++){
    var rowIdx = n + 1;
    if(array.indexOf(rowIdx) > -1){
      for(var c = 0; c < columns; c++){
        backgrounds[n][c] = colour;
      }
    }
  }
  Logger.log("Highlighting non-translated rows...");
  range.setBackgrounds(backgrounds);
}

2 个答案:

答案 0 :(得分:3)

也许这个更快(?)并以一种方式构建,使您的工作更轻松(带参数的函数)。

它仅向工作表写入一次(如果在写入前清除颜色,则为2)...

使用如下:

((ImageView) findViewById(R.id.imageView2)).setBackgroundResource(R.drawable.your_image_name_here)

test sheet in view only,制作副本进行测试。

答案 1 :(得分:1)

我就是这样做的:

function createRanges() {
  var rowNumsToHighlight = [5,7,8,9,18,19];
  var arrayLength = rowNumsToHighlight.length;
  var loopCounter = 0, thisNumberInArray=0, nextNumberInArray=0, crrentNmbrPlusOne=0;
  var currentRangeBegin=0, numberOfRowsInRange=1;

  currentRangeBegin = rowNumsToHighlight[0];

  for(loopCounter=0; loopCounter < arrayLength; loopCounter+=1) {
    thisNumberInArray = rowNumsToHighlight[loopCounter];
    nextNumberInArray = rowNumsToHighlight[loopCounter+1];
    crrentNmbrPlusOne = thisNumberInArray+1;

    if (nextNumberInArray===undefined) {
      workOnTheRange(currentRangeBegin, numberOfRowsInRange);
      return;
    };

    if (nextNumberInArray!==crrentNmbrPlusOne) {
      workOnTheRange(currentRangeBegin, numberOfRowsInRange);
      numberOfRowsInRange = 1; //Reset to 1
      currentRangeBegin = nextNumberInArray;
    } else {
      numberOfRowsInRange+=1;
    };
  };

};

function workOnTheRange(first,numRows) {
  var range = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet11').getRange(first, 1, numRows, 4);
  range.setBackground("red");
};

我已经测试了代码,但它确实有效。