I'm working on a way to automate a report that sometimes has different dates that fall out of a period. For example, my report has data similar to the below that has different sets of dates. Each period consists of two weeks, I'm trying to replace all of the dates that fall out of the current period to the current period (10/15/2022 & 10/22/2022).
In this scenario, I would want 10/1/2022 to be replaced with 10/15/2022 and 10/08/2022 to be replaced with 10/22/2022. In other words, assign the first week in a prior period to the first week in the current period and the same with the second week.
Is this something that can be automated?
I'm familiar with the basics of VBA but do not know where to start.
Related
I'm trying to put together an excel spreadsheet to show the day-by-day impact of stays by 3rd country citizens in the EU's Schengen area (it's a fairly complex rolling 180 day window). At the moment, I have a column with every day from a start date (so lots of rows) and another where I enter a 1 if there was a stay in a Schengen country for that day. Then other columns calculate when the 180 day period started and how many days have been in Schengen for that day.
It's a bit of a faff having to enter a 1 for every day away. I'd like to have another worksheet where I simply enter the start and end dates of (an arbitrary number of) each stay and then the calculation spreadsheet simply works out if each date falls within a stay or not. Working out whether a date falls within one date range is pretty straightforward, but working out if it falls within several date ranges isn't obvious to me. Any suggestions please?
After a very fair comment, here's a couple of images that hopefully illustrate what I'm trying to do (please ignore the colours).
Example of date ranges, but the number of these should be arbitrary:
The calculated sheet - currently I have to enter the 1s individually whereas I'd like them evaluated from the date ranges:
here's my problem:
We have an Excel sheet at work in order to manage various tasks all set on individually specified timelines - we're talking hundreds of tasks per month with dates that are currently all being maintained manually.
Let's say we have Task A and that task has a Due Date. That Task is split into several subtasks, all with their individual due dates. Date 1 would then always be Due Date - 10 days, Date 2 would be Due Date - 20 days, Date 3 would be Due Date - 17 days and so on. This then creates a neat timeline of when everything needs to be done.
That in itself would be easy enough, problem is that all of these subtasks have to be done on a specific workday as well. Meaning that subtask 1 would not only have to be done Due Date - 10 days, but it would also have to fall on a Monday - if for whatever reason Due Date - 10 would happen to fall on like a Wednesday, it would have to subtract another 2 days. And then the real problem is that Date 2 and 3 each have to fall on different workdays and Task B has an entirely different schedule again.
Now, the first thing that came to my mind was attempting to just nest a couple IFs - and I've even managed to come up with a working formula for that. Problem here is that it's so stupidly long and (thanks Excel) utterly unreadable - if for some reason someone else had to change something about it or troubleshoot the entire file 1-2 years from now, they'd probably have to spend at least an hour reconstruct how the hell any of it actually worked. Which doesn't sound particularly appealing to us.
Here's a screenshot to help illustrating the situation:
And here's a draft of the current formula that I'm really not happy with, despite it somewhat doing the job:
=IF(AND(WEEKDAY(K2-VLOOKUP(B2,Table1,3,FALSE),11)>5,VLOOKUP(B2,Table1,5,FALSE)=0),(K2-VLOOKUP(B2,Table1,3,FALSE))-(WEEKDAY(K2-VLOOKUP(B2,Table1,3,FALSE),11)-5), IF(VLOOKUP(B2,Table1,5,FALSE)=0,K2-VLOOKUP(B2,Table1,3,FALSE), IF(WEEKDAY((K2-VLOOKUP(B2,Table1,3,FALSE)),11)=0,K2-VLOOKUP(B2,Table1,3,FALSE), (VLOOKUP(B2,Table1,5,FALSE)-WEEKDAY(K2-VLOOKUP(B2,Table1,3,FALSE),11))+K2-VLOOKUP(B2,Table1,3,FALSE))))
My question is now: Does anyone have an idea how to solve this in a less confusing and unclear manner? I was trying to get something done using =CHOOSE() but ultimately ended up with the same problem of eventually having to resort to 7 IFs and dozens of LOOKUPs, making the final formula just as long. I wouldn't be disinclined towards some kind of helper table that asigns the last 7 days and their workdays to every single day of the year... but I don't think tossing another 20,000 calculated cells into a file that already has tens of thousands other calculated cells would really be a serviceable alternative... or make the situation any less obscure at all tbh.
So, anyone any idea how to go about this? Or is there really no realistic alternative than to use a bunch of IFs?
Edit: Forgot to mention that 1 special case:
There's also the situation when a date doesn't have to fall on a specific workday - in which case it's simply due date - X days. The problem here is that in those cases the dates could fall on a weekend, so the formula would have to move these dates to the previous Friday as well.
Assume you have some date and you want to "back up" ten days and then to the preceding Monday, unless the resultant date is a Monday. The general formula would be something like:
=A2-10+1-WEEKDAY(A2-10-DOW)
Where DOW translates into
Sunday=0
Monday=1
Tuesday=2
...
You should be able to modify your formulas to use this algorithm for day of the week.
If the two tables are named thisTable and keyTable, the following 365 formula is one way of implementing:
If your tables are as below, you can enter the formula in B2 and fill down and across. The references should self-adjust and return the proper dates.
Note that in keyTable, I enter the day of the week DOW as defined above, and not the textual date.
=LET(dys,VLOOKUP(thisTable[#[Task]:[Task]],KeyTable,COLUMNS($A:A)*2,FALSE),
dow,VLOOKUP(thisTable[#[Task]:{Task]],KeyTable,COLUMNS($A:A)*2+1,FALSE),
due,thisTable[#[DueDate]:[DueDate]],
IF(dow="flexible",WORKDAY(due-dys+1,-1),due-dys+1-WEEKDAY(due-dys-dow)))
If you want to have the result be the closest workday, instead of the preceding workday, then you need to add two clauses to the LET function
Calculate the subsequent workday date
Then use an IF to return the closest one to the original target
eg:
=LET(dys,VLOOKUP(thisTable[#[Task]:[Task]],KeyTable,COLUMNS($A:A)*2,FALSE),
dow,VLOOKUP(thisTable[#[Task]:[Task]],KeyTable,COLUMNS($A:A)*2+1,FALSE),
due,thisTable[#[DueDate]:[DueDate]],
dayPrev,IF(dow="flexible",WORKDAY(due-dys+1,-1),due-dys+1-WEEKDAY(due-dys-dow)),
daySubseq,IF(dow="flexible",WORKDAY(due-dys+1,-1),due-dys+7-WEEKDAY(due-dys-1-dow)),
IF((daySubseq-due+dys)>3,dayPrev,daySubseq))
I have a column that needs split based on "morning" and "evening" although the morning and evening times move every day (it's based on sidereal day). Calling them morning and evening is a little deceiving though because eventually the time will creep into the next day and I want to keep the groups distinct. It is more accurate to call them group 1 and group 2. It just so happens that they are around 12 hours apart so it looks like you can just separate based on time of day but once the later group creeps into the AM hours, it would start to get counted as "morning" and the earlier group would roll into the afternoon and be counted as "afternoon" See screenshot below for example data.
I need them split so I can perform operations on the value column so I can distinguish the values in the first group from the values in the second group. I thought of doing some sort of flip flop algorithm based on the previous cell but there may be a more elegant way to do it. Also, it's not shown on the example data but sometimes the day may skip but the times more or less continue in the same pattern of increasing by 3-5 minutes each day.
A date with a time stamp is stored as a number in Excel. Days are stored as whole numbers, time is stored in decimals. So, disregarding the date part, look at the decimal of the number and determine if that is before or after the time you want.
0.5 for example is midday, or 12 noon. So if the decimal part of A1 is less than 0.5, the time stamp would be in the morning.
=if(A1-int(A1)<0.5,"before noon","after noon")
It is not clear from your question how sidereal relates to the data in your sample.
I have the following worksheet:
The grid is filled with the following formula (this example is from cell H4) that populates the grid based on inputs from the table on the left, =IF($A4="","",IF(AND($E4="Daily",H$2>=$D4,H$2<=$G4),IF(RIGHT($F4,2)="30",LEFT($F4,LEN($F4)-2)&"/",IF(RIGHT($F4,2)="00",LEFT($F4,LEN($F4)-2),$F4)),IF(AND($E4="Weekly",H$2>=$D4,H$2<=$G4,TEXT(H$2,"DDD")=TEXT($D4,"DDD")),IF(RIGHT($F4,2)="30",LEFT($F4,LEN($F4)-2)&"/",IF(RIGHT($F4,2)="00",LEFT($F4,LEN($F4)-2),$F4)),IF(AND($E4="Bi-Weekly",H$2>=$D4,H$2<=$G4,MOD($D4+14,H$2)=0),IF(RIGHT($F4,2)="30",LEFT($F4,LEN($F4)-2)&"/",IF(RIGHT($F4,2)="00",LEFT($F4,LEN($F4)-2),$F4)),IF(AND($E4="Monthly",H$2>=$D4,H$2<=$G4,TEXT(H$2,"MM/DD/YYYY")=CONCATENATE(TEXT(H$2,"MM"),"/",TEXT($D4,"DD"),"/",TEXT($D4,"YYYY"))),IF(RIGHT($F4,2)="30",LEFT($F4,LEN($F4)-2)&"/",IF(RIGHT($F4,2)="00",LEFT($F4,LEN($F4)-2),$F4)),IF(COUNTIF('PowerPoint Gantt'!$A$5:$A$12,$A4)=1,IF(H$2=VLOOKUP($A4,'PowerPoint Gantt'!$A$5:$E$12,5,FALSE)+31,"R",""),""))))))
The only part of the function that isn't working is the Bi-Weekly selection. I can't figure out how to get recurring entries. I can get the start date and one 14 day period after. I've tried using the CEILING function also but still only gets me the next 14th day marked, instead of every 14th day. And ideas?
In your rule for Bi-Weekly meetings, it seems that
MOD($D4+14,H$2)=0
should be replaced with
MOD(H$2-$D4,14)=0
The latter takes the difference between the starting date and the actual date and checks to see if that can be divided by 14, the number of days in 2 weeks.
Your rule for Weekly meetings could be approached similarly, which seems simpler to me than a rule based on the name of the day, like you are using now.
I have a Task month calendar. when i change the month of the calendar it shows me what I have to do which day of the month.
I basically have a list of task, when i change the month the tasks date automatically change accordingly a series of rules and that list will populate the calendar.
Calendar
Tasks
But I have some tasks that are bi-weekly, and I dont have a specific week to be done, they have to be done in the fortnight after the last time.
so I have the first week (day) that the task was done and i have the first day of the month i am... and with that i would wanted to know which days of the month i have to do that specific task.
Can you help me?
use the last reference point as the basis for creating the next due date. this would be the date the task was last performed. If it is due a fortnight from that last date then add 14 days. You may want to record the date that task was performed each time so that your formula is based on the date it was last completed each time it is calculated.
If you are wanting to plan ahead then make an assumption that it will be done in consistent 14 day iterations then build your formula to consider the actual date it was completed to readjust the plan going forward. So it will assume this will be done consistently until advised otherwise with an actual date it was last completed.
The trick is to get the first date in the month that matches the weekday of the last date and then you can easily add 14 days. Much like finding the first Monday/Sunday in a month to build a calendar.
A1 contains the last time the task was performed
C1 contains the 1st of the month
C1+7-WEEKDAY(C1+7-weekday(A1))
will return the next weekday that matches the weekday the task was last performed.
=C1+7-WEEKDAY(C1+7-weekday(A1))-A1
returns the number of days since
=(C1+7-WEEKDAY(C1+7-weekday(A1))-A1)/2
returns the number of days divided by 2. If this result is not a whole number (#.5) then it's not in the bi-weekly cycle and we need to add another 7 days to get the correct start date. If it is a whole number then it is our start date. We can use the mod function to find out if there is a decimal value.
=if(mod((C1+7-WEEKDAY(C1+7-weekday(A1))-A1)/2,1)>0,C1+7-WEEKDAY(C1+7-weekday(A1))+7,C1+7-WEEKDAY(C1+7-weekday(A1)))
Below or next to this cell you can simply reference the cell and add 14 =D1+14 and then add as many as you want to display.