Error On Sending Email From Google App Script - javascript

I'm trying to send an email to a user form after the submit the form. But I got an error:
Uncaught at emailCode2 at processForm2
Is there anything I did wrong? Your respond would be appreciated.
Here's my .html code:
<script>
function handleFormSubmit(formObject) {
google.script.run.processForm2(formObject);
document.getElementById("myForm").reset();
alert("Your form is submitted. Thank you!");
}
</script>
Here's my .gs code:
function processForm2(formObject) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ws = ss.getSheetByName("Sheet1");
var tz = ss.getSpreadsheetTimeZone();
var d = Utilities.formatDate(new Date(), tz, 'dd/MM/yyyy # HH:mm:ss');
var code = Math.floor(Math.random() * 99999) + 10000;
ws.appendRow([code, d, null, null, formObject.name, formObject.email,
formObject.things]);
emailCode2(code);
}
function emailCode2(code){
var url = "https://docs.google.com/spreadsheets/d/11X8e10TGQwzUQVJzTJ24JB1KMCTzkL5F5vObKrH0__k/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var lastRow = ss.getLastRow();
var sheet= ss.getSheetByName("Sheet1");
var name = sheet.getRange(lastRow,5).getValue();
var emailAddress = sheet.getRange(lastRow,8).getValue();
var subject = 'Code';
var message = 'Dear ' + name + ',\n\nHere is your code: ' + code;
MailApp.sendEmail(emailAddress, subject, message);
}

How about this answer?
Modification points:
I think that the error means that an error occurs at Google Apps Script side.
I think that the reason of your issue might be the following part.
var ss = SpreadsheetApp.openByUrl(url);
var lastRow = ss.getLastRow();
var sheet= ss.getSheetByName("Sheet1");
In this case, lastRow is the 1st tab of the Spreadsheet. If Sheet1 is not the 1st tab, the last row might be different. Please be careful this. So please modify as follows.
var ss = SpreadsheetApp.openByUrl(url);
var sheet= ss.getSheetByName("Sheet1"); // Modified
var lastRow = sheet.getLastRow(); // Modified
If the active Spreadsheet is the same with var url = "https://docs.google.com/spreadsheets/d/11X8e10TGQwzUQVJzTJ24JB1KMCTzkL5F5vObKrH0__k/edit#gid=0";, after the value was appended with appendRow, the email address is retrieved the column "H". But the appended values has the email at the column "F". By this, the email is not declared. By this, an error occurs.
When above points are reflected to your script, it becomes as follows.
Pattern 1:
If the active Spreadsheet is the same with var url = "https://docs.google.com/spreadsheets/d/11X8e10TGQwzUQVJzTJ24JB1KMCTzkL5F5vObKrH0__k/edit#gid=0";, how about the following modification?
Modified script:
function processForm2(formObject) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ws = ss.getSheetByName("Sheet1");
var tz = ss.getSpreadsheetTimeZone();
var d = Utilities.formatDate(new Date(), tz, 'dd/MM/yyyy # HH:mm:ss');
var code = Math.floor(Math.random() * 99999) + 10000;
ws.appendRow([code, d, null, null, formObject.name, formObject.email, formObject.things]);
emailCode2(code);
}
function emailCode2(code){
var url = "https://docs.google.com/spreadsheets/d/11X8e10TGQwzUQVJzTJ24JB1KMCTzkL5F5vObKrH0__k/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var sheet= ss.getSheetByName("Sheet1"); // Modified
var lastRow = sheet.getLastRow(); // Modified
var name = sheet.getRange(lastRow,5).getValue();
var emailAddress = sheet.getRange(lastRow,6).getValue(); // Modified
var subject = 'Code';
var message = 'Dear ' + name + ',\n\nHere is your code: ' + code;
MailApp.sendEmail(emailAddress, subject, message);
}
Pattern 2:
If the active Spreadsheet is NOT the same with var url = "https://docs.google.com/spreadsheets/d/11X8e10TGQwzUQVJzTJ24JB1KMCTzkL5F5vObKrH0__k/edit#gid=0";, how about the following modification?
Modified script:
function processForm2(formObject) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ws = ss.getSheetByName("Sheet1");
var tz = ss.getSpreadsheetTimeZone();
var d = Utilities.formatDate(new Date(), tz, 'dd/MM/yyyy # HH:mm:ss');
var code = Math.floor(Math.random() * 99999) + 10000;
ws.appendRow([code, d, null, null, formObject.name, formObject.email, formObject.things]);
emailCode2(code);
}
function emailCode2(code){
var url = "https://docs.google.com/spreadsheets/d/11X8e10TGQwzUQVJzTJ24JB1KMCTzkL5F5vObKrH0__k/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var sheet= ss.getSheetByName("Sheet1"); // Modified
var lastRow = sheet.getLastRow(); // Modified
var name = sheet.getRange(lastRow,5).getValue();
var emailAddress = sheet.getRange(lastRow,8).getValue();
var subject = 'Code';
var message = 'Dear ' + name + ',\n\nHere is your code: ' + code;
MailApp.sendEmail(emailAddress, subject, message);
}
Note:
In this modification, it supposes that formObject of processForm2(formObject) has the correct values. If this has wrong values, an error might occur. Please be careful this.
Reference:
getLastRow()

