Unchecking Checkboxes in Google Sheets - google-apps-script

For the life of me I can't figure out how set it up. I would like the function to check the entire sheet... alternatively I do know which specific ranges (B5:B26; G5:G26...AF5:AF26) on a specific sheet, if i can't set it up for the entire sheet...
function setFalse()
{
var sheet = SpreadsheetApp.getSheetByName("Test");
var dataRange = sheet.getRange('A:AN28');
var values = dataRange.getValues();
for (var i = 0; i < values.length; i++)
{
for (var j = 0; j < values[i].length; j++)
{
if (values[i][j] == true)
{
values[i][j] = false; // Modified
}
}
}
dataRange.setValues(values);
};

There's a built-in method to uncheck called uncheck(). You can effectively apply it to the sheet by using getDataRange().
function setFalse() {
SpreadsheetApp.getActive().getSheetByName("Test").getDataRange().uncheck();
};
Lastly, looking at your original code, don't forget to get a spreadsheet file before selecting the sheet.

Related

Delete all Sheets except one, loop within a loop

I have a spreadsheet that contains a list of URLS for spreadsheets and the sheet name that I want to keep.
The idea is that I delete all sheets within each of those spreadsheets except the sheet I want to keep.
I have written a script but I can not seem to get it to work, I get an error message of "invalid argument line 20" but I can not figure out why.
I have pasted my code below, any help would be appreciated.
function DeleteImportedData(){
var s3 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("URL's")
var s1 = SpreadsheetApp.getActiveSpreadsheet()
var sh1 = s1.getSheetByName("MasterSheet")
var copy = sh1.getRange(1,1,sh1.getLastRow(),sh1.getLastColumn()).getValues()
var getHeader = sh1.getRange(1,1,1,25).getValues()
for (var j = 1;j<s3.getLastRow(); j++){
var filterName = s3.getRange(j+1, 1).getValue()
var id = s3.getRange(j+1,2).getValue()
var open = SpreadsheetApp.openById(id)
var sheet = open.getSheets()[0];
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
var sh3 = open.getSheetByName("STSOR - "+filterName)
}
for (i = 0; i <= sheets.length; i++) {
switch(sheets[i]) {
case sheet.getSheetName() === sh3:
break;
default:
open.setActiveSheet(sheet[i]);
open.deleteActiveSheet;
open.deleteSheet(del)
}
}
}
when you delete the first sheet from the list Sheet1, Sheet2, Sheet3 - Sheet2 changes its index to Sheet1. So it is better to delete sheets from the end
try to use the reverse loop
for (i = sheets.length-1; i >=0 ; i--){
... your code ...
}
There is something wrong between your variable sheet and sheets and your second loop.
Try this way :
for (var j = 1;j<s3.getLastRow(); j++){
// your code
// second loop inside the first loop
for (i = 0; i <= sheets.length; i++) {
switch(sheets[i]) {
case sheets[i].getSheetName() === sh3: //instead of 'sheet'
break;
default:
open.setActiveSheet(sheets[i]); //instead of 'sheet'
open.deleteActiveSheet;
open.deleteSheet(del)
}
} // close first loop
} // close second loop
but I think the second loop would be cleaner that way (IMHO):
for (i = 0; i <= sheets.length; i++) {
if (sheets[i].getSheetName() !== sh3) {
open.deleteSheet(sheets[i].getSheetName());
}
}
If this code doesn't answer your question, please provide more informations about your spreadsheets

Why does ss.deleteSheet() unhide one hidden sheet

