I'm trying to come up with a function that will clear contents (not delete row) if all cells in a range have values. The script below isn't functioning as expected, and I would really appreciate any help/advice you all have. It's currently only clearing out a single line, and doesn't appear to be iterating over the whole dataset. My thought was to iterate over the rows, and check each cell individually. If each of the variables has a value, clear that range and go to the next row.
Here's a link to a sample Google Sheet, with data and the script in Script Editor.
function MassRDDChange() {
// Google Sheet Record Details
var ss = SpreadsheetApp.openById('1bcrEZo3IkXiKeyD47C_k2LIRy9N9M6SI2h2MGK1Cj-w');
var dataSheet = ss.getSheetByName('Data Entry');
// Initial Sheet Values
var newLastColumn = dataSheet.getLastColumn();
var newLastRow = dataSheet.getLastRow();
var dataToProcess = dataSheet.getRange(2, 1, newLastRow, newLastColumn).getValues().filter(function(row) {
return row[0]
}).sort();
var dLen = dataToProcess.length;
// Clear intiial sheet
for (var i = 0; i < dLen; ++i) {
var row = 2;
var orderNumber = dataToProcess[i][0].toString();
var rdd = dataToProcess[i][1].toString();
var submittedBy = dataToProcess[i][2].toString();
var submittedOn = dataToProcess[i][3].toString();
if (orderNumber && rdd && submittedBy && submittedOn) {
dataSheet.getRange(row, 1, 1, newLastColumn).clear();
row++;
} else {
row++; // Go to the next row
continue;
}
}
}
Thanks!
Since you don't want to delete the rows, just
clear()
them, and they're all on the same worksheet tab, this is a great use case forRangeList
s, which allow you to apply specificRange
methods to non-contiguousRange
s. Currently, the only way to create aRangeList
is from a an array of reference notations (i.e. aRangeList
is different than an array ofRange
objects), so the first goal we have is to prefix our JavaScript array of sheet data to inspect with a usable reference string. We could write a function to convert array indices from 0-base integers to A1 notation, but R1C1 referencing is perfectly valid to pass to theRangeList
constructor, so we just need to account for header rows and the 0-base vs 1-base indexing difference.The strategy, then, is to:
Array
Filter
the sheet data array based on the contents of each elementRangeList
constructorRangeList
methods on theRangeList
Because this approach uses only 3 Spreadsheet calls (besides the initial setup for a batch read), vs 1 per row to clear, it should be considerably faster.
Note that because these cleared rows are possibly disjoint, your resulting sheet may be littered with rows having data, and rows not having data. A call to
sheet.sort(1)
would sort all the non-frozen rows in the sheet, moving the newly-empty rows to the bottom (yes, you can programmatically set frozen rows). Depending how this sheet is referenced elsewhere, that may not be desirable though.Additional references:
Array#filter
Array#reduce
Array#map