Macro to delete the old data - google-apps-script

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.

Related

Is there a way to set up Google Apps Script trigger to be based on the edit of one of multiple spreadsheets?

I want to send an email when one of three spreadsheets have been edited. I have set up a trigger in the UI that runs a function on edit for one spreadsheet, but how do I make it so it runs on edit for one of three spreadsheets?
One solution is I put the function in scripts for each file and set up separate triggers, but is there a way to do this without having three scripts?
When I say spreadsheet, I mean a google sheets file
If the information required isn't time sensitive, Create a time based trigger on a standalone script, which checks each of the three spreadsheet files every hour or so for modifications and sends a email, if modifications are inferred. It is possible to use PropertiesService
to store last modified date time and compare it to the current modified date time.
get last row of sheet and compare it to last row currently, if data is added in that format.
There is no way to make that a single on edit trigger, simple or installable, be triggered by the edits made on several spreadsheets.
One option is to use code to create multiple triggers to run the same function, one trigger for each spreadsheet.
Reference
https://developers.google.com/apps-script/guides/triggers
https://developers.google.com/apps-script/guides/triggers/installable

Email after Form Submit, Problem with Calculations

I've currently got a trigger on form submit to run my code which pulls in the submitted data and emails a summary to the user. I need to perform calculations on the submitted data and provide those results in the summary email. I've been able to hard code this and I have a working script but I want to do the calculations on one of the sheets instead. I've got another sheet setup to pull in the form data and perform the calculations but it seems the problem is that when the form data is submitted, none of the other sheets are updated so if I try to pull calculations from the other sheets it will not include the latest entry.
I've tried getting data from other sheets but I don't think the other sheet calculations are refreshing to include the newly submitted data, or the code is executing before the sheets can refresh, possibly order of operations limitation. The desired goal would be to have a user submit the form, then have all sheets using that data pull it in and complete calculations, then send an email using the newly calculated results. Ideally pulling data from multiple sheets.
I'm thinking the "on form submit" trigger is not appropriate here, instead maybe I need to have an event occur on the sheet or sheets I'm using to calculate that triggers an email. Or does anyone know if there's a way to force all sheets to update and fields to calculate before continuing to execute the code?
Any ideas? Thanks!
I'm not sure if I got 100% what you're looking for but you need to know that if it's your function who is opening a Spreadsheet and writing data on it, you can't add any trigger.
Trigger can only run following a "human" action (onOpen, onEdit..)
Pl. try importrange in the target sheet/sheets to pull data from the form sheet.
You have to maintain "completed" in a seperate sheet.
If you see a new entry, do the calculation, send mail and update the completed field.

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 allow users to run a macro which edits a range or sheet they don't have 'edit' permissions to?

I have made a macro that takes a set of input data, transfers it to a master data table, graphs trend lines of the data, and then clears the data entry sheet. All sheets are protected to avoid employees from changing or deleting data that has already been entered and only the cells which require data entry are available for editing by the employees who I've shared the sheet with. The macro works well if I try to run it but if another employee attempt to run the macro they get an error stating they don't have permission to edit certain ranges.
When I wrote the Excel macro for the same task I was able to unlock the sheets up front, transfer the required data, and then re-lock the sheets but can't figure out how to replicate this type of behavior in Google Apps Script.
The Protection class on the Google Developers page did not prove to be helpful, since I kept getting an error saying the function protect could not be located in the Object spreadsheet. I also tried the addEditor function without much luck. This is my first Google Apps Script and I've been trying to learn as I go but this project is proving difficult.
Thank you to #Tedinoz for helping me realize you can rename the onEdit function so long as you designate 'e' as a function input. I was able to use an Installed Trigger on the sheet set to run RenamedonEdit(e) whenever the sheet is edited.

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.