Trouble with a simple GoogleScript code (google sheets + gmail integration) - javascript

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();
// 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 10 (the 'date end' column)
var range = sheet.getRange(2,10,lastRow-startRow+1,1 );
var numRows = range.getNumRows();
var date_end_values = range.getValues();
// Now, grab the Event name data
range = sheet.getRange(2, 5, lastRow-startRow+1, 1);
var reminder_info_values = range.getValues();
var warning_count = 0;
var msg = "Send out a follow-up email asking how the event was!";
}
//Get today's date
var todaysDate = new Date();
var numRows = numRows
// Loop over the days left values
for (var i = 0; i <= numRows - 1; i++) {
var date_end = date_end_values[i][0];
//call setHours to take the time out of the comparison
if(date_end == todaysDate.setHours(0,0,0,0)) {
MailApp.sendEmail("max#xpogo.com",
"Reminder Spreadsheet Message", msg);
}
What I'm trying to do is have gmail send me a reminder when a certain column in my data set is equal to the present date. Im new to coding and am running into trouble. Please help?

I added the following after your variables were set, to determine whether they were commensurate for your comparison (hit ctrl+Enter after executing to view the log).
Logger.log(date_end);
Logger.log(todaysDate.setHours(0,0,0,0));
They weren't comparable at all. Here are the lines I changed to make this work:
var todaysDate = Utilities.formatDate(new Date(), "GMT+1", "MM/dd/yyyy");
var date_end = Utilities.formatDate(date_end_values[i][0], "GMT+1", "MM/dd/yyyy");
if(date_end == todaysDate) {
HTH

Related

Getting error when set values ​into getRange() - Google Apps Script

Objective
Get the rows where the dates in column A are within the range of this current month and year. In the rows that coincide in month and year with the current date, the value "yes" will be placed in the cell of column O (col. 15 - Array 14). The non-matching rows will be placed the value "no" in the cell of column 0 (col.15). Finally, checkboxes will be created for the entire column O (col.15), and depending on the value of the cell, the checkboxes will be marked or not.
Problem
I am getting an error "Exception: Service error: Spreadsheets" in the line of code dataRange.setValues(dataValues); And I don't know why or how to fix it.
This error in GAS is not explained any more. I have looked for solutions online but despite following the instructions, I can not solve this.
My code
function thisMonth() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('πŸ“… Todos los eventos');
const lastRow = sheet.getLastRow();
const lastCol = sheet.getLastColumn();
var dataRange = sheet.getRange(2, 1, lastRow -1, lastCol);
var dataValues = dataRange.getValues();
const now = new Date();
const month = now.getMonth();
const year = now.getFullYear();
dataValues.forEach((fila)=> {
var dateColA = new Date(fila[0]);
if ( month == dateColA.getMonth() && year == dateColA.getFullYear() ){
fila[14] = 'yes';
Logger.log(dateColA + ' - ' + fila[3]);
} else {
fila[14] = 'no';
}
})
dataRange.setValues(dataValues);
sheet.getRange(2, 15, lastRow -1, 1).insertCheckboxes('yes');
}
I tested your code and it works with a small sample sheet I made. Not sure about your exact error but I've heard it could be related to reaching some kind of limit when handling Sheet data. With that in mind, you should try to optimize it. You don't need to get the entire x-rows by 15-columns range and manipulate it then completely rewrite it to the Sheet, when all you want is to edit the "O" column.
I suggest you instead try to optimize your code to only get the values from column "A" to compare the dates, then create a local array to build the "O" column and then set the values to just that column. Here's a sample that worked for me:
function thisMonth() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('πŸ“… Todos los eventos');
const lastRow = sheet.getLastRow();
const lastCol = sheet.getLastColumn();
var dataRange = sheet.getRange(2, 1, lastRow -1);
var checkboxRange = sheet.getRange(2, 15, lastRow -1)
var dataValues = dataRange.getValues();
var checkboxValues = []
const now = new Date();
const month = now.getMonth();
const year = now.getFullYear();
for (i = 0; i<dataValues.length; i++){
if (dataValues[i][0].getMonth()==month && dataValues[i][0].getFullYear()==year){
checkboxValues.push(["yes"])
}else{
checkboxValues.push(["no"])
}
}
checkboxRange.setValues(checkboxValues);
sheet.getRange(2, 15, lastRow -1).insertCheckboxes('yes');
}

Auto Move Data of Specific Date

