Script to update Google Form from Spreadsheet - google-apps-script

Here's my problem:
I can't seem to piece this info together nor find it anywhere even though it seems simple enough. When I find help, they just tell me to enter it manually (but my users can't be trusted) or make a new form (not an option).
What I need is to be able to keep:
the same google form
it's ID and link to the same spreadsheet
the same 20 "paragraph text" questions (titles remain the same).
There can't be any new questions or anything that would change the name or layout of the response destination page in the spreadsheet.
However, what I want is:
to update the help text below these questions from twenty cells in the spreadsheet. If my cells are from a range called questions!b2:b19 in the same spreadsheet, how do I use a script to take their contents and write over and update the help text in these paragraph questions on the google form?
Any help would be greatly appreciated.

It might be easiest to create your form in AppScript. With your form created, you can then use AppScript to access your spreadsheet. Read the information from the sheet and use it to create the help text on your questions with setHelpText.
Here's a basic sample.
var form = FormApp.create('New Form');
var item = form.addCheckboxItem();
var ss = SpreadsheetApp.openById("<ID>");
var val = ss.getRange(<RANGE>).getValue();
item.setTitle('Question');
item.setHelpText(val);
item.setChoices([
item.createChoice('ONE'),
item.createChoice('TWO'),
item.createChoice('THREE')
]);

Related

Possible to pre-assign user to google form?

I am creating a Google Form dynamically, and emailing it, using Google Apps Script.
I have all the users info, and have figured out how to record the response. However, I would like to add that person's email to the row in the sheet.
It would be ideal if there was a way, since we already collected their email, to pass this email in the "background" to the form we send, and it is attached with there answer in the responses sheet.
Thanks!
I was not able to rest until I got this worked out. This article from almost three years ago really helped.
Not exactly what I was going for, still open if anyone knows how to actually pass info in the background to a sheet.
var items = formName.getItems();
var itemOfInterest;
for(var i in items){
if(items[i].getTitle()=='QUESTION_TITLE'){
itemOfInterest=items[i];
}
}
var preFilledUrl =
schedForm.createResponse().
withItemResponse(itemOfInterest.asTextItem().createResponse(email)).
toPrefilledUrl();
This prefills that question box, so also giving the user the ability to edit before they send. It'll work.

How to get url from Google Spreadsheet cell with Google Apps Script?

