How to activate a script if a cell has a certain value - javascript

I have the following script in google sheets script which works fine.
function morningemail() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
var sheet = doc.getSheetByName("clock script");
var startRow = 9; // First row of data to process
var numRows = 1; // Number of rows to process
var dataRange = sheet.getRange(startRow, 1, numRows, 4)
var data = dataRange.getValues();
for (i in data) {
var row = data[i]
var emailAddress = row[0]; // First column
var message = row[2] + row[3]; // Second & third column
var subject = row[1]; // First column
MailApp.sendEmail(emailAddress, subject, message);
}
}
I will set the project trigger to activate every 5 minutes but only want the script to send an email if cell "A20" (on the same spreadsheet) is ">10".
I've tried a few ways of doing this but can't get it to work. Any suggestions would be great.

Short answer
Add if( data[19][0]>10) return; between the following lines:
var data = dataRange.getValues();
for (i in data) {
Explanation
In order to minimize the number of calls to the API, and considering that your script already got the data range values, use data[19][0] to get the value of A20, then use if to test if the desired condition is met and in such case use return to finalize the execution of the script.
References
Early exit from function?

Related

TypeError: Cannot read property 'getRange' of null (line 14, file "Code")

I am getting this error while trying to run the email sending script in Google App script. I don't have any knowledge of Javascript(I plan to learn after learning Python) and I got this code from samples code provided by Google App script.
The number of rows and columns in Google spreadsheet: https://prnt.sc/tha2o1
Below is the code.
// This constant is written in column C for rows for which an email
// has been sent successfully.
var EMAIL_SENT = 'EMAIL_SENT';
/**
* Sends non-duplicate emails with data from the current spreadsheet.
*/
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 6; // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, 7);
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var emailSent = row[3]; // Third column
if (emailSent !== EMAIL_SENT) { // Prevents sending duplicates
var subject = 'Sending emails from a Spreadsheet';
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 3).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
I was running a standalone script and it didn't work. You are supposed to run container-bound script if you wish to work with Google Sheets/Docs/Forms/Sites. Here is how you can run the container bound script. https://developers.google.com/apps-script/guides/bound

Google Script - send email only for a new change in cell value

I have searched and troubleshooted for many hours, but I can't get this to work.
I am trying send an email when a cell in Column C is marked Complete. The email will contain info from Column D as well as the sheet name. The code below works, but if Column C has more than one item marked Complete, it will send multiple emails.
How can I modify this code to only send an email once for newly marked items?
I'd rather avoid adding a column labeling the item as 'email sent'.
EDIT: For the avoidance of doubt, I wanted to note that I have this set up as an OnEdit Trigger, so that's not the issue.
function sendNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.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 3 (the Project Status column)
var range = sheet.getRange(2,3,lastRow-startRow+1,1 );
var numRows = range.getNumRows();
var projectStatus_values = range.getValues();
// grab column 4 (the Project Name column)
var namerange = sheet.getRange(2,4,lastRow-startRow+1,1 );
var nameNumRows = namerange.getNumRows();
var projectName_values = namerange.getValues();
// Get Active Sheet Name
var sheetname = SpreadsheetApp.getActiveSheet().getName();
// Loop over the Project Status values
for (var i = 0; i <= numRows - 1; i++) {
var projectStatus = projectStatus_values[i][0];
if(projectStatus == "Complete")
{var projectName = projectName_values[i][0];
//Define Notification Details
var recipients = "EMAIL#EMAIL.com";
var subject = sheetname + " has a new project marked Completed.";
var body = sheetname + " has a new project marked Completed:\n\n" + projectName + ".\n\nVisit " + ss.getUrl() + " to view the changes.";
//Send the Email
MailApp.sendEmail(recipients, subject, body);
}
}
//End sendNotification
Of the many threads I perused I found two approaches that seemed like they should work, but both didn't workfor me.
First, I tried Hyde's suggestions here---but I ran into an error ("TypeError: Cannot find function getvalue in object Range.") which I understand because I am using a custom function and not passing a range, but rather an object (probably butchered that).
I also tried this thread's suggestion to incorporate a background color check but haven't had any luck (script is just not sending emails at all despite complete lack of debug errors).

Update data from a Spreadsheet - Apps Script

I'm doing a data transfer of several spreadsheets to a single one, what I do is transfer the last data of certain columns to the master spreadsheet and also insert them in the last available row of certain columns, for now, I insert all the data but I would like to to know how I can have it examine the master spreadsheet so that if those data already exist, it does not delete them but update them. The script that I have is the following ...
function Gas10(){
var ss1 = SpreadsheetApp.openById("ID");
var ssh1 = ss1.getSheetByName("Sheet 1");
var lastRow1 = ssh1.getLastRow();
var gtRange1 = ssh1.getRange("C"+(lastRow1)+":K"+(lastRow1)).getValues();
var gtRange2= ssh1.getRange("A" + (lastRow1)).getValue();
var ss2 = SpreadsheetApp.getActiveSpreadsheet();
var ssh2 = ss.getSheetByName("Sheet 2");
var lastRow2 = ssh2.getLastRow() + 1;
var setRange1 = ssh2.getRange(lastRow2, 4, gtRange1.length, gtRange1[0].length).setValues(gtRange1);
var setRange2 = ssh2.getRange(lastRow2, 3).setValue(gtRange2);
}
I need to know how I can do it when I insert a piece of information (I already do that), but update it if it already exists. This is the example that I created so that it can be better understood, in this example I have two sheets of which from sheet 1 I pass data to sheet 2 and what I'm looking for is that sheet 2 updates all the data that are equal to (Name, Num, Proyect). I hope that now I understand better what I'm looking for.
Basically what you have to do is
get the new Line you want to add to the destination spreadsheet
get all the required datas of the destination spreadsheet
Check if the new Line datas have the same datas than in the destination data array
If so change ID value
paste changed datas in the destination spreadsheet
based on this spreadsheet The code should look something like this
function Gas10(){
var ss1 = SpreadsheetApp.getActiveSpreadsheet();
var ssh1 = ss1.getSheetByName("Sheet 1");
var ssh2 = ss1.getSheetByName("Sheet 2");
var lastRow1 = ssh1.getLastRow();
var lastCol1 = ssh1.getLastColumn();
var newLine = ssh1.getRange(lastRow1, 2, 1, lastCol1 - 1 ).getValues();
var destDatas = ssh2.getDataRange().getValues();
for (var i = 1; i < destDatas.length; i++)
{
if (newLine[0][0] == destDatas[i][0]
&& newLine[0][1] == destDatas[i][1]
&& newLine[0][2] == destDatas[i][2])
{
destDatas[i][3] = newLine[0][3];
}
}
// add newLine to destDatas
destDatas.splice(destDatas.length, 0, newLine[0]);
var lastColumn = ssh2.getLastColumn();
var lastRow2 = ssh2.getLastRow() + 1;
ssh2.getRange(1, 1, destDatas.length, lastColumn).setValues(destDatas);
ssh1.deleteRow(lastRow1);
}
Here's an example I played around with:
It looks at the slave sheet for any data. When it finds data it puts the row and col and value into an obj which is then added to an array. When it finishes it calls the updMaster which then looks for data in those same cells (assuming that the cells are in the same place if those cells are blank then it adds data and I also changed the background to lightblue to show me where it updated the cells.
You could run the getSlaveData() for different sheets if you wish.
function getSlaveData(){
var ss=SpreadsheetApp.getActive();
var ssh=ss.getSheetByName('Sheet2');
var sA=[];
var srg=ssh.getDataRange();
var svA=srg.getValues();
for(var i=0;i<svA.length;i++){
for(var j=0;j<svA[i].length;j++){
//if(svA[i][j]){
if(!ssh.getRange(i+1,j+1).isBlank()){//optional way to look for values
var sObj={};
sObj['row']=i + 1;
sObj['col']=j + 1;
sObj['value']=svA[i][j];
sA.push(sObj);
}
}
}
updMaster(sA);
}
function updMaster(sA){
var ss=SpreadsheetApp.getActive();
var msh=ss.getSheetByName('Sheet1');
for(var i=0;i<sA.length;i++){
if(msh.getRange(sA[i].row,sA[i].col).isBlank()){
msh.getRange(sA[i].row,sA[i].col).setValue(sA[i].value);
msh.getRange(sA[i].row,sA[i].col).setBackground('lightblue');
}
}
}

Send an Email to a Static Email Address based on a Trigger Word in a Column of a Google Spreadsheet

I have the following code, but my 'if' argument to send the 'message' array doesn't seem to execute for every row that has ALERT as the text in col[19]. Rather, only one email is being sent each time the script is run, even though there are several ALERTs in col[19].
function analyzeAlerts() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 4; // First row of data to process
var numRows = 30; // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, 30)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var col = data[i];
var subject = "Upcoming Bill Alerts";
var message = "The bill for "+col[13]+" Invoice #:"+col[11]+" for $"+col[12]+" is due on "+col[14];
if (col[19]="ALERT") {
MailApp.sendEmail("hello#world.com", subject, message);
}
}
}

