Is it possible for a GAS script to lock a Google Sheet so nobody else can alter it until the script is done - google-apps-script

I am familiar with the Lock Service but that is only for locking scripts.
I have some code that will "process" a large Google Sheet. My script needs to re-order the rows. I need/want to make it so while the script is running nobody else can change the order. However, I still need another script to be able to append rows.
We use a Google Form for our team's intake. It appends rows to a sheet. I have an hourly job that will go through all the rows/records and "process them". I have a column that stores the last time a record/row was "processed". I want to sort on that column such that the "oldest" records are on top and then start processing from the top down. If the script fails or times out then the next iteration will just start over...
I know I could use getValues or getDisplayValues to get an array and then write the array back but I worry what would happen if someone sorted the rows as it would muck things up when writing the array back.
Is there some way to accomplish my goal? I want to be able to process the records, and maintain row order to avoid breaking my processing.

The way to block a spreadsheet "completely" is by changing the spreadsheet sharing settings. Remove all editors or change them to viewers, once your script finish, change them back as editors. In a extreme case, usa a second account to act as the owner of the critical files / spreadsheets and only use it for this purpose,so you could block your regular account for doing changes to the spreadsheet.
NOTE: A Google Form editResponseUrl could be used to edit the linked spreadsheet.
I'm facing a similar situation but I took a different approach, I'm using an index/key column (you could use the timestamp column) and using the index/key to save each edited row to the right position, then write the whole resulting array in a single operation (by using setValues()). In my case this is simple because I only require values, I'm not worried about notes, data validation, conditional formatting, comments, etc. and there isn't a Google Form linked to my spreadsheet.
Related
Google Spreadsheet -- get sharing permissions by script
Any way to share google docs programmatically?

Related

How to solve the limitation of IMPORTRANGE formula in google sheet?

I have 50 google sheet files for 50 students. They need to key in their answers in their own google sheet file when they are asked to do so. I have a main google sheet to consolidate their data by using IMPORTRANGE formula. This is my formula:
=QUERY({IMPORTRANGE(...);IMPORTRANGE(...);IMPORTRANGE(...);...},"Select * where Col1 is not null")
I will have 50 IMPORTRANGE in the formula. So as expected, the main google sheet is very lag when the 50 students start to key in their answers at the same time. Sometimes, the formula will show #Value when all the students started to answer the questions at their own google sheet file. I need to keep refreshing the main google sheet so that the data will come out, but it will disappear again in a short while then I need to refresh it again (although it will settle down once most of the students finished answering the questions).
I know that using IMPORTRANGE is really not an efficient way to consolidate their answers in main google sheet file but I don't have other better way.
I tried to write a script so that they can send in their data by clicking the button assigned with the script. However, all the students need to go through the authorization process when they run the script for the first time. They don't know how to proceed when they saw the authorization process (not very good in using computer).
May I know is there any ways or tricks that I can use to solve the IMPORTRANGE issue? Or there are some way to write the script where we are not required to go through the authorization process when we run the script for the first time?
Hope to get some advice and help on this as I couldn't find a better way from Google already. Any help will be greatly appreciated!
If I understood correctly what you are looking is that your spreadsheet show in real-time the data being entered simultaneously on 50 different spreadsheets. I'm afraid that Google Sheets is not the right tool for what you are trying to do the way that you are trying to do it. Basically you have two options : change it or use a different tool.
It's not a good idea to have and array of multiple IMPORTRANGE functions that are being edited simultaneously because while the official docs says that IMPORTRANGE functions are updated every 30 minutes when the source and the spreadsheet having formula are opened at the same time the import is done practically immediately and could happen multiple times during the recalculation making causing it to start over an over again.
Replacing the above array by script might help only if you are open to not have the destination spreadsheet updated on real time as scripts are slow.
Replacing the above array by a program that uses the Google Sheets API also might help only if you are open to not have the destination spreadsheet updated on real time as the spreadsheet refresh.
Regarding running a script without requiring authorization that is only possible when using simple triggers and / or removing all the scopes that require authorization to run. Please bear in mind that you might create installable triggers to run other using the authorization of the user who creates them.
Related
Combining multiple spreadsheets in one using IMPORTRANGE
Why do two users sometimes see different values from importrange?
Multiple IMPORTRANGE
Using that many IMPORTRANGE formulas is definitely a bad idea. What I'd suggest you to do:
keep a list of all your student spreadsheet in your main document
write a script that will browse through all of the spreadsheets from that list and copy/paste values into your main document
create a time based trigger that will run the script every X minutes (or hours), depending on how accurate you want the results to be
This is a simple solution, but efficient. Depending on the amount of data and number of students/spreadsheets you may consider other solutions (like writing a cloud function that will do the same as the script) but I think this will work for your use case

Why do two users sometimes see different values from importrange?

