Script to open "Today" in multi-sheet Google Sheet - google-drive-api

Sample Sheet- So, I am new to this part. Our work schedule is in by-weekly format, each two-week pay-period is on a separate sheet.
I need a script to cause it to open to the current date whenever a user accesses the sheet from their Google Drive.
Similar to this, but something isn't right:
function onOpen() {
var today = new Date();
var ss = SpreadsheetApp.getActive();
ss.setActiveSheet(ss.getSheets()[today.getMonth()]);
}

This script should bring you to the sheet with the current date..
function onOpen() {
var today = format(new Date());
var ss = SpreadsheetApp.getActive();
var sheets = ss.getSheets()
.forEach(function (s) {
var val = s.getRange("C2:P2")
.getValues()[0];
for (var i = 0, len = val.length; i < len; i++) {
if (format(val[i]) === today) {
ss.setActiveSheet(s)
break;
}
}
});
}
function format(date) {
return formattedDate = date.getMonth() + 1 + "/" + date.getDate()
}
See if this works ?

Related

How to allow non-sheet owners run scripts that involve protected cells

I have the script below where some cells are protected because they contain formula but I can script linked to buttons that when executed, it updates the cell values in these protected cells, this is fine if you are the sheet owner but if you are not you get a error saying 'You are editing protected cells....'
I have seen some solutions where the script has been deployed as a web app and then set so it always runs as the owner but can't get this working for my use case, I deployed and set as to always run as me but this only seems like half the solution?
My code is below:
//
// Save Data
function submitData() {
var SPREADSHEET_NAME = "Data";
var SEARCH_COL_IDX = 0;
var RETURN_COL_IDX = 0;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Tool"); //Form Sheet
var datasheet = ss.getSheetByName("Data"); //Data Sheet
var str = formSS.getRange("A10").getValue();
var values = ss.getSheetByName(SPREADSHEET_NAME).getDataRange().getValues();
for (var i = 0; i < values.length; i++) {
var row = values[i];
if (row[SEARCH_COL_IDX] != str ) {
//SpreadsheetApp.getUi().alert(' "Dmp #' + formSS.getRange("A4").getValue() + ' "');
// return row[RETURN_COL_IDX];
//} else {
//Input Values
var values1 = [[formSS.getRange("A10").getValue(),
formSS.getRange("B10").getValue(),
formSS.getRange("C10").getValue(),
formSS.getRange("D10").getValue(),
formSS.getRange("E10").getValue(),
formSS.getRange("F10").getValue(),
formSS.getRange("G10").getValue(),
formSS.getRange("H10").getValue(),
formSS.getRange("I10").getValue(),
formSS.getRange("J10").getValue(),
formSS.getRange("K10").getValue()]];
var values2 = [[formSS.getRange("A10").getValue(),
formSS.getRange("B10").getValue(),
formSS.getRange("C10").getValue(),
formSS.getRange("D10").getValue(),
formSS.getRange("E10").getValue(),
formSS.getRange("F10").getValue(),
formSS.getRange("G10").getValue(),
formSS.getRange("I10").getValue(),
formSS.getRange("J10").getValue(),
formSS.getRange("K10").getValue()]];
values2[0].forEach(function(val) {
if (val === "") {
throw new Error("Please fill in Project, Category, Subsystem, Description and Created By Fields.");
}
})
// Save New Data
datasheet.getRange(datasheet.getLastRow()+1, 1, 1, 11).setValues(values1);
SpreadsheetApp.getUi().alert(' New Record Created ');
formSS.getRange("D10").clearContent();
formSS.getRange("E10").clearContent();
formSS.getRange("F10").clearContent();
formSS.getRange("G10").clearContent();
formSS.getRange("H10").clearContent();
formSS.getRange("I10").clearContent();
formSS.getRange("J10").setValue(new Date())
return row[RETURN_COL_IDX];
}
}
}
//=========================================================
// Clear form
function clearCell() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Tool"); //Form Sheet
formSS.getRange("D10").clearContent();
formSS.getRange("E10").clearContent();
formSS.getRange("F10").clearContent();
formSS.getRange("G10").clearContent();
formSS.getRange("I10").clearContent();
formSS.getRange("J10").setValue(new Date())
return true ;
}
//=====================================================================
var SPREADSHEET_NAME = "Data";
var SEARCH_COL_IDX = 0;
var RETURN_COL_IDX = 0;
function searchStr() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Tool"); //Form Sheet
var str = formSS.getRange("F4").getValue();
var values = ss.getSheetByName(SPREADSHEET_NAME).getDataRange().getValues();
for (var i = 0; i < values.length; i++) {
var row = values[i];
if (row[SEARCH_COL_IDX] == str) {
formSS.getRange("A6").setValue(row[0]) ;
formSS.getRange("B6").setValue(row[1]);
formSS.getRange("C6").setValue(row[2]);
formSS.getRange("D6").setValue(row[3]);
formSS.getRange("E6").setValue(row[4]);
formSS.getRange("F6").setValue(row[5]);
formSS.getRange("G6").setValue(row[6]);
formSS.getRange("H6").setValue(row[7]);
formSS.getRange("I6").setValue(row[8]);
formSS.getRange("J6").setValue(row[9]);
return row[RETURN_COL_IDX];
}
}
}
//===================================================================
function rowDelete() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Tool"); //Form Sheet
var datasheet = ss.getSheetByName("Data"); //Data Sheet
var ui = SpreadsheetApp.getUi();
var response = ui.alert(
'Are you sure you want to delete this record?',
ui.ButtonSet.YES_NO);
// Process the user's response.
if (response == ui.Button.YES) {
var str = formSS.getRange("F4").getValue();
var values = ss.getSheetByName(SPREADSHEET_NAME).getDataRange().getValues();
for (var i = 0; i < values.length; i++) {
var row = values[i];
if (row[SEARCH_COL_IDX] == str) {
var INT_R = i+1
datasheet.deleteRow(INT_R) ;
formSS.getRange("A6").clearContent();
formSS.getRange("B6").clearContent();
formSS.getRange("C6").clearContent();
formSS.getRange("D6").clearContent();
formSS.getRange("E6").clearContent();
formSS.getRange("F6").clearContent();
formSS.getRange("G6").clearContent();
formSS.getRange("H6").clearContent();
formSS.getRange("I6").clearContent();
formSS.getRange("J6").clearContent();
return row[RETURN_COL_IDX];
}
}
}
}
//====================================================================
function updateData() {
var SPREADSHEET_NAME = "Data";
var SEARCH_COL_IDX = 0;
var RETURN_COL_IDX = 0;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Tool"); //Form Sheet
var datasheet = ss.getSheetByName("Data"); //Data Sheet
var str = formSS.getRange("A6").getValue();
var values = ss.getSheetByName(SPREADSHEET_NAME).getDataRange().getValues();
for (var i = 0; i < values.length; i++) {
var row = values[i];
if (row[SEARCH_COL_IDX] == str) {
var INT_R = i+1
formSS.getRange("J6").setValue(new Date())
var values1 = [[formSS.getRange("A6").getValue(),
formSS.getRange("B6").getValue(),
formSS.getRange("C6").getValue(),
formSS.getRange("D6").getValue(),
formSS.getRange("E6").getValue(),
formSS.getRange("F6").getValue(),
formSS.getRange("G6").getValue(),
formSS.getRange("H6").getValue(),
formSS.getRange("I6").getValue(),
formSS.getRange("J6").getValue()]];
var values2 = [[formSS.getRange("A6").getValue(),
formSS.getRange("B6").getValue(),
formSS.getRange("C6").getValue(),
formSS.getRange("D6").getValue(),
formSS.getRange("E6").getValue(),
formSS.getRange("F6").getValue(),
formSS.getRange("G6").getValue(),
formSS.getRange("I6").getValue(),
formSS.getRange("J6").getValue()]];
values2[0].forEach(function(val) {
if (val === "") {
throw new Error("Please fill in Revisions, Project, Category, Subsystem, Description and Updated By Fields.");
}
})
datasheet.getRange(INT_R, 1, 1, 10).setValues(values1);
formSS.getRange("A6").clearContent();
formSS.getRange("B6").clearContent();
formSS.getRange("C6").clearContent();
formSS.getRange("D6").clearContent();
formSS.getRange("E6").clearContent();
formSS.getRange("F6").clearContent();
formSS.getRange("G6").clearContent();
formSS.getRange("H6").clearContent();
formSS.getRange("I6").clearContent();
formSS.getRange("J6").clearContent();
formSS.getRange("E4").clearContent();
SpreadsheetApp.getUi().alert(' Record Updated ');
return row[RETURN_COL_IDX];
}
}
}
There are several posts about this, I'll paste a response from one from yesterday. What I recommend specifically in your case is to run the script when there's an edit bye the user in a certain cell. For example a Tickbox, or a Drop-down menu (in a cell) that allows the user to select which function to run:
If you already have an onEdit function working, that's a simple trigger run by whoever is editing the sheet. Meaning that if you protect column A, it won't be editable by that simple trigger because the user won't have permissions
In order to work this out, I encourage you to protect your column as explained here, change your name function or extract in a new function the part about this specific code you're talking about; and set an installable trigger that runs on event. This way it'll be run as you used to but as it came from your own account. As you have permissions for editing ColA the timestamp will be set by the installable trigger but the other user won't be able to edit it since he/she doesn't have the permissions. Try it and let me know!

