Sort events in google scripts - google-apps-script

Is it possible to intercept the range sort event? For example when user select a range, select sort range, click on sort, I need intercept the sort event. The business problem that I am trying to resolve is, if user doesn't include a particular col for sort, I want to either warn the user or include the required col in the sort.
Please let me know. Thanks.

Currently this is not possible. The events you can use to trigger an Apps Script are quite limited, and they don't behave the way traditional Javascript events do, because they run on the server, not in the users browser. Even if a Sort event was made available, your code likely wouldn't be triggered until the default action was completed and the sorting finished.
You could experiment with the Edit event, that will be triggered any time the spreadsheet values are edited, which may include sorting (I've never tested this). But as I mentioned above, you can't block the edit from occurring, just respond to it's results.
https://developers.google.com/apps-script/guides/triggers/

You could tie the sort you would like to performed to a custom button or script menu command, but you cannot captue a sort event or even disable sort in any sheet where a user has edit rights.
To create a button, follow Insert > Drawing, make a shape (rounded rectangle recommended), save it on the sheet, and use the drawing's drop down menu to assign the script by its name.

Related

Looking For Solution to Automate Calendar Event Creation from Google Sheets

Background:
At my (new) job, we have a number of Sales Reps who book gigs for our organization. Until now, they handle all of their sales tasks in our CRM (Pipedrive [PD]). They then use that information to create an "activity" (event) on PD's calendar, which is set up for two-way sync with our general work Calendar (Outlook [OL]).
Problem:
Between the number of different Reps who edit the PD Calendar, the variety in bookings for our org, and just general human error, our Calendar system is a NIGHTMARE. Formatting inconsistencies, typos, lack of necessary information, and even straight up wrong details make my job (creating a program around, and then organizing the talent for each booking) nearly impossible.
"Genius" "Solution":
Even though it's a mess, I hate the type of person who comes into a new position and instantly tries to make changes to a system that has (somehow) worked before their arrival. So instead I sat down with the reps, learned what their needs were for the calendar, as well as their process, and built a system that not only gives me what I need, but also cuts the busy work on their end in half.
Previously, they not only entered into into PD, and then manually created the events, they also created three separate supplementary Word files that documented the details, created a detailed schedule of events, and outlined contractual needs based on the type of event.
So to solve all of this, I created a Spreadsheet (SS) Template that had all the fluff prefilled, was able to fill in all the contact info from an external contact database, and fill in the entire event schedule based on "type" and "start time". So basically they just need to enter in "Where", When", and "What", and the SS would auto populate the rest.
How that benefits me, is I then painstakingly scoured YouTube, Reddit, and Stack overflow for information on how to build Scripts for Google. And managed to make a function that can pull all the information from their new fancy form, and automatically create a 100% accurate and consistent Event for me.
Everybody wins, right?
New Problem:
Due to things well beyond my current knowledge, I am unable to create a dummy proof way for the event to "Trigger". I know it has to do with user permissions, and the limitations of Simple Triggers yada yada, but I'm incredibly annoyed that I managed to eliminate so much busy work, entirely solve my problem in the process, and yet the thing blocking me in the end is that I have to actively go to my Script and hit "Run" for it to properly function.
(For any "Expedition Force" readers out there, this feels a lot like how for so long Skippy could program intricate FTL Jumps across Spacetime, but still needed a "filthy monkey" to push the "jump" button)
Relevant Additional Details:
As I said, we use Office, but we're likely switching to Google down the road (and as someone who works in the arts and has been a poor student/struggling artist for the last two decades, I am much more versed with Google than Microsoft. I've also rarely found anything of value within my needs that one could do that the other couldn't, so I've built this whole system in Google Apps Script. However, if someone finds a potential solution where this will work in Excel with VBA instead, then I'd learn to translate what I've written so far.
Also, the Script works. I can make it work 100% of the time via the Apps Dashboard (where they don't worry as much about permissions), so it's not a problem with the code itself, which is why I haven't posted it here (but I can if anyone has a reason to think it's relevant).
It is a frequent need for our Reps to go in and edit the gig (people get sick, availabilities change, or mistakes were made the first time, etc.), so to combat this, I've actually written two Scripts. The first is a "Create" script which takes all the information, creates an event, and then pulls the EventID # which it pastes in a safe cell on a different tab. The second is an "Edit" script which searches for the previously created event by ID, and then makes the changes as needed.
In addition to PD and Office, we also use Monday.com and have a Zappier account. But I'd rather avoid either of those if possible since they have apparently changed software packages every other year before I got here, and we are in the middle of a search for a new Executive Director, so I'd rather not have this whole thing come crashing down because one minor part of it depended on Zappier, which our next ED cut from the budget, ya know?
Potential Solutions:
I can make the whole thing run via their Installable Triggers. However, I find them limiting:
I can do it by "Open" which creates the event every single time the SS is opened (which is both obnoxious AND useless, since the edits happen AFTER it is opened).
I can do it by "Edit" or by "Change", but again this just creates a whole new Event every time. I even tested it and made three random edits on empty cells in a useless tab, and it made three identical events to match the first (although this could be a solution for my 2nd Script...). I wish they could do onEdit of specific Cell, because THAT would be useful.
I can do it by form submission.. which means I can instead make a form that they fill out that creates the whole doc, and after they submit, it creates the doc AND event, but this limits the idea of having a different SS for every contract.
And lastly, which I really want to avoid, since I don't trust the Reps who manage to spell the same name wrong three different ways in three different places with having to open Scripts and hit "run", I could create a macro that notifies ME whenever changes are made, and then I could go in and manually hit the button. But..... Is that REALLY the best solution?
I know that's a lot, but I'm more looking for creative coding ways to solve a general problem, rather than a specific fix to a single string. Anything that could make what I want happen, without making me do annoying extra steps, or without requiring me to trust others with a keyboard, I am open to suggestions!
You would benefit from more research on triggers gerenally, onEdit in particular. It is broadly true that onEdit is triggered "when anything was edited" but the script can be written so that it evaluates specific rows &/or columns &/or cells &/or sheets &/or values. It can do this by using Event Objects which involve including an argument (often the letter "e", or the word "event"). The Event objects provide a lot of information about the nature of the edit.
For example, if you had a checkbox in sheet "Sheet2", column D, and you wanted to trigger something if the checkbox value was changed to "checked", then an onEdit(e) script might include an IF statement such as:
if(e.range.getSheet().getName() == "Sheet2" && e.range.columnStart == 4 && e.value == true){//do stuff}
In the scenario described, an automated trigger might not be necessary - a user might select a row (or a cell in a row), and click the "Button" in order to execute the script. However, it might be desirable to "check" a checkbox so that there is no doubt about that row has been calendarized or not. The advantage of this is that an event is not calendarized twice.
The following script might be an appropriate example:
function buttonTrigger() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheetName = "Sheet1"
var sheet = ss.getSheetByName(sheetName)
// get the row to be calendarized
var row = sheet.getCurrentCell().getRow()
// Logger.log("DEBUG: the cursor is on row is "+row)
// check is this row is already processed
if (sheet.getRange(row,4).getValue == true){
// this row already processed
// insert abend code
return
}
else{
// this row is OK to update
// insert script to calendarize event
// update checkbox to show event is updated
// checkbox is in Column 4
sheet.getRange(row,4).setValue("true")
}
}
Example
Creating a button and assigning a script
There is a good explanation of this process in StackOverflow topic Run script only on click on button instead with open the sheets

How to avoid saving a google sheet and have multiple people editing at the same time?

I’ve created a Google Sheet – kind of like an app – using script. It’s a number of blank cells where once added some information, it creates a string with that information in the right order. I created this to help some colleagues. We are using free accounts.
I face 2 problems:
The app is supposed to be used by only one person at a time, but I’m sure at some point two or more people will want to use it at the same time. Is there a way to allow this without they interfering with each other? I’ve read you can share a link that creates copies of your doc, but that wouldn’t work in this case because I intend to keep updating it regularly.
The changes people make to the sheet will stay there. Right now I have a onOpen function that just rewrites everything, but if someone accesses the document while someone is using it they’ll rewrite everything and ruin their work.
Any ideas on how to solve these two problems? Thank you so much in advance!
I think that you have to find another way to implement your "app" because Google Sheets not a good tool for limiting that only one user edit a spreadsheet a time, but if for any reason you decide to keep with it,...
... you need to implement a workflow like the following
Save the active user email on PropertiesService.getUserProperties().
This should be done by each user by running a script themselves. The most user-friendly will be by using a macro, custom menu or button (a drawing with an assigned Google Apps Script function). You might use an open installable trigger to validate that the active user have already done this.
You might have to make the function that clears the data a "smart" function.
You might have to consider additional cases, like if the owner of the spreadsheet opens it when there is an editor working on the spreadsheet.
Use installable triggers to manage the sharing settings.
Use an open trigger to remove all the editors except the active user
Use a time-driven trigger to add again the editors. To make this work effectively should define how the time-driven trigger will know that the last editor have finished their session, i.e. you might use DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId()).getLastUpdated()
The above should help you with both problems, as long you as the owner do not open the spreadsheet as is used by someone else.
Other alternatives that might work better is to create an add-on or a web application.
Related
Determine current user in Apps Script
Last modified date in Google App Script GAS sheets

