过滤或隐藏行

时间:2013-09-09 21:05:15

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

[返回故事] 我有一张Google工作表,用于通过电子邮件将时间表发送给分包商。每个分包商都有自己的表格,我还有一张名为MasterSchedule的最后一张表。

主计划使用对所有单个工作表的引用,以便所有转包计划都可见。尽管如此,这仍然很重要。因此,我在所有工作表中都包含了一个帮助列,只返回 true false ,指示是否应在主数据库中显示行。

然而,行仍然显示在主服务器上,但是帮助程序列恰好是假的。所以我用AutoFilter来隐藏它。

TLDR:

问题:Google Apps脚本没有自动过滤器的API。像VBA使用标准等。所以我看到的唯一选择是隐藏行。但这很慢。我知道这个想法是为了减少对Google服务的调用次数,谷歌建议制作一个阵列然后在阵列上拨打电话。我不知道该怎么做。

我需要一个高效的脚本/函数来查看列和每个读取 false 的单元格,该函数将隐藏整行,并显示所有其他行。

最快的非脚本方法是使用Google表格版自动过滤器,只需取消选中 false

我尝试创建一个for循环来读取列中的每个单元格,如果单元格值为false,则每次迭代都会隐藏该行。 速度非常慢。

请参阅:

function MasterFilter() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var maxRows = sheet.getMaxRows();

  //show all the rows
  sheet.showRows(1, maxRows);

  //get data from column B
  var data = sheet.getRange('B:B').getValues();

  //iterate over all rows
  for(var i=5; i< data.length; i++){
    if(sheet.getRange(i,2).getValue() == false){
      sheet.hideRow(i);
    }
  }
}

1 个答案:

答案 0 :(得分:1)

我必须更改原始代码的一行,才能使其正常工作:

  sheet.hideRow(sheet.getRange(i,2));  // Operates on a range

有了这个,我把它计时在一个测试电子表格上,大约200行,true / false个单元格均匀分布。执行记录报告[4.656 seconds total runtime]

如您所料,您可以通过使用包含一组数据的数组(在本例中为B列的所有内容)来减少服务调用。这是“隐藏”方法,使用数组来测试可见性:

function MasterFilter() {
  var headers = 4; // # rows to skip
  var sheet = SpreadsheetApp.getActiveSheet();
  var maxRows = sheet.getMaxRows();

  //show all the rows
  sheet.showRows(1, maxRows);

  //get data from column B
  var data = sheet.getRange('B:B').getValues();

  //iterate over all rows
  for(var i=headers; i< data.length; i++){
    if(data[i][0] == false){
      sheet.hideRow(sheet.getRange(i+1,1));
    }
  }
}

根据执行记录,这需要[0.106 seconds total runtime]作为测试表。观看屏幕时,刷新时看起来像是3或4秒。

这是另一种方法。在这一篇中,我们读取了主表上的所有数据,然后使用Array.filter()将二维数组简化为只有列B中true的行。然后将这个较小的集合写入在我们清除所有以前的内容后,主表。根据执行记录,这会将执行时间缩短一半[0.059 seconds total runtime]。再一次,刷新查看副本的延迟使它看起来像几秒钟。

// Evaluation function for Array.filter()
function isVisible(row) {
  return (row[1] === true);  // Check column B
}

function MasterFilter2() {
  var headers = 4; // # rows to skip
  var sheet = SpreadsheetApp.getActiveSheet();
  var data = sheet.getDataRange().getValues();
  var headerData = data.splice(0,headers); // Skip header rows
  var filteredData = data.filter( isVisible );
  var outputData = headerData.concat(filteredData);  // Put headers back

  sheet.clearContents();  // Clear content, keep format

  // Save filtered values
  sheet.getRange(1, 1, outputData.length, outputData[0].length).setValues(outputData); 
}