Installable trigger onFormSubmit from non-Google form?

Thanks to everyone for their help in advance.
As a general novice to scripts and Installable Triggers specifically, I have searched all over for the technique of how to do this and haven't found what I need. I will try to break down what I am looking for as best I can.
1.) I am using a form service that is not through Google and I need this email script to trigger when a form is submitted via this service.
Currently I am using a Simple Trigger that runs every 5 minutes which is super annoying because it slows down the whole project and is obviously not very efficient.
2.) I don't know where the 'Trigger' function needs to be placed within the script so I will post the simple script that I am using and hopefully you guys can direct me to where it needs to be placed (and if it even matters?).
Finally, I have already visited all of the links both through Google and Formstack on this issue and have been unable to piece together the result I am looking for. Again, I am a novice at this trigger part so a walk-through is very much appreciated! :-)
Thanks again!
Edit: script
function Email1() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("Sheet3"));
var startRow = 2; // First row of data to process
var numRows = 18; // Number of rows to process
// Fetch the range of cells A2:B19
var dataRange = (ss.getSheetByName('Sheet3')).getRange(startRow, 1, numRows, 19)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var EMAIL_SENT = "EMAIL_SENT";
var row = data[i];
var emailAddress = row[0]; // First column
if(row[0]!="")
var message = row[1]; // Second column
var emailSent = row[2]; // Third column
var clientEmail = row[13]; // Thirteenth column
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
var subject = "APPOINTMENT SCHEDULED";
MailApp.sendEmail(emailAddress, subject, message, {noReply:true, cc:clientEmail, bcc:
'xxxxx.myemail.com'});
(ss.getSheetByName('Sheet3')).getRange(startRow + i, 3).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}

Categories

Resources