Calculate elapsed time using NOW() with conditional formatting - google-sheets

I'm trying to set up a Google Sheet for volunteers at the local dog shelter. The idea is to have an auto-updating spreadsheet that shows at a glance which dogs really need to be walked, in two ways:
conditional formatting the rows with color based on time elapsed:
red if it's been >6 hours since their last walk,
yellow for 3-6 hours, or
green if they were walked <3 hrs ago.
auto-sorting the rows so that the dogs that have gone the longest are always at the top of the list, and when they get walked, they go to the bottom of the list.
Here's where I'm at.
Problem 1: I'm trying to calculate time elapsed by using the NOW() function (which returns the current date and time), minus the time of the last walk. The problem is that if you only enter a time, Google apparently assumes the date is 12/30/1899. So if I put in 8:00 am, and the current time based on NOW() is 4:00 pm, instead of returning 8:00 hours, it calculates the the duration as 10,000,000+ hours that have elapsed since 8:00 am on December 30, 1899 up to the current date and time. (Similar problem discussed here).
If I keep the output cells in the HH:MM format, it'll initially look OK, because it'll just return the HH:MM as 8:00, BUT I can't use that because then the conditional formatting won't work - it's still actually calculating the 10,000,000 hours since 1899. So I can't set duration values for red/green/yellow because all the output values will be slowly increasing every day we get further away from 1899, meaning I would have to reset the ranges daily.
Obviously I could work around this by always including the time and date, but the idea is to have a spreadsheet that is idiot-proof so that any volunteer can use it by just adding the time they walked the dog. It won't work if they have to input the date too.
Problem 2: Assuming I can get the above to work, how can I set it up so the table automatically sorts itself after any change (i.e. when a dog gets walked and the entry gets updated)?
Help?

Please try:
Problem 1
Green is easy, just format all your data that way with standard fill (CF will override this where applicable).
Select A1 and apply a Custom formula is of:
=and($D1<>"",timevalue(now())>$D1+6/24)
with colour Red and Range A:E
Repeat (the order of these two is important):
=and($D1<>"",timevalue(now())>$D1+3/24)
with colour Yellow and Range A:E.
Save rules and close window.
Problem 2
Create a pivot table by selecting ColumnA:E (may have to get rid of some content present low down in the sheet first) and Data > Pivot Table Report..., to Rows Add field Dog name (do not Show totals), to Values Add field Time since last walk and Summarise by:SUM. Name the sheet PT.
In say J2 of your other sheet (not PT) enter:
=query(PT!A:B, "Select * order by B desc ")
May be worth noting that without the day part there might be problems where times span midnight - if you have walkers with insomnia?!

For the autosorting, I found a script elsewhere on stackoverflow and modified it slightly for my purposes:
function onEdit(event){
var sheet = SpreadsheetApp.getActiveSheet();
if(sheet.getName()=='Sheet1'){
var editedCell = sheet.getActiveCell();
var columnToSortBy = 4;
var tableRange = "a2:f91";
if(editedCell.getColumn() == columnToSortBy){
var range = sheet.getRange(tableRange);
range.sort( { column : columnToSortBy, ascending: true } );
}
}
}

Related

Google Sheets. Automatically change given date plus n days

Good afternoon. I have 2 cells for 2 dates with date format on them and formula =DATE(2022; 1; 19). One cell is a first day of a current week period. Another cell is first day of a next week (=B17+7). I want to make both those cells to automatically change +7 days every week after i enter for example the first current date.
You can use for the first day (monday)
=today()-WEEKDAY(today(),2)+1
One way of solving your need while escaping circular dependency error is to do the following:
Keep cell B17 as is (=B13+7), however, instead of putting a date in cell B13, just put the following formula :
=TODAY()-WEEKDAY(TODAY(),2)+1
The result would be that the 2 cells will always update to the correct dates every time you'd open the spreadsheet.

COUNTIFS date in row is a workday

