I'm trying to write a script that finds all the checkboxes in a Google Sheet, and resets them all to unchecked. (A daily sheets cleanup) I am able to get an array of all the cells that contain checkboxes from one sheet and uncheck them, but I'm spinning my wheels here on how to efficiently get all the checkboxes on all sheets to uncheck. I see there is a method called uncheck() so that's what I'm trying to use. My script and array is below. My questions are...
Currently I'm looping through the array and unchecking each box one at a time. The script is kinda slow and my end goal is to have this go through all sheets within the spreadsheet. I'm concerned the script may time out. Is there a way to uncheck all the checkboxes on 1 sheet at once, without doing a loop that goes through them 1 at a time? Or even better having it do all checkboxes on all sheets at once? Obviously unchecking them in 1 go would be more efficient, but idk if that's an option and everything I've tried has not worked. (I've also considered replacing the file each day with a template file that has all the checkboxes unchecked already, however I need the document ID to never change)
How do I get my script to go through all tabs of the spreadsheet? Would that be getting all the sheets and doing another for loop? Or is there a more efficient way to do this too?
Script:
function uncheckCheckboxes() {
var spreadsheet=SpreadsheetApp.getActive(); // get spreadsheet
var sheet=spreadsheet.getActiveSheet(); // get current sheet
var allRange=sheet.getDataRange(); // get all data in sheet
var validations=allRange.getDataValidations();
var Checkboxes=[]; // create empty array
for(var i=0;i<validations.length;i++) {
for(var j=0;j<validations[i].length;j++) {
var rule=validations[i][j];
if(rule!=null) {
var criteria = rule.getCriteriaType();
if(criteria == SpreadsheetApp.DataValidationCriteria.CHECKBOX) {
Checkboxes.push(Utilities.formatString('%s', sheet.getRange(i+1,j+1).getA1Notation())); // get array of only cells w/ checkboxes
}
}
}
}
Logger.log(Checkboxes) // Logging
for (var CB in Checkboxes) { // Loop through array
var checkbox = Checkboxes[CB];
sheet.getRange(checkbox).uncheck(); // uncheck checkbox
}
}
Array from 1 sheet (stored in 'Checkboxes' variable): [C3, D3, E3, F3, G3, H3, C4, D4, E4, F4, G4, H4, C5, D5, E5, F5, G5, H5, C6, D6, E6, F6, G6, H6, C7, D7, E7, F7, G7, H7, C8, D8, E8, F8, G8, H8, C9, D9, E9, F9, G9, H9, C10, D10, E10, F10, G10, H10, C11, D11, E11, F11, G11, H11, C12, D12, E12, F12, G12, H12, C13, D13, E13, F13, G13, H13, C14, D14, E14, F14, G14, H14, C15, D15, E15, F15, G15, H15, C16, D16, E16, F16, G16, H16, C17, D17, E17, F17, G17, H17, C18, D18, E18, F18, G18, H18, C19, D19, E19, F19, G19, H19, C20, D20, E20, F20, G20, H20, C21, D21, E21, F21, G21, H21, C22, D22, E22, F22, G22, H22, C23, D23, E23, F23, G23, H23, C24, D24, E24, F24, G24, H24, C25, D25, E25, F25, G25, H25, C26, D26, E26, F26, G26, H26, C27, D27, E27, F27, G27, H27, C28, D28, E28, F28, G28, H28, C29, D29, E29, F29, G29, H29]
I've been working on this for hours and would love some expertise from someone who actually knows what they are doing. (I'm definitely no JavaScript expert!)
Untested, can't test at the moment.
function uncheckCheckboxesFromAllSheets() {
// Should uncheck all checkboxes from all worksheets
// in a given document.
const spreadsheet = SpreadsheetApp.getActive();
for (const sheet of spreadsheet.getSheets()) {
Logger.log(`About to uncheck checkboxes in sheet ${sheet.getName()}`);
sheet.getDataRange().uncheck();
}
}
Documentation for Range.uncheck()
(https://developers.google.com/apps-script/reference/spreadsheet/range#uncheck):
Changes the state of the checkboxes in the range to “unchecked”. Ignores the cells in the range which currently do not contain either the checked or unchecked value configured.
Think that means you can pass it a multi-cell range and the uncheck
function will internally take care of details for you (like skipping irrelevant cells).
Unrelated: If you have an array and you need to loop over its values directly, maybe use for-of
loop instead of for-in
.