Sending email when a date count down is triggered - google-apps-script

I am trying to set up a sheet with varying email address and
dates. when a date (due) counts down to 20 say, I'd like to send the
owner of the issue an automatic email. All info in in the same row
just varying columns. I post my semi-functional script here, I can get the correct line item to pull based on date, I just cant get the script to pull the associated email with the date. Or I get a ton of emails that i dont want. Sheet
Any help would be much appreciated!!
function checkReminder() {
// get the spreadsheet object
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// set the first sheet as active
SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[0]);
// fetch this sheet
var sheet = spreadsheet.getActiveSheet();
// Number of rows to process
var numRows = sheet.getLastRow()-1;
// figure out what the last row is
var lastRow = sheet.getLastRow();
// the rows are indexed starting at 1, and the first row
// is the headers, so start with row 2
var startRow = 2;
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 2 ,lastRow,
sheet.getLastColumn());
// Fetch values for each row in the Range.
var data = dataRange.getValues();
//Logger.log(data)
// grab column 20 (the 'days left' column) changed numrow to last r
row
get last row change
var range = sheet.getRange(startRow,20,lastRow-startRow+1,1 );
var numRows = range.getNumRows();
var days_left_values = range.getValues();
// Now, grab the reminder name column
range = sheet.getRange(2, 16, lastRow-startRow+1, 1);
var reminder_name_values = range.getValues();
var warning_count = 0;
var msg = "";
//msg = msg + "Trial Reminder Trial: "+reminder_name+" is due in
"+days_left+" days.\n"
//for (i in data) {
// var row = data[i];
// First column
// var emailAddress = row[13];
// Recipe column (Priority HIGH)
// var message = row[14];
// var subject = "Reminder CAPA ";
//subject = subject + reminder_name;
// Loop over the days left values
for (var k = 0; k <= numRows-1; k++) {
var days_left = days_left_values[k][0];
if(days_left == 20) {
// if it's exactly 20, do something with the data.
var reminder_name = reminder_name_values[k][0];
msg = msg + "Reminder CAPA: "+reminder_name+" is due in
"+days_left+" days.\n";
warning_count++;
}
if(warning_count) {
//MailApp.sendEmail(emailAddress, subject, message);
Logger.log(msg);
}
}}

Related

Automating Google Spreadsheets – Email Reminders

I have a Google Spreadsheet and have modified the code below as indicated to send an email alert 7 days before the date condition is due. This works perfectly, however it only looks at the first sheet and the spreadsheet contains 23 sheets in total. I think I need to include an array and loop the code but cannot work this out so would appreciate some help! Thanks in advance.
function checkReminder() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// set the first sheet as active
SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[0]);
// fetch this sheet
var sheet = spreadsheet.getActiveSheet();
// figure out what the last row is
var lastRow = sheet.getLastRow();
// the rows are indexed starting at 1, and the first row
// is the headers, so start with row 2
var startRow = 7;
// grab column 14 (the 'days left' column)
var range = sheet.getRange(7, 14, lastRow - startRow + 1, 1);
var numRows = range.getNumRows();
var days_left_values = range.getValues();
// Now, grab the reminder name column
range = sheet.getRange(7, 15, lastRow - startRow + 1, 1);
var reminder_info_values = range.getValues();
// Now, grab the deceased name column
range = sheet.getRange(3, 1);
var name_of_sheet = range.getValue();
var warning_count = 0;
var msg = "";
// Loop over the days left values
for (var i = 0; i <= numRows - 1; i++) {
var days_left = days_left_values[i][0];
if (days_left == 7) {
// if it's exactly 7, do something with the data.
var reminder_name = reminder_info_values[i][0];
msg = msg + "Reminder: " + name_of_sheet + " inscription work is due in " + days_left + " days.\n";
warning_count++;
}
}
if(warning_count) {
MailApp.sendEmail("my#email.com",
"Reminder Inscription Schedule Message", msg);
}
};

Confirm that a value is in a spreadsheet column using Google Apps Script