Ok, so what I'm trying to do is for each month count the number of workdays, minus public holidays.
B2 -- the current year
E2:E13 -- the first day of each month
F2:F13 -- the amount of days (workday or otherwise) in that month, that year
G2:G13 -- the amount of WORK days in that month (i.e. the formula I'm trying ot write)
A8:A -- the public holidays
I can take these and create a formula (here for G2)
=NETWORKDAYS(CONCATENATE("1.",MONTH(E2),".",$B$2),CONCATENATE(F2,".",MONTH(E2),".",$B$2), $A$8:A)
(which leverages the date format dd.mm.yyyy)
The problem with that is that some of these holidays are only half a day off, whereas this formula will give people the full day off.
So an approach could be to simply add half a day back in for every half day off that was wrongfully counted as a full day off, that month.
Assuming I have
C8:C -- is the holiday in the A cell of the same row a half-day?
That turns our formula into
=NETWORKDAYS(CONCATENATE("1.",MONTH(E2),".",$B$2),CONCATENATE(F2,".",MONTH(E2),".",$B$2), $A$8:A)+COUNTIFS($A$8:A,">"&EOMONTH(E2,-1),$A$8:A,"<"&EOMONTH(E2,0)+1,$C$8:C,TRUE)*0.5
(EDIT: example sheet)
But now here's the problem: that holiday may fall on a weekend.
So if a holiday that happens to be half a day off accidentally lies on a Sunday, say, we've just wrongfully added an extra half day of work.
What I need is an additional condition that will evaluate to "true" iff the holiday date is a workday, something along
[...]+COUNTIFS([...], $A$8:A, NETWORKDAYS(ROW,ROW) > 0)*0.5
I have no idea how to reference the row like that, though.
The easy way out would be a helper column that would calculate this boolean for me, but that's ugly as unlike the 'half-day' column, we do not want the user to be able to modify these values so having them see the column will just confuse them.)
How do I write the condition in the countifs?
I have found a simple solution without using countifs. The result you are looking for is the sum of three values:
Result = Working days in a month - Full holidays days - Half holidays days * 0.5
To do this, we will start by calculating the workdays in a month, the workdays minus full holidays and the workdays minus half holidays
WD: =NETWORKDAYS( CONCATENATE("1.",MONTH(E5),".",$B$2), CONCATENATE(CONCATENATE(F5,".",MONTH(E5),".",$B$2))
WD_FULL_H :=NETWORKDAYS( CONCATENATE("1.",MONTH(E5),".",$B$2), CONCATENATE(F5,".",MONTH(E5),".",$B$2), filter(A8:A,C8:C=FALSE)))
WD_HALF_H: =NETWORKDAYS( CONCATENATE("1.",MONTH(E5),".",$B$2), CONCATENATE(F5,".",MONTH(E5),".",$B$2), filter(A8:A,C8:C=TRUE)).
In this way we make sure that any vacation that coincides with a public holiday does not alter the final result. Next, we calculate the final working days. To do this we need to get how many full and half holidays we have in the month, which we get by subtracting the number of working days in the month:
FINAL WD: WD - (WD - WD_FULL_H) - (WD - WD_HALF_H) * 0.5
Simplifying:
FINAL WD: WD_FULL_H - (WD - WD_HALF_H) * 0.5
Finally, without auxiliary calculations:
FINAL WD:
=NETWORKDAYS(
CONCATENATE("1.",MONTH(E5),".",$B$2),
CONCATENATE(F5,".",MONTH(E5),".",$B$2),
filter(A8:A,C8:C=FALSE))
-
(NETWORKDAYS(
CONCATENATE("1.",MONTH(E5),".",$B$2),
CONCATENATE(F5,".",MONTH(E5),".",$B$2)))
-
NETWORKDAYS(
CONCATENATE("1.",MONTH(E5),".",$B$2),
CONCATENATE(F5,".",MONTH(E5),".",$B$2),
filter(A8:A,C8:C=TRUE)))
*0.5
UPDATED FORMULA:
I think this should do it. though there are probably other, maybe even tidier ways.
It adds back in half days if it finds matches in a FILTER().
=ARRAYFORMULA(NETWORKDAYS(E2,EOMONTH(E2,0),A$8:A$18)+IFERROR(FILTER(C$8:C$18,EOMONTH(A$8:A$18,0)=EOMONTH(E2,0),C$8:C$18,WEEKDAY(A8:A18,2<6))/2))

Highlight Duplicate Within 24 hours timestamp but a different date