I've got a google spreadsheet copied from excel ANd I have some problem with that.
This is my document https://docs.google.com/spreadsheets/d/1Ok_phu5OXtvKHLj3MLa7N3WV2qBdMWRz8dLHnTqjHrc/edit?usp=sharing
This is my code
function myFunction() {
cel = SpreadsheetApp.getActiveSpreadsheet().getActiveCell()
Logger.log(cel.getFormula())
Logger.log(cel.getValue())
}
And this is my log:
[16-10-05 13:39:59:628 EEST]
[16-10-05 13:39:59:629 EEST] RU: VTB Arena - Park and Hotel
And I need to get an URL (https://na3.salesforce.com/0065000000a1b8p) How can I do that?
At this time the Spreadsheet Service of Google Apps Script is not able to get the properties of cells rich text content, just the plain text by using getValue() method. Other methods like getFormula(), getNote() are able to get the corresponding cell property, but none of the them includes the URL of the link.
On Google Sheets the workaround is to get the URL manually. A programmatically alternative is, to use VBA on the Excel file to get the hyperlinks before converting the file to the Google Sheets format. See the answer to Can I use an excel formula to extract the link location of a hyperlink in a cell? for details.
I think it's best to publish the google spreadsheet to the web and then parse the html with BS4 to get the urls.
Here's a workaround I used to get links from cells. Apparently when you use ctrl+K to add links they are added as rich text rather than as formulas. I used the function below in a google sheet to turn these rich text fields with links into html. If there is a link in the field then it returns the html code for the link. If there isn't a link then it simply returns the text passed in. Of course this could be done more elegantly ... I used lots of variables to make it easier to follow what was going on.
//get link from a cell given by A1 notation
function getHtmlfromRichTextRange(theRange){
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var range = sheet.getRange(theRange);
var cell = range;
var cellValue = cell.getRichTextValue();
var cellText = cell.getValue();
var theThing = cellValue.getLinkUrl();
if (theThing == null){
return cellText;
} else {
return ''+cellText+'';
}
}
In a spreadsheet you could do something like (see image 1):
In cell A1, enter "a link to apple"
With cell A1 highlighted, press ctrl+k to add the hyperlink to http://www.apple.com
In cell B1, enter A1
In Cell C1, enter the formula =getHtmlfromRichTextRange(B1)
As a result, you should see the value
a link to apple in cell C1
A couple of things I noticed when working with this example in this way:
If the function in C1 returned just the url and not the url with some String text around it, then Google sheets turned C1 into RichText, too. Since I was using this to create html emails, I had the function return the HTML code for the link.
I could have simplified and passed the String "A1" in quotes the function. I was trying to find a way to have the formula in C1 update when the richtext link in A1 was updated. My thought was that if A1 changed (e.g. the URL changed), then the result of the function in C1 would automatically update. It doesn't. I didn't pursue it. What is written above did the trick for me.
This code worked if the link was all the text in the cell. If the cell had some text in it that had the hyperlink and some text that did not (e.g. the hyperlink was only part of the text in the cell) then this code returned it as plain text and not as a URL.
I used the function as-is in AppScript to loop over a range that contained links. Inside the loop I passed the function the A1 notation of the cells, some of which had links. It worked beautifully and saved me loads of time!
I'm sure there's an easier way. I typically find that after doing it the harder way and thus don't need to do it anymore.
Thanks for asking this question! I've been looking for this myself! I copied a list of Facebook friends into a spreadsheet. They copied as Rich Text, meaning they contained a link, but it wasn't available in =Hypertext format.
I searched forever and it seemed certain there's no easy way around this.
Then I stumbled upon it.
Just select the cell containing the Rich Text (assuming you want to get the link it contains when you hover over it) and hit Command-K to Edit Link.
It will bring up a window where you can enter the Cell Text in the top field, and the URL in the bottom field.
No need to enter anything - it's there by default. So just hit [Enter] and BAM! It's now formatted as =HYPERLINK("URL","Text")
But I had HUNDREDS of these to convert and wanted to find an easier way.
And so I stumbled upon AppleScript (I've never used it til today - even though I'm transitioning away from Apple entirely).
I created a simple AppleScript:
tell application "Google Chrome" to activate
delay 0.5
tell application "System Events"
delay 0.5
tell process "Chrome"
keystroke "k" using command down
delay 0.2
keystroke return
delay 0.2
keystroke return
delay 0.2
keystroke return
delay 0.2
end tell
end tell
Select the cell you want to edit in your spreadsheet (assuming you're using Google Chrome) and then run this AppleScript.
I made several Scripts, all in US Currency amounts. So I have one that runs just once, and then a 5x, a 10x, a 20x, a 50x, and a 100x.
So for my list of 143 names, I just now ran the 100x script, then a 50x script. I sad back and took a sip of coffee while I watched my computer rapidly do the work for me.
Sorry if this is more info than people are looking for -- it's my first time answering a question here (that I recall) and, well, if I had stumbled across the answer I'm writing now -- it would have been a godsend earlier this year!
Happy coding!
This code works to fetch the URL from a column.
function testForUrlGet(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName("Zoom");
const range = sheet.getRange('C1:C500');
const values = range.getRichTextValues();
for(i=0; i<=values.length ; i++){
Logger.log(values[i][0].getLinkUrl());
}
}
I hope it helps as I could not find the answer for myself.
Try this:
var url = /"(.*?)"/.exec(cel.getFormulaR1C1())[1];
Logger.log(url);
It pulled the URL when I added it as a link manually.
Note that I used the following i my test:
var dataSheet = CentralSS.getSheetByName(CENTRAL_DATAFILES_SHEETNAME);
var range = dataSheet.getRange("E2");
var url = /"(.*?)"/.exec(range.getFormulaR1C1())[1];

Google Forms: Is it possible to update a title of a form onLoad?

I'm looking for a way to update a header of an element of a google form with specific data from a cell of google spreadsheet. As the data in the spreadsheet is changing, so should the header of the form element.
Here is my code I'm using.
function readTheSheet() {
var ss = SpreadsheetApp.openById("SpreadsheetKey");
var active = SpreadsheetApp.setActiveSpreadsheet(ss);
var sheet = SpreadsheetApp.setActiveSheet(ss.getSheets()[4]);
var data = ss.getDataRange().getValues(); // Data for pre-fill
var formUrl = ss.getFormUrl();
var form = FormApp.openByUrl(formUrl);
var items = form.getItems();
var formItem = items[0].asTextItem();
formItem.setTitle('Aktueller Clankrieg: ' + data[1][0]);
Logger.log(data[1][0]);
};
This code is running fine, exept that it's not updating when someone is responding to the form. As per Google Dev the onOpen() trigger runs only when a user opens a form, not when responding to one.
Does anyone know if and how this could be done?
If yes, any help or direction will be GREATLY appreciated.
Thank you in advance! Smite
OnOpen() only triggers when someone opens a form to edit it. :(
To get around this, I set the sheet up to edit the form whenever the relevant columns/rows were changed using onEdit() (onChange() would work also) triggers for those sections.
That was a problem though if someone updated part of the data and then went to lunch/home for the day/etc and someone else used the form in between. If you have a single column/row that matters or if it doesn't matter if it gets piecemeal updates or if you have users that will follow instructions that should work for you.
I ended up changing it to a manually triggered event. The users kept forgetting to use the menu item though so I stuck a "Big Red Button" jpg on the sheet with the data that mattered and associated the script to that. Seems to have done the trick. Whenever they change the part of the sheet that deals with the form they remember to hit the button and the form updates.
Basically grab your updated data from your sheet and then use a combination of:
//code to get the value to update into the form
var Form = FormApp.openById('form id') //to open the form
//more code to get the list of form items and select the right one if you are updating more than one thing
item.getTitle() == 'Item name that you want to update' //That is literally what you typed in that section on the form
Hollar if you need more specifics on logic/syntax.

Google Apps Scripts - Appending a paragraph after making a table?

I'm pretty new to working with Google Apps Scripts - So I apologize in advance if the answer to this question is really obvious. Here goes:
I have created a Google Doc from a spreadsheet. I've selected specific columns from the spreadsheet to display in a nicely formatted table in a new created Google Doc. I'd like to append a paragraph after the table has been created. I'd even be happy to append an additional row with a cell to the end of the table. I want to do this so I can simple write a little reminder at the end of the document.
I've tried using table.appendTableRow( index) where index is the number of the last row generated but that doesn't seem to be working. I've tried using body.appendTable( table) and then appending a row and cell and paragraph but that isn't working. Does anyone have any suggestions?
Thanks in advance
Here you can add a row to the last table in your document.
var d = DocumentApp.getActiveDocument();
var body = d.getBody();
var tables = body.getTables();
tables[tables.length-1].appendTableRow().appendTableCell("yoyo");
If this is not what you are looking for please provide more details.
Hope it helps!

Can I fill in TextItem by Google apps script?

I made a form with Google Form Builder, then I add a script for it.
I can run Session.getEffectiveUser().getEmail() to the respondent's email address. but I cant fill it in the textbox to assist them. Can I do such thing with Google App Script?
I think I found a solution to your problem. But I must admit it was not evident.
In apps scripts documentation you've got everything to create a prefilled url.
BUT for that you need to have a ItemResponse element and I didn't found any explaination to build one. The trick is when you've got an item you can get a ItemResponse from it if you get it as a defined type "asTextItem()".
Best way to understand it, is to watch the code below:
function getPreFilledItem(){
var form = FormApp.openById("YOUR_FORM_ID");
var items = form.getItems();
var itemOfInterest;
for(var i in items){
if(items[i].getTitle()=="YOUR_QUESTION_TITLE"){
itemOfInterest=items[i];
}
}
Logger.log(
form.createResponse().
withItemResponse(itemOfInterest.asTextItem().createResponse("PREFILLED_TEXT")).
toPrefilledUrl()
);
}
Hoping this will help you,
Harold
You can't dynamically modify Google Forms by attaching a script to the Form. See a recent question I asked to get a better understanding.
Basically, you can only use Google Apps Script to create forms in an automated manner. You can't set values for the items as of yet (I certainly hope they add this in the future...).
You can also see the limitations for Forms by looking at the documentation (TextItem, for example).