If it is a date and its before todays date, mark in red. apps script

Im trying to detect:
If it is a date
If it is before todays date (Regardless of the hour)
If point 1 and point 2 are ok, than mark in red.
Can somebody help me please? Here is my google sheet: https://docs.google.com/spreadsheets/d/1EPW4qbv1K55risE9hpiy5rdYWtmufJb4T3o-3Dzhp-g/edit?usp=sharing
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
for (var i=2; i<=8; i++){
var data = ss.getRange(i,1).getValue();
var isDate = data instanceof Date;
var today = now.getTime().getValue();
if(data = isDate && data < today){
ss.getRange(i,1).setBackground("red");
}
}
}
Try it this way:
function myFunction() {
var ss = SpreadsheetApp.getActive();
const sh = ss.getActiveSheet();
const vs = sh.getRange(2, 1, 7).getValues().flat();
const bs = sh.getRange(2, 1, 7).getBackgrounds();
const dt = new Date();
const td = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate());
const tdv = td.valueOf();
vs.forEach((e, i) => {
if (Object.prototype.toString.call(e) === '[object Date]' && e.valueOf() < tdv) {
bs[i][0] = '#ff0000';
}
})
sh.getRange(2,1,bs.length,1).setBackgrounds(bs);
}
I believe your goal is as follows.
In the column "A" of the Spreadsheet, when the value is the date object and the date is before today, you want to set the background color of the cell to "red" using Google Apps Script.
In this case, how about the following sample script?
Sample script:
function myFunction() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var range = sheet.getRange("A2:A" + sheet.getLastRow());
var today = new Date().getTime();
var colors = range.getValues().map(([a]) => [a instanceof Date && a.getTime() < today ? "red" : null]);
range.setBackgrounds(colors);
}
When this script is used, I thought that your goal might be able to be achieved.
In your script, getValue and setBackground are used in a loop. In this case, the process cost will become high. Ref So, I proposed the above sample script.
In the above script, the background color of cells is overwritten. For example, if you want to set the background color to only the searched cells, how about the following sample script?
function myFunction() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var today = new Date().getTime();
var ranges = sheet.getRange("A2:A" + sheet.getLastRow()).getValues().flatMap(([a], i) => a instanceof Date && a.getTime() < today ? [`A${i + 2}`] : []);
sheet.getRangeList(ranges).setBackground("red");
}
References:
getValues()
map()
setBackgrounds(color)
Added:
From your following reply,
but that code you offer is a bit advanced for me.
How about the following modified script?
Sample script:
function myFunction2() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var range = sheet.getRange("A2:A" + sheet.getLastRow());
var values = range.getValues();
var today = new Date().getTime();
var ranges = [];
for (var i = 0; i < values.length; i++) {
if (values[i][0] instanceof Date && values[i][0].getTime() < today) {
ranges.push(`A${i + 2}`);
}
}
sheet.getRangeList(ranges).setBackground("red");
}

