Questions about data formatting using UiApp and google spreadsheet - google-apps-script

Thank you in advance for any help you can provide. As background, I built a simple UiApp using GAS that I use to populate a google spreadsheet and a calendar with entries about events including time, date, location, etc. I've had it working for awhile but I want to keep improving it and I have a few questions about format and functionality.
1.) I now want the script to copy the information to a second spreadsheet, I've established how to do this, but the second spreadsheet already has some columns in use that I don't want to override and I don't want to just place the info from this Ui into the first 'X' number of columns, is there any easy way to essentially "copy these 5 columns to the first then skip and column and bring in the rest". Here is the code I have for the copy action right now:
var ss = SpreadsheetApp.openById(ssID);
var sheet = ss.getSheets()[0];
sheet.getRange(sheet.getLastRow()+1, 1, 1, 20).setValues([[new Date(), eventTitle, eventDateFrom, eventStartTimeb, eventEndTimeb, eventLocationName, eventLocationCity,eventActivity, eventLeadContact, eventNSLContact, eventContactAttending, eventDepartment, eventStaff, eventMaterials, eventCost, eventIncentive, eventMSTarget, eventSolar, eventNotes,eventRegion]]);
Also, in the same vein as this question, I've been wondering if it is possible to write something that will choose when an entry is copied to the second spreadsheet based on the value of one of the elements. For example, if eventStaff=0 or is blank, the script will copy the designated information to first spreadsheet but not the second.
2.) Date format: I added two listboxes for to capture event time start and event time end and I would like them to show up in the spreadsheet formatted as 00:00 AM/PM, but have only accomplished to get 00:00:00 or whole number so far.
3.) Using multiple elements to fill the location and events portion of calendar entries. This script works to create a basic event with start/end time and a title, but I'd like to use some of the information to fill in the location and description of an event. Is there a way for me to do this or do I need to concatenate those fields into one in able to enter them in the event creation. Current event creation code:
cal.createEvent(eventTitle,eventDateFrom,eventDateTo);
Sorry for the wall of text, if any clarification/additional code sample is needed just ask. Thank you in advance for any help/insight you might be able to provide.

Please don't be offended but I'm afraid your questions are more general programming question than GAS question, by formulating the question you almost answer it by yourself (question 1).
As for question 2, have a look to Utilities.formatDate and you'll get what you want, see also this.
Question 3: see CalendarApp documentation, createEvent, there is a set of optional arguments that suits your needs. - best regards,

Related

Generating hyperlinks to prepopulate Google form

Context:
I created a Google Sheets/Forms workflow using sequential stages of Google Forms.
Form 1 (public facing) Accepts some data submitted by a public user and saves to Sheet 1.
Internal staff then contacts the submitter by telephone and conduct a more in-depth interview.
Form 2 (internally facing) is used by the interviewer to document
answers to the phone interview.
This question concerns the generation of Form 2 because I am partially pre-populating it with information from Sheet 1 (Form 1 submissions.) The way I figured out was to formulaically generate a URL with appended pre-population arguments e.g. "&entry.NNNNNN=whatever". I copied-down this formula in the last column of Sheet 1. Clicking on the cell and then the generated hyperlink successfully pre-populates Form 2 with data from the respective row of Sheet 1 as intended.
Problem: As soon as a new Form 1 submission is received, a new row is inserted into the Sheet 1 that does NOT contain the desired hyperlink formula in the last column. I would like that to be automatic so the interviewer is not responsible for performing a copy-down before every request for a Form 2.
I have pursued a couple of approaches to automating this:
One thread advised instead of copy-down, to create an arrayformula in the top cell so that it applies to the entire column including newly inserted rows as well. I tried every way I could think of but was unable to get my formula to produce a column of results with arrayformula(). If there is a way to fix this, that would be a satisfactory solution.
=HYPERLINK(CONCATENATE("https://docs.google.com/forms/d/e/XXXXXXXXXXXXXXXX/viewform?usp=pp_url&entry.251357138=",C2,"&entry.966351469=",D2,"&entry.384696201=",E2,"&entry.1366694528=",F2,"&entry.463407115=",M2,"&entry.1557144679=",B2,if(P2,"&entry.1777888516=Email",""),if(O2,"&entry.1777888516=Phone",""),if(H2,"&entry.2110474669=Individual+(Adult)",""),if(I2,"&entry.2110474669=Individual+(Under+18,+Minor)",""),if(J2,"&entry.2110474669=Couple",""),if(K2,"&entry.2110474669=Family",""),if(L2,"&entry.2110474669=Group",""),if(R2,"&entry.1892971721=San+Jose",""),if(S2,"&entry.1892971721=Sunnyvale","")), "Complete Intake")
I tried to create a ModalDialogue and display a script generated hyperlink in it. I used this approach found in this forum. But this did not open any dialog at all and threw no errors (even after hyperlink was removed.) There was no indication of pop-up blocking. Other parts of my script use Browser.msgBox without any pop-up troubles, but I don't think that will pass a hyperlink.
var htmlOutput = HtmlService
.createHtmlOutput('Click to open and prefill intake interview form.')
.setWidth(250) //optional
.setHeight(50); //optional
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Ready to fill intake interview form:');
Using onFormSubmit() and scripting a copydown after a new row has been inserted. But I have been unable to figure out how to identify which row was inserted into Sheet 1. I see some people using lastRow(), but it isn't always inserted into the last row - typically it goes in the middle somewhere.
Request:
Help getting arrayformula to work in my case.
Or help getting ModalDialog to display a script generated hyperlink.
Or help on how to identify the row the Form submission inserted. Or do I just need to make sure the table remains sorted by TimeStamp and then I can use lastrow()?
Suggestion for a cleaner approach to get to the same place (generating a prepopulated Form from a row of data in Sheet 1.)
Thank you for illuminating a path forward.
You should consider using ArrayForumlas to automatically copy down the formula to other rows that have a value in the first column.
Put this formular in row 2 of the column that has the Google Form links.
=ARRAYFORMULA(
IF(ISTEXT(A2:A),
HYPERLINK(
CONCATENATE(
"https://docs.google.com/forms/d/e/XXXXXXXXXXXXXXXX/viewform?usp=pp_url&entry.251357138=",C2:C,"&entry.966351469=",D2:D
)),""))
I wrote a tutorial on copying formulas if you need more examples.
It turned out I was able to successfully employ approach 2, the modalDialog. For some reason no dialog was appearing when I first attempted so I didn't know if there was something fundamental wrong with this approach. I tried again and it worked as shown below so I suppose I just had some typos. Adding target="_blank" was helpful so as to open in a new tab.
var htmlOutput = HtmlService
.createHtmlOutput('Click to open and prefill intake interview form.')
.setWidth(250) //optional
.setHeight(50); //optional
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Ready to fill intake interview form:');

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++)