Link of My sheet is :
https://docs.google.com/spreadsheets/d/1czJbRU5ELNft1IfGq1cABGe30j8BWjnffVCEa8A_AeY/edit?usp=sharing
I am trying to move data if N is equal to today. I have set the trigger. This script runs on time driven between 8 PM to 9 PM. It copies the data in Row 8 when column K onwards there is noting mentioned. In the current Payment Approval Sheet, while running the script it copies the data in 1500th row.
The script I am using is as below:
function copyrange() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Complete Invoice Sheet'); //source sheet
var testrange = sheet.getRange('N:N');
var testvalue = (testrange.setNumberFormat("#").getValues());
var ds = ss.getSheetByName('Payment Approval Sheet'); //destination sheet
var data = [];
var j =[];
var dt = new Date();
var today = Utilities.formatDate(new Date(), 'GMT-0', 'dd/MM/yyyy')
//Condition to check in N:N, if true, copy the same row to data array
for (i=0;i<testvalue.length;i++) {
if (testvalue[i] == today) {
data.push.apply(data,sheet.getRange(i+1,1,1,13).getValues());
//Copy matched ROW numbers to j
j.push(i);
}
}
//Copy data array to destination sheet
ds.getRange(ds.getLastRow()+1,1,data.length,data[0].length).setValues(data);
}
Issue:
Your current solution considers the last row of your destination
sheet Payment Approval Sheet. However, in that sheet, checkboxes
are populated in column N until the bottom of the sheet. Therefore,
getLastRow() returns the row at the bottom of column N which is not
what you want.
Explanation:
Instead of using getLastRow(), calculate the number of elements after cell A7 by using the filter() operation and then use this as a starting point when you copy & paste the data to the destination sheet:
var start_row=ds.getRange('A8:A').getValues().filter(String).length +7; //calculate max row
ds.getRange(start_row+1,1,data.length,data[0].length).setValues(data);
Solution:
function copyrange() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Complete Invoice Sheet'); //source sheet
var testrange = sheet.getRange('K:K');
var testvalue = (testrange.setNumberFormat("#").getValues());
Logger.log(testvalue);
var ds = ss.getSheetByName('Payment Approval Sheet'); //destination sheet
var data = [];
var j =[];
var dt = new Date();
var today = Utilities.formatDate(new Date(), 'GMT-0', 'dd/MM/yyyy')
//Condition to check in N:N, if true, copy the same row to data array
for (i=0;i<testvalue.length;i++) {
if (testvalue[i] == today) {
data.push.apply(data,sheet.getRange(i+1,1,1,13).getValues());
//Copy matched ROW numbers to j
j.push(i);
}
}
//Copy data array to destination sheet
var start_row=ds.getRange('A8:A').getValues().filter(String).length +7; //calculate max row
ds.getRange(start_row+1,1,data.length,data[0].length).setValues(data);
}

Google Sheets - Delete Expired Rows Based On Date

I'm currently trying to make a script or literally anything that will be able to delete a row after the given date in Column C.
The site is a giveaway site so I need the rows/entries to delete themselves once the date specified on Column C is passed.
Eg: If one giveaway had an expiration date # 20/13/2016, once the date reaches this date of 20/13/2016 it will delete the row. I am following the metric system of dd/mm/yy as a note.
I saw a question similar to this at Google Sheets - Script to delete date expired rows but the code won't work for my needs.
Here is the code that was used in the other question.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Foglio1");
var datarange = sheet.getDataRange();
var lastrow = datarange.getLastRow();
var values = datarange.getValues();// get all data in a 2D array
var currentDate = new Date();
var oneweekago = new Date();
oneweekago.setDate(currentDate.getDate() - 7);
for (i=lastrow;i>=2;i--) {
var tempdate = values[i-1][2];// arrays are 0 indexed so row1 = values[0] and col3 = [2]
if(tempdate < oneweekago)
{
sheet.deleteRow(i);
}
}
}
If you could change it to work for my above needs it will be greatly appreciated!
Assuming your dates are in column C as stated, this should do it. The adjustment is just to the date to which we compare and to handle missing dates. I am also messing with the case on some names for readability.
function DeleteOldEntries() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Live Events");//assumes Live Events is the name of the sheet
var datarange = sheet.getDataRange();
var lastrow = datarange.getLastRow();
var values = datarange.getValues();// get all data in a 2D array
var currentDate = new Date();//today
for (i=lastrow;i>=3;i--) {
var tempDate = values[i-1][2];// arrays are 0 indexed so row1 = values[0] and col3 = [2]
if ((tempDate!=NaN) && (tempDate <= currentDate))
{
sheet.deleteRow(i);
}//closes if
}//closes for loop
}//closes function