App Script Google Sheet creating multiple PDFs from 20+ sheets without it timing out

I have the below which hides all tabs but the current and exports to a pdf in a specified drive folder. Then unhides all, cycles to the next and repeats. Works fine but want to be able to scale the tab to fit to one page.
Other methods using URLfetchapp allow for scaling but it causes time outs by too many requests.
function Exportpdf() {
var spreadsheet = SpreadsheetApp.getActive();
nextSheet()
exportSheet()
if (SpreadsheetApp.getActiveSheet().getName()=='Data'){}
else {Exportpdf()}
};
function nextSheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var numSheets = ss.getSheets().length; // number of sheets
var activeSheetIndex = ss.getActiveSheet().getIndex() - 1; // see below
var newSheetIndex = (activeSheetIndex + 1) % numSheets; // add 1; wrap around
ss.setActiveSheet(ss.getSheets()[newSheetIndex]);
}
function exportSheet() {
var actualSheetName = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
for (var i = 0; i < sheets.length; i++) {
if (sheets[i].getSheetName() !== actualSheetName) {
sheets[i].hideSheet()
}
}
var pdfName = (SpreadsheetApp.getActiveSpreadsheet().getName() + " - " + SpreadsheetApp.getActiveSheet().getName());
var newFile = DriveApp.createFile(ss.getBlob().getAs('application/pdf').setName(pdfName));
for (var i = 0; i < sheets.length; i++) {
sheets[i].showSheet()
}
newFile.moveTo(DriveApp.getFolderById("11ZLhYZgpLuq5VWB90TdGbDrOUzP2SUlr"));
}

