So, i have a google form, and based on the data of the submitted form, a response is generated, i want that response to be emailed to the person who completed the form
Is there a way to send an email when a new row is inserted in the answer sheets?
The way I've accomplished this in the past is to write a simple google docs script to listen to the onChange trigger of a spreadsheet and send an email with the contents of the row of said sheet. Here are the specific steps:
With your google sheet open go to Tools > Script editor...
This will bring you to the script associated to this file where you can write a simple function to send the contents of the last rows of your sheet. Something like the following would work:
function sendEmailOfLastEditedRow() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow();
var numRows = 1; // Number of rows to process
var cols = sheet.getLastColumn();
// Fetch the range of cells A2:D5
var dataRange = sheet.getRange(lastRow, 1, numRows, cols)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
// Fetch your row as an array
var lastRowData = data[0];
// Format data by separating values into comma separated list for email
var emailContent = lastRowData.join(",");
// Send an email (change this to your email)
MailApp.sendEmail('alex#simoes.com', 'Email subject', emailContent);
// Log contents for debugging
Logger.log(emailContent);
}
Add a trigger in the script editor to run this function when the google sheet is edited: Edit > Current project's triggers
Related
function readDataFromRange() {
//Read data from the range OPTION CHAIN - NIFTY!D1:G1
var data = SpreadsheetApp.getActive().getRange("OPTION CHAIN - NIFTY!D1:G1").getValues();
//Log the data that was read.
Logger.log(JSON.stringify(data));
//Write the data to the range A1:D1 in Sheet "GRAPHDATA"
SpreadsheetApp.getActive().getRange("GRAPHDATA!A1:D1").setValues(data);
//apennd the rows
}
I am trying to fetch the data from one sheet and write it another sheet.I wish to append the destination sheet so as to aufill data in destination cell.
If I understood correctly and you wish to append the data to the destination sheet, you can try
function readDataFromRange() {
//Read data from the range OPTION CHAIN - NIFTY!D1:G1
const ss = SpreadsheetApp.getActive();
const data = ss.getRange("OPTION CHAIN - NIFTY!D1:G1").getValues().flat();
//Log the data that was read.
Logger.log(JSON.stringify(data));
//Append data to Sheet "GRAPHDATA"
ss.getSheetByName("GRAPHDATA").appendRow(data)
}
Reference
appendRow()
Trying to copy a range and paste only formulas, formatting, and data validation (no values) at the end of my sheet so I can enter new values in the freshly pasted range. All is working except I can't figure out how to exclude values when pasting.
Here is my code:
function addCue() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// copy the first cue range as template
var copyCueRange = ss.getRange("A10:AA11");
// Find the end of the sheet and set pasteRange to match copyRange
var l = ss.getDataRange().getValues().length;
var pasteCueRange = ss.getRange( "A"+(l+1)+":AA"+(l+2) );
// This pastes all data, How do I paste without values?
copyCueRange.copyTo(pasteCueRange);
};
I am very new to coding and appreciate the help. Thank you.
Data Validation: the Range class has a couple of methods for getting and setting data validation rules, setDataValidations() and getDataValidations().
Formulas: just as data validation, Range also has get/set methods for formulas, setFormulas() and getFormulas().
Formatting: looks like the Range.copyTo() method has some options specified here. Try using the formatOnly additional parameter.
function addCue() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// copy the first cue range as template
var copyCueRange = ss.getRange("A10:AA11");
// Find the end of the sheet and set pasteRange to match copyRange
var l = ss.getDataRange().getValues().length;
var pasteCueRange = ss.getRange( "A"+(l+1)+":AA"+(l+2) );
//Getting data validation and formulas
var dataValidationRules = copyCueRange.getDataValidations();
var formulas = copyCueRange.getFormulas()
//Setting formatting, data validations, and formulas
copyCueRange.copyTo(pasteCueRange, {formatOnly:true});
pasteCueRange.setDataValidations(dataValidationRules);
pasteCueRange.setFormulas(formulas);
}
I would like to persist the last row with yesterday's date.
My data looks like the following:
I have tried the following to persist the data, which works well.
function moveValuesOnly() {
var ss = SpreadsheetApp.getActive().getSheetByName('Store values');
Logger.log(ss.getName());
// get yesterday's date
var now = new Date();
var yesterday = new Date();
yesterday.setDate(now.getDate()-1);
yesterday = Utilities.formatDate(yesterday, "GMT+1", 'yyyy-MM-dd');
Logger.log("yesterday: " + yesterday);
var source = ss.getRange('4:4');
source.copyTo(ss.getRange('4:4'), {contentsOnly: true});
source.setFontWeight("bold");
}
Find below an example spreadsheet:
Sample Spreadsheet
As you can see I am getting yesterday's date correctly formatted in my script as in my Date column. I also can correctly 'persist' the data.
My problem is that I do not know how to get the range where yesterday's date occurs so that I can hand it over in my script to persist it.
Any suggestions how to get the row that matches yesterday's date.
not totally sure what you mean by "persist" but the function below returns the row number for the first row with yesterday's date in it:
function getYesterdayRow(yesterdayDate,columnRange) {
var displayValues = columnRange.getDisplayValues();
for (var i = 0; i < displayValues.length; i++) {
var displayValue = displayValues[i][0];
if (displayValue === yesterdayDate) return i + 1;
}
return 0;
}
You can call it like this in your code after you've defined yesterday:
var yesterdayRow = getYesterdayRow(yesterday,ss.getRange(A:A))
Note that this function quickly fixes your current need, but it uses getdisplayValues(), which is a quick cheat to not have to deal with processing the date. You should probably modify this function so that it would work with other date formats. (Use getValues(), get the day, time and month from yesterday, then the same from each value in the for loop, and make sure to account for any timezone offsets.)
Using Google Scripts, I have a program that retrieves the text from one account's tweets and uses it for various other things. It's been running for over a year with minimal issues, but now the tweets are being adjusted to 280 characters and I can't retrieve the second half of the tweet. I have:
function refreshing_v2() {
var service = getTwitterService();
if (service.hasAccess()) {
var url = 'https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=(redacted)&count=1&include_rts=0&exclude_replies=1';
var response = service.fetch(url);
var tweets = JSON.parse(response.getContentText());
for (var i = 0; i < tweets.length; i++) {
//Parse the tweet
var latest = new String(tweets[i].text);
var maxi_id = tweets[i].id;
var startpos = latest.indexOf("1: ");
etc, etc, continues doing stuff with what it's found.
This allows me to get the FIRST half of the text. What's retrieved looks something like "[Content of first half]...(link to tweet)"
How do I get the full text?
You need to add tweet_mode=extended to get the full text in the response. You may need to check the entities you receive to see if it is what you are expecting.
Documentation link - https://developer.twitter.com/en/docs/tweets/tweet-updates
Additionally, you will need to use full_text rather than just text
So:
//Parse the tweet
var latest = new String(tweets[i].full_text);
See the sample tweet at https://github.com/twitterdev/tweet-updates/blob/master/samples/initial/compatibilityplus_extended_13997.json
I am using a google forms to collect responses which I will then use to score people. Unfortunately some of those responses only make sense in a non numeric form, here is an example:
Q: What is your most common mode of transportation?
Car
Carpool
Public transportation
Bike
Walk
I want to be able to have google sheets automatically convert those string responses into a number, as in Car will be 20, carpool 15 and so on so that I can "grade" them and give them a score. Can this be done through google forms? Or maybe some sort of dictionary function?
Thank you!
Another method, requiring no coding, would be to make a worksheet with the encoding of the options and then use VLOOKUP to translate them.
Yep, this can be done through Google Forms. Have a look at https://developers.google.com/apps-script/reference/forms/duration-item#setPoints(Integer)
Using their code, you could go something like
var formResponses = FormApp.getActiveForm().getResponses();
// Go through each form response
for (var i = 0; i < formResponses.length; i++) {
var response = formResponses[i];
var items = FormApp.getActiveForm().getItems();
// Assume it's the first item
var item = items[0];
var itemResponse = response.getGradableResponseForItem(item);
if (itemResponse != null && itemResponse.getResponse() == 'Car') {
var points = item.asMultipleChoiceItem().getPoints();
itemResponse.setScore(points * 20);
// This saves the grade, but does not submit to Forms yet.
response.withItemGrade(itemResponse);
}
}
// Grades are actually submitted to Forms here.
FormApp.getActiveForm().submitGrades(formResponses);