How to change background color of a cell if it is edited after a specific duration?

I have a google spreadsheet which we use to feed inventory purchase and issue data. The only problem is my staff can manipulate purchased quantity, prices and other variables at a later date. I want that if they enter the data in a cell and try to edit it whenever after 12 hours of entering the data, the cell should get highlighted. If possible, the cell should not highlight if I edit the data.
A simple solution is to have a column when this data is entered (if the data is added with a google form, then you are already set to go on that front). At that point all you need is a onEdit triggered function that fetches that timestamp, does var curTime = new Date() and then check what is the difference between them, and if it's greater than 12 hours you do a e.range.setBackground('red') or whatever color you wish (remember that the function must have e defined like function checker(e)).
Having it ignore edits done by you is also simple, just have an a simple
var editUser = Session.getEffectiveUser().getEmail()
if (editUser == 'myEmail#gmail.com`)
return 1;
and it will stop the script if the session users email matches your own.
For future reference please also provide what code you have so far, as currently we don't know what research you have done so far, what worked and what did not. Remember — here you won't get someone to write the program for you, only solve issues you have with code you already have.

Carry out equations using Google Sheet Script to update database values

So I'm trying to create a simple Elo model for our table tennis league at work, I'm using the spreadsheet to generate match ups and then depending upon the winner going in and manually updating the rankings.
I attempted to try and do this (As seen below) but I was blissfully unaware that set.formula was definitely not the correct coding to be using.
Is there a way for me to carry out what I've outlined below, I essentially want to be able to click a button for Player A or Player B and have their Elo rank update on the back end and then generate a new match combination? Also how do I update the record based on a variable? Everyone has a unique player number but is there a function similar to VLOOKUP that will let me find a record and perform a formula?
I've put as many sheet callouts in the code below as I can:
var sheet =SpreadsheetApp.getActive().getSheetByName("Data");
var cell = sheet.getRange("=VLOOKUP("!MatchC18,A:C,3,False")
cell.setFormula ("=SUM(VLOOKUP(!MatchC18,A:C,3,FALSE)+!MatchA6*(1-E$4))");
cell.setFormula ("=SUM(VLOOKUP(!MatchE18,A:C,3,FALSE)+!MatchA7*(0-F$4))");
var sheet =SpreadsheetApp.getActive().getSheetByName('Match');
var cell = sheet.getRange ("C18");
cell.setFormula("=TRUNC(RANDBETWEEN(100,632))");
var sheet =SpreadsheetApp.getActive().getSheetByName('Match');
var cell = sheet.getRange ("E18");
cell.setFormula("=TRUNC(RANDBETWEEN(100,632))");
Any help will be massively appreciated!
Thanks!
As commented, your post is too broad.
Anyhow, to help you in any ways, you may use the following as additional references.
There's already an existing issue 456 in google-apps-script-issues tracker on using bulk methods such as setValues, setFormulas, etc.
and based from the thread, this issue hasn't been totally fixed yet. You may, however, try to use the given work around.
For the usage of VLOOKUP in Google Spreadsheets, more information can be found in Find Data in Google Spreadsheets with VLOOKUP.

Referencing cell on other tab in formula

How to reference the same (row,column) on the different tab in the same google spreadsheet document?
So, I want to do something like this:
=SOME_FORMULA('First tab'!(ADDRESS(ROW(),COLUMN()))). This doesn't work.
If the formula isn't apsolutly referenced, entries of Google Forms questionnaire change the reference and mess up the formula. (the formula that looked at row number 5 after insert looks at row number 6) I can't use apsolute referencing ($A$1) because I have to enter it manually.
Can I change the reference on multiple cells? (for one I can use cmd + f4)
I had that annoying reference problem too. If I understand correctly you are trying to get the information on some cells, but every time someone sends information to the spreadsheet by filling up a Form, that reference moves down a row.
The best solution I came up with was to create a new SpreadSheet and import all the information with this:
=importrange("spreadsheet-key","Form Responses!A1:B2107")
That function updates the info in realtime, so you can do all the processing on the new spreadsheet.
Hope this helps.
Do not quite understand what you need. Need to reference a cell in another sheet given coordinates on the current cell where it is located?
If so, the following formula can be useful:
=INDIRECT("First tab!"&ADDRESS(ROW(), COLUMN()))