Can I update a Google Sheets spreadsheet using a Google Form? - google-apps-script

I'm looking to store data about foster animals from a google form. Essentially, it will just input the information entered into the spreadsheet. This works well for the first submission, but is not useful for if I would like to change information recorded for a specific animal. I think name is my best bet for a unique identifier, so I figure that I would want to write a script that would search for the name through a given column if the same name was entered and then repopulate that row.
Is this even something I can do to begin with? In addition, am I thinking about it in a very backwards way? If more information is needed, I am happy to provide it.

The best approach in this situation is to make use of Apps Script triggers.
You could start by using an onFormSubmit which will run when a user ends up submitting the form needed.
This is an installable trigger which means that it will require a setup first.
If you plan on using the form for modifying the information, you can easily create an id field for instance in the form and setup a script something similar to this:
function onFormSubmit(e) {
let ss = SpreadsheetApp.openById('SS_ID').getSheetByName('SHEET_NAME');
let idCol = ss.getRange('ID_RANGE').getValues();
let submissions = e.namedValues();
for (let i = 0; i < idCol.length; i++) {
if (idCol[i][0] == submissions.Id)
//update the sheet accordingly
else {
//add the new values to the sheet
}
}
}
In order to gather the submissions from the form, the e.namedValues has been used. Assuming, you have a column in your spreadsheet in which you store the id of each animal which corresponds to an item in your form, you can simply check if the submitted form is addressed for an existing item - so you can update it with the new info or simply just add the new submissions to the sheet.
Please bear in mind that you will have to adapt this so it fits your current setup.
Reference
Apps Script Installable Triggers;
Apps Script Event Objects.

Related

tracking editing values from Google Form

I've a google form, and I split data based on sections. I've 3 sections for example and data is get separated into 3 different sheets when user submits the form, I've successfully done it using form events, but now I want to know how I can track changes if user edits the form and make those fields red.
Sorry I am not including the code, here just want to know about suggestion to do it?
Can you suggest methods I can use for this?
Get response id:
Assuming you are using an onFormSubmit trigger (for Forms, not for Sheets), you can use the corresponding event object to get information about the form response.
More specifically, you can retrieve the form response id, which will be the same every time the form response is edited, as well as the different form item ids. You can use these field to identify the response in your sheet and each of the corresponding items and update those. For example, if this was your trigger function:
function onFormSubmit(e) {
const responseId = e.response.getId();
const itemResponses = e.response.getItemResponses();
itemResponses.forEach(itemResponse => {
const response = itemResponse.getResponse();
const itemId = itemResponse.getItem().getId();
// Find cells with corresponding responseId and itemId
// Update cells if found, populate new ones if it's a new submission
});
}
Find cells in spreadsheet:
Then you should find the responseId in your spreadsheet. You can use Range.getValues to look for the sheet values or, if you feel so inclined, use TextFinder to find the corresponding cell.
Update cells:
Once you've identified the cells, you can update the corresponding values (Range.setValues) and/or update the background color (Range.setBackgrounds).
Note:
This solution requires you to add the different responseId and itemId for every form response in your sheets. Otherwise, there will be no way to identify these whenever a response is submitted or edited.
The exact workflow for this would depend on the data structure you have, the form items you want to track, etc. I hope there's enough indications here to help you though.

Automatically copy information once text in cell was changed

