I am trying to build a full name from three fields (First, MI, and Last). If the middle initial field is blank, I do not want a period to appear in the assembled name. My code is below and when the MI field is blank, a period still appears between the first and last names. The partial_name is not being applied in this case.
// Get field values
var F_Name = this.getField('First_Name').value;
var M_Name = this.getField('MI').value;
var L_Name = this.getField('Last_Name').value;
// Build full_name string
var full_name = F_Name + " " + M_Name + ". " + L_Name;
// Build Partial Name string
var partial_name = F_Name + " " + L_Name;
if(M_Name="") {event.value = partial_name;
}
else {event.value = full_name;
}
screen capture of error
// Get field values
var F_Name = this.getField('First_Name').value;
var M_Name = this.getField('MI').value;
var L_Name = this.getField('Last_Name').value;
// Build full_name string
var full_name = F_Name + " " + M_Name + ". " + L_Name;
// Build Partial Name string
var partial_name = F_Name + " " + L_Name;
if(this.getField('MI').value=="") {
event.value = partial_name;
// I think that's because you used single (=) instead of (==) or (===) and you //wrote If with a capital I
}
else {event.value = full_name;
}
Related
For a new course project, I'm coming back to a google script for SendEmail from Google Sheets that worked perfectly a couple of years ago. (Original code from https://medium.com/#sebfung/custom-emails-from-a-spreadsheet-b11ff050bc5f ). Now I get three errors and can't figure out how to fix the third.
The full code is below. I've got limited code experience, but I figure I can work around the first two errors I get because they're cosmetic and my students can deal with it. (First, I can take out code to live without the "split" that used to let me drop off the second half of email addresses in the SendToName salutation. Second, I can take out the "replace" code that switches newline to paragraph breaks.)
But I can't figure out how to get around the third error. Something in the last command (MailApp.SendEmail) gives me a "Invalid email: undefined (line 66, file "Code")" error.
I don't see that any of these could be a spreadsheet-related error, since I went back to the earlier spreadsheets that worked a couple years ago and the debug now brings up the same three errors.
I'd be happy for suggestions on the first two, but I really most need and value help with that third error. I can't even run or test anything unless I fix it. Thanks!
function sendEmail(to, score, questions, answer1, answer2, answer3, answer4, answer5) {
var ss = SpreadsheetApp.getActiveSheet();
var range = ss.getActiveRange();
var numRows = range.getNumRows();
var values = range.getValues();
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
var to = row[1];
var score = row[2];
var questions = row[3]
var answer1 = row[4];
var answer2 = row[5];
var answer3 = row[6];
var answer4 = row[7];
var answer5 = row[8];
var sendToName = to.split('#')[0];
// email content
var emailSubject = "Quiz 1 Response";
// plain text body - just in case receiver can't parse html formatted email
var plainTxtBody = "Hello " + sendToName + ",\n" +
"You scored:\n" + score + "\n" +
"The questions were:\n" + questions + "\n" +
"Your answer:\n" + answer1 + "\n" +
"Your answer:\n" + answer2 + "\n" +
"Your answer:\n" + answer3 + "\n" +
"Your answer:\n" + answer4 + "\n" +
"Your answer:\n" + answer5;
// html formatting isn't necessary, but nice for reading :)
var htmlBody = '<html><body>';
var htmlFooter = '</body></html>';
// replacing newline characters with paragraph breaks to make it more readable
var scoreHTML = score.replace(/\n/g, "</p><p>");
var questionsHTML = questions.replace(/\n/g, "</p><p>");
var answer1HTML = answer1.replace(/\n/g, "</p><p>");
var answer2HTML = answer2.replace(/\n/g, "</p><p>");
var answer3HTML = answer3.replace(/\n/g, "</p><p>");
var answer4HTML = answer4.replace(/\n/g, "</p><p>");
var answer5HTML = answer5.replace(/\n/g, "</p><p>");
var emailMessage = "<p>Hello " + sendToName + ",</p>" +
"<p><strong>You scored:</strong><p>" +
"<p>" + scoreHTML + "</p>" +
"<hr>" +
"<p><strong>Here are the questions--see the answer key on the Quiz 1 page on the wiki:</strong></p>" +
"<p>" + questionsHTML + "</p>" +
"<hr>" +
"<p><strong>Here are your answers:</strong></p>" +
"<p>" + answer1HTML + "</p>" +
"<p>" + answer2HTML + "</p>" +
"<p>" + answer3HTML + "</p>" +
"<p>" + answer4HTML + "</p>" +
"<p>" + answer5HTML + "</p>";
htmlBody += emailMessage + htmlFooter;
// GmailApp must have default recipient, subject, body attributes followed by jsobject options {}
// Differs from MailApp syntax but has more options -- see documentation on GmailApp
MailApp.sendEmail(to, emailSubject, plainTxtBody, {
htmlBody: htmlBody,
});
}
}
The script does work. Var "to" probably doesn't contain a valid email adres. Make sure you have selected an active range in your spreadsheet. Please also note the first item in an array has index 0. Which reflects to the first column in your selection.
You can set a break point and use the debugger or use Logger.log(to); View -> Logs will show the outcome of var to.
I'm trying to solve an string assignment problem in Swift:
Here we have a struct:
struct Student {
var name: String
var id: String
var mentor: String?
var grade: String?
}
And we want to parse it into a string, something like:
if (mentor != nil && grade != nil) {
return "Student info: name:" + name + " id:" + id + " mentor:" + mentor! + " grade:" + grade! + "."
} else if (mentor != nil) {
return "Student info: name:" + name + " id:" + id + " mentor:" + mentor! + "."
} else if (grade != nil) {
return "Student info: name:" + name + " id:" + id + " grade:" + grade! + "."
} else {
return "Student info: name:" + name + " id:" + id + "."
}
I'm new to the Swift, the code above is based on other language's experience, I'm wondering if there's any more concise way to achieve that in Swift? Like deal with optional toString(), if it's nil then return a empty string ""?
Alexander's answer is good, and makes good use of the higher order function map(), but it might be a bit over your head if you're just starting out. You could simplify your code quite a bit with judicious use of if let "optional binding":
var result = "Student info: name:" + name + " id:" + id
if let mentor = mentor {
result += " mentor:" + mentor
}
if let grade = grade {
result += " grade:" + grade
}
result += "."
return result
Or rewritten to avoid the + operator:
var result = "Student info: name:\(name) id:\(id)"
if let mentor = mentor {
result.append(" mentor:\(mentor)")
}
if let grade = grade {
result.append(" grade:\(grade)")
}
result.append(".")
return result
Here are the improvements I would make:
Firstly, you should remove the unnecessary parentheses around the if predicates. You may be used to them from other C-like languages, but in Swift they're just noise.
Secondly, you should replace string concatenation (+) with interpolation. It has much faster compile times (operator type inference slows the compiler substantially), and will soon (with the rework of string interpolation) have better runtime performance (no redundant string allocation).
Next, I would use Optional.map to construct all the parts of the sentence that are optional. Then, I would default them to the empty string, if they're nil.
Then, I would take all the segments of the string, and join them together with a space as a separator:
struct Student {
var name: String
var id: String
var mentor: String?
var grade: String?
}
extension Student: CustomStringConvertible {
var description: String {
let start = "Student info:"
let nameSegment = "name: \(self.name)"
let idSegment = "id: \(self.id)"
let mentorSegment = self.mentor.map { "mentor: \($0)" } ?? ""
let gradeSegment = self.grade.map { "grade: \($0)" } ?? ""
return [start, nameSegment, idSegment, mentorSegment, gradeSegment].joined(separator: " ")
}
}
print(Student(name: "Bob", id: "id123", mentor: "Mr. Mentor", grade: "123"))
// => Student info: name: Bob id: id123 mentor: Mr. Mentor grade: 123
I'm having a problem sending an html body message from a Google sheet from another email address that is an alias.
I can send it using the mailApp, but when I switch to the GmailApp I can't seem to get it to work.
The script I am using is below:
function sendNotification(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var emailAdd = "email#yourdomain.com";
if(event.range.getA1Notation().indexOf("G") > -1 && sheet.getRange("G" + row).getDisplayValue() > 999 && emailAdd.length > 1)
{
var rowVals = getActiveRowValues(sheet);
var aliases = GmailApp.getAliases();
Logger.log(aliases);
GmailApp.sendEmail(
"email#yourdomain.com",
"Allocation Request - " + rowVals.quantity + " cases on " + rowVals.date,
{htmlBody: "There has been a new allocation request from " + rowVals.name + " in the " + rowVals.team + " team.<br \> <br \> "
+ "<table border = \"1\" cellpadding=\"10\" cellspacing=\"0\"><tr><th>Issuing Depot</th><th>Delivery Date</th><th>Case Quantity</th></tr><tr><td>"+rowVals.depot+"</td><td>"+rowVals.date+"</td><td>"+rowVals.quantity+"</td></tr></table>"
+ "<br \>To view the full details of the request, use the link below.<br \> <br \>" +
"Allocation Requests"
+"<br \> <br \><i>This is an automated email. Please do not reply to it.<\i>"},
{from: aliases[0]}
);
}
}
function getActiveRowValues(sheet){
var cellRow = sheet.getActiveRange().getRow();
// get depot value
var depotCell = sheet.getRange("E" + cellRow);
var depot = depotCell.getDisplayValue();
// get date value
var dateCell = sheet.getRange("F" + cellRow);
var date = dateCell.getDisplayValue();
// get quantity value
var quantCell = sheet.getRange("G" + cellRow);
var quant = quantCell.getDisplayValue();
// return an object with your values
var nameCell = sheet.getRange("B" + cellRow);
var name = nameCell.getDisplayValue();
var teamCell = sheet.getRange("C" + cellRow);
var team = teamCell.getDisplayValue();
return {
depot: depot,
date: date,
quantity: quant,
name: name,
team: team
} }
I've managed to get the email to send from my alias, but it just sends and message containing [object], whereas not sending it from an alias works fine.
Could someone take a look and see what I'm doing wrong? I've not been able to find an answer on here yet. Thanks.
Create an object then add elements to the object:
var bodyHTML,o,sendTO,subject;//Declare variables without assigning a value
o = {};//Create an empty object
bodyHTML = "There has been a new allocation request from " + rowVals.name;
o.htmlBody = bodyHTML;//Add the HTML to the object with a property name of htmlBody
o.from = aliases[0]; //Add the from option to the object
sendTO = "email#yourdomain.com";
subject = "Allocation Request - " + rowVals.quantity + " cases on " + rowVals.date;
GmailApp.sendEmail(sendTO,subject,"",o);//Leave the third parameter as an empty string because the htmlBody advanced parameter is set in the object.
I'm new to using the google doc script editor so please be kind. Here's what I have so far:
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
//Get Active cell
var mycell = ss.getActiveSelection();
var cellcol = mycell.getColumn();
var cellrow = mycell.getRow();
//Define variables from sheet by column
//Column count starts at 0, not 1.
var timestamp = e.values[cellrow,14];
var yourName = e.values[cellrow, 0];
var email = e.values[cellrow, 1];
var plot2013 = e.values[cellrow, 5];
var plotrequest = e.values[cellrow, 6];
var sharing = e.values[cellrow, 7];
var totalprice = e.values[cellrow, 8];
var paid = e.values[cellrow, 13];
var subject = "TSF Payment Confirmation"
//email body
var emailBody = "Thank you for your payment submitted on " + timestamp +
"\n\nThe details you entered were as follows: " +
"\nYour name: " + yourName +
"\nYour plot #: " + plot2013 +
"\nNumber plots requested: " + plotrequest +
"\nSharing plot with: " + sharing +
"\nTotal payment: " + totalprice;
//html version of email body
var htmlBody = "Thank you for your payment submitted on <i>" + timestamp +
"</i><br/> <br/>The details you entered were as follows: " +
"<br/><font color=\"red\">Your Name:</font> " + yourName +
"<br/>Your Email: " + plot2013;
"<br/>Plots requested: " + plotrequest;
"<br/>Sharing plot with: " + sharing +
"<br/>Total payment: " + totalprice;
//sends email if cell contents are 'yes'
if (e.values[13,cellrow] == "yes") {
//Sends email
MailApp.sendEmail(email, subject, emailBody);
}
}
And what I'm hoping is that once a user clicks in column 13 (assuming its counting from 0 on the left, and not variable numbers) and types 'yes' it will email the information from that users row as specified.
I'm getting an error message, saying:
var timestamp undefined
I got that from this example here: http://alamoxie.com/blog/tech-tips/sending-confirmation-emails-google-docs-form/
You're trying to reference the cells in a way that doesn't make sense (or work). Try this tested/working code instead:
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
// Ensure the event was triggered by typing "yes" in the appropriate column
if(e.range.getColumn() == 14 && e.value.toUpperCase() == "YES"){
// Get the corresponding row
var row = sheet.getRange(e.range.getRow(), 1, 1, sheet.getLastColumn()).getValues()[0];
// Define variable from row by column
var timestamp = row[14];
var yourName = row[0];
var email = row[1];
var plot2013 = row[5];
var plotrequest = row[6];
var sharing = row[7];
var totalprice = row[8];
var paid = row[13];
var subject = "TSF Payment Confirmation"
// Construct the email body
var emailBody = "Thank you for your payment submitted on " + timestamp +
"\n\nThe details you entered were as follows: " +
"\nYour name: " + yourName +
"\nYour plot #: " + plot2013 +
"\nNumber plots requested: " + plotrequest +
"\nSharing plot with: " + sharing +
"\nTotal payment: " + totalprice;
// Construct an HTML version of the email body
var htmlBody = "Thank you for your payment submitted on <i>" + timestamp +
"</i><br/> <br/>The details you entered were as follows: " +
"<br/><font color=\"red\">Your Name:</font> " + yourName +
"<br/>Your Email: " + plot2013;
"<br/>Plots requested: " + plotrequest;
"<br/>Sharing plot with: " + sharing +
"<br/>Total payment: " + totalprice;
// Send email
MailApp.sendEmail(email, subject, emailBody);
}
}
Notice I put everything in a conditional statement; there's no sense in trying to parse all that data if a cell in column N wasn't changed to "yes". Immediately after, I retrieve all the values from the edited row and fill all your variables with the result. The rest is pretty much the same as you wrote it.
Good luck!
I have created a script that automatically sends out emails that pulls information from several cells and populates the body of the email with the information alongside a standard body of the text.
However I can't work out a way to script in a paragraph space between the lines. I have done a workaround of creating a variable with the value of a cell that is just a paragraph space but, as other people will be using this spreadsheet, I am worried that the cell will get deleted and the formatting will change.
Is there another way to format paragraphs into the body of the email?
See my code below if that helps! The variable I need to format is "Var Message"
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var numRows = 99;
var dataRange = sheet.getRange(startRow, 1, numRows, 16)
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var EMAIL_SENT = "Contacted";
var currentdate = Utilities.formatDate(sheet.getRange("n2").getValue(), "GMT" , "dd/MM/yyyy" );
var staffmember = sheet.getRange("o2").getValue();
var paragraph = sheet.getRange("f2").getValue();
var row = data[i];
var emailAddress = row[0];
var name = row[1];
var company = row[2];
var website = row[3];
var role = row[4];
var show = row[9];
var date = Utilities.formatDate(row[15], "GMT" , "dd/MM/yyyy" );
var date2 = Utilities.formatDate(row[15], "GMT" , "dd/MM" );
var time = Utilities.formatDate(row[11], "GMT" , "HH:mm" );
var message = "Hello," + paragraph + "Could you please authorise or decline the following Arts Industry comp request from the Fringe Office? If you could reply within 72 hours, that would be great:" + paragraph + name + " " + company + " " + website + " " + role + paragraph + show + " " + date + " " + time + paragraph + "Many thanks," + paragraph + staffmember ;
var subject = "ARTS INDUSTRY REQUEST";
var emailSent = row[12];
if (emailSent != EMAIL_SENT) {
if (date > currentdate) {
var subject = "ARTS INDUSTRY REQUEST";
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 13).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
else if (emailSent != EMAIL_SENT) {
if (date < currentdate) {
var subject2 = "URGENT: ARTS INDUSTRY REQUEST" + " " + date2;
MailApp.sendEmail(emailAddress, subject2, message);
sheet.getRange(startRow + i, 13).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
}
}
}
}
For plaintext emails, you can use the "newline" escape sequence \n.
If you have K&R "C - The Programming Language", you'll find a full list of escape sequences in chapter 2. An online reference is available here.
var message = "Hello,\n"
+ "Could you please authorise or decline the following Arts Industry comp request from the Fringe Office? If you could reply within 72 hours, that would be great:\n\n"
+ name + " " + company + " " + website + " " + role
+ '\n' + show + " " + date + " " + time
+ '\n\n'
+ "Many thanks,"
+ '\n\n'
+ staffmember ;
You can use the advanced options of MailApp.sendEmail() function to achieve paragraph and line breaks more efficiently. Here is an example
var content = "Here is some text <br> " +
"that is split over two lines" ;
MailApp.sendEmail(recipient, subject, '',{'htmlBody' : content } );