Google sheets script onEdit of form response clear cells - google-apps-script

I am trying to make a Google script to run on form edit but not sure if it would be onEdit or onSubmit when a person edits their Google form through the Google edit URL with new answers at a later date.
I need to grab the row their response is on and clear contents of cells AO, AP, AQ, and AR only.
I know this has to be a big mess up but I am trying. Here is what I have so far:
function onEdit(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var editRange = sheet.getActiveRange();
var editRow = editRange.getRow();
var editCol = editRange.getColumn();
var range = sheet.getRange("A2:AL");
var rangeRowStart = range.getRow();
var rangeRowEnd = rangeRowStart + range.getHeight()-1;
var rangeColStart = range.getColumn();
var rangeColEnd = rangeColStart + range.getWidth()-1;
if (editRow >= rangeRowStart && editRow <= rangeRowEnd
&& editCol >= rangeColStart && editCol <= rangeColEnd)
{
var ss = e.range.getSheet();
ss.getRange(thisRow,"AO" & i & ":AR" & i) // Get cells in range AO,AP,AQ,AR to clear out
.clearContent();
}
};

I have started over again. I have this script working but not the way needed quite yet. I need it to only clear contents of the cell (AH) for the row where firstdate != secdate. Right now it clears all cells of column AH when one cell meets the criteria.
function compareClear() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
var firstdate = sheet.getRange("E3:E").getValues();
var secdate = sheet.getRange("AG3:AG").getValues();
if(firstdate != secdate){
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("AH3:AH").clearContent();
}
}

Just in case anyone else might need a helping hand on this subject:
The script with a big helping hand from Spencer in Google Docs forum and some added changes by me works like a charm. It may not be the prettiest script but it does what I need.
function compareClear() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Form Responses 1");
var firstdate;
var secdate;
for (var i = 3; i < sheet.getLastRow(); i++) {
firstdate = new Date(sheet.getRange(i, 4).getValue());
secdate = new Date(sheet.getRange(i, 45).getValue());
if(firstdate > secdate){
sheet.getRange(i, 41).clearContent();
sheet.getRange(i, 42).clearContent();
sheet.getRange(i, 43).clearContent();
sheet.getRange(i, 44).clearContent();
}
}
}

Related

How to send calendar based when checkbox is ticked