I need some help from the experts here.
Please take a look at this spreadsheet:
https://docs.google.com/spreadsheets/d/1tSl8LxhLGoQMVT_83Ev4jMu_Fo1AW8lN6N8Yw8kX44U/edit#gid=640017957
Here is the story (in short):
Our company deals with many different sellers of e-commerce businesses that want to sell their business to new owners. For each seller, we have a specific sheet (seller A, seller B, seller C in the example spreadsheet above) where we fill out various data, including the last action and next action that we took/need to take when handling the communication regarding the sell of the business with each of our potential buyers. We try to find an easy way to automatically store the data that we fill out in the “last step” column so that every time we update a cell in this column, the data will be automatically copied to a sheet that store all the communication history with each buyer for each deal.
I thought about creating a tab such as the “all actions” sheet in the example spreadsheet above, where every time we update the data in the “last action” column, a new row will be automatically added to the “all actions” sheet with the relevant data shown there.
Is there any way to achieve this goal? If not, will you recommend a different method to get similar results so that we can automatically store (and see once needed) all the data that was entered in the past in the “last action” column?
You can use triggers to do this.
In your sheet, click Tools > Script Editor.
In the script editor, click Edit -> Current Project Triggers
In that window, in the lower right, there is a button to "Add Trigger".
When you add the trigger set the "Select Event Type" to "On Change".
Reference the function you wish to run that will do the work of adding the information.
You will need to write the JavaScript function (in the script editor) to do the insert.
If you are not familiar with JavaScript and using it to work with Google Sheets, the learning curve isn't very steep to do this basic thing. I recommend digging in. The power you will wield with your spreadsheets is well worth the time.
You need to use Google Apps Script and the onEdit trigger in particular.
Try this:
function onEdit(e) {
var row = e.range.getRow();
var col = e.range.getColumn();
if ( e.source.getActiveSheet().getName() != "All actions" && row>1 && col==2 ){
s_name = e.source.getActiveSheet().getName();
b_name = e.source.getActiveSheet().getRange(row,1).getValue();
a_taken = e.source.getActiveSheet().getRange(row,2).getValue();
e.source.getSheetByName("All actions").appendRow([s_name,b_name,a_taken,new Date()])
}
}
In order to use this function you need to go to the Spreadsheet file menu; click on Tools => Script editor, clear the code.gs file and copy the aforementioned code snippet. Then, everytime a seller edits the last action column the relevant information will be appended to the All actions sheet.
Try this:
function onEdit(e) {
var sh=e.range.getSheet();
var s_name=sh.getName();
if ( s_name!= "All actions" && e.range.rowStart>1 && e.range.columnStart==2 ){
values=sh.getRange(e.range.rowStart,1,1,2).getValues()[0];
e.source.getSheetByName("All actions").appendRow([s_name,values[0],values[1],new Date()])
}
}

Is there a way to have google form responses to record in sheets depending on what section of the form is filled out?

I made a form with multiple conditional paths and my response sheet is ungodly I could really use some help.
The way I set up the form has a total of 19 sections
Location Dropdown (we have 3)> Machine dropdown (a total of 15)> A Machine Specific measurement section and Submit.
I split the Measurements sections by machine because, I was hoping I could have each section record numbers into separate sheets. This way I could keep each Machine's data on its own google sheet.
So logically I am trying to get MachineX measurements to record sheet X but, Get Machine Y to record In Sheet Y. Is what I'm looking for feasible/ even possible?
I know I can try and organize the form responses into the sheets manually, but I am trying my best to avoid that, cause its gonna take a lot of time out of the week.
Maybe there is a way to organize the form response sheet to filter the data into their appropriate sheets.
I am out of my depth and could really use some help.
You can set up a linked Sheet to the Form and then an Apps Script function that gets the data and prints it into the Sheet.
First you have to create an Installable trigger: On form submit so every time the form is submitted the Sheet will be updated
Once you have your trigger set up, you have to write the function.
I would suggest you to create variables for each sheet you want your data in.
You can select the sheet by name like: sheet.getSheetByName("MachineX")
I recommend setting up the questions in an order that allows you to say:
From question 1 to 6 -> go to "MachineX"
From question 7 to 19 -> go to "MachineY"
Now you have to iterate over the answers and get the latest responses:
- If you just want the latest response to the form you could use something like:
for (var i = formResponses.length - 1; i < formResponses.length; i++)

Calculated Value For Google Form Item Not Refreshing

I have been using the script suggested by Mogsdad here. I have hit a bit of a brick wall trying to use the timestamp as per my post here.
So, my approach now is to try to get a unique ID in to the form before submission so that I can use it in the form response feedback in to the sheet. I am try to force a list item to have a selection of one value via the below script -
function updateForm(){
// a way to get the items from the form
var form = FormApp.openById("1t4NG2KYk09YiVzeVypWKpYTiWN97VuLBibafKbKfzP4");
var seqList = form.getItemById(1050085080).asListItem();
var d = new Date();
var n = d.valueOf();
seqList.setChoiceValues([n]);
}
While this is indeed creating a unique value, and putting it on the form response sheet, when I go in to the form to create a new submission, the same ID number is still there. Any ideas on how I force that value to be recalculated each time the form is brought up ?
We don't have the very important thing. It's called like a pre-form action or a trigger or an automate action. You can't do that.
You need create your own Form to manage your data. Look at I need to create a Google form to check if data being entered already exists in sheet
Cheers!