I've written a little script that automatically deletes all Sheets my user accidentally create.
Often, when accessing the spreadsheet with their phone, they accidentally click on "+" and create tons of empty sheets, like Sheet101, Sheet102, etc.
My script is very simple: gets all sheets, and if the name starts with Sheet, just deletes it.
It works perfectly, but after deleting all the undesired sheets, the problem is that it automatically unhides the first hidden sheet (some sheets are hidden for practical use, like they contain lists).
For example, if I have the following hidden sheets:
oldform, list1, list2, ...
After executing the script, the sheet oldform will be unhidden, thus appearing to the users.
Here is two codes I've tried:
The simple one:
function DELETESHEETS2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
for (i = 0; i < sheets.length; i++) {
if ( sheets[i].getName().indexOf("Sheet") > -1 ) {
ss.deleteSheet(sheets[i]);
}
}
}
The one I tried to modify to solve my problem:
function DELETESHEETS3() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
for (i = 0; i < sheets.length; i++) {
if ( sheets[i].getName().indexOf("Sheet") > -1 ) {
label = sheets[i].getName();
toto = ss.getSheetByName(label);
ss.deleteSheet(toto);
}
}
}
The reverse loop
With this one, the hidden sheet appears at the beginning and not at the end:
function DELETESHEETS2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
for (i = sheets.length -1; i > 0 ; i--) {
if ( sheets[i].getName().indexOf("Sheet") > -1 ) {
ss.deleteSheet(sheets[i]);
}
}
}
A partial solution
This one works, thanks to #OMila. But it does not explain the weird behavior of a simple loop. Maybe I missed something?
function DELETESHEETS2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var hdnShts = [];
for (var i = 0; i < sheets.length; i++) {
if(sheets[i].isSheetHidden()) {
hdnShts.push(sheets[i].getName()); //saving all the hidden sheet names for later
}
}
for (i = 0; i < sheets.length; i++) {
if ( sheets[i].getName().indexOf("Sheet") > -1 ) {
ss.deleteSheet(sheets[i]);
}
}
for(var i = 0; i<hdnShts.length; i++) {
ss.getSheetByName(hdnShts[i]).hideSheet(); //just to make sure all the hiddens remain hidden
}
}
Thanks for your help if you have any idea!
PS: this problem is easy to reproduce, just create lots of sheets including one with a name other than Sheetxxx
Try this:
function delSheetsKeepHidden() {
var ss = SpreadsheetApp.getActive();
var shts = ss.getSheets();
var hdnShts = [];
for (var i = 0; i < shts.length; i++) {
if(shts[i].isSheetHidden()) {
hdnShts.push(shts[i].getName()); //saving all the hidden sheet names for later
}
}
for(var i = 0; i < shts.length; i++) {
if(shts[i].getName().slice(0,5).toLowerCase() == "sheet") {
ss.deleteSheet(shts[i]); //I think this is just deleting the sheet and not the array element in shts so no reason to keep track of deleted sheets like when deleting rows in a spreadsheet
}
}
for(var i = 0; i<hdnShts.length; i++) {
ss.getSheetByName(hdnShts[i]).hideSheet(); //just to make sure all the hiddens remain hidden
}
}
I've been forcing myself to get away from old school loops.
function delSheetsKeepHidden() {
var ss=SpreadsheetApp.getActive();
var shts=ss.getSheets();
var hdnShts=[];
shts.forEach(function(sht){if(sht.isSheetHidden()){hdnShts.push(sht.getName())}});
shts.forEach(function(sht){if(sht.getName().slice(0,5).toLowerCase()=="sheet"){ss.deleteSheet(sht);}});//I think this is just deleting the sheet and not the array element in shts so no reason to keep track of deleted sheets like when deleting rows in a spreadsheet
hdnShts.forEach(function(name){ss.getSheetByName(name).hideSheet();});//just to make sure all the hiddens remain hidden
}

Reset Checkboxes and Delete Notes on Defined sheets

