[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);
}
}
}
I had to change one line of your original code, to get it to work:
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:
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 withtrue
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.