Dynamically edit multiple choice options in live Google Form using Apps Script

I'm a high school teacher in L.A. trying to create a course registration system using Apps Script. I need the Google Form I'm using for this registration to:
Question 1) Update the choices available in subsequent multiple choice questions on new pages based on a student's current response choices.
Question 2) Eliminate choices from the form when a multiple choice option has reached it's "cap".
Question 1 Example)
A student registers for “tie-tying” in workshop 1, and gets taken to a new page. The Script edits the available choices on that new page based on the student’s first choice, and removes “tie-tying” from the list of possible choices on that new page, so “etiquette” is their only remaining option.
Question 2 Example)
Students can either register for “tie-tying” or “etiquette”, both responses are initially available in the Google Form. 30 students take the survey, all 30 register for the “tie-tying” workshop. The Apps Script references the response spreadsheet, realizes the “tie-tying” workshop is full, then removes it from the Google Form's list of possible choices. Student 31 goes to register, and their only option is “etiquette”.
If my question has already been asked and answered (believe me, I did search!) I'd appreciate the redirection.
I believe we can achieve your second objective without too much difficulty and modify the form, based on the current state of response.
The approach is to
Create the form and associate it with a response spreadsheet
In that response spreadsheet, create a script with a function (updateForm for instance)
Bind that function with the onFormSubmit event, see Using Container-Specific Installable Triggers.
Analyse the response in the updateForm function and modify your form using the Form Service
For instance
function updateForm(e) {
if (e.values[1] == 'Yes') {
Logger.log('Yes');
var existingForm = FormApp.openById('1jYHXD0TBYoKoRUI1mhY4j....yLWGE2vAm_Ux7Twk61c');
Logger.log(existingForm);
var item = existingForm.addMultipleChoiceItem();
item.setTitle('Do you prefer cats or dogs?')
.setChoices([
item.createChoice('Cats'),
item.createChoice('Dogs')
])
.showOtherOption(true);
}
}
When it comes to achieving the goal in your first question, its more delicate, as the form will not submit mid way. What is possible is to go to different pages based on different responses to a Multiple Choice question, your use case may fit this method, although its not very dynamic.
Further its possible to use html Service to create completely dynamic experience.
Let me know if you need further information.
You are not able to create this type of dynamic form using the Google Forms Service, because there is no interaction between the service and scripts during form entry, except upon Form Submission. In the case of a multi-page form, a script has no way to know that a student has completed one page and gone on to another.
You could achieve this using the HtmlService or UiService, though. In either case, you'd rely on the client-side form interacting through server-side scripts to get updated lists of course options, then modifying the next 'page'. It will be complex.
The other answer to this question will keep adding a multichoice select each time for the form is submitted. Using similar approach of:
Create the form and associate it with a response spreadsheet
In that response spreadsheet, create a script with a function (updateForm for instance)
Bind that function with the onFormSubmit event, see Using Container-Specific Installable Triggers.
Analyse the response in the updateForm function and modify your form using the Form Service
I've used the following code to modify a list select which could be easiliy modified for a multiple choice.
function updateForm(){
var form = FormApp.openById('YOUR_FORM_ID'); // Base form
// need to read what dates are available and which are taken
var doc = SpreadsheetApp.getActiveSpreadsheet();
var dates = doc.getRange("dates!A1:A10").getValues(); //available options
var taken_dates = doc.getRange("responses!F2:F51").getValues(); //just getting first 50 responses
// joining the taken dates into one string instead of an array to compare easier
var taken_dates_string = taken_dates.join("|");
var choice = [];
// loop through our available dates
for (d in dates){
// test if date still available
if (dates[d][0] != "" && taken_dates_string.indexOf(dates[d][0]) === -1){
choice.push(dates[d][0]); // if so we add to temp array
}
}
var formItems = form.getItems(FormApp.ItemType.LIST); // our form list items
// assumption that first select list is the one you want to change
// and we just rewrite all the options to ones that are free
formItems[0].asListItem().setChoiceValues(choice);
}