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))
Related
I know it's basic but I'm new to this. I just want to know how can I calculate the days duration of the two dates?
For example, I have my start date and time 11/22/2021 15:20:43 and end date and time 11/23/2021 14:51:29 I want to calculate the total days from start to end date and time.
Also, If start date time column is BLANK, return to count of days including date today.
Thank you
All you need to do is use the following formula: '=(C2-A2)'. This will give you the elapsed time between the two cells and display it as hours. You can take this calculation further by adding dates too. This is useful if you have work shifts that go more than 24 hours or that include two days within a single shift.
Assuming start dates in column A and end dates in column B, you can try
={"Duration in Days"; Arrayformula(if(len(A2:A) * len(B2:B), datedif(A2:A, B2:B, "d"),))}
Change ranges to suit and see if that works?
EXAMPLE
REFERENCES:
DATEDIF
there is a DAYS formula exactly for that purpose:
update:
=INDEX(IFERROR(1/(1/DAYS(
REGEXREPLACE(TO_TEXT(B1:B), "(.|..)[\/\-\.](.|..)[\/\-\.](.+) (.*$)", "$2\/$1\/$3"),
REGEXREPLACE(TO_TEXT(A1:A), "(.|..)[\/\-\.](.|..)[\/\-\.](.+) (.*$)", "$2\/$1\/$3")))))
demo sheet
I have a sheet that contains an amount in column D and the week number(A), month number (B), and year(C). How do I get the average of the last month's amount (D)? So in the example below, I am looking for the average of D251 to D254 based on last month (Column B) 7. Then next month, with it's September, The same cell would average all the "Amounts" in column D for the month of last month, Aug 8th. I hope that all makes sense.
How do I get the average of the last month's amount (D)?
You can use AverageIF, or possibly AverageIFs (plural) to account for prior year. I updated my example. You also might consider a different structure/column for time that combines Year_Month. See example in sheet.
Formula used:
=IFERROR(AVERAGEIFS(D:D,B:B,if(B2=1,12,B2-1),C:C,if(B2=1,C2-1,C2)),"First Period")
See this example.
Please try the following
=AVERAGE(INDEX(FILTER(A2:D,B2:B=MAX(B2:B)),,4))
I have a column with month day numbers, so 20 means the 20th of the month.
I want to know how to check if a value in this column, say 20 is more than or less than today's month day.
I would use conditional formatting to color the cell in red if that day had not passed already.
What I tried to do was set a cell with today's date:
=TODAY()
Then based on this calculate if the month day was less than or greater by using this:
=DATEDIF(F2, "MD")
I was hoping this wold return a number which I could then do a compare with but this is wrong and I am not sure if what I want to do is even possible.
I have read through the documentation and Stackoverflow but I cannot find any close examples.
Thank you.
If you want to check the day of the month you need to extract exactly that.
If your date is in Cell A1 and your threshold (20) in A2 the conditional formatting formula to check if the date has not passed yet would then go:
=DAY(A1) < A2
Here is what I'm trying to do:
I have three Spreadsheets.
(1) Days (holds increase in user-nr per day)
(2) Weeks (is supposed to sum up user increases so they are shown each week)
(3) Months (is supposed to sum up user increases so they are shown each month)
To give an example: if we have 10 users on Monday, 20 more on Tuesday, 15 more on Wednesday (that's when the next calendar week starts), then I want in the sheet "weeks" to see e.g. 45 users in calendar week 27 or so.
So what I try is this: =SUMIF(WEEKNUM(Days!A2:A977); A2; Days!B2:B977)
A holds the date of the day
B holds the number of users.
What happens is it does not sum up the number of the users shown in B, but only gives the number in the first cell of the weeknumber shown in A2.
What is my mistake?
The formula seems to be correct, but two things are needed.
You should embrace it in ArrayFormula()
You should use one more weeknum()
=ArrayFormula(sumif(weeknum(Days!A2:A977);weeknum(Days!A2);Days!B2:B977))
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 } );
}
}
}