right now , im having trouble to figuring out a script where when user ticks the checkbox, it will send an email invite 3 weeks in advance based on the payment date
would need your help.
Here is my code which is rather incomplete.
function sendreminder(){
var sheet = SpreadsheetApp.getActiveSheet();
var sheetName = sheet.getName();
var range = e.range;
var approvalEdit = range.getValue().toString(); // Use string to avoid accidentally accepting truthy values.
var column = range.getColumn();
var emailsend = "EMAIL_SENT";
var approvalColumnNo = 12;
var invoice = sheet.getRange(e.range.getRow(),12).getValue();
var calend = CalendarApp.createAllDayEvent();
if( sheetName === "Sheet1" && column === approvalColumnNo && approvalEdit === "true" ){
calend.createAllDayEvent('TEST', new Date('November 20, 2022')
SpreadsheetApp.flush();
Many thanks!
it will send an email invite 3 weeks in advance based on the payment date
You can try the following script:
function calendarEvent(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var sheetName = sheet.getName();
var val = e.value;
var rCol = e.range.getColumn();
var rRow = e.range.getRow();
if(rCol==12 && val=="TRUE" && sheetName=="Sheet1")
{
var val = sheet.getRange(rRow, 10).getValue();
var day = new Date(val).getTime() + 86400000*21; // 21 for the number of days
var nDay = new Date(day);
CalendarApp.createAllDayEvent('This is a test event',nDay);
}
}
Example:
References:
How to add days to date?
createAllDayEvent()

Google Script - How to generate template when cell within a range is modified?

I hope everybody is fine in those times
Posting this message to have some help on a tool I'm working on.
I'm very new to this, and my questions might be syntax / simple logic issues, as I lack the scripting basis
Here is what I'd like to do :
When cells in AC column are ticked (modified), I'd like my script to generate a template, and fill in that template with data A, B, C from the corresponding row that has been modified in AC column
So 3 steps here :
1 => When cells in AC columns are ticked (modified), I'd like my
script to
2 => to generate a template
3 => fill in that template with data A, B, C from the corresponding
row that has been modified in AC column
As for now, I'm stuck trying to make 1 and 2 work together.
3 might be another post if I don't find any solution
So here is the code for the onEdit function.
It is working. When I tick a cell in AC clumn, I get a "COOL" alert. (I've found this on Stackoverflow)
function onEdit()
{
var sheet = SpreadsheetApp.getActiveSheet();
var editRange = sheet.getActiveRange();
var editRow = editRange.getRow();
var editCol = editRange.getColumn();
var range = sheet.getRange("AC3:AC31");
var rangeRowStart = range.getRow();
var rangeRowEnd = rangeRowStart + range.getHeight();
var rangeColStart = range.getColumn();
var rangeColEnd = rangeColStart + range.getWidth();
if (editRow >= rangeRowStart && editRow <= rangeRowEnd
&& editCol >= rangeColStart && editCol <= rangeColEnd){
SpreadsheetApp.getUi().alert('COOL')
}
}
Here is the code for GenerateTemplate, which is working as well
function GenerateTemplate() {
var documentId = DriveApp.getFileById('XXXXXXXXXXXXXX').makeCopy().getId() ;
DriveApp.getFileById(documentId).setName('CONTRACT_2021_V2');
var body = DocumentApp.openById(documentId).getBody() ;
var sheet = SpreadsheetApp.getActiveSheet() ;
var range = sheet.getRange(3,5);
var data = range.getValue() ;
body.replaceText('##Nom##' , data) ;
}
What I'd like to do is the articulate both functions.
I've tried several ways, but never succeeded.
Following the "if" statement, I've tried to add the GenerateTemplate function, but it doesn't seem to work
function onEdit()
{
var sheet = SpreadsheetApp.getActiveSheet();
var editRange = sheet.getActiveRange();
var editRow = editRange.getRow();
var editCol = editRange.getColumn();
var range = sheet.getRange("AC3:AC31");
var rangeRowStart = range.getRow();
var rangeRowEnd = rangeRowStart + range.getHeight();
var rangeColStart = range.getColumn();
var rangeColEnd = rangeColStart + range.getWidth();
if (editRow >= rangeRowStart && editRow <= rangeRowEnd
&& editCol >= rangeColStart && editCol <= rangeColEnd){
GenerateTemplate()
}
}
I've also tried to put both functions on the same page. But still no success :
function GenerateTemplate() {
var documentId = DriveApp.getFileById('XXXXXXXXXXXXXXXXXXX').makeCopy().getId() ;
DriveApp.getFileById(documentId).setName('CONTRACT_2021_V2');
var body = DocumentApp.openById(documentId).getBody() ;
var sheet = SpreadsheetApp.getActiveSheet() ;
var range = sheet.getRange(3,5);
var data = range.getValue() ;
body.replaceText('##Nom##' , data) ;
}
function onEdit()
{
var sheet = SpreadsheetApp.getActiveSheet();
var editRange = sheet.getActiveRange();
var editRow = editRange.getRow();
var editCol = editRange.getColumn();
var range = sheet.getRange("AC3:AC31");
var rangeRowStart = range.getRow();
var rangeRowEnd = rangeRowStart + range.getHeight();
var rangeColStart = range.getColumn();
var rangeColEnd = rangeColStart + range.getWidth();
if (editRow >= rangeRowStart && editRow <= rangeRowEnd
&& editCol >= rangeColStart && editCol <= rangeColEnd){
GenerateTemplate()
}
}
When I click "execute", my drive do get updated with a new copy of the template, correctly named. But nothing happens when I tick a cell in AC column.
If someone could help me making those 2 functions work together, that would be great
Best,
onEdit is a simple trigger.
Simple triggers cannot access services that require authorization.
Drive service (DriveApp) requires authorization => you can't call it from onEdit.
https://developers.google.com/apps-script/guides/triggers#restrictions
PS: I think this is the cause of your problem, if you post an exact error message you are getting, then I will be able to confirm that.
So, for other people, here is how it worked
Thx again to Milan and iansedano
Trigger can't launch access services that require authorization.
My tool goes through DriveApp, which is why the trigger wasn't working.
Script is working. But, for the trigger to work, you need to install it, through the specific windows in google script.
Here are the pictures :
then, choose your function
Thx again !
Kind regards

Sheets Run script on edit of a range of cells (False to True)

I have a script that needs to run when a sheet is edited. I need it to run anytime a box in column L (L2:L260) is checked. I originally wrote the script to run on a button push (check a number of boxes, click the button and it would run), but it can't be run by other people who need to be able to use it. The script originally worked great when it was click the button, but once I added in the onEdit stuff...it completely stopped working. Here's what I have:
function onEdit(e) {
//Get the sheet you want to work with.
var editrange = {
top : 2,
bottom : 260,
left : 11,
right : 11};
var thisrow = e.range.getrow();
if (thisrow < editrange.top || thisrow > editrange.bottom)
return;
var thiscolumn = e.range.getcolumn();
if (thiscolumn < editrange.left || thiscolumn > editrange.right)
return;
var ss = e.range.getSheet();
var sheet = ss.getSheetByName("Responsible");
//Grab the entire Range, and grab whatever values you need from it. EX: rangevalues
var range8 = sheet.getRange("K3:K90");
var range28 = sheet.getRange("M3:M90");
var range2values8 = range28.getValues();
var rangevalues8 = range8.getValues();
//Loops through range results
for (var i in rangevalues8) {
// for (var j in rangevalues) {
Logger.log("rangevalues8["+i+"]["+0+"] is:"+rangevalues8[i][0]);//Added
//Set the rules logic
if (rangevalues8[i][0] == true) { //Modified
//Set the cell
range2values8[i][0] += 1; //Directly add 1 to range2values
Logger.log(range2values8);//Added
}
}
//copy new information
var destination = ss.getSheetByName('Compiled Data');//whatever page
var destCell8 = destination.getRange("I183:I270");
destCell8.setValues(range2values8);
//clear checkboxes
var cleaning = ss.getSheetByName('Asset Bank');
var cleaningcell8 = cleaning.getRange("A3:A90").getValues();
range8.setValues(cleaningcell8);
}
Thanks for any help I can get!
After review of your code I guess the getcloumn() you've edited in an also erroneous method getcolumn(), the
var ss = e.range.getSheet();
var sheet = ss.getSheetByName("Responsible");
and the
e.range.getrow()
seems to be the major problems
correct syntax is:
getColumn();
getRow();
and you need to use the function getSheetByName(name) out from a spreadsheet object not a sheet object.
Here is the corrected code:
function onEdit(e) {
//Get the sheet you want to work with.
var editrange = {
top: 2,
bottom: 260,
left: 11,
right: 11
};
//getRow() and not getrow()
var thisrow = e.range.getRow();
if (thisrow < editrange.top || thisrow > editrange.bottom) return;
//getColumn() and not getcolumn()
var thiscolumn = e.range.getColumn();
if (thiscolumn < editrange.left || thiscolumn > editrange.right) return;
//Line that replaces the erroneous 'var ss = e.range.getSheet()';
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Responsible");
//Grab the entire Range, and grab whatever values you need from it. EX: rangevalues
var range8 = sheet.getRange("K3:K90");
var range28 = sheet.getRange("M3:M90");
var range2values8 = range28.getValues();
var rangevalues8 = range8.getValues();
//Loops through range results
for (var i in rangevalues8) {
Logger.log("rangevalues8[" + i + "][" + 0 + "] is:" + rangevalues8[i][0]); //Added
//Set the rules logic
if (rangevalues8[i][0] == true) { //Modified
//Set the cell
range2values8[i][0] += 1; //Directly add 1 to range2values
Logger.log(range2values8); //Added
}
}
//copy new information
var destination = ss.getSheetByName('Compiled Data'); //whatever page
var destCell8 = destination.getRange("I183:I270");
destCell8.setValues(range2values8);
//clear checkboxes
var cleaning = ss.getSheetByName('Asset Bank');
var cleaningcell8 = cleaning.getRange("A3:A90").getValues();
range8.setValues(cleaningcell8);
}

One trigger to activate two functions

Self taught noob, working in google sheets, sorry in advance for the mess here. I am trying to pull data from two cells into a new sheet. Both of these are pulled in after I trigger them with an onEdit. I need to enter a value and hit enter on both cells for them to be placed into the new sheet. How would I set this up so that when I trigger "D9" I would pull in "C9" plus "D9"?
function onEdit(e){
// Set a comment on the edited cell to indicate when it was changed.
if(e.range.getA1Notation() === 'C9'){
var input = e.range.getValue();
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var inputSheet = sheet.getSheetByName("input")
var masterSheet = sheet.getSheetByName("master inventory");
var currentRow = inputSheet.getRange("E9").getValue();
masterSheet.getRange("A3:A1000").getCell(currentRow, 1).setValue(input);
inputSheet.getRange("E9").setValue(currentRow, 1);
}
if(e.range.getA1Notation() === 'D9'){
var input = e.range.getValue();
e.range.clearContent();
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var inputSheet = sheet.getSheetByName("input")
var masterSheet = sheet.getSheetByName("master inventory");
var currentRow = inputSheet.getRange("E9").getValue();
masterSheet.getRange("B3:B1000").getCell(currentRow, 1).setValue(input);
inputSheet.getRange("E9").setValue(currentRow + 1);
}
}
I am not sure exactly what you are trying to do, but try this:
function onEdit(e) {
var x=e.source.getSheetName()
if( x == "input" ) { //checks that we're on the correct sheet
var y = e.range.getSheet().getActiveCell();
var z= e.range.getSheet().getActiveCell().getA1Notation()
var row=e.range.getSheet().getActiveCell().getRow()
if(z=="D9" && x=="input"){
var cell=e.range.getSheet().getActiveCell().getValue()
e.range.getSheet().getActiveCell().clearContent()
var nextCell =e.range.getSheet().getActiveCell().offset(0,-1).getValue()
e.range.getSheet().getActiveCell().offset(0,-1).clearContent()
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var masterSheet = sheet.getSheetByName("master inventory");
masterSheet.getRange("A3:A1000").getCell(row-2, 1).setValue(nextCell);
masterSheet.getRange("B3:B1000").getCell(row-2, 1).setValue(cell);
}}}

Message Box if Cell Range is Today

I'm new to Google App Script and new to coding for Google Sheets.
I'm attempting to:
Have a pop-up box show if any date in a range of cells is equal to today.
Here's the code I have so far:
function onOpen()
{
var ss = SpreadsheetApp.getActiveSheet();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Required Items List');
var ss = SpreadsheetApp.getActive();
var range = sheet.getRange('Required Items List!E8:G22');
var data = range.getValue();
var today = new Date();
Logger.log(data);
Logger.log(today);
if (data == today)
{
Browser.msgBox('Send Required Items Reminders Today!', Browser.Buttons.OK);
}
else {}
}
Range Example
It appears by data variable on reads the first cell for E8. I'm sure its a simple solution, I'm just missing some logic for it. Any help would be greatly appreciated.
You may code something like this :
function onOpen(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var lastrow = ss.getLastRow();
var lastcol = ss.getLastColumn();
var today = Utilities.formatDate(new Date(), "GMT+05:30", "''yyyy-MM-dd");
var flag = 'false';
for(var i =8; i<=22; i++){
for(var j =5; j<=7; j++){
var data = sheet.getRange(i, j, i, j).getValue();
var shDate = Utilities.formatDate(new Date(data), "GMT+05:30", "''yyyy-MM-dd");
if (shDate == today){
Browser.msgBox('Send Required Items Reminders Today!', Browser.Buttons.OK);
flag = 'true';}
if(flag == 'true')
break;
}
if(flag == 'true')
break;
}
}
Hope this will help you.
Thanks.