I need to reset checkboxes to FALSE (Unchecked) and also delete all notes from defined sheets.
Also need a script that deletes all notes from a Google sheet (all sheets)
I tried combining numerous different scripts.
https://webapps.stackexchange.com/questions/115076/how-to-run-script-on-multiple-google-sheet-tabs
Re-set checkboxes to false - Google Apps Script -- The problem with this script is that is turns cells with a value of 1 into cells that say "FALSE"
function ResetCheckBoxesAndClearNotesOnDefinedSheets(){
var tabs = [
'Checkboxes 1',
'Checkboxes 2',
'Checkboxes 3',
'Another Checkbox tab',
'Yet another checkbox tab'
];
//LOOP THROUGH TABS LISTED ABOVE
var ss=SpreadsheetApp.getActiveSpreadsheet();
for (var i = 0; i < tabs.length; i++) {
var sheet=ss.getSheetByName(tabs[i]);
//CLEAR NOTES ON TABS LISTED ABOVE
sheet.clearNotes();
// CLEAR CHECKBOXES ON TABS LISTED ABOVE
var dataRange = sheet.getRange('A:I');
var values = dataRange.getValues();
for (var i = 0; i < values.length; i++) {
for (var j = 0; j < values[i].length; j++) {
if (values[i][j] == true) {
values[i][j] = false; // Modified
}
}
}
dataRange.setValues(values);
}//end of sheets loop.
}
ACTUAL RESULTS:
-It does not loop through the pages and delete the notes. It also does not loop through and change all checkboxes in the tabs to unchecked.. and it sometimes replaces a "1" with a FALSE
EXPECTED RESULTS:
-Reset all checkboxes on defined sheets
-Clear all notes on Defined sheets (or entire Spreadsheet)
How about this modification?
Modification points:
In your script, the variable of i is used at both for (var i = 0; i < tabs.length; i++) { and for (var i = 0; i < values.length; i++) {.
By this, the value of i of for (var i = 0; i < tabs.length; i++) { is not increased every 1.
I think that this is one of your issues of It does not loop through the pages and delete the notes..
For example, please modify to for (var k = 0; k < tabs.length; k++) {var sheet=ss.getSheetByName(tabs[k]);.
Equality comparison == is used for comparing the boolean.
I think that this is another issue of it sometimes replaces a "1" with a FALSE.
Please modify this to the strict equality comparison ===.
Modified script:
Please modify as follows.
From:
for (var i = 0; i < tabs.length; i++) {
var sheet = ss.getSheetByName(tabs[i]);
To:
for (var k = 0; k < tabs.length; k++) {
var sheet = ss.getSheetByName(tabs[k]);
And
From:
if (values[i][j] == true) {
To:
if (values[i][j] === true) {
Reference:
Equality comparisons and sameness
If I misunderstood your question, please tell me. I would like to modify it.

Refreshing custom function on every change

I have a custom function using DeveloperMetadata from other sheets in the workbook. The issue I have is that if I e.g. delete one of previous sheets (thus removing that metadata) the cell value doesn't change. The only trigger which recalculates this function is to make a simple whitespace change in the Script Editor and save the file.
Is there a method in Google Sheets to do this refresh automatically?
function get_prev_days(rest_key) {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheets = spreadsheet.getSheets();
var sheet_index = SpreadsheetApp.getActiveSheet().getIndex();
var value = 0;
for (var i = 0; i < sheet_index; i++) {
var meta = sheets[i].getDeveloperMetadata();
for (var j = 0; j < meta.length; j++) {
if (rest_key == meta[j].getKey()) {
value += Number(meta[j].getValue());
}
}
}
return value;
}

Delete Row from all google sheets based on value of a cell

I am trying to achieve a script that will delete a row based upon a string in a cell within that row,
I can achieve my mission if I want to name each individual sheet, however my sheets are constantly changing names, so this would mean updating the the script daily.
I have tried to create a loop, but that does not seem to work either, any suggestions?
The script I am working on is below.
function RemoveInvoiced() {
var ss = SpreadsheetApp.openById("1pxWr3jOYZbcwlFR7igpSWa9BKCa2tTeliE8FwFCRTcQ").getSheets();
for (var k=0; k<ss.length; k++)
var values = ss[k].getDataRange().getValues();
var rows_deleted = 0;
for (var i = 0; i < values.length; i++) {
for (var j = 0; j < values[i].length; j++) {
var value = values[i][j];
var row = i + 1 - rows_deleted;
if (typeof value === 'string') {
var result = value.search("INVOICED");
if (result !== -1) {
ss.deleteRow(row);
rows_deleted++;
}
}
}
}
};
Instead of using the sheet name to access them, you could access them by Id.
The id will never change as long as you don't delete the sheet, even if you change the name.
You'd first have to get the sheets Id, a simple function could do that for you
function getId(sheet){
Logger.log(sheet.getSheetId());
}
Once you have gotten your sheet ids, you can make a function that will open the right sheet by the ID
function openSheetById(doc, id){
var sheets = doc.getSheets();
for(var i = 0; i< sheets.length ; i++){
if( sheets[i].getSheetId() == id)
return sheets[i];
}
return false;
}
And then you can access the right sheet.
function myFunc(){
var doc = SpreadsheetApp.openById("1pxWr3jOYZbcwlFR7igpSWa9BKCa2tTeliE8FwFCRTcQ");
var id = // your id here
var sheet = openSheetById(doc, id);
if(sheet){
//do other stuffs
}
}