how do I open my sheet automatically on next week's date?

I have used a code found in another post (thank you very much, see below), to make a sheet open on Today's date.
Please, could you advise where I would need to add "+7" (or something else) to make it open on the date a week from now (Today + 7 days)?
How do I get my google spreadsheet to open to today's date?
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getRange("1:1");
var values = range.getValues();
values = values[0];
var day = 24*3600*1000;
var today = parseInt((new Date().setHours(0,0,0,0))/day);
Logger.log(today);
var ssdate;
for (var i=0; i<values.length; i++) {
try {
ssdate = values[i].getTime()/day;
}
catch(e) {
}
if (ssdate && Math.floor(ssdate) == today) {
sheet.setActiveRange(range.offset(0,i,1,1));
break;
}
}
}
Try this:
function onOpen() {
var ss=SpreadsheetApp.getActive();
var sheet=ss.getActiveSheet();
var range=sheet.getRange("1:1");
var values=range.getValues()[0];
var today=new Date();
var nextweek=new Date(today.getFullYear(),today.getMonth(),today.getDate()+7);
for (var i=0;i<values.length;i++) {
var ssdate = values[i].getTime()/86400000;
if (ssdate && Math.floor(ssdate) == nextweek) {
sheet.setActiveRange(range.offset(0,i,1,1));
break;
}
}
}

Why would forSpreadsheet(ss).onFormSubmit() trigger run too many times (i.e. more than once=7)

I am very new to google script (also fairly new to stackoverflow) so excuse any inconvenience.
I modified this guide and ended up with the code at the bottom.
https://developers.google.com/apps-script/quickstart/forms
My ultimate goal is to simply receive some numbers, do calculations on them and return some numbers from different users.
In the code, I use a spreadsheet and create a form, when a response is submitted the code should return an e-mail to the user. Everything works as expected but instead of 1, 7 e-mails are sent.
I simplified the code and it sends the same e-mail each time still does the same (sends 7 emails) with this easier to read version too
Thanks in advance
function onOpen() {
var menu = [{name: 'Set up conference', functionName: 'setUpConference_'}];
SpreadsheetApp.getActive().addMenu('Butten', menu);
}
function setUpConference_() {
if (ScriptProperties.getProperty('calId')) {
Browser.msgBox('Your conference is already set up. Look in Google Drive!');
}
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('but');
var range = sheet.getDataRange();
var values = range.getValues();
setUpForm_(ss, values);
ScriptApp.newTrigger('onFormSubmit').forSpreadsheet(ss).onFormSubmit()
.create();
ss.removeMenu('Butten');
}
function setUpForm_(ss, values) {
var form = FormApp.create('Conference Form');
var header = form.addSectionHeaderItem().setTitle('Bilgileriniz');
form.addTextItem().setTitle('Name').setRequired(true);
form.addTextItem().setTitle('Email').setRequired(true);
form.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId());
var header = form.addSectionHeaderItem().setTitle('Pratik notlariniz');
for (var i = 1; i < values.length; i++) {
var session = values[i];
var ders = session[0].toString();
var item = form.addTextItem().setTitle(ders);
var textValidation = FormApp.createTextValidation()
.setHelpText('0 le 100 arasinda bir sayi olmali')
.requireNumberBetween(0, 100)
.build();
item.setValidation(textValidation);
}
}
function onFormSubmit(e) {
MailApp.sendEmail({
to: 'exp#gmail.com',
subject: 'exp',
body: 'exp'});
}
function setUpConference_() {
var ss = SpreadsheetApp.getActive();
var triggerId = ScriptApp.newTrigger("onFormSubmit")
.forSpreadsheet(ss)
.onFormSubmit()
.create()
.getUniqueId();
Logger.log("New ID: "+triggerId);
var allTriggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < allTriggers.length; i++) {
if (allTriggers[i].getUniqueId() != triggerId) {
Logger.log("Delete ID: "+allTriggers[i].getUniqueId());
ScriptApp.deleteTrigger(allTriggers[i]);
}
}
ss.toast("already done.", "TriggerBuilder");
}