This function sends email reminders based on a few conditions. One of the things I need to check for is that the Visit ID (which is in column 11 in the "email log" sheet) exists in a separate sheet ("DATA", stored in the enrollmentData variable). How do I search this array and return the ID to match in the IF statement below?
function sendReminders() {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var sheet = ss.getSheetByName("Email Log");
var rows = sheet.getLastRow()-1;
var startRow = 2; // First row of data to process
var numRows = rows; // Number of rows to process
var now = new Date();
// Fetch the range of cells
var dataRange = sheet.getRange(startRow, 1, numRows, 22)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
var today = Utilities.formatDate(new Date(), "GMT-5", "m/d/yyyy")
var reminderSent = "Reminder Sent";
//get email body and subject
var bodyTem = ss.getSheetByName("Email Templates").getRange('b8').getValues();
var subject = ss.getSheetByName("Email Templates").getRange('d13').getValues();
//get enrollments data to search for visit ID
var enrollmentData = ss.getSheetByName("DATA").getRange('H:H').getValues();
for (var i = 0; i < data.length; i++) {
var row = data[i];
//set conditions
var sendReminder = row[18];
var reminderDate = row[19];
var reminderStatus = row[20];
var visitID = row[11]
//need condition to look for visit ID to not include already cancelled. Search enrollmentData for visitID and return as foundID for conditional below
if (sendReminder == "Yes" && reminderStatus != reminderSent && reminderDate >= today && visitID == foundID) {
//assemble email
var studentEmail = row[13];
var firstName = row[12];
var instructor = row[0];
var body1 = bodyTem.replace(/*name*/gi,firstName);
var body2 = body1.replace(/*instructorFull*/gi,instructor);
MailApp.sendEmail(studentEmail, subject, body2);
//need to write in that the reminder email was sent.
sheet.getRange(startRow + i, 20).setValue(reminderSent);
sheet.getRange(startRow + i, 21).setValue(now);
};
};
};
You want to search the array
var enrollmentData = ss.getSheetByName("DATA").getRange('H:H').getValues();
The method getValues always returns a double array: in this case, it's of the form [[1], [2], [3],..] since each row has one element. I usually flatten this:
var enrollmentDataFlat = enrollmentData.map(function(row) {return row[0];});
Now enrollmentDataFlat is like [1, 2, 3, ..] so indexOf will work as usual:
if (enrollmentDataFlat.indexOf(visitID) != -1) {
// it's there
}
else {
// it's not there
}

Google Sheet Script - Unsuccessful Email Automation

