I'm trying to make a script that sends out a custom email confirmation to the user. However, I noticed that if any of the cells are blank the script will not work. I was wondering how to I like highlight the last entry of the table and check the cells, that if the cell is empty then change it's value to 0 or a dash. Here's what I got going:
function Confirmation(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var lastRange = sheet.setActiveRange(sheet.getRange(lastRow,5,1,2));
//lastRange.setValues(1111);
var EmailAdd = e.values[1];
var Name = e.values[2];
var Type = e.values[3];
var Criteria1 = e.values[4];
var Criteria2 = e.values[5];
var Criteria3 = e.values[5];
MailApp.sendEmail(EmailAdd, "Your request has been received" ,
"Thank you, " + Name + " for submitting your request.
)
}
the
lastRange
line already highlights the last entry. How can I evaluate each cell and check if it's empty change it's value and if not move to the next cell.
*I always get an "cannot read property "values" from undefined" is this because it's empty or because I set it as an event triggered function. Sorry I'm new to javascript & google apps script
As indicated in the comment above, Mogsdad's link provides a good work around for this problem. See link: e.values in google forms skips empty answers, is there a workaround?
Related
I have a script I am using to copy data from a form in a Google Sheet. ( Yes I know I can just use Google Forms but the client I am working with would like to keep it all in one Google Sheet)
Here is the code I am using now, and it works great. It does exactly what I want, but there is one field that an image is to be placed into. I have it set up so the user goes to "Insert" and then from there inserts an image into the cell. I can manually copy and paste the image from one sheet to another but when I run the script it will not copy over the image all the other data does copy over. Any help would be amazing. Here is the script. The image is in cell I3, as I said everything else works as expected.
function submitData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Form"); //Form Sheet
var datasheet = ss.getSheetByName("Data"); //Data Sheet
//Input Values
var values = [[formSS.getRange("E3").getValue(),
formSS.getRange("I3").getValue(),
formSS.getRange("E6").getValue(),
formSS.getRange("I6").getValue(),
formSS.getRange("E10").getValue(),
formSS.getRange("I10").getValue(),
formSS.getRange("E15").getValue(),
formSS.getRange("I15").getValue(),
formSS.getRange("E19").getValue(),
formSS.getRange("I19").getValue(),
formSS.getRange("E22").getValue(),
formSS.getRange("I22").getValue(),
formSS.getRange("E25").getValue(),
formSS.getRange("I25").getValue(),
formSS.getRange("E28").getValue()]];
datasheet.getRange(datasheet.getLastRow()+1, 1, 1, 15).setValues(values);
formSS.getRange('E3:E29').clearContent();
formSS.getRange('I3:I29').clearContent();
}
I have modified your script to fit the image in the Data sheet.
IMPORTANT: Unmerge the picture cells on the Form sheet and leave the background white. What the script will do is move the values from the Form to the Data (the background color will be moved as well)
The script will get the first value alone and put it in the first column, last row +1.
Now the last row is the one required (not the last +1), and then the script moves the image and inserts the other values as you were doing before.
The script:
function submitData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Form"); //Form Sheet
var datasheet = ss.getSheetByName("Data"); //Data Sheet
//Input Values
var values = [[formSS.getRange("E6").getValue(),
formSS.getRange("I6").getValue(),
formSS.getRange("E10").getValue(),
formSS.getRange("I10").getValue(),
formSS.getRange("E15").getValue(),
formSS.getRange("I15").getValue(),
formSS.getRange("E19").getValue(),
formSS.getRange("I19").getValue(),
formSS.getRange("E22").getValue(),
formSS.getRange("I22").getValue(),
formSS.getRange("E25").getValue(),
formSS.getRange("I25").getValue(),
formSS.getRange("E28").getValue()]];
// Get the first value and insert into the first column
var firstColumn = formSS.getRange("E3").getValue()
datasheet.getRange(datasheet.getLastRow()+1, 1,).setValue(firstColumn);
// Get the image and intert into the second column of the same row
var image = formSS.getRange("I3").moveTo(datasheet.getRange(datasheet.getLastRow(), 2));
// Get all the other values and insert them into the other columns of the same row
datasheet.getRange(datasheet.getLastRow(), 3, 1, 13).setValues(values);
formSS.getRange('E3:E29').clearContent();
formSS.getRange('I3:I29').clearContent();
}
So I have a Google sheet that collects registration data from customers. Included in the data collected is a student's name, the session the student elected to attend and a credit card number. Once a submission has been made, I get a notification. Upon notification, I go to my Google sheet and charge the credit card the appropriate amount.
Once the credit card has been charged, I then want to generate a confirmation email to the customer, which is based on a text template in cell A1, i.e., (1,1) on sheet2, that includes the student's name (Range C2), the session the student registered to attend (range D2) and the amount charged to the credit card (Range E2). Simply put, I want to replace curly bracket placeholders in my "template text" (i.e., {Name},{sessions} and {Cost} with the actual values which I've defined as variables.
For the life of me, I cannot get this to work.
Here's the error detail I get when I try to run this code:
Type Error: Cannot find function replace in object This is the email body. This is the amount charged to the credit card: {Cost}.
I've been all over the web on this. I've watched YouTube videos. I've read what seems like mountains of online documentation, none of which has provided any meaningful help. I've frustrated myself trying to figure out how the logger works and still, it's a complete mystery to me. Very frustrated!
Also, is there a way I can share my project with the forum community so someone out there can actually look at my code in action??? I wish there was a site for Apps Script that works like the ExcelForum does for questions about VBA programming.
function SendEmail2() {
// fetch these values as you need
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("B2").getValues();
var studentRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("C2").getValues();
var sessionRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("D2").getValues();
var chargeAmt = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("E2").getValues();
var studentName = studentRange;
var sessionName = sessionRange;
var emailAddress = emailRange;
var charge = chargeAmt;
var templateText = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Template").getRange(1,1).getValues();
// This is what needed to change
var emailText = templateText
.replace("{Name}", studentName)
.replace("{Sessions}", sessionName)
.replace("{Cost}", charge);
var subject = 'Junior Golf Clinic Registration Receipt';
var message = emailText;
MailApp.sendEmail(emailAddress, subject, message);
}
This is the email body.
This is the amount charged to credit card {Cost} // should be replaced with the value of the var "charge".
This is the student's name: {Name}. //Should be replaced with the value associated to the var "studentName"]
These are the sessions the student is scheduled to attend: {Sessions} //Should be the value associated with the var "sessionName".
At the moment your script is trying to do replace on whatever values it gets, but the values are not treated as a string, therefore .replace will not work as you're expecting.
Try using .toString() like below, I've also cleaned up some of the other variables in your script as there's no real reason to define then rename them.
function SendEmail2() {
//spreadsheet variables
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = spreadsheet.getSheetByName("Sheet1");
//fetch values from spreadsheet
var emailAddress = dataSheet.getRange("B2").getValues();
var studentName = dataSheet.getRange("C2").getValues();
var sessionName = dataSheet.getRange("D2").getValues();
var charge = dataSheet.getRange("E2").getValues();
var templateText = spreadsheet.getSheetByName("Template").getRange(1,1).getValues();
//get templateText as string and replace values with variables defined above
var emailText = templateText.toString()
.replace("{Name}", studentName)
.replace("{Sessions}", sessionName)
.replace("{Cost}", charge);
var subject = 'Junior Golf Clinic Registration Receipt';
var message = emailText;
MailApp.sendEmail(emailAddress, subject, message);
}
As you can see I have added .toString() at the start of your replace:
var emailText = templateText.toString()
I am trying to create a code to Google Spreadsheets . In VBA code it is very simple. My goal is, when a particular cell is filled , another cell displays the date and time of completion .
In VBA:
Function DateTime()
DateTime = NOW
End Function
Based on your most recent comment stating that you want to call a custom function from the Google Sheet frontend, all you will need in your Script Editor (backend) is:
function timeStamp() {
return new Date();
}
You can then call that function from a formula in your Sheet, very similar to what you wrote already:
=IF( ISBLANK(A1), "", timeStamp() )
This is the code that will help you out of what you are trying to achieve.
Code below will add the date in the very next column of whichever field you will input a value into.
//onEdit is the default "on edit event handler" provided by google app script
function onEdit(e){
var spreadSheet = e.source;
var sheet = spreadSheet.getActiveSheet();
var range = e.range;
//only add the date in the next column if value in cell is not empty
if(range.getValue() != ""){
var col = range.getColumn();
var row = range.getRow();
//get the very next column
var newRange = sheet.getRange(row, col + 1);
newRange.setValue(new Date());
}
}
Hope this will help.
NB: Please note this code will work with scripts bound to google apps only.
I've been busy trying to use the build-in javascript in Google Spreadsheet, however, not having worked in either javascript or Google Spreadsheet, i'm having a few difficulties.
My script is supposed to read a number (1-3) in a cell, and from that number parse an image to the cell below (I've been using the setFormula command for this).
So far it's working for 1 cell (B6 as i've choosen right now), but i would like to loop through a column with numbers in every other cell (So that after the script has run, it's number-picture-number-picture etc) - i just can't figure out how.
The code i'm using right now:
function numbtoimage() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var url = 'IMAGE("https://dl.dropboxusercontent.com/s/bpqy8o796casqjl/belt.JPG?dl=0", 2)';
var url2 = 'IMAGE("https://dl.dropboxusercontent.com/s/4q8sakhkpot0h65/belt2.JPG?dl=0",2)';
var url3 = 'IMAGE("https://dl.dropboxusercontent.com/s/kvsf4z6z45rcg53/belt3.JPG?dl=0",2)';
var cell = sheet.getRange("B6")
var data = cell.getValue()
if(data==1) {cell.offset(1, 0, 1).setFormula(url);}
else if(data==2) {cell.offset(1, 0, 1).setFormula(url2);}
else if(data==3) {cell.offset(1, 0, 1).setFormula(url3);}
}
I've looked at This similar problem, but have been unable to make it work for my case.
Any help is greatly and truly appreciated!
Nicklas
You need some sort of loop to go through the data. I Would suggest a FOR loop.
Your script is currently written to get one single cell value, rather than all the values.
So it might be an idea to get all values in one go, then check whats in them.
Also from you question, it's not clear where the numbers will be found.
Only in column B?
Here is a quick example (untested), that goes through column B looking for a number and it should insert the link in the cell below based on that number. This code is based on your original example and untested but hopefully it helps.
function numbtoimage() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var url = 'IMAGE("https://dl.dropboxusercontent.com/s/bpqy8o796casqjl/belt.JPG?dl=0", 2)';
var url2 = 'IMAGE("https://dl.dropboxusercontent.com/s/4q8sakhkpot0h65/belt2.JPG?dl=0",2)';
var url3 = 'IMAGE("https://dl.dropboxusercontent.com/s/kvsf4z6z45rcg53/belt3.JPG?dl=0",2)';
var values = sheet.getValues();
for(i=0; i < values.lenth ; i++){
if(values[i][1]==1) {sheet.getRange(i+2, 2).setFormula(url);}
else if(values[i][1]==2) {sheet.getRange(i+2, 2).setFormula(url2);}
else if(values[i][1]==3) {sheet.getRange(i+2, 2).setFormula(url3);}
}
}
The context: I need to process/correct many text documents containing multiple particular textual errors, highlight keywords in 'bold' and then output the result. I have a Google spreadsheet with two worksheets: one with two columns of 'wrong wordforms' and 'replacement wordforms' (2d array) that I intend to add to over time and use it as a datastore to 'call from;' the other, a single-column collection of words (1d array) I designate "keywords" to check for and then highlight in the target documents.
Things I've tried that worked: I used a basic array iteration loop from a beginner video (I can't add more links yet, I apologize) and swapped in body.replaceText() for the sendEmail(), successfully, to process the corrections from my "datastore" into my target document, which works nearly perfectly. It ignores text values without the exact same case...but that's a problem for another day.
function fixWords() {
// Document to edit
var td = DocumentApp.openById('docId1');
// Document holding comparison datastore
var ss = SpreadsheetApp.openById('docId2');
// Create data objects
var body = td.getBody();
var sheet = ss.getSheetByName("Word Replacements");
var range = sheet.getDataRange();
var values = range.getValues();
// Create a loop (iterate through the cell data)
for (i=1;i<values.length;i++) {
fault = values[i][0];
solution = values[i][2];
body.replaceText(fault, solution);
}
}
Things I've tried that fail: I then tried just swapping out values for setBold() with the replaceText() code, but the closest I got was the first instance of a keyword from the array would be styled correctly, but no further instances of it...unlike ALL of the instances of an incorrectly spelled word being corrected from the Word Replacements array using the fixWords function.
I found the 'highlightTextTwo' example here at stackoverflow which works very well, but I couldn't figure out how to swap in an external data source or force the included different iteration loop to work in my favor.
I've scanned the GAS reference, watched Google developer videos for snippets that might apply...but clearly I'm missing something that's probably basic to programming. But I honestly don't know why this isn't as easy as the body.replaceText() functionality.
function boldKeywords() { // https://stackoverflow.com/questions/12064972
// Document to edit
var doc = DocumentApp.openById('docId1');
// Access the keyword worksheet, create objects
var ss = SpreadsheetApp.openById('docId2');
var sheet = ss.getSheetByName("Keywords");
var range = sheet.getDataRange();
var values = range.getValues();
var highlightStyle = {};
highlightStyle[DocumentApp.Attribute.BOLD] = 'true';
for (i=1; i<values.length; ++i) {
textLocation = values[i];
if (textLocation != null && textLocation.getStartOffset() != -1) {
textLocation.getElement().setAttributes(textLocation.getStartOffset(),textLocation.getEndOffsetInclusive(), highlightStyle);
}
}
}
This throws out 'TypeError: Cannot find function getStartOffset in object DIV. (line 15, file "boldIt").' I guess this means that by just blindly swapping in this code, it's looking in the wrong object...but I cannot figure out why it works for x.replaceText() and not for x.setAttributes() or x.setBold or .getElement().getText().editAsText()...there just doesn't seem to be a "Learn Google Apps Script example" that deals with something this low on a scale of mundane, uninteresting use cases...enough for me to figure out how to direct it to the right object, and then manipulate the "if statement" parameters to get the behavior I need.
My current brick wall: I spotted this example, again, Text formatting for strings in Google Documents from Google Apps Script, and it seemed promising, even though the DocsList syntax has been deprecated (I'm fairly sure). But now I get "bold is not defined" thrown at me. Bold...is not defined. :: mouth agape ::
function boldKeywords() {
// Access the keyword worksheet, create objects
var ss = SpreadsheetApp.openById('docId1');
var sheet = ss.getSheetByName("Keyterms");
var range = sheet.getDataRange();
var values = range.getValues();
// Open target document for editing
var doc = DocumentApp.openById('docId2');
var body = doc.getBody();
// Loop function: find given keyword value from spreadsheet in target document
// and then bold it (highlight with style 'bold')
for (i=1; i<values.length; ++i) {
keyword = values[i];
target = body.findText(keyword);
body.replaceText(target,keyword);
text = body.editAsText();
text.setBold(text.startOffset, text.endOffsetInclusive, bold);
}
}
I will happily sacrifice my firstborn so that your crops may flourish for the coming year in exchange for some insight.
I use this for my scripts, the setStyleAttribute method.
Documentation : https://developers.google.com/apps-script/ui_supportedStyles
Example :
TexBox.setStyleAttribute("fontWeight", "bold");
The bold parameter is a Boolean data type. You need to use the word true or false.
Replace "bold" with "true".
text.setBold(text.startOffset, text.endOffsetInclusive, true);
Check out the "Type" column in the documentation:
Google Documentation - setBold