Do Google Calendar Triggers execute in order?

I run a google calendar trigger for every user (10k users) which notifies some external resources when something changes in the users calendar.
However I have some issues because it seems like the triggers don't always execute in order. When for example one user moves an event several times in a second it could be that the notification to an external resource of the last event movement hits first before the others do.
When I look into the Google Stackdriver logging I also could see that the same behavior when logging the trigger. But of course the issue could also be the logger itself.
How can I fix this when my business logic relies on the correct order of changes for a calendar? I know that there is also the Push Notification for Calendar but there is no watch for a single calendar and this will also mean that I need to watch 10k of users which I don't think it's very practical.
So how can I solve this? Or am I wrong about the trigger execution order and the problem lies on the external resources execution order of requests?

Add new Google sheet row when new value exists

I have two Google spreadsheets, A and B: A gets replaced every day when a scheduled report copies over it and B remains the same (and is the one I want to update).
On a scheduled basis, I want to take email addresses that appear in A and see if they also exist in B. If they don't, then I want them added to a new row in B.
I have tried coming up with a way to automate this - either through macros or Zapier and I'm coming up short. All I want to know is if this is possible and what the best way to accomplish this would be. (I'm thinking of paying a contractor to do this, but I don't really know what I'd be asking for at this stage.)
You can create a script in one of your sheet,
In your sheet open the script editor, by clicking on tool > Script editor.
create a function let's say :
function saveAtoB(e){
}
then on the left menu you have some clock icon, where you can add triggers.
click on add trigger button (right bottom).
select your saveAtoB function,
select HEAD
select trigger on time
select daily.
then save.
The automation part is Done, quite easy.
Now it is quite easy to write the code inside the saveAtoB function, if your are familiar to code in JavaScript. Else it could be little tricky.
If you share a copy of your sheet I might help.
(I suggest not to pay a contractor to do this since it probably would take less that one hour).

onMove() or onCursor() or onSelection() trigger in Google Apps Script?

I've looked at the documentation for triggers, but couldn't find what I wanted. I essentially want to auto-fill certain spreadsheet cells when the cursor/selection moves to the cell.
For example, say I want any cell in column 'B' that is empty to be filled with the current time when it is highlighted.
How should I be doing that? I see Extending Google Sheets refers to UIService and HtmlService, but I didn't find anything about triggers for when current cell changes.
For your particular example, I would suggest creating a custom function Docs for Custom Functions (using apps script) which produces the current time and enters the value in the cell. It doesn't need parameters either. You could then call the function with something as simple as:
=time()
Add a few clicks for copy and paste, and you have a lot of functionality to play with.
Built in functions which produce the current time may or may not update as you reload the spreadsheet.
There are no triggers for the events you describe, and while you may post a request on the issue tracker, I would not expect to see such triggers implemented.
Using existing capabilities, the closest you could get would be a menu-driven function that fills the current cell with a timestamp. Hardly as automatic as you are looking for.