I'm trying to put together a script which cycles through a two dimensional range from a spreadsheet; when the criteria is met (in this case, when training is a month and a week respectively before needing renewed) an email should be sent.
I was able to achieve this when the script only had to cycle through one column with several rows; however now that I'm attempting to cycle through several columns and several rows, the script is running without error, but the data is not triggering an email to be sent.
A smaller version of the script I'm attempting to use is displayed below, though the original is much more extensive in an attempt to cover the large range of data. The script not present here is a repetition of the 'Column' sections for each individual column that needs to be taken into consideration.
function trainingReminder() {
//For testing purposes
//You can view the log by typing CMD+ENTER (CTRL + E) after you run the script.
Logger.log(msg);
// grab the Google Sheet object
var googleSheets = SpreadsheetApp.getActiveSpreadsheet();
// activates the first sheet
SpreadsheetApp.setActiveSheet(googleSheets.getSheets()[0]);
// grabs the sheet
var currentSheet = googleSheets.getActiveSheet();
// find the last row
var lastRow = currentSheet.getLastRow();
// The first row starts at row 2 to account for headers
var startRow = 2;
//**************************************************************//
// Column AU //
//**************************************************************//
// get AU column data (Training Name)
var range = currentSheet.getRange(2,48,lastRow-startRow+1,1 );
var numRows = range.getNumRows();
var remainingDays = range.getValues();
// get AR column data (Employee Names)
//range = currentSheet.getRange(2, 45, lastRow-startRow+1, 1);
var columnAR = range.getValues();
var warning_count = 0;
var msg = "";
// Loop column AU (Training Name) (1 Month)
for (var i = 0; i <= numRows - 1; i++) {
var daysLeft = remainingDays[i][0];
if(daysLeft == 30) {
// Checks to see if a cell value in column AU equals 30
var employeeName = columnAR[i][0];
msg = msg + "Don't Forget: "+employeeName+"'s "+employeeTraining+" is due in
"+daysLeft+" days.\n";
warning_count++;
}
}
// Loop column AU (Training Name) (1 Week)
for (var i = 0; i <= numRows - 1; i++) {
var daysLeft = remainingDays[i][0];
if(daysLeft == 7) {
// Checks to see if a cell value in column AU equals 7
var employeeName = columnAR[i][0];
var employeeTraining = range.getValue(1,48);
msg = msg + "Don't Forget: "+employeeName+"'s "+employeeTraining+" is due a week.\n";
warning_count++;
}
}
//**************************************************************//
// Column AV //
//**************************************************************//
// get AV column data (Training Name)
var range = currentSheet.getRange(2,49,lastRow-startRow+1,1 );
var numRows = range.getNumRows();
var remainingDays = range.getValues();
// get AR column data (Employee Names)
//range = currentSheet.getRange(2, 45, lastRow-startRow+1, 1);
var columnAR = range.getValues();
var warning_count = 0;
var msg = "";
// Loop column AV (Training Name) (1 Month)
for (var i = 0; i <= numRows - 1; i++) {
var daysLeft = remainingDays[i][0];
if(daysLeft == 30) {
// Checks to see if a cell value in column AV equals 30
var employeeName = columnAR[i][0];
var employeeTraining = range.getValue(1,49)
msg = msg + "Don't Forget: "+employeeName+"'s "+employeeTraining+" is due in "+daysLeft+" days.\n";
warning_count++;
}
}
// Loop column AV (Training Name) (1 Week)
for (var i = 0; i <= numRows - 1; i++) {
var daysLeft = remainingDays[i][0];
if(daysLeft == 7) {
// Checks to see if a cell value in column AV equals 7
var employeeName = columnAR[i][0];
var employeeTraining = range.getValue(1,49);
msg = msg + "Don't Forget: "+employeeName+"'s "+employeeTraining+" is due a week.\n";
warning_count++;
}
}
//**************************************************************//
// Column AW //
//**************************************************************//
// get AW column data (Training Name)
var range = currentSheet.getRange(2,50,lastRow-startRow+1,1 );
var numRows = range.getNumRows();
var remainingDays = range.getValues();
// get AR column data (Employee Names)
//range = currentSheet.getRange(2, 45, lastRow-startRow+1, 1);
var columnAR = range.getValues();
var warning_count = 0;
var msg = "";
// Loop column AW (Training Name) (1 Month)
for (var i = 0; i <= numRows - 1; i++) {
var daysLeft = remainingDays[i][0];
if(daysLeft == 30) {
// Checks to see if a cell value in column AW equals 30
var employeeName = columnAR[i][0];
var employeeTraining = range.getValue(1,50)
msg = msg + "Don't Forget: "+employeeName+"'s "+employeeTraining+" is due in "+daysLeft+" days.\n";
warning_count++;
}
}
// Loop column AW (Training Name) (1 Week)
for (var i = 0; i <= numRows - 1; i++) {
var daysLeft = remainingDays[i][0];
if(daysLeft == 7) {
// Checks to see if a cell value in column AW equals 7
var employeeName = columnAR[i][0];
var employeeTraining = range.getValue(1,50);
msg = msg + "Don't Forget: "+employeeName+"'s "+employeeTraining+" is due a week.\n";
warning_count++;
}
}
// Loop column CG (Training Name) (1 Week)
for (var i = 0; i <= numRows - 1; i++) {
var daysLeft = remainingDays[i][0];
if(daysLeft == 7) {
// Checks to see if a cell value in column CG equals 7
var employeeName = columnAR[i][0];
var employeeTraining = range.getValue(1,86);
msg = msg + "Don't Forget: "+employeeName+"'s "+employeeTraining+" is due a week.\n";
warning_count++;
}
}
if(warning_count) {
MailApp.sendEmail("example#email.com",
"Training Reminder", msg);
}
};
I realise there's probably something very obvious to anyone competent with writing scripts, but unfortunately I'm not there yet with it. Any help would be greatly appreciated!

Email Reminder for multiple Column

