I'd like to send a notification to someone when a particular cell (ie document) is updated. Specifically, when a cell in one row is updated, it would send a notification to the owner listed in the same row. For example B47 gets updated, it send an email to B3.
I've gotten the script to work when it's pointed to one sheet. But when I try to ask the script to run over multiple sheets/tabs, I get error 'Script function not found: sendNotification' Is it possible to have this script work for multiple sheets/tabs in the same google doc? Updates are pulling from a different source so I'd like to keep using getSheetbyName instead of getActiveSheet.
Any help would be much appreciated. Here's my code where it stands:
function shellFunction() {
var sheets = ['Arabic', 'Portuguese'];
for (var s in sheets) {
toTrigger(sheets[s]);
}
function toTrigger(sheetName) {
function sendNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheets[s]);
var cell = ss.getActiveCell().getA1Notation();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var recipients = sheet.getRange('J' + sheet.getActiveCell().getRowIndex()).getValue();
var message = '';
if (cell.indexOf('B') != -1) {
message = sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue()
}
var subject = 'The ' + sheet.getRange('F' + sheet.getActiveCell().getRowIndex()).getValue() + ' ' + sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue() + ' needs your Translation';
var body = sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue() + ' has been updated. Can you please update ' + sheet.getRange('G' + sheet.getActiveCell().getRowIndex()).getValue() + '? Please remember to update the date column in the Resource Document when the translation is complete:' + ss.getUrl();
MailApp.sendEmail(recipients, subject, body);
}
}
}
Should this line
var sheet = ss.getSheetByName(sheets[s]);
be changed to
var sheet = ss.getSheetByName(sheetName);
since that is the name of the passed sheet?
EDIT
There were a couple other items which may have caused issue. I made edits for this result:
function shellFunction() {
var sheets = ['Arabic', 'Portuguese'];
for (var s in sheets) {
toTrigger(sheets[s]);
}
}
function toTrigger(sheetName) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheetName);
var cell = ss.getActiveCell().getA1Notation();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var recipients = sheet.getRange('J' + sheet.getActiveCell().getRowIndex()).getValue();
var message = '';
if (cell.indexOf('B') != -1) {
message = sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue()
}
var subject = 'The ' + sheet.getRange('F' + sheet.getActiveCell().getRowIndex()).getValue() + ' ' + sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue() + ' needs your Translation';
var body = sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue() + ' has been updated. Can you please update ' + sheet.getRange('G' + sheet.getActiveCell().getRowIndex()).getValue() + '? Please remember to update the date column in the Resource Document when the translation is complete:' + ss.getUrl();
MailApp.sendEmail(recipients, subject, body);
}
My first change was to not nest the functions. To do this I added a closing curly bracket before the toTrigger function and removed one of the last in your code. After that there was another nested function which actually made up all of the toTrigger function. It was called sendNotifocation which matched your error. I removed that by removing the line after the toTrigger function declaration and another curly bracket at the end of your code.
Last, I made the above edit. In my test it seemed to work fine, except that I commented out the call to actually send an email and only debugged to the line just prior to that point.
Related
I am creating a google script that when a person changes a column to "Approved" it sends an email out that grabs the cell that was changed. However, I am not a expert scripter at all and am having a hard time in figuring out how to get the script to call the information from the actual row into the email either.
Here is my script:
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var sheetName = sheet.getName();
var cell = sheet.getActiveCell().getA1Notation();
var rowData = sheet.getActiveRange().getRow();getValue();
var row = sheet.getActiveRange().getRow();
var cellvalue = sheet.getActiveCell().getValue().toString();
var recipients = "test#sendemail.com";
var message = '';
if(cellvalue === 'Approved'){
message = 'Cell ' + cell + ' ' + ' ' + rowData + ' was changed to Approved.';
var subject = 'Cell Changed to Approved in Interns List';
var body = message;
MailApp.sendEmail(recipients, subject, body);
}
}
I couldnt find any solution thats been done already that would include the entire row that was triggered.
Try this:
function onMyEdit(e) {
const sh=e.range.getSheet();
var rowData = sh.getRange(e.range.rowStart,1,1,sh.getLastColumn()).getValues()[0].join(',');
var recipients = "test#sendemail.com";
var message = '';
if(e.value == 'Approved'){
message = 'Cell ' + e.range.getA1Notation() + ' ' + ' ' + rowData + ' was changed to Approved.';
var subject = 'Cell Changed to Approved in Interns List';
MailApp.sendEmail(recipients, subject, message);
}
}
I am very new to google script and cannot work out why my script is not functioning. When I try to run the code I get the following error code -
TypeError: Cannot read property "range" from undefined. (line 2, file "Code"
If anybody could give a novice some help that would be greatly appreciated!
function sendEmail(event){
var sheet = event.range.getSheet();
if(sheet.getName() !== 'Sheet1') {
// if it's not the correct sheet we end the function here
return;
}
var range = event.range;
var row = range.getRow(); // we get the index of the row of the
edited
cell
var dataRange = sheet.getRange("A" + row + ":C" + row);
var values = dataRange.getValues();
var rowValues = values[0];
var recipient = rowValues[0];
var email = rowValues[1];
var refillsNumber = rowValues[2];
if (refillsNumber = 2) {
// if 'refillsNumber' is not equal to 2 we end the function here
var message = 'Dear ' + recipient + ',\n\n'+ 'You have ' +
refillsNumber + ' remaining would you like to buy more?' + '\n\n' +
'Kind regards,' + '\n\n' + 'The revol team.';
var subject = 'Refill reminder';
MailApp.sendEmail(email,subject,message);
return
}
if (refillsNumber !== 0) {
return}
var message = 'Dear ' + recipient + ',\n\n'+ 'You have ' +
refillsNumber + ' remaining would you like to buy more? If not then
would you like to end your subsription?' + '\n\n' + 'Kind regards,'
+ '\n\n' + 'The revol team.';
var subject = 'Refill reminder';
MailApp.sendEmail(email,subject,message);
return
}
// in addition to this script which aims to send an email to the
customer when they only have 2 refill remaining -
/// I also want to set up a function that sends an email when they
have 0 refills remaining
Send Emails by Editing Column C
I changed the Sheet name and added an extra condition. I also commented out the MailApp.sends and replaced them with writes to the sidebar so that I could test it without trying to send emails.
You will need to create an onEdit trigger for this function.
function sendMailOnEdit(event){
var sheet = event.range.getSheet();
if(sheet.getName() !== 'Sheet2' || event.range.columnStart!=3) {return;}
var range=event.range;
var row=range.rowStart;
var dataRange = sheet.getRange(row,1,1,3);
var values=dataRange.getValues();
var rowValues=values[0];
var recipient = rowValues[0];
var email = rowValues[1];
var refillsNumber = rowValues[2];
if (refillsNumber==2) {
var message = 'Dear ' + recipient + ',\n\n'+ 'You have ' + refillsNumber + ' remaining would you like to buy more?' + '\n\n' + 'Kind regards,' + '\n\n' + 'The revol team.';
var subject = 'Refill reminder';
//MailApp.sendEmail(email,subject,message);
var html=Utilities.formatString('<br />Email: %s<br />Subject: %s<br />message: %s<br /><hr>', email,subject,message);
var userInterface=HtmlService.createHtmlOutput(html);
SpreadsheetApp.getUi().showSidebar(userInterface);
return
}
if (refillsNumber !== 0) {return}
var message = 'Dear ' + recipient + ',\n\n'+ 'You have ' + refillsNumber + ' remaining would you like to buy more? If not then would you like to end your subsription?' + '\n\n' + 'Kind regards,' + '\n\n' + 'The revol team.';
var subject = 'Refill reminder';
//MailApp.sendEmail(email,subject,message);
var html=Utilities.formatString('<br />Email: %s<br />Subject: %s<br />message: %s<br /><hr>', email,subject,message);
var userInterface=HtmlService.createHtmlOutput(html);
SpreadsheetApp.getUi().showSidebar(userInterface);
}
This is what my spreadsheet looks like:
And let me remind you that you cannot run this function without an event object.
I am trying to send email when value of column 8 matched column 3 for all the rows in a google script .
function sendEmailNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var lrow=ss.getLastRow()
var sheet = SpreadsheetApp.getActiveSheet();
for (var i = 2; i < lrow; i++)
{
if (sheet.getRange(i, 8).getValue() = sheet.getRange(i, 3).getValue())
var emailSubject = 'Value of ' + sheet.getRange(i, 1).getDisplayValue() + ' triggered, now pending your attention';
var emailBody = 'Person1 has approved the item on row ' + ' of spreadsheet "' + '".\n\n';
emailBody += 'To open the spreadsheet, click this link: ' + ss.getUrl() + '\n\n';
emailBody += '(this is an automatically sent message)';
MailApp.sendEmail("sdas22#gmail.com", emailSubject, emailBody);
; }}
The main problem is the IF statement
This is yours which does not work and which is generating an error message
if (sheet.getRange(i, 8).getValue() = sheet.getRange(i, 3).getValue())
This is mine which does work
if ((sheet.getRange(i, 8).getValue()) == (sheet.getRange(i, 3).getValue())){
}
A couple of things to note.
The comparison operator is "==" rather than "="
The each of the getValue statements are encapsulated in brackets
There are no "curly brackets" to indicate the purpose of the IF statement. This is particular important.
There's also semicolon on the last line that seem out of place.
This is my version of your code - which runs
function sendEmailNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var lrow=ss.getLastRow()
var sheet = SpreadsheetApp.getActiveSheet();
for (var i = 2; i < lrow; i++)
{
if ((sheet.getRange(i, 8).getValue()) == (sheet.getRange(i, 3).getValue())){
var emailSubject = 'Value of ' + sheet.getRange(i, 1).getDisplayValue() + ' triggered, now pending your attention';
var emailBody = 'Person1 has approved the item on row ' + ' of spreadsheet "' + '".\n\n';
emailBody += 'To open the spreadsheet, click this link: ' + ss.getUrl() + '\n\n';
emailBody += '(this is an automatically sent message)';
MailApp.sendEmail("sdas22#gmail.com", emailSubject, emailBody);
}
}
}
I am having trouble copying a single row to a second sheet with google sheets.
I am using Google script editor to send automated email updates which works fine. However I am now trying to log each update from specific columns. I need all the information in the row to move with the cell that is edited.
Each Row is a separate job-site and I will have up to 30 concurrent job-sites going on at one time. So the update may come in in cell "M3" or "M28"
What I am trying to do is capture only the row that is edited not the whole sheet. My current code is copying the whole sheet. I am drawing a blank on how to just define the single row as active and set it to a range.
Here is what I have. I am no java script programmer but searching this site has gotten me this far. Bare with the code is not perfect.
function sendupdate() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var cell = ss.getActiveCell().getA1Notation();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var recipients = '';
var message = '';
var techname = '';
var branchname = '';
var city = '';
var state = '';
var technumber = '';
if(cell.indexOf('M')!=-1){
message = sheet.getRange('B'+ sheet.getActiveCell().getRowIndex()).getValue()
techname = sheet.getRange('N'+ sheet.getActiveCell().getRowIndex()).getValue()
branchname = sheet.getRange('H'+ sheet.getActiveCell().getRowIndex()).getValue()
city = sheet.getRange('J'+ sheet.getActiveCell().getRowIndex()).getValue()
state = sheet.getRange('K'+ sheet.getActiveCell().getRowIndex()).getValue()
recipients = "(emailaddress";
var subject = ' Update: ' +techname + ' ' + message + ' ' + city + ' ' + branchname +' ' ;
var body = ': ' + message + ' Technician: « ' + techname + ' » New Update: « ' + cellvalue + ' » has been posted to the Update Sheet Visit ' + ss.getUrl() + ' to view the changes on row: ' + row + '';
MailApp.sendEmail(recipients, subject, body);
var target_sheet = ss.getSheetByName('Log')
var last_row = target_sheet.getLastRow();
target_sheet.insertRowAfter(last_row);
sheet.getRange('A:P').copyTo(target_sheet.getRange('A'+(last_row+1)+':P'+(last_row+1)));
}
debugger
Here is the code I added which made it work
var target_sheet = ss.getSheetByName('Log')
var last_row = target_sheet.getLastRow();
var activeRow = sheet.getRange( row ,1, 1 ,16)
target_sheet.insertRowAfter(last_row);
activeRow.copyTo(target_sheet.getRange('A'+(last_row+1)+':P'+(last_row+1)));
Get the Range of the active row by calling getRange(row, column, numRows). You can then use that range to copy it to the other sheets
I could really use some help, and I'd really appreciate any pointers anyone can give. I know there are some other similar questions out there, but from what I can find, no one else has this specific issue/request.
I have a Google Sheet that three different people collaborate on. I have this notification script that will notify specific users via email about any changes to any of the cells in the F column. Importantly, this email notification also contains the value of the A cell in that row that has had it's F cell value changed.
However, what I'm really trying to achieve is a notification script that will email a specified person only when any cell in column F has a new value of "Yes" in Sheet2 of the master sheet.
The code I have so far is (that sends a notification when any change happens in the F column):
function sendNotification(e) {
var received = e.value; //Gets the value of the edited cell
};
function sendNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet 2");
var cell = ss.getActiveCell().getA1Notation();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var received = ss.getRange('F2:F').getValue();
var recipients = "example#gmail.com";
var message = '';
if(received==="Yes"){
message = sheet.getRange('A'+ sheet.getActiveCell().getRowIndex()).getValue()
var subject = 'A cell value '+ sheet.getRange('A'+ sheet.getActiveCell().getRowIndex()).getValue() + ' has been received';
var body = sheet.getName() + ' has been updated. Visit ' + ss.getUrl() + ' to view the changes on row: «' + row + '». New comment: «' + cellvalue + '». For message: «' + message + '»';
MailApp.sendEmail(recipients, subject, body)};
Logger.log('received value: ' + received);
};
If it helps, below is a code that works in my tests : (set up an installable trigger to make it work)
note : I added a couple of Logger.log here and there to check the variables and a Browser message to avoid sending mails while testing.
function sendNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet 2");
var cell = ss.getActiveCell();
var row = sheet.getActiveRange().getRow();
var col = cell.getA1Notation().replace(/[0-9]/g,'').toLowerCase();
Logger.log('col = '+col);
var cellValue = cell.getValue().toString().toLowerCase();
Logger.log(cellValue);
var recipients = "example#gmail.com";
var message = '';
Logger.log(cellValue=="yes" && col=='f');
if(cellValue=="yes" && col=='f' ){
message = sheet.getRange('A'+ sheet.getActiveCell().getRowIndex()).getValue()
var subject = 'A cell value '+ sheet.getRange('A'+ sheet.getActiveCell().getRowIndex()).getValue() + ' has been received';
var body = sheet.getName() + ' has been updated. Visit ' + ss.getUrl() + ' to view the changes on row: «' + row + '». New comment: «' + cellValue + '». For message: «' + message + '»';
// MailApp.sendEmail(recipients, subject, body)
Browser.msgBox('mail sent');
}
Logger.log('message body: ' + body);
};
To set up an event object use:
function sendNotification(e) {
var received = e.value; //Gets the value of the edited cell
};
The code that is sending the email, is outside of the if body. So the email is being sent no matter what.
Change to this:
if(received==="Yes"){
message = sheet.getRange('A'+ sheet.getActiveCell().getRowIndex()).getValue()
var subject = 'A cell value '+ sheet.getRange('A'+ sheet.getActiveCell().getRowIndex()).getValue() + ' has been received';
var body = sheet.getName() + ' has been updated. Visit ' + ss.getUrl() + ' to view the changes on row: «' + row + '». New comment: «' + cellvalue + '». For message: «' + message + '»';
MailApp.sendEmail(recipients, subject, body);
};
In this line of code:
if(received="Yes"){
You are using an assignment operator to check for equality. Equality checks are done with double or triple equal signs.
Should be:
if(received==="Yes"){