Calculated Value For Google Form Item Not Refreshing - google-apps-script

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!

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.

Can I update a Google Sheets spreadsheet using a Google Form?

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.

Is there a way to auto save data in google sheet?

Is there a way to auto save data entered in a temp area (risk is a calculated value based on the values entered) on google sheet. I have a working space and all my logs is now needing to be saved for later review.
see sample sheet.
Created a sample data screenshot
Thanks
There's two ways to do it. You'll need to create a log of sorts and have the dashboard reference the bottom most entry. If you have App Script experience, that would be the better solution, however without it you could use the a Google Form for editing the dashboard. There wouldn't be any formulas alone that will work for this due to needing to hardcode the inputs, and formulas can only return values as arrays (mirror/change values in other cells).
You can use a Google Form that is linked to the spreadsheet so that someone has to submit the form with the inputs to change the dashboard. You would then use a =Max() function on the timestamp column, and then either Vlookup or Index(match()) to return the variables for the dashboard based off Max(timestamp).
The alternative method would be to create basically set of cells similar to the input table, and add a button that if clicked, takes, the values and updates them in the variables for the dashboard, but also logs them on another sheet. (It would be something like this)
Thank you all for the suggestions. I end up using the below script to accomplish the task.
function FormExec() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sinput = ss.getSheetByName("sheet1");
var soutput = ss.getSheetByName("sheet2");
var input = sinput.getRange(14, 3, 15).getValues();
var flatin = [].concat.apply([], input);
soutput.getRange(soutput.getLastRow()+1, 1,1, 15).setValues([flatin]);
soutput.insertRowAfter(soutput.getLastRow());
Logger.log(input);
}

How to make a google form using apps script

I want to make a google form in apps script that will be like an inventory check out/in form. I want all the options to be under the check out section and every time a response gets submitted for checking out an item, the next time the form opens that item will appear under the check in section. I also want the item to go from check in to check out as well but I'm not even sure that functionality is available, just thought I'd put it out there. I started creating the form but I'm not sure where to go from here, the documentation for apps script isn't the most detailed.
//variable for new form
var newForm = FormApp.create('CS IT Checkout Form test');
//making name field
var name = newForm.addTextItem();
//variable for email
var email = newForm.addTextItem();
//variable for checkout checkboxes
var checkBoxItem = newForm.adCheckBoxItem();
//variable for checkin checkboxes
var checkBoxItem2 = newForm.addCheckboxItem();
function myFunction() {
//making description
newForm.setDescription('Checkout and check-in form for CS tech');
//making name field
//at some point make the name field required or just do it in actual
form
name.setTitle('Name');
//making email field
email.setTitle('Email')
//making checkout equipment fields
checkoutItem.setTitle('Check Out');
//default options until responses are made then it begins to change
checkBoxItem.setChoiceValues(['Laptop', 'Tablet', 'Monitor', 'Camera']);
//once form submissions start values will be put in the check in section
checkBoxItem2.setTitle('Check In');
checkBoxItem2.setChoiceValues();
}
Writing this as an answer rather than a comment because formatting.
First you have to figure out a flow that would work for what you want. Does this sound about right?
I think you need a form, and an inventory spreadsheet connected to that form.
The form asks the user whether it is a check/check out choice, and then the user select the appropriate item from the correct dropdown (check in or check out). I think you can tie this logic to a first page yes/no, but I haven't tried it. So worst case scenario three questions and they leave one dropdown blank. tie the form to the spreadsheet.
You need an onsubmit function in the spreadsheet that does the following:
Determine whether the form was checking in or checking out
Move the item to the appropriate sheet (two otherwise identical sheets for
items that are checked in, and checked out).
Update the values for the form with the right items in the dropdown
Now it is ready for the next usage. Is this what you envision?
Actually I didn't need to store the information in a sheet, I figured out how to do it by making a function that gets the latest response and passes it to another function that creates a new choice for the new section

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);
}