I want to send email reminder if the date columns is 7 or 1 days away from today. I have already made the script and what i want to add is it should consider others columns too, not only 1 with one script, for sending reminder for respective columns.
For eg:
It should remind for Plan Date, Plan Date 1, Plan Date 2 and Plan Date 3.
Please see the Sample Attached.
Script:
function checkReminder() {
// get the spreadsheet object
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// fetch this sheet
var sheet = spreadsheet.getSheets()[0];
// figure out what the last row is
var lastRow = sheet.getLastRow();
// figure out what the last column is
var lastCol = sheet.getLastColumn();
// the rows are indexed starting at 1, and the first row
// is the headers, so start with row 2
var startRow = 2;
// the columns are indexed starting at 2, and the first column
// is the headers, so start with column 2
var startCol = 2;
// grab column 3 (the 'days left' column)
var range = sheet.getRange(2,3,lastRow-startRow+1,1 );
var numRows = range.getNumRows();
var days_left_values = range.getValues();
// Now, grab the reminder name column
range = sheet.getRange(2, 1, lastRow-startRow+1, 1);
var reminder_info_values = range.getValues();
// Now, grab the first row
range = sheet.getRange(1, 2, lastCol-startCol+1, 1);
var column_info_values = range.getValues();
var warning_count = 0;
var msg = "";
// Loop over the days left values
for (var i = 0; i <= numRows - 1; i++) {
var days_left = days_left_values[i][0];
if(days_left == 1) {
// if it's exactly 1, do something with the data.
var reminder_name = reminder_info_values[i][0];
var column_name = column_info_values[0][0];
msg = msg + "Reminder: "+reminder_name+" - "+column_name+" is due in "+days_left+" day.\n";
warning_count++;
}
}
for (var i = 0; i <= numRows - 1; i++) {
var days_left = days_left_values[i][0];
if(days_left == 7) {
// if it's exactly 7, do something with the data.
var reminder_name = reminder_info_values[i][0];
var column_name = column_info_values[0][0];
msg = msg + "Reminder: "+reminder_name+" - "+column_name+" is due in "+days_left+" days.\n";
warning_count++;
}
}
if(warning_count) {
MailApp.sendEmail("myidsample#gmail.com",
"Reminder Spreadsheet Message", msg);
}
};
You're currently fetching only single column and processing that only.
In order to make this script run over other columns too, you'll need to loop through them, fetch data and then process them one by one.
Here you're fetching data from 3rd column :
// grab column 3 (the 'days left' column)
var range = sheet.getRange(2,3,lastRow-startRow+1,1 );
var numRows = range.getNumRows();
var days_left_values = range.getValues();
Like wise you can run a loop till last column and fetch data from 3rd, 5th, 7th .. columns and keep processing them.
So the code goes like this
function checkReminder() {
// get the spreadsheet object
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// fetch this sheet
var sheet = spreadsheet.getSheets()[0];
// figure out what the last row is
var lastRow = sheet.getLastRow();
// figure out what the last column is
var lastCol = sheet.getLastColumn();
// the rows are indexed starting at 1, and the first row
// is the headers, so start with row 2
var startRow = 2;
// the columns are indexed starting at 2, and the first column
// is the headers, so start with column 2
var startCol = 2;
// Now, grab the reminder name column
range = sheet.getRange(2, 1, lastRow - startRow + 1, 1);
var reminder_info_values = range.getValues();
// Now, grab the first row
range = sheet.getRange(1, 2, lastCol - startCol + 1, 1);
var column_info_values = range.getValues();
var warning_count = 0;
var msg = "";
for (var u = 3; u <= lastCol; u += 2) {
// grab the day's left column
var range = sheet.getRange(2, u, lastRow - startRow + 1, 1);
var numRows = range.getNumRows();
var days_left_values = range.getValues();
// Loop over the days left values
for (var i = 0; i <= numRows - 1; i++) {
var days_left = days_left_values[i][0];
if (days_left == 1) {
// if it's exactly 1, do something with the data.
var reminder_name = reminder_info_values[i][0];
var column_name = column_info_values[0][0];
msg = msg + "Reminder: " + reminder_name + " - " + column_name + " is due in " + days_left + " day.\n";
warning_count++;
}
}
for (var i = 0; i <= numRows - 1; i++) {
var days_left = days_left_values[i][0];
if (days_left == 7) {
// if it's exactly 7, do something with the data.
var reminder_name = reminder_info_values[i][0];
var column_name = column_info_values[0][0];
msg = msg + "Reminder: " + reminder_name + " - " + column_name + " is due in " + days_left + " days.\n";
warning_count++;
}
}
if (warning_count) {
MailApp.sendEmail("myidsample#gmail.com",
"Reminder Spreadsheet Message", msg);
}
}
}
This is un-tested code, let me know if any issue arises. I'll be happy to help you.
Thank you!