I am trying to figure if the following can be done. If there are duplicate names in the B column then it will see if the date and time were within 24 hours of each other in the A column, if so it will highlight the cell yellow.
Currently, the formula I have will only highlight if it was on the same date. Is there a way I can add to the formula to all take into account time? So that if one response is on 5/20/20 at 17:00 and the next duplicate name is at 5/21/20 at 16:00 then the cell would be highlighted.
Here is the formula I am using the just highlights if it is within the same date:
=ARRAYFORMULA(COUNTIFS(B:B, B2, DATEVALUE(A:A), DATEVALUE(A2))>1)
I am not sure if something like this is possible. I am guessing that the formula would have to compare both datevalue and timevalue. Any help would be appreciated.
Instead of DATEVALUE you can use TO_PURE_NUMBER
This will return you the number of days from January 1, 1900 including the fraction for past hours and minutes opposed to DATEVALUE that rounds the value down to an integral day number.
Sample:
This allows you to calculate the real difference time between your timestamp.
For example like this:
=ARRAYFORMULA(or(COUNTIFS(B:B, B2, TO_PURE_NUMBER(A:A), ">"&TO_PURE_NUMBER(A2)-1, TO_PURE_NUMBER(A:A), "<"&TO_PURE_NUMBER(A2))>0,COUNTIFS(B:B, B2, TO_PURE_NUMBER(A:A), "<"&TO_PURE_NUMBER(A2)+1,TO_PURE_NUMBER(A:A), ">"&TO_PURE_NUMBER(A2))>0))

Find if a month belongs to a date range

I have a date range and a corresponding value.
On a the right-hand side of this data table, I want to separate the value monthly.
Available Data
Result Expected
*I have the limits of the date range any row can have. Ex: Mar 1st to Jun 30th.
I can take the number of days in a month and divide the value by that to get the value to fill in.
Problem is automatically deciding the cells which needs to be filled and which has to be marked as 0.
The solution I'm looking for is a formula that can be dragged into many more months.
My approach was to check at each cell if the Month Code("Mar", "Apr", "May"....etc) includes in the date range in A and B columns.
I have searched ways to check this and have failed. Is there a way to check if a month includes within a particular date range?
Or is there any other way I can fill the cells from D2 to G6?
*Actual scenario has more than 4 months and more than 6 Rows of data.
This is a formula giving the exact amounts for first row - not sure if that is what you want though:
=(max(0,min($B2,eomonth(datevalue("1-"&left(D1,3)&"2020"),0)))-max($A2,datevalue("1-"&left(D1,3)&"2020"))+1)*$C2/($B2-$A2+1)
Alternatively
=if(min($B2,eomonth(datevalue("1-"&left(D1,3)&"2020"),0))-max($A2,datevalue("1-"&left(D1,3)&"2020"))>=0 [your formula] ,0)

How to auto create a Month calendar in google sheets. Where first day of the month start in the colum of the (name)day

I want to create a calendar like in the second image. But I can not figure out how to start the first column is a monday. So I fill it by 'hand' like in the first image.
I tried to create it automatic. Starting with the first day of the month and add one day the next columns like in the second picture:
How I want it to look like:
How it is currently looking:
Google sheets example
I was solving the same problem for my bussiness, and I think I got the answer.
Your first task is to determine the first "calendar monday" of the month.
First, build the first day of the corresponding month:
[B2] =DATE(YEAR(A1); MONTH(A1); 1)
Then, get the WEEKDAY of the corresponding first day. The second argument represents what day your week starts with:
If type is 1, days are counted from Sunday and the value of Sunday is 1, therefore the value of Saturday is 7.
If type is 2, days are counted from Monday and the value of Monday is 1, therefore the value of Sunday is 7.
If type is 3, days are counted from Monday and the value of Monday is 0, therefore the value of Sunday is 6.
In my case, we count the week starting from Monday. This means when the first day of the month lands on Monday, the return value will be 0.
[C2] =WEEKDAY(B2; 3)
The number you get represents how many days you need to substract from the initial date to get the first "calendar monday" of the month:
[D2] =B2 - C2
This date is what you are looking for. The final formula:
[A3] =DATE(YEAR(A1); MONTH(A1); 1) - WEEKDAY(DATE(YEAR(A1); MONTH(A1); 1); 3)
The rest of the days, simply add 1 to each preceding date.
[A4] =A3 + 1
[A5] =A4 + 1
And so on.
Secondly, set the Number Format on the calendar cells to just show the day.
Format -> Number -> More Formats -> More Date and Time Formats.
Select just the day from the drop down.
Finally, use conditional formatting to "hide" the values that don't match the initial date
Use a custom formula for the formatting, as follows:
=MONTH(A3) <> MONTH(A1)
Apply to the calendar range. This will format dates that don't belong to the current date, so make sure to paint that white.
And that's about it. Good luck!

Resources