How to send calendar based when checkbox is ticked - google-apps-script

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()

Related

I want to add a timestamp using apps script, but it doesn't work when I paste multiple rows

The code works when one row is edited at a time. But I need to copy and paste multiple rows as well, and the timestamp only appears on the first row (where I paste it).
function onEdit(e) {
var range = e.range;
var spreadSheet = e.source;
var sheetName = spreadSheet.getActiveSheet().getName();
var row = range.getRow();
var activeSheetName = 'Analysis';
var statusColumnNum = 17;
var updateColumnNum = 15;
if(sheetName == activeSheetName)
{
if(spreadSheet.getActiveSheet().getRange(row,statusColumnNum).getValues() == 'No Further Action' || spreadSheet.getActiveSheet().getRange(row,statusColumnNum).getValues() == 'Invalid Code' || spreadSheet.getActiveSheet().getRange(row,statusColumnNum).getValues() == 'For BAF Filing'){
if(spreadSheet.getActiveSheet().getRange(row,updateColumnNum).getValue() == ''){
var new_date = new Date();
spreadSheet.getActiveSheet().getRange(row,updateColumnNum).setValue(new_date).setNumberFormat("MM/dd/yyyy hh:mm:ss A/P");
}
}
else{
spreadSheet.getActiveSheet().getRange(row,updateColumnNum).setValue('');
}
}
}
In your script, how about the following modification?
Modified script:
function onEdit(e) {
var range = e.range;
var spreadSheet = e.source;
var sheet = spreadSheet.getActiveSheet();
var sheetName = sheet.getName();
var activeSheetName = 'Analysis';
var statusColumnNum = 17;
var updateColumnNum = 15;
var texts = ['No Further Action', 'Invalid Code', 'For BAF Filing'];
if (sheetName == activeSheetName) {
var range = sheet.getRange(range.rowStart, statusColumnNum, range.rowEnd - range.rowStart + 1);
var values = range.getValues();
var new_date = new Date();
range.offset(0, updateColumnNum - statusColumnNum)
.setNumberFormat("MM/dd/yyyy hh:mm:ss A/P")
.setValues(values.map(([q]) => [texts.includes(q) ? new_date : null]));
}
}
In this case, when this script is run by copying and pasting the values, all edited rows are checked. By this, the date is inserted into your expected rows.
Reference:
map()

Google Apps Script - Append Array of Variables to Sheet

I've got the following code that grabs all of the information I need form the active line, and puts them into an array of variables. However, I can't seem to find good documentation on how to append the variables to a another sheet in the same document:
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
var spreadsheetTimeZone = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
var lastUpdatedString = Utilities.formatDate(new Date(), spreadsheetTimeZone, "MM/dd/yyyy' 'HH:mm:ss");
var sessionEmail = Session.getActiveUser().getEmail();
if (s.getName() == "Workload") { //checks that we're on the correct sheet
var r = s.getActiveCell();
if (r.getColumn() == 14) { //checks the column
var status = r.getValue();
var note = r.offset(0, -1);
var noteValue = note.getValue()
var delivery = r.offset(0, -5);
var deliveryValue = delivery.getValue()
}
var array = [lastUpdatedString, sessionEmail, deliveryValue, noteValue]
// get destination range
var ss = SpreadsheetApp.getActiveSpreadsheet();
var pasteSheet = ss.getSheetByName("Historical Notes Sheet");
var destination = pasteSheet.getRange(pasteSheet.getLastRow() + 1, 1, 1, 1);
}
}
I'd like to append the values from var array into the "Historical Notes Sheet", in the same order they are in the array.
Any help/advice you all could provide would be greatly appreciated.
Thanks!
Try this
pasteSheet.appendRow(array);
More info https://developers.google.com/apps-script/reference/spreadsheet/sheet#appendRow(Object)

Why is my .appendRow from Array adding an extra row?

I pretty much have the Apps Script file working as intended. However, each time it is triggered, it also adds a second line where the sessionEmail is not captured and is blank.
function onEdit() {
var sessionEmail = Session.getActiveUser().getEmail();
var spreadsheetTimeZone = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
var lastUpdatedString = Utilities.formatDate(new Date(), spreadsheetTimeZone, "MM/dd/yyyy' 'HH:mm:ss");
var s = SpreadsheetApp.getActiveSheet();
if (s.getName() == "Workload") { //checks that we're on the correct sheet
var r = s.getActiveCell();
if (r.getColumn() == 14) { //checks the column
var status = r.getValue();
var note = r.offset(0, -1);
var noteValue = note.getValue()
var delivery = r.offset(0, -5);
var deliveryValue = delivery.getValue()
}
// Validating fields are filled in
if (status == "Complete") {
var ui = SpreadsheetApp.getUi();
if (noteValue == '') { // if no note is entered, stop script with message box
var noStatus = ui.alert(
'Warning!',
'Please enter notation before choosing Complete.',
ui.ButtonSet.OK);
r.setValue('')
return;
}
// get destination range
var array = [lastUpdatedString, sessionEmail, deliveryValue, noteValue]
var ss = SpreadsheetApp.getActiveSpreadsheet();
var pasteSheet = ss.getSheetByName("Historical Notes Sheet");
pasteSheet.appendRow(array)
// clear response row
note.setValue('')
r.setValue('')
}
}
}
Image of what the results look like:
If any of you have any ideas on how to resolve this, and only append 1 line that has all the values, I would really appreciate it.
Thanks!
Update:
Logging the variable produces the following (expected) results, where the e-mail address appeared in the string.
Results still populating 2 rows:
Thanks for helping me troubleshoot.
I went into View>Executions, and noticed that the script was running twice each time at about 2 milliseconds apart. I think the function name onEdit() was acting like an On Edit trigger, and causing the script to run with another On Edit trigger that I had set up for it.
I tried removing the trigger, and leaving it with the onEdit()name, but that was causing it to not grab the sessionEmail. Changing the code to the below, and adding the trigger back causes the code to run as expected.
function appendLine() {
var sessionEmail = Session.getActiveUser().getEmail().toString();
var spreadsheetTimeZone = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
var lastUpdatedString = Utilities.formatDate(new Date(), spreadsheetTimeZone, "MM/dd/yyyy' 'HH:mm:ss");
var s = SpreadsheetApp.getActiveSheet();
if (s.getName() == "Workload") { //checks that we're on the correct sheet
var r = s.getActiveCell();
if (r.getColumn() == 14) { //checks the column
var status = r.getValue();
var note = r.offset(0, -1);
var noteValue = note.getValue()
var delivery = r.offset(0, -5);
var deliveryValue = delivery.getValue().toString();
}
// Validating fields are filled in
if (status == "Complete") {
var ui = SpreadsheetApp.getUi();
if (noteValue == '') { // if no note is entered, stop script with message box
var noStatus = ui.alert(
'Warning!',
'Please enter notation before choosing Complete.',
ui.ButtonSet.OK);
r.setValue('')
return;
}
// get destination range
var array = [lastUpdatedString, sessionEmail, deliveryValue, noteValue]
var ss = SpreadsheetApp.getActiveSpreadsheet();
var pasteSheet = ss.getSheetByName("Historical Notes Sheet");
pasteSheet.appendRow(array)
// clear response row
note.setValue('')
r.setValue('')
}
}
}
Thanks again to everyone for your help!

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.