Google Spreadsheet Script - Analyze table for value (1) and post several rows with this value in another

i want to analyze a sheet (name: 1) for a value (e.g. 1) and post some values from these rows with this value in another sheet (name: 2).
"search for all cells in column F which got the value (e.g. 1). copy columns A, E and G (if F is 1) and post it at the end of sheet 2.
My Script just post one result actually. Could you please help me? I think i just dont get any kind of loop?
function checkWS() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(spreadsheet.getSheetByName("1"));
var sheet = spreadsheet.getActiveSheet();
// figure out what the last row is
var lastRow = sheet.getLastRow();
// the rows are indexed starting at 1, and the first row
// is the headers, so start with row 2
var startRow = 2;
// grab column 5 (the 'month left' column)
var range = sheet.getRange(2, 6, lastRow - startRow + 1, 1);
var numRows = range.getNumRows();
var soll_values = range.getValues();
// Now, grab the reminder name column
range = sheet.getRange(2, 1, lastRow - startRow + 1, 1);
var branch_values = range.getValues();
// and the count column
range = sheet.getRange(2, 7, lastRow - startRow + 1, 1);
var count_values = range.getValues();
var warning_count = 0;
var msg = "";
// Loop over the days left values
for (var i = 0; i <= numRows - 1; i++) {
var soll = soll_values[i][0];
if (soll == 1) {
// if it's exactly 1, do something with the data.
var name = branch_values[i][0];
var count = count_values[i][0];
warning_count++;
}
}
if (warning_count) {
var ss = SpreadsheetApp.openById("1vn4xTwdNk7E1Av4VNugtW6KWgZns2LzKS1lN1F6CTPw");
var Tab = ss.getSheetByName('2');
var lastRow = Tab.getLastRow();
Tab.getRange(lastRow + 1, 1).setValue(name);
Tab.getRange(lastRow + 1, 5).setValue(count);
Tab.getRange(lastRow + 1, 10).setValue(new Date());
SpreadsheetApp.flush();
}
}
now it's done. I just worked with a little helping-coloumn:
function checkWS() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(spreadsheet.getSheetByName("NAME"));
var sheet = spreadsheet.getActiveSheet();
// figure out what the last row is
var lastRow = sheet.getLastRow();
// the rows are indexed starting at 1, and the first row
// is the headers, so start with row 2
var startRow = 6;
// grab date (the 'month left' column)
var range = sheet.getRange(6, 54, lastRow - startRow + 1, 1);
var numRows = range.getNumRows();
var soll_values = range.getValues();
// Now, grab the branch column
range = sheet.getRange(6, 11, lastRow - startRow + 1, 1);
var branch_values = range.getValues();
// and the count column
range = sheet.getRange(6, 49, lastRow - startRow + 1, 1);
var count_values = range.getValues();
var warning_count = 0;
var msg = "";
// Loop over the days left values
for (var i = 0; i <= numRows - 1; i++) {
var soll = soll_values[i][0];
if (soll == 1) {
// if it's exactly 1, do something with the data.
var name = branch_values[i][0];
var count = count_values[i][0];
warning_count++;
// if (warning_count) { -> not needed
var ss = SpreadsheetApp.openById("ID");
var Tab = ss.getSheetByName('NAME_other_ss');
var lastRow = Tab.getLastRow();
Tab.getRange(lastRow + 1, 10).setValue(name);
Tab.getRange(lastRow + 1, 14).setValue(count);
Tab.getRange(lastRow + 1, 20).setValue(new Date());
SpreadsheetApp.flush();
// }
}
}
}