Google Sheets JS Event - google-apps-script

I created a countdown timer in google sheets based off a set date and time.
I know how to change the date with javascript events but how would I create a trigger for the event when the time reaches 0?
Thanks in advance.
My code:
'
function dateChange(A1) {
var d = new Date("4/10/2020 00:00:00");
d.setDate(15);
}
'

Solution
Based on my understanding of your question, you are basically trying to trigger something in your sheet after you reach a certain date. Please correct me if I understood wrongly.
To achieve this, you will need to use a time driven trigger for your script function.
Go to your script and create a function with what you want to run when the countdown is 0 (i.e when you reach that specific date). In this example I am setting the C1 cell to the value TIME'S UP.
function test() {
SpreadsheetApp.getActive().getSheetByName('Sheet1').getRange('C1').setValue('TIMES IS UP');
}
In your script window, head over to Edit-> Current's project triggers and add the following trigger as shown in the following picture (but of course changing the date limit of your countdown, in your case the 04/10/2020 00:00.
Done ! Now this will trigger once the countdown reaches that date.
I hope this has helped you. Let me know if you need anything else or if you did not understood something. :)

Related

Adding Date+Time without 12AM moving to the next day

I am using the attached to automate a time entry to go along with the date for a calendar import. The entries don't have times, and the staff will not enter them try as I might. I need to automate them to simplify the entry procedure.
The issue I am facing is that the Calendar API needs the data to be in DATE/TIME format. To do this I need to use the =DATE+TIME formula. When I do so and the time reaches 12:00AM, the dates thereafter change to the following day.
Essentially I need to either override the logic that makes it move into the next day after midnight appears, or I need to tell either the function in column B-C that it can never roll to midnight. I am trying to think of perhaps a way that I can tell the function to reset the time if the date in column A changes to a new day, and if it doesn't change to a new day go ahead and use the existing function and add 5 minutes to the time that is shown previously to it.
I am stumped, any help would be greatly appreciated.
Here is a sheet to show you the issue
Here is the formula I tried, which worked to sort out the problem but did not work with the Calendar API requirements to format at DATE/TIME. Even when using the importrange formula to move the data into a new sheet with the cells formatted as DATE/TIME it still recognizes it as TEXT as this is what the formula prescribes.
=IF(A2<>"",(CONCATENATE(TEXT(A2,"MM/DD/YYYY")&" "&TEXT(B2,"HH:MM:SS"))),"")
I need this to work in both the sheet and in the import to Calendar using the Calendar API requirements through APPScript.
If I understood correctly your question, here a suggestion with a custom Apps Script function called like a normal Google Sheet function.
Open Apps Script Editor and paste the function below
Call the function rebuildDateTime(COL1, COL2) inside your spreadsheet
Spreadsheet:
Code:
function rebuildDateTime(arg0, arg1) {
var date = new Date(arg0);
var str = arg1.toString().split(':');
date.setHours(str[0]);
date.setMinutes(str[1]);
return date;
}
Warning :
Your COL2 (which contains only the time), must be forced to TEXT FORMAT
References :
Create a custom function

Apps Script: How to capture oldValue of a cell after a change made by sheets api?

I am running a python script that updates my google sheet (named 'Notifications') through the sheets api every 5 minutes. The python script first clears and resizes the sheet to only two rows and then adds the new data on top and the sheet's size gets automatically expanded. I've done that not to have empty rows if my new data is smaller in size than the old one.
So the sheet is updated every 5 minutes but if nothing new happened in my data source, the new values are going to be the same as the old. In particular, the value in 'A2' is going to be the same as before the update. If something new has happened, the value in 'A2' is going to be different. I want to track that and get a pop-up message that notifies me that something new has happened after the update.
So as far as I understand I have to use onChange because onEdit only works if the changes are made by a human and cannot track changes made by the api. I'm uncertain how to do that though.
With onEdit I've achieved it and get a pop-up if I modify the content of 'A2' manually but nothing happens when python updates my sheet.
Here's the code with onEdit:
function onEdit(e) {
if (e.range.getA1Notation() === 'A2') {
let oldValue = e.oldValue
let newValue = e.newValue
if (oldValue != newValue) {
Browser.msgBox('The value in A2 changed from ' + oldValue + ' to ' + newValue);
}
}
}
So the end goal is to get a pop-up not every time python updates my sheet, but only if there's a change in the value of 'A2' after the update.
How can I do this?
The only way to get a pop-up when a a change is made through an API is by using polling function from client-side code. One way to do this is by using a sidebar to hold the client-side code.
You should store somewhere the old values then compare with the current values.
Related
How do I make a Sidebar display values from cells?
How to get all old values for a mulitple cell range with onEdit trigger
onEdit(e) not generating trigger event when cell value changes due to inbuilt function
You can use onChange trigger with a "ValueInputOption"="USER_ENTERED" to trigger a function when a script edits a sheet. But you can't show anything in the UI from the triggered context so getting a pop up will be impossible.

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.