Related

Script eror message

I have a big query that I am using in google scripts and I can't make it past the following as I keep getting the error.
TypeError: Cannot read property 'makeCopy' of undefined
createReport # Report Automation - Sent via Slack.gs:13
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Attribution Extract");
var lr = sheet.getLastRow();
var lc = sheet.getLastColumn();
var sourceData = sheet.getRange(1, 1, lr, lc).getValues();
var timestamp = Utilities.formatDate(new Date(), "America/New_York", "M/d");
for (row in sourceData) {
if (sourceData[row][12] === "RunNow" && sourceData[row][7] !== "")
var templateId = DriveApp.getFileById("1CLzYIh6UqNUrJW5lz9DENoiopOqhQpVLd-XpZ9otzg0");
var copy = templateId.makeCopy();
var newId = copy.getId()
var newSheet = SpreadsheetApp.openById(newId);
var rowNum = parseInt(row);
var opp = sourceData[row][7];
var AMslackID = sourceData[row][14];```

Trying to sort and remove few columns before email it as an attachment using App Scripts but shows errors?

I am sending a Google sheet Tab to students and it is working fine. But before sending it to them, I need to sort the sheet using Column3 value and then remove column2, column4, column5, column7. But it shows errors:
"TypeError: The comparison function must be either a function or
undefined" at contents.sort() and contents.delete() in the codes
below.
I reviewed many posts but can't figure out the issue.
Function sendEmails(){
var sss = SpreadsheetApp.getActiveSpreadsheet();
var ssID = sss.getId();
var sheetName = sss.getName();
var sh = SpreadsheetApp.getActive();
var sheet1 = sh.getSheetByName("TempDataSet");
var shID = sheet1.getSheetId().toString();
var subject = 'Your Attendance Record at BDU';
var body = 'Dear Student,'+ '\n\n' + 'Greetings! Please find the attendance record attached for your reference.' + '\n\n' + 'Thank you.';
var requestData = {"method": "GET", "headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}};
var url = "https://docs.google.com/spreadsheets/d/"+ ssID + "/export?format=xlsx&id="+ssID+"&gid="+shID;
var result = UrlFetchApp.fetch(url , requestData);
var contents = result.getContent();
var column = 3;
contents.sort({column: column, ascending:true});
contents.delete({column: column2, column4, column5, column7});
var sheet2 = sh.getSheetByName('StudentList');
var data = sheet2.getLastRow();
var students = [];
var students = sheet2.getRange(2, 6, data).getValues();
for (var i=0; i<students.length; i++){ // you are looping through rows and selecting the 1st and only column index
if (students[i][0] !== ''){
MailApp.sendEmail(students[i][0].toString(), subject ,body, {attachments:[{fileName:sheetName+".xlsx", content:contents, mimeType:"application//xlsx"}]});
}
}
}
Explanation:
My suggestion would be to just create a copy of the TempDataSet sheet and do all the sort and delete columns operations on that sheet:
var sh = SpreadsheetApp.getActive();
var sheet = sh.getSheetByName("TempDataSet");
var sheet1 = sheet.copyTo(sh).setName('TempDataSet_temp');
var shID = sheet1.getSheetId().toString();
sheet1.getRange(2, 1, sheet.getLastRow() -1, sheet.getLastColumn()).sort({column: 3, ascending: true});
var columns_delete = [7,5,4,2];
columns_delete.forEach(col=>sheet1.deleteColumn(col));
then you can delete the temporary sheet after you saved it in the result variable:
sh.deleteSheet(sh.getSheetByName('TempDataSet_temp'))
Solution:
function sendEmails(){
var sss = SpreadsheetApp.getActiveSpreadsheet();
var ssID = sss.getId();
var sheetName = sss.getName();
var sh = SpreadsheetApp.getActive();
var sheet = sh.getSheetByName("TempDataSet");
var sheet1 = sh.insertSheet('TempDataSet_temp');
sheet.getDataRange().copyTo(sheet1.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
sheet.getDataRange().copyTo(sheet1.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false);
var shID = sheet1.getSheetId().toString();
sheet1.getRange(2, 1, sheet.getLastRow() -1, sheet.getLastColumn()).sort({column: 3, ascending: true});
var columns_delete = [7,5,4,2];
columns_delete.forEach(col=>sheet1.deleteColumn(col));
var subject = 'Your Attendance Record at BDU';
var body = 'Dear Student,'+ '\n\n' + 'Greetings! Please find the attendance record attached for your reference.' + '\n\n' + 'Thank you.';
var requestData = {"method": "GET", "headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}};
var url = "https://docs.google.com/spreadsheets/d/"+ ssID + "/export?format=xlsx&id="+ssID+"&gid="+shID;
var result = UrlFetchApp.fetch(url , requestData);
var contents = result.getContent();
sh.deleteSheet(sh.getSheetByName('TempDataSet_temp'))
var sheet2 = sh.getSheetByName('StudentList');
var data = sheet2.getLastRow();
var students = [];
var students = sheet2.getRange(2, 6, data).getValues();
for (var i=0; i<students.length; i++){ // you are looping through rows and selecting the 1st and only column index
if (students[i][0] !== ''){
MailApp.sendEmail(students[i][0].toString(), subject ,body, {attachments:[{fileName:sheetName+".xlsx", content:contents, mimeType:"MICROSOFT_EXCEL"}]});
}
}
}

How to get the cell values (Sheet1 from Google Form, Sheet2 from Formula) to google doc template

I have 2 sheets. Sheet1 is from Google Form and query them to Sheet2 then make the formula. I would like to get the cell values from them to Google Doc template and send the email. I can get values from Sheet1 but can't from Sheet2. Please help me solve this problem. Thank you.
enter image description here
enter image description here
function onFormSubmit(e){
var docs_email = e.values[1];
var Name = e.values[2];
var Date1 = e.values[3];
var Date2 = e.values[4];
var Money1 = e.values[5];
var Money2 = e.values[6];
//Values from Sheet2
var TotalDate = e.values[7];
var Money3 = e.values[8];
var TotalMoney = e.values[9];
var copyId = DriveApp.getFileById('Doc ID') //Temp document ID
.makeCopy('Report-'+Name)
.getId();
var copyDoc = DocumentApp.openById(copyId);
copyDoc.getBody()
var copyBody = copyDoc.getActiveSection();
copyBody.replaceText('keyName', Name);
copyBody.replaceText('keyDate1', Date1);
copyBody.replaceText('keyDate2', Date2);
copyBody.replaceText('keyMoney1', Money1);
copyBody.replaceText('keyMoney2', Money2);
copyBody.replaceText('keyTotalDate', TotalDate);
copyBody.replaceText('keyMoney3', Money3);
copyBody.replaceText('keyTotalMoney', TotalMoney);
copyDoc.saveAndClose();
//convert to pdf
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
//Send the email
var subject = "Your Report";
var body = "Dear " +Name+" \n\n"+"<br> This is your report";
GmailApp.sendEmail(docs_email, subject, body,{htmlBody: body, attachments: pdf});
}
How about this answer?
Modification points:
In order to retrieve the values from the columns "H" to "J" in "Sheet2", getValues is used.
From your question, I could understand that the columns "H" to "J" have the formula. So I thought that getLastRow() might not be able to be directly used. So I thought that it is required to retrieve the 1st empty row at the column "A".
When above points are reflected to your script, it becomes as follows.
Modified script:
Please modify your script as follows.
From:
var TotalDate = e.values[7];
var Money3 = e.values[8];
var TotalMoney = e.values[9];
To:
SpreadsheetApp.flush(); // This might be not required.
var sheet = e.source.getSheetByName("Sheet2"); // Values are retrieved from the sheet name of "Sheet2".
var row = 0;
for (var i = 1; i < sheet.getLastRow(); i++) {
if (sheet.getRange(i, 1).isBlank()) {
row = i - 1;
break;
}
}
var [TotalDate, Money3, TotalMoney] = sheet.getRange(row, 8, 1, 3).getValues()[0];
References:
getValues()
getSheetByName(name)
getLastRow()

error in assigning values to google spreadsheet cell

I am new to google script. I want to assign a value to variable from spreadsheet cell and after doing arithmetic operations, want to assign it to particular cell in spreadsheet.
I am using following code :
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("PATTERNS");
var dd = sh.getRange("C4").getValue();
var ee = sh.getRange("D4").getValue();
var x = dd - ee;
sh.getRange("P4").setValue(x);
}
however, value at cell P4 is showing error : #NUM!
please help!
also i want to use for loop for cell no such as
for (var i = 1, i <60, i++)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("PATTERNS");
var dd = sh.getRange("C[i]").getValue();
var ee = sh.getRange("D[i]").getValue();
var x = dd - ee;
sh.getRange("P[i]").setValue(x);
}
How to get this? Can someone please help me?
Try this:
function myFunction() {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sh=ss.getSheetByName("PATTERNS");
var rg=sh.getDataRange();
var vA=rg.getValues();
var change=false;
for(var i=0;i<vA.length;i++)
{
if(!isNan(vA[i][2]) && !isNan(vA[i][3]))
{
vA[i][15]=vA[i][2]-vA[i][3];
change=true;
}
}
if(change)
{
rg.setValues(vA);
}
}
Try this code
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("PATTERNS");
var dd = sh.getRange("C4").getValue();
var ee = sh.getRange("D4").getValue();
var x = parseInt(dd) - parseInt(ee);
sh.getRange("P4").setValue(x);
}

Passing a value to other sheet

I have a value in my sheet where I want to pass the value to other sheet using Google App Script, I have a simple code that can get the value but I don't know on how I can pass it to other sheet and create a new row in other sheet.
function doit() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var FromSheet = ss.getSheetByName('s1');
var ToSheet = ss.getSheetByName('s2');
var firstname = fromsheet.getRange('A2');
var lastname = fromsheet.getRange('B2');
var data = firstname.getValue();
var data1 = lastname.getValue();
//To sheet code???
}
You can simplify a bit the code and it i almost same code to paste value.
function doit() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var FromSheet = ss.getSheetByName('s1');
var ToSheet = ss.getSheetByName('s2');
var firstname = fromsheet.getRange('A2').getValue();
var lastname = fromsheet.getRange('B2').getValue();
//Copy to others sheet
ToSheet.getRange('A2').setValue(firstname);
ToSheet.getRange('A2').setValue(firstname);
}
You can also copy the data with copyValuesToRange()
see : https://developers.google.com/apps-script/reference/spreadsheet/range#copyvaluestorangegridid-column-columnend-row-rowend
code example from site :
var ss = SpreadsheetApp.getActiveSpreadsheet();
var FromSheet = ss.getSheetByName('s1');
var ToSheet = ss.getSheetByName('s2');
var range = FromSheet.getRange("A2:B2");
range.copyTo(ToSheet.getRange("A2"), {contentsOnly:true});
Stéphane
Your code has a couple errors in it:
function doit() {
var ss = SpreadsheetApp.getActiveSpreadsheet() // missing ;
var FromSheet = ss.getSheetByName('s1');
var ToSheet = ss.getSheetByName('s2');
var firstname = fromsheet.getRange('A2'); // fromsheet must be FromSheet (Caps Matter)
var lastname = fromsheet.getRange('B2'); // same here
var data = firstname.getValue();
var data1 = lastname.getValue();
//To sheet code???
}
Here's what I would do:
function doit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var FromSheet = ss.getSheetByName('s1');
var ToSheet = ss.getSheetByName('s2');
var firstname = FromSheet.getRange('A2').getValue(); // simplify lines
var lastname = FromSheet.getRange('B2').getValue(); // simplify lines
ToSheet.getRange("CELL TO PUT FIRSTNAME").setValue(firstname);
ToSheet.getRange("CELL TO PUT LASTNAME").setValue(lastname);
}

Categories

Resources