I have a very strange problem, the description can be a bit chaotic.
I have two spreadsheets A and B. One sheet inside A is importing data with importrange from the B. The problem is that sometimes two user see different values in that sheet.
Details:
I have two scripts inside A:
one that copies the values from the imported range to another sheet
one that calls that WebApp that changes data in B.
When two users have the A open and one of them makes changes to the B via script and then uses the other script which copies the values, everything is fine. But if one user closes the A, the other makes changes in the B with the script and when the first user reopens the spreadsheet, he will see new values, but if he uses the values copying script, the range containing the values from importrange will show old values. Oddly enough, the script that copies values from that range will copy the new correct values even if we don't see them.
The problem goes away when I manually make some changes to spreadsheet B. I don't know, it's like spreadsheet B doesn't refresh when I make changes via script or something
Do you have any ideas what is the reason for this and maybe how to solve it. I think that I can get round this problem but I would not.
Two Google Sheets users might see diffent values on the same spreasheet because formula calculation (including those that make API calls like IMPORTRANGE) are triggered by user actions like opening or edited the spreadsheet.
Some function also might recalculated by changes made by scripts so it's actually possible that an script could "see" different values than those that are seeing by the users.
If you need that the users see the same values, should consider to periodically "freeze" them i.e. make a copy of the spreadsheet then replace the formulas by their results.
Another option is to share the screen rather than relaing on the "real time" collaboration feature of Google Sheets.

Macro to delete the old data

I'm really new to this and would love some help where I'm currently stuck. I've created a macro to clear a spreadsheet. I've tried multiple triggers of onedit and onchange and haven't had luck with my end goal. I'm sending data (about 10 columns and 100 rows into a google sheets via zapier. Basically, I'm refreshing the data by replacing the data. So, before the data comes in, I wanted the macro to delete the old data. However, the macro actually deletes the new data coming in once it posts. Any scripts or workarounds that could help?
From what I know about Zapier it works on timed intervals. You can have a script run on time intervals just before the time Zapier inputs information and delete the old info.
Another approach would probably be to have a intermediary sheet.(Lets call this sheet, "sheet1". The final sheet can be called "sheet2". When Zapier writes data to sheet1 it can trigger the onChanged event. Take the information in sheet2 delete everything, then post the new data to sheet 2.
Finally, Zapier supports webhooks. You can publish your script as a web app and have it do a get or post to the app which runs the delete function. To give it time you can use the delay that Zapier provides.
What you are describing sounds like the perfect candidate for the IMPORTDATA worksheet function. The function is entered in a cell, as are all worksheet functions, and it takes a URL which points to a CSV or TSV file. Once entered the data referred to by the URL is expanded out into the appropriate number of rows and columns. Seeing as the function resides in a single cell you would only need to update that cell when you wanted to change the data. This means that you would no longer need to use a .gs file to remove old data and could instead complete everything from within Zapier. I have answered a question similar to this here, I describe how this is done within Zapier. The only prerequisite is that the data you are using is in either CSV or TSV format.

syncing Google spreadsheet and Google (my) Maps

I would like to synchronize a google spreadsheet with a map so that I don't have to upload everything everyday.
I found that it's possible to synch a google form to google map using Google Fusion.
See, YouTube: Syncing Google Forms with Google Fusion Tables for Crowdsourced Maps.
But I couldn't replicate the process to my situation (I guess it's maybe because the spreadsheet content is not originated from a google form and maybe the script take that into account)
I don't know much about coding scripts but automating this process would be a blast for me!!
I hope someone will be able to help me out on this
thanks a lot and have a good day
The only thing to account for this situation is the difference of form submit. The guy in the video sets up two triggers: one for onFormSubmit, and one hourly trigger for syncing whenever any manual changes are made.
I haven't looked directly over the code, but all you should have to do is modify the onFormSubmit code and trigger. Change the code to look for and update the fusion table with any new rows from your spreadsheet. And then change the trigger to your desired need, timer would probably be the best option. So every hour, or day, or run it manually after your done adding rows.
Now, if you were to edit the rows of data after they've already been updated, the hourly syncing will take care of those changes.
I could imagine that the hourly sync method could be changed in such a manner to look for rows that need to be added, could be as simple as calling the submit function.
I had the same problem but i could solve it.
A time trigger is not needed if you set the sync function at the end of the function OnFormSubmit (so "sync();" under "insertRowId(rowId, row);" Syncing takes place after each sending of the form automatically.
For larger forms I found out that you should not make a special column Location in the Fusion table. The address column should marked as Location in Fusion table. In the script properties of the spreadsheet give the addressColumn the value of the column title of the address column and the third property keeps unchanged ("latlng">Location. What happens is that the value of the adres is overwritten by "latlng". So if you have trouble to loose the original addresses, add a new column, copy by apps script the same address (that piece of script direct at the beginning of the function OnFormSubmit) and (after syncing) give the addressColumn the value of the column title and in the Fusion table marks the original addess column as Text and the new column as Location.

Running Google Script without updating spreadsheet?

I have multiple scripts that I want to run on data in my spreadsheet. Some of the data is populated by random number function.. so they change every time the spreadsheet is updated/edited.
It seems that my scripts update the spreadsheet even if it doesn't explicitly edit any cells. This causes all of the data to change mid-script and mess things up.
Is there any way to stop the spreadsheet from updating while a script is running?
No, I don't think so. You'll need to come up with a way of structuring the retrieval and updating of data, and the timing of the flow of events. You could check for certain conditions, and halt the script if need be. You could set key cell values from a script, rather than a function in the cell.