Multiple users using spreadsheet without overwriting content - google-apps-script

I'm new and appreciate help on my question!
My spreadsheet acts as a sales tool, where info is entered in various cells to run sensitivity analysis. Once the salesperson picks a desired option they "submit it". The data submitted is then stored on a separate sheet in the spreadsheet (call it the "database").
I want the database sheet to store all user submissions. The problem is when multiple users are using the sales tool worksheet at the same time, the info they enter gets overwritten by other user's inputs before they can submit.
I'd like multiple users to be able to use the "sales tool" sheet simultaneously without overwriting eachother, but still be able to submit data to the "database" sheet.
Appreciate ideas?

You can use the Lock Service to take a lock on the spreadsheet and then release it once you've written to it.

Besides the Lock Service (already mentioned by Srik) there's the Sheet.appendRow function, which is way easier to use and much faster. But only makes sense if you're inserting new data to a sheet and not really writing to the same cells.

Can't you use a form?
This way people could insert data without actually modify the spreadsheet...

Related

How to delete a row on the master tab (destination) and also delete the same row value on the tab it was queried from automatically?

This is a probably convoluted process in data collection. Any advice on how to best do this will be appreciated.
I am working on data collection and I am trying to clean it real time. The data is set up such hat each RA has their own tab on google sheet to put in observations. Then I have this master sheet that queries from all the RA tabs to create this master data. The master sheet can tell me which are duplicates and which of those duplicates have a better quality of information.
Doing a master data using query does not allow me to edit on it, for some reason. So, I copy and paste as value to another tab. I use the master tab to analyze any duplicate information. Ideally, when I clean the master tab and delete the lesser quality duplicate, it also deletes from the RA tab it originated from. How do I do this? Is this the best way of doing this? In a similar fashion, if I would like to edit in the master sheet and also have that row to be edited in the original tab.
I created a trial sheet to practice with.
https://docs.google.com/spreadsheets/d/12XhUzH_v565C8fll_JwjloU0E12XmVarXesrUY83D-4/edit?usp=sharing
I have been doing this manually and wondering if there is a better way. I am open to using google apps script but I am still a new at that. I am thinking of using onEdit function but I do not know how to test my code or how to know what is in e.
The data is set up such hat each RA has their own tab on google sheet to put in observations.
One easy solution would be to keep all the data in the master tab, have everyone edit that tab only, and use filter views to give every user their own private view so that everyone only sees "their" rows. This feature lets multiple simultaneous users sort, filter and edit the sheet without disturbing each other.
For additional ease of use, you can insert links in the frozen section of the sheet to easily switch between filter views, instead of having to go to Data > Filter views to switch. See the Filter views example spreadsheet for an illustration.

Sharing google sheet with restrictions

I've built my google sheet, and shared it with the team, the sheet has an entry point, where the user is entering some data, and balance data of the sheet is changing dynamically based on this input.
If 2 persons are using the sheet at the same time, the data will be changed based on the last guy who use this entry field, and the data the other guy seeing will be changed accordingly.
my sheet is here
The sheet is locked except the yellow shaded cell, which is allowed to be changed by the user.
Is there a way to allow each user to see the data based on his input parameter, without getting it destroyed when used by others!
I don't think what you're looking for is possible as Sheets is designed to be used for collaboration and edits will always be shown in real time. Consider adding multiple sheets and assign them to each of your team members with the exact formatting and formulas as the original so they can access and input their data independently.

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

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?

How to generate an EditResponseUrl() for manually entered rows in a Google Form response spreadheet?

I have an spreadsheet linked with a form and made it as, all the user to edit the response after submit. And connected it with Awesome Table. When i insert a data through the form, the spreadsheet automatically generate the edit response url. this is done by gas. This isworking fine. But, what i want now is, how can i generate the response url for the data which i paste directly to the sheet from another sheet? is it possible? please help me with some suggestions or a piece of code.
Thanks in advance.
It's not possible to do this.
The forms services and the sheets service are two separate services. This is a simplified version of what happens when you submit a response to a form:
The form is submitted.
The forms service stores the response.
The forms service writes the response to a sheet.
When you use the EditResponseURL() method, you're getting the information from step 2), and editing it. This then causes the form to complete step 3) a second time, updating the sheet.
If you write the response directly to the sheet, you're skipping step 1) & 2). If the response is not stored in the form, there's no way to use the EditResponseURL() (As this is a forms only method).
Easy solution: Submit everything via the form, and do not write directly to the sheet.
More complicated solution: Write a custom form that allows you to pull the information in a range of cells from a sheet, update the information, then writes the edited information back to the sheet.
The second Sheet would need to "know" what it was looking for. The second sheet can retrieve anything it needs from the first sheet, but it needs information about what to retrieve. You would need to explicitly record information that matches some kind of key to the information that should be retrieved. The first Sheet could have information on what response is matched to what row of information. You could have an ID that was just sequential numbers, or you could have an ID (key) that encoded the user name, the date, the time, a random number, a row number, etc. if you need/want that. Your essentially designing a database structure.
It might help to define a flow chart of the process.

How to hide certain columns for a user?

On a shared Google spreadsheet:
I don't want a specific user in my domain to view columns with sensitive data, but this person should still be able to edit the rest of the spreadsheet.
I tried creating a 'master' spreadsheet and using importrange to bring the data into a 'shared' sheet, but once I edit any cell in the shared spreadsheet, importrange no longer works as the sheet is emptied out.
Is there a quick way to do this, maybe using scripting?
After some research and trying various different options, I was finally able to achieve what I want using the importrange function.
At first, I tried using a combination of hide columns & protect range, but this wouldn't work because a simple copy & paste would reveal the contents of the hidden columns.
Solution: The 'master' spreadsheet does not have any sensitive column data and can be shared with everyone in the organization... I then ADD the sensitive data to a new spreadsheet and use importrange to grab contents from the 'master'. (Previously I had the roles reversed, but this didn't work)
You may want to add unique keys per row entry so that sorting etc won't mess things up when you zip-up the sensitive data and the 'master' data.
I came here looking for a way to share only certain columns of a spreadsheet with a customer, but not all.
As noted in the other answer, using =IMPORTRANGE works well, but a clever customer could simply edit the function and see the other columns.
My solution was to first create a 'proxy' spreadsheet that imported only the columns I want the customer to see. This proxy spreadsheet is not shared.
Then, I created another spreadsheet that imported the columns from the proxy, and shared that spreadsheet with the customer. This way, even with edit privileges, it's impossible for him to see anything that isn't on the proxy spreadsheet.
A bit clunky to be sure, but it worked perfectly for my situation.