Filter Or Hide Row

老子叫甜甜 提交于 2020-01-11 04:12:06

问题


[Back story] I have a Google Sheet I use for emailing schedules to subcontractors. Each subcontractor has their own sheet, and I also have one last sheet called MasterSchedule.

The master schedule uses references to all the individual sheets such that all subcontractor schedules are visible. This is reaaaaaal long though. So I included a helper column in all sheets that simply returns true or false indicating whether a row should be displayed or not on the master.

However the row is still displayed on the master, but the helper column just happens to say false. So I used the AutoFilter to Hide it.

TLDR:

Problem: Google Apps Script doesn't have API for the auto-Filter. Like VBA using criteria etc. So The only option I see is to hide rows. But this is very slow. I know the idea is to reduce the number of calls to the Google services, and Google suggests making an array then excuting a call on the array. I have no idea how to do this.

I need an efficient script/function to look at a column and every cell that reads false, the function will hide the entire row, and show all other rows.

The fastest non script method is to use Google Sheets version of auto-filter and simply un-check false.

I tried making a for loop that reads each cell in a column and per iteration hides the row if the cell value is false. It is incredibly slow.

See:

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:


I had to change one line of your original code, to get it to work:

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

With that, I timed it on a test spreadsheet, ~200 rows with an even distribution of true / false cells. The execution transcript reported [4.656 seconds total runtime].

As you suspected, you can reduce the Service calls by using an array with a set of data (in this case, all of column B). Here's the "hide" method, using an array for testing visibility:

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));
    }
  }
}

According to the execution transcript, this took [0.106 seconds total runtime] for the test sheet. Watching the screen, it looked like 3 or 4 seconds by the time it refreshed.

Here's another way to do it. In this one, we read all the data on the Master Sheet, then use Array.filter() to reduce the two-dimensional array to just the rows with true in column B. This smaller set is then written to the Master Sheet, after we clear all previous contents. This cut the execution time in half, [0.059 seconds total runtime] according to the execution transcript. Once again, delays in the refresh of the viewed copy made it look like a couple of seconds.

// 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); 
}


来源:https://stackoverflow.com/questions/18707027/filter-or-hide-row

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