Time/Date-Based Rule for Conditional Formatting via Google Apps Scripting

Alright, I'm stuck.
I've got a sheet that an entire team of people use to communicate with each other and sign up for timeslots for internal logins.
I've got the sheet formatting performing the way I want to, but, it's too easily edited by people, because they have to be able to edit the values in the cells.
It's currently running Conditional Formatting rules, based upon time/date. Basically, if the cell's timeslot has passed, then it's blacked out. It is also blacked out if the cell isn't associated with the current day.
https://docs.google.com/spreadsheets/d/1TP5iJ9AA_xqDQPiyl89ntZehd7aqDPELcN0bRMGP-SU/edit?usp=sharing
I'm trying to create a script that "onEdit" will restore any formatting (not the value) that had been changed during the edit.
Got it this far, but I'm struggling to make it conditional like the UI rules allow me to do.
function myFunction() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
var range1 = sheet.getRange('A1:B10');
range1.mergeAcross()
range1.setBackground('white');
range1.setBorder(true,true,true,true,true,true);
range1.setFontColor('black');
range1.setFontFamily('Arial');
range1.setFontSize(10);
range1.setFontWeight("normal");
range1.setFontStyle("normal");
range1.setHorizontalAlignment("left");
range1.setVerticalAlignment("center");
range1.setWrap(false);
}
Here's where I'm struggling (notes inserted)
function myFunction() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
var range1 = sheet.getRange('A1:B10'); // I'd have this repeated for multiple ranges
range1.mergeAcross()
range1.setBackground('white'); // Need an "IF" argument for this, such as if today is Wednesday and time is before 2:30pm, then white, otherwise black. Could probably put this at a different point in the script.
range1.setBorder(true,true,true,true,true,true); // All the following attributes would simply restore defaults
range1.setFontColor('black');
range1.setFontFamily('Arial');
range1.setFontSize(10);
range1.setFontWeight("normal");
range1.setFontStyle("normal");
range1.setHorizontalAlignment("left");
range1.setVerticalAlignment("center");
range1.setWrap(false);
}
Thanks in advance for any help you might offer!
Adam
I've actually been trying to deal with this same problem.
Sadly, google scripts doesn't seem to have a way programmatically set the conditional programming. (Here's a link to the issue. You can cast a vote at the bottom on to get them to implement it)
However, I think you might be able to implement a solution to your problem it by scratch.
The onEdit trigger passes a variable to the function it's assigned to.
function testOnEdit(e) {
Logger.log(JSON.stringify(e));
}
Here is an example of the JSON from the event object for onEdit.
{"range":{"columnStart":3,"rowStart":2,"rowEnd":2,"columnEnd":3},"source":{},"value":"I typed this into B3!","authMode":{},"triggerUid":*********}
You might be able to use this to directly reset the format of the cells they edit. BUT... Unfortunately, onEdit is only fired when a range's values are changed--not when formatting is changed, not when data validation is changed, not when conditional formatting is changed--so to catch the cases that some rouge user decides that purple looks nice, you may want to also make the script run every minute using a timed trigger (but you need to make sure it doesn't take too long to run since it will be going off every minute and google puts a limit on total amount of time triggers can run).
As for comparing dates, these functions may be useful, but be warned that they return the local time (if you have users from multiple time zones you may need to convert to UTC).
function myFunction() {
var date = new Date();
date.getDay(); // the value returned by getDay() is the index of the day of the week, where 0 is Sunday, 1 is Monday...
date.getHours(); // the value returned by getHours() is an integer between 0 and 23
date.getMinutes(); // the value returned by getMinutes() is the current minute in the range 0-60
}
Since I too am dealing with this problem, I plan to add more insight to this solution later. Let me know if you have any insights, Adam.

Creating a script that runs every second

I am trying to create a script that edits a particular cell on a particular sheet every second with a random text like, "SetTime".
This Particular Cell is: X2
This Particular Sheet is: "System_Info"
You may ask why I need this, essentially, I have a cell that displays a time using the =NOW formula. When a spreadsheet is edited, it will refresh the =NOW formula.
So, I need a script that loops every second and runs a function that edits that cell.
I've used this:
setInterval(function(){ SpreadsheetApp.getSheet("System_Info").getRange('X2').setValue('SetTime'); }, 1000);
However, set interval is not defined.
Thanks for any help,
Shaun.
you are mixing server with client code. even if you use time driven apps script triggers its not possible because they run at most once a minute, and changes through api do not cause a refresh.
Alternative: go to spreadsheet menu,file,properties. Select the option to update calculated functions every minute. No script needed.
Here is a function that will update the time in a cell every second for 15 seconds. It should be at least a starting point for you.
function updateCell() {
for (i=0; i<15; i++){
Utilities.sleep(1000);
var date = new Date();
SpreadsheetApp.getActiveSheet().getRange("A1").setValue(date);
SpreadsheetApp.flush();
}
}