I finally got the code to post here!
I figured out most of it, but just two things.
It is sending two e-mails instead of one for some reason.
I would like to print the arrays as a list like this:
object 1
object 2
etc.
instead of printing "object 1, object 2, etc" in the e-mail. Any suggestions how to do this would be helpful. Thanks!
picture of code is attached
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 3;
var numRows = 2;
var dataRange = sheet.getRange(startRow, 1, numRows, 15)
var data = dataRange.getValues();
for (i = 0; i < data.length; ++i) {
var row = data[i];
if(row[6]==0) {
var emailSent = row[14];
if(emailSent != EMAIL_SENT) {
var emailAddress = row[0];
var name = row[2]
var list1 = [];
for (j = 10; j < 12; ++j) {
if(row[j] != "") {
list1.push(row[j]); //if you know how to make this print in different rows in the e-mail, that would be helpful
}
}
var list2 = [];
for (j = 12; j < 14; ++j) {
if(row[j] != "") {
list2.push(row[j]); //if you know how to make this print in different rows in the e-mail, that would be helpful
}
}
var message = " " +emailSent+ "Hello, \n\n The first part of " +name+ "'s Unit 8 Project for Geometry is due this Friday, March 23rd. This includes sections 8-1 and 8-2. By this date, students are expected to have received feedback from me on their 8-1 and 8-2 assignments and revised their work for a summative grade. Unfortunately, " +name+ " still has not submitted all of these assignments to receive feedback from me. The following assignments are currently missing: \n" +list1+ "\n\n It is also important that the independent practice be completed as well to make sure that students grasp a full understanding of what we are learning in the project. Currently " +name+ " is missing the following independent practice for these lessons: \n" +list2+ "\n\n Please check with " +name+ " to make sure these assignments are completed as soon as possible. Let me know if you have any questions about what needs to be completed for Friday. Thank you!";
var subject = "" +name+ "'s Unit 8 Project Missing Work";
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 15).setValue(EMAIL_SENT); //this doesn't work after I added the array. Any idea why?
SpreadsheetApp.flush();
}
}
}
}
var spreadsheet = SpreadsheetApp.getActive();
var menuItems = [
{name: 'Send Emails', functionName: 'sendEmails'}
];
spreadsheet.addMenu('Send Emails', menuItems);
Figured it out :)
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 3;
var numRows = 13;
// Fetch the range of cells A3:I17
var dataRange = sheet.getRange(startRow, 1, numRows, 25)
var data = dataRange.getValues();
for (i = 0; i < data.length; ++i) { //collects data for all values in rows and columns specified in 5,6, and 8
var row = data[i]; //gives an index to data in each row
if(row[3]=="YES") { //ensures that it says "YES" in the e-mail column
var emailSent = row[24]; //checks value of emailSent row
if(emailSent != EMAIL_SENT) { //avoids sending duplicates if an e-mail is sent
var emailAddress = row[0]; //collects parent e-mail address
var name = row[2] //collects student name
var list1 = []; //creates an empty list for missing assignments
for (j = 15; j < 20; ++j) { //adds assignments to list if cells are not blank
if(row[j] != "") {
list1.push(row[j]);
}
}
texta = "" //creates an empty textbox for the list of assignments
if(list1.length>0) { //creates a textbox for assignments as a bulleted list if list is not empty
text1 = "";
for (k=0; k<list1.length; ++k) {
text1 += " • " +list1[k]+ "\n";
}
texta += "The second part of " +name+ "'s Unit 8 Project for Geometry is due next Tuesday, April 3rd. This includes sections 8-1, 8-2, 8-3, 8-4, and the interview/research portion. By this date, students are expected to have received feedback from me on all of their assignments and revised their work for a summative grade. Unfortunately, "
+name+ " still has not submitted all of these assignments to receive feedback from me. The following assignments are currently missing: \n" +text1;
}
var list2 = []; //creates a second empty list for missing assignments - IP
for (j = 20; j < 24; ++j) { //adds assignments to list if cells are not blank
if(row[j] != "") {
list2.push(row[j]);
}
}
textb = "" //creates an empty textbox for list of missing IP
if(list2.length>0) { //adds assignments to textbox as a bulleted list if list is not empty
text2 = "";
for (k=0; k<list2.length; ++k) {
text2 += " • " +list2[k]+ "\n";
}
textb += "\n\n It is also important that the independent practice be completed as well to make sure that students grasp a full understanding of what we are learning in the project. Currently " +name+ " is missing the following independent practice for these lessons: \n"
+text2+ "";
}
var message = "Hello, \n\n " +texta+ "" +textb+ "\n\n Please check with " //message body for e-mail
+name+ " to make sure these assignments are completed as soon as possible. Let me know if you have any questions about what needs to be completed for next week. Thank you!";
var subject = "" +name+ "'s Unit 8 Project Missing Work"; //subject line for e-mail
MailApp.sendEmail(emailAddress, subject, message); //sends e-mail with given e-mail address, subject, and message
sheet.getRange(startRow + i, 25).setValue(EMAIL_SENT); //updates spreadsheet once an e-mail is sent
SpreadsheetApp.flush(); //adds code to spreadsheet before continuing
}
}
}
}
var spreadsheet = SpreadsheetApp.getActive(); //creates a send e-mails button in spreadsheet
var menuItems = [
{name: 'Send Emails', functionName: 'sendEmails'}
];
spreadsheet.addMenu('Send Emails', menuItems);
Related
Can i get this script to work from sheet id or sheet name
This script works when i use the active spreadsheet but i want it to get it from the spreadsheet name or the sheet id. If i add .getSheetByName("Test") to line 2 it returns "TypeError: Cannot read property 'getRange' of null"
i am running the script from the sheet named "test" and there is a value in cell a1
Thanks in advance for the help
function CheckPrice() {
var priceRange = SpreadsheetApp.getActiveSpreadsheet().getRange("A1").getValue();
var ui = SpreadsheetApp.getUi();
if (priceRange < 10){
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getRange("A2");
var emailAddress = emailRange.getValue();
var message = 'This is your Alert email!';
var subject = 'Your Google Spreadsheet Alert';
MailApp.sendEmail(emailAddress, subject, message);
}
} ```
Change twice SpreadsheetApp.getActiveSpreadsheet() to SpreadsheetApp.getActiveSpreadsheet().getSheetByName('mySheetName')
For instance
function CheckPrice() {
var priceRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Test').getRange("A1").getValue();
// get value from cell a1
var ui = SpreadsheetApp.getUi();
if (priceRange < 10){
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Test').getRange("A2");
// get email from cell a2
var emailAddress = emailRange.getValue();
// Send Alert Email.
var message = 'This is your Alert email!';
var subject = priceRange + " %up";
// adds cell value to subject
MailApp.sendEmail(emailAddress, subject, message); }
}
I'm trying to write a script where an automatic email is sent to a specific person upon edit of a cell and the cell equals "Done". However, I want the subject to be the first cell of the edited row. Cell that will contain "Done" is always going to be in the AA Column, and I want the subject to be the A column of the same row. Ex: AA3 was edited so subject is A3. I have spent hours sifting through tutorials and came up with this:
function checkValue() {
var sp = PropertiesService.getScriptProperties();
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName("Accts");
var valueToCheck = sheet.getRange("AA2:AA1000").getValue();
if (valueToCheck = 'Done') {
MailApp.sendEmail("a***a#gmail.com", activeCell.offset(-26,0).getValue(), Email.html);
}
}
Am I doing this entirely wrong or is there hope?
EDIT:
Now that it's resolved. I thought I'd share what my script ended up looking like. I added a UI and an option to execute using a menu option. Hope this helps someone else.
function onEdit(e)
{
var editRange = { // AA2:AA1000
top : 2,
bottom : 1000,
left : 27,
right : 27
};
// Exit if we're out of range
var thisRow = e.range.getRow();
if (thisRow < editRange.top || thisRow > editRange.bottom) return;
var thisCol = e.range.getColumn();
if (thisCol < editRange.left || thisCol > editRange.right) return;
var thisthang = e.value;
var doit = 'TRUE'
// We're in range; timestamp the edit
if(thisthang == doit)
{
doFinish();
}
else{return};
}
function onOpen()
{
var ui = SpreadsheetApp.getUi();
ui.createMenu('Finished')
.addItem('Finish', 'doFinish')
.addToUi();
}
function doFinish()
{
var cell = SpreadsheetApp.getActiveSheet().getActiveCell();
var row = cell.getRow();
var Campaign = getCampaignFromRow(row, 1);
var ui = SpreadsheetApp.getUi();
var response = ui.alert('Finish '+Campaign.name+'?', ui.ButtonSet.YES_NO);
if(response == ui.Button.YES)
{
handleFinish(row, Campaign);
}
if(response == ui.Button.NO)
{
SpreadsheetApp.getActiveSheet().getRange(row, 27).setValue('FALSE');
}
}
function getCampaignFromRow(row)
{
var values = SpreadsheetApp.getActiveSheet().getRange(row, 1).getValues();
var rec = values[0];
var Campaign =
{
Campaign_Name: rec[0]
};
Campaign.name = Campaign.Campaign_Name;
return Campaign;
}
function handleFinish(row, Campaign)
{
var templ = HtmlService
.createTemplateFromFile('Campaign-email');
templ.Campaign = Campaign;
var message = templ.evaluate().getContent();
MailApp.sendEmail({
to: "a***a#gmail.com",
subject: "A Campaign has been finished!",
htmlBody: message
});
SpreadsheetApp.getActiveSheet().getRange(row, 27).setValue('TRUE');
}
You are trying to trigger an email when the spreadsheet is edited on the "Accts" sheet, in Column "AA" and the value = "Done".
The best solution is to use an onEdit trigger and also make use of Event Objects. In the case, "a simple trigger cannot send an email" ref, so you will need to create an Installable Trigger.
The main differences to your script are:
- var valueToCheck = sheet.getRange("AA2:AA1000").getValue();
- a couple of things here.
- 1) you are trying to get all the values in the column, but you use the getValue (the method for a single cell) instead of getValues.
- 2) you could have defined the ActiveCell and just returned that value
- 3) though you tried to get the values for the entire column, your if statement is designed as though there is a single value rather than an array of values.
- 4) This demonstrates the benefit of the using the Event Objects. You can succinctly get the values of the edited cell and sheet.
- in your if comparison, you use "="; this is only used to assign a value. When comparing values you must use "==" or "===".
- To get the value of the "subject", the script uses the row number derived from the Event Objects; compared to the offset in your script - they are both acceptable. I used the getRange to demonstrate the alternative.
- your email body was defined as "Email.html", but this isn't declared. The answer uses a very simple body but could just as easily use another solution.
function so5967209001(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet()
// establish the values to be checked
var checkSheetname = "Accts"
var checkValue = "Done"
var checkColumn = 27; // column AA
// this will return the event objects
//Logger.log(JSON.stringify(e)); // DEBUG
// variables to use for checking
var editedrange = e.range;
var editedrow = editedrange.getRow();
var editedcolumn = editedrange.getColumn();
var editedsheet = editedrange.getSheet().getSheetName();
var editedvalue = e.value;
//Logger.log("DEBUG: row = "+editedrow+", column = "+editedcolumn+", sheet = "+editedsheet+", value"+editedvalue)
// test the sheet, the column and the value
if (editedsheet ==checkSheetname && editedcolumn==checkColumn && editedvalue == checkValue){
//Logger.log("DEBUG: this is a match");
var subject = sheet.getRange(editedrow,1).getValue(); // Column A of the edited row
//Logger.log("DEBUG: email subject = "+subject);
// build your own body
var body = "this is the body of the email"
// send the email
MailApp.sendEmail("ejb#tedbell.com.au", subject, body);
//Logger.log("DEBUG: mail sent")
}else{
//Logger.log("DEBUG: this isn't a match");
}
}
I manage a large email list for my gaming society. In column A, I have the e-mails, and in column B, I have the usernames. I populate column B with a formula that extracts the name of the user from their e-mail address, which is often in the firstname.lastname#email.com form. Column B therefore returns "Firstname" after I run the formula if the user's email is in the firstname.lastname#email.com format.
Sometimes, however, the emails have just the initial of the first name (f.lastname#email.com) and, in these case, I want to have Column B return the word 'Gamer' rather than, for example, the first letter of the user's email.
Here is the script I use at the moment, which current deletes all rows with four or more numbers:
function removeNumbers() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
if (row[0].toLowerCase().indexOf("robot") > -1) {
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
On your shared spreadsheet, use this
function firstName() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var lr=sheet.getLastRow()
var val = sheet.getRange(2,1,lr-1,2).getValues();//get the col A email addrs
var newVal=[]//new array for before fitst period
for (var i = 0; i <= val.length-1; i++) {
var str=val[i][0].split(".")//split email at period
var len=str[0].length // determine lenght of number string of first split
if(val[i][1]=="inactive"){
newVal.push(["inactive"])
continue
}
if(len<=1){//if 1 or less
def="Gamer"
newVal.push([def]) //put Gamer in new array
}
else{
newVal.push([toTitleCase(str[0])]) //keep first name
}}
sheet.getRange(2, 2, newVal.length, 1).setValues(newVal)//set new values in col B
}
function toTitleCase(str) {
return str.replace(/\w\S*/g, function (txt) {
return txt.charAt(0)
.toUpperCase() + txt.substr(1)
.toLowerCase();
});
}
This well also run on the active sheet.
I'm new to coding. I am attempting to import e-mail addresses from a Google Sheet to my gmail account. Any help on why this code is not working would be greatly appreciated! Here is the code I have entered:
function myFunction() {
var alreadyAdded = "Already added";
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 396; // Number of rows to process
// Fetch the range of cells A2:F397
var dataRange = sheet.getRange(startRow, 1, numRows, 400
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for
var
for (var i = 0; i < data.length; ++i)
};
var row = data[i];
var lastName = row[0]
var firstName = row[1]
var emailAddress = row[2]
var address = row[3]
var notes = row[4]
if (addedAlready != alreadyAdded) {
// Create contact in Google Contacts
var contact = ContactsApp.createContact(firstName, lastName, emailAddress);
// Add values to new contact
contact.addAddress(address, "");
contact.setNotes(notes);
sheet.getRange(startRow + i, 7).setValue(alreadyAdded);
};
};
}
try it var dataRange = sheet.getRange(startRow, 1, numRows, 400);
I am facing a problem in the following script. I am not much into scripting at all and this is not my script also but here am getting the result which is grouping the values( For Example if i have a value A in three cells it should return the value as 3 instead it is returning AAA. Can someone help me out to count the values and return it
Thanks in Advance,
Here is the script :
function sumBackgroundColors(rangeString, color) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet();
var sumRange = s.getRange(rangeString);
//var sum = 0;
var openCount = 0;
var sumRangeBackground = sumRange.getBackgroundColors();
var sumRangeValues = sumRange.getValues();
for(var row = 0; row < sumRangeBackground.length; row++ ) {
for(var col = 0; col < sumRangeBackground[0].length; col++ ) {
if( sumRangeValues[row][col]=="LG M"&& sumRangeBackground[row][col] == color ) {
openCount = openCount + sumRangeValues[row][col];
//if(sumRangeBackground[row][col] == color && sumRangeValues[row][col] == 1 ) {
// sum = sum + parseFloat(sumRangeValues[row][col]);
}
}
}
return openCount;
//return sum;
}
Here is a function which will take the value to be searched as argument. Rest of the things have been explained in comment lines.
function searchCount(value){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
//Get the whole data from activesheet in a 2D array
var data = sheet.getDataRange().getValues();
//Initialize counter
var count = 0;
//Iterate through the array
for(var i in data){
for(var j in data[i]){
// if a match found, increament the counter
if(value.toString == data[i][j]){
count++;
}
}
}
// return the count value
return count;
}
your problem could be due to openCount = openCount + sumRangeValues[row][col];
According to your example sumRangeValues[row][col] isn't an int. int + not an int = ??? if you want to keep a count of things you probably want openCount++ to replace that line instead, which is just a shortcut to openCount = openCount + 1;
Even if sumRangeValues[row][col] was an int, that line still wouldn't be what you're looking for. If you're searching for all the 3s in your spreadsheet your code would find your first 3, and then that line would execute 0 = 0 + 3 congrats, you just found 3 threes. You would continue to add three every time you found a three.
Waqar's code is essentially your code (amazingly simplified, but it iterates the same way) except he doesn't check color and he uses ++ instead of that line.