Cannot find method getRange(number,number,number,number)

In an attempt to stream line some processes I have attempted to create a script to move a paper process into a google form. I've nhever really tinkered with Javascript but I have been following the trail of errors down to this one which I cannot seem to shake.
Currently I'm trying to define the range of data but keep getting the error mentioned in the title. Am I incorrectly calling the sheet in the script? I cannot seem to figure out how to properly define them.
Below is the section that defines the variables and sheets. Anything I'm doing incorrectly?
function sendEmail() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
Logger.log(ss.getName());
var sheet = ss.getActiveSheet()[0];
var startRow = 2;
// First row of data to process
var numRows = 12;
// Number of rows to process
var dataRange = ss.getRange(startRow, 2, numRows, 12)
//Assigning spreadsheet feilds
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var firstName = row[1];
var guestFirstN = row[6];
var guestLastN = row[7];
var arrivalDate = row[8];
var numberNights = row[9];
var rmName = row[10];
var rmAgree = row[11];
You first need to define the Sheet you want to get the data from since a Spreadsheet can have multiple Sheets.
Try replacing
var dataRange = ss.getRange(startRow, 2, numRows, 12)
with
var dataRange = ss.getActiveSheet().getRange(startRow, 2, numRows, 12);

Google Apps Script - Send email based on data in cell

So I'm trying to set up a reminder email to automatically be sent based on the date in a cell. Kind of like this: Google Apps Script - Send Email based on date in cell
Here's my sample workbook: https://docs.google.com/spreadsheet/ccc?key=0AiHAV8ZZ5nexdDJqODhmamhldjN1ZTRKc09iZXNBZ3c#gid=0
This is the code that I have:
function sendEmail() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = sheet.getLastRow()-1; // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, sheet.getLastColumn());
// Fetch values for each row in the Range.
var data = dataRange.getValues();
//Logger.log(data)
for (i in data) {
var row = data[i];
var date = new Date();
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
//Logger.log(date);
var sheetDate = new Date(row[2]);
//Logger.log(sheetDate);
var Sdate = Utilities.formatDate(date,'GMT+0200','yyyy:MM:dd')
var SsheetDate = Utilities.formatDate(sheetDate,'GMT+0200', 'yyyy:MM:dd')
Logger.log(Sdate+' =? '+SsheetDate)
if (Sdate == SsheetDate){
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var subject = "It's time to practice!" +message;
MailApp.sendEmail(emailAddress, subject, message);
//Logger.log('SENT :'+emailAddress+' '+subject+' '+message)
}
}
}
But I'm not sure if it's working, and will it automatically send the email out? Obviously, I know very little script.
You only have 1 error in your existing code shared here, that is keeping it from working:
var sheetDate = new Date(row[2]);
You only have 2 indexes in your array, so this should be:
var sheetDate = new Date(row[1]);
Also, because you are using Utilities.formatDate to yyyy:MM:dd format, you do not need to set the hours minute and seconds, because Utilities.formatDate is returning a string with no time component. Furthermore, you do not need to create sheetDate or date, those can both be constructed as the first parameter in the Utilities.formatDate (see below). One other thing on this topic, because your date values are formatted as a date in your spreadsheet, they are being returned to your script as a date object, so really, it isn't necessary to call new Date(row[1]) .. but it doesn't hurt anything.
function sendEmail() {
try{
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = sheet.getLastRow()-1; // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, sheet.getLastColumn());
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
//Logger.log(sheetDate);
var Sdate = Utilities.formatDate(new Date(),'GMT-0500','yyyy:MM:dd')
var SsheetDate = Utilities.formatDate(new Date(row[1]),'GMT+0200', 'yyyy:MM:dd')
Logger.log(Sdate+' =? '+SsheetDate)
if (Sdate == SsheetDate){
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var subject = "It's time to practice!" +message;
MailApp.sendEmail(emailAddress, subject, message);
//Logger.log('SENT :'+emailAddress+' '+subject+' '+message)
}
}
}catch(err){
Logger.log(err.lineNumber + ' - ' + err);
}
}

Categories