To many if statements to handle - excel

I have a sheet I want to maintain regarding progress in a evaluation project.
Current DATE (today())
Columns (cannot make a table here)
Date 1, is when the initial request has been send.
Date 2, is when the 1st reminder has been send.
Date 3, is when the 2nd reminder has been send.
Date 4, is when the evaluation has been recieved.
I want a field that gives a value when action is needed. (this is so i can assign a conditional format rule to it).
These are the action rules:
- Date 4 is empty
AND
- Date 1 is more than 7 days ago ( if(currentdate-date 1)>7, 1, 0)
(this is the easy part and now comes the part where i start getting lost)
If there is a Date 2:
- Date 2 is less then 7 days ago - NO action
- Date 2 more then 7 days ago - action needed
If there is a Date 3:
- Date 3 is less then 7 days ago - NO action
- Date 3 more then 7 days ago - action needed
In the end I just want 1 cell that said either 1 or 0 for action/no action.
I tried making 1 long string of if's but that does not work. I have tried making it in seperate cells but could not make it work.

you can nest them :) it seems easier to read if you flip the >
if(currentdate - date1 < 7, "No Action", if(currentdate - date2 < 7, "No Action", if(currentdate - date3 < 7, "No Action", "Action")))

I assume you want to use formulas. Instead of nesting lots of If-formulas, I would advise you to write a user defined function.
That function can be used just like any Excel-Formula, with the small exception that you need to save your workbook with an *.xlsm file extension.
Also note that you gave explanations on what to do if the DateDiff is >7 and <7, but didn't mention what should be done the date is exactly 7 days in the past - therefore this isn't included in the formula below. ;)
Paste this into your "ThisWorkbook"-Module, and use ActionRequired just like any normal formula.
Public Function ActionRequired(Optional date1 As Date = 0, Optional date2 As Date = 0, Optional date3 As Date = 0, Optional date4 As Date = 0) As Boolean
If date4 = 0 And DateDiff("d", date1, Now) > 7 Then
If Not DateDiff("d", date2, Now) < 7 Then
ActionRequired = True
Exit Function
End If
If Not DateDiff("d", date3, Now) < 7 Then
ActionRequired = True
Exit Function
End If
End If
End Function
That's not to say that nesting If-excel formulas doesn't work (it does), but in my experience stuff like that is pretty prone to error, since it gets messy rather fast (in addition, your formula is stored in 100s of cells - with an UDF, its stored in exactly one place - your code - and only called in the the cells)

Related

VBA - How can I get all Mondays in a month then multiply to working hours?

I'm trying to figure out how to get the total of Mondays in a month then multiply by working hours.
This is my example code it works but it counts wrong output:
If UCase(val) Like "EVERY MONDAY" Then
Dim numString As Integer
Dim strDays() As String
Dim wordCount As Long
numString = 2
strDays = VBA.Split(val, " ")
wordCount = UBound(strDays)
strWhEveryDay = ThisWorkbook.Sheets("Input").Cells(X, 4).Value
strWhEveryDay = strWhEveryDay * var_month
Debug.Print "Every = " & strWhEveryDay
Explanation:
It depends on the user if what they like to input in a TEXTBOX. However, the CALCULATION it depends on the date where the user input in TEXTBOX.
I have Textbox which is the target month where the user input the format of date like this:
**Jan-2023 or Feb-2023 **
I have a table like this:
Place this text in a table start in Column B Row 2:
**every Monday**
Place this text in a table Column D Row 4:
**1.2**
All I need is to get all the total of Mondays based on the given month and year. The calculation of the days in a table of "every Monday" once I change the text from "every Monday" to "every Tuesday" so the calculation will adjust or automatically knows where the calculation days start to end:
Example of expected calculation: every Monday (January 2023 = 5 Days) * 1.2 so, the expected result will be 5.
Note: use Debug.Print to see the result or output
So, using networkdays.intl() as suggested in my comment:
NETWORKDAYS.INTL($A$3,$A$33,"0111111",)
The result shown is 5, which is correct by inspection, for cells A3:A33 the long date format was used.
So multiplying by 1.2 is:
NETWORKDAYS.INTL($A$3,$A$33,"0111111",)*1.2
and 5 * 1.2 = 6
Also, the string "0111111" can be put in cell F5 and referred to so it is easier to edit.
The easiest way I know to recognise any day of the week is the following:
=WEEKDAY(B2,2)
The "2" means that weekdays are counted, starting with "Monday" as 1, "Tuesday" as 2, ...
So, if you want to know if your date is a Monday, you can use this formula:
=IF(WEEKDAY(B2,2)=1,...)
This can easily be translated into VBA, using a standard IF-clause.

Need to change date into current work week (1-52), but skip to the next week if the day is Wed - Sat in VBA

I'm having trouble writing code in VBA that would allow me to input any given date then have an output of the current work week. I need a restriction of if the date is Sunday through Tuesday, it will keep that current work week and year but if the date is Wednesday through Saturday, then the next work week and year will show. For example, I'm looking to input (5/28/19) and have an output of 201922 or an input of (5/29/19) with an output of 201923 even though its technically the same work week.
Before getting too in depth, I do have a working function that provides the year and work week, but I'm trying to adapt the function or add a separate function that will change in to the next work week according to the given date.
I'm new to VBA but have tried to do a little research over the last few days. I was thinking that I could somehow have one input of the date then have two outputs where one would be the year and work week then the other would be the number associated with that date (1 for Sunday, 2 for Monday, and so on). I tried to create an if then statement that says if the number associated with that date is 1, 2, or 3 then the workweek would stay the same. If it was any other number then 1 would be added to that work week so it would move to the next one. I'm having trouble with trying to make two outputs and have them connected, if that makes any sense.
This is the code that I tried to create, but continuously failed at making. The function that gives the correct work week (without the adaptation of the work week based on the date weekday) is WWV1
Function WWV2(WeekdayName As Integer)
Dim WWV1 As Integer
If WeekdayName(Date) = 1 Or 2 Or 3 Then WWV1 = WWV1
Else: WWV1 = WWV1 + 1
End Function
This provides the cell with #NUM! when I use the function in that cell, which I assume is because I need to somehow connect the two functions.
how about this:
=YEAR(A1) & TEXT(WEEKNUM(A1,13),"00")
WeekNum returns the weeknumber with 13 saying it starts on Wednesday:
VBA
wkcd = Year(Range("A1")) & Format(Application.WeekNum(Range("A1")),"00")

Determine number of days (not including weekend) based on hours given

I have two important details that are inputted into an excel table, Job_Start_Date and Job_Hours (meaning the hours required to complete the job). Given certain working hours (eg 7:00am-3:30pm) I need to calculate what day and what time they will finish. I already have that basic bit working, but I cannot for the life of me figure out how to skip weekends in that calculation (Note that there is a boolean for Sat/Sun that defines whether that day should be skipped).
Here is an example of the data
and an example of the data visualization: (The DIV errors are because employee count equals 0, pay this no mind.)
.
This is the formula used in the visualizer (a massive index match)
=IFNA(INDEX(INDIRECT(Allocation!$A$1), MATCH(1,($A3 = INDIRECT(Allocation!$K$1))
* (C$1 >= INDIRECT(Allocation!$C$1)) * (C$1 <= INDIRECT(Allocation!$D$1))
* IF(C$1 = INDIRECT(Allocation!$C$1), ($B3 >= INDIRECT(Allocation!$E$1)),
($B3 >= INDIRECT(Allocation!$I$1))) * IF(C$1 = INDIRECT(Allocation!$D$1),
($B3 < INDIRECT(Allocation!$F$1)), ($B3 < INDIRECT(Allocation!$J$1))), 0)),"")
As you can see in the image, Saturdays need to be skipped (being FALSE), but it is still shown on the visualizer. However, if I include a statement that matches the Saturday condition (so it only shows up on a Saturday if TRUE), it will not alter the end date and thus will not push the final day to Monday.
Essentially the question is: How can I skip days but preserve the 'working hours'. This must be done in excel formulas in the same Job table (first image).
Thanks.
Here is how I got it working using WORKDAY.INTL.
First is a nested IF to determine which weekend type to use for the workday.intl function
Weekend=IF(OR([#[JOB SATURDAY]], [#[JOB SUNDAY]]), IF(AND([#[JOB SATURDAY]], [#[JOB SUNDAY]]), -1, IF([#[JOB SATURDAY]], 11, 17)), 1)
Then a second if statement that references that value and then spits out the correct date
=IF([#[Weekend]] = -1, [#[JOB START DATE]]+[#[Working Days]], WORKDAY.INTL([#[JOB START DATE]], [#[Working Days]], [#[Weekend]]))

Date status function to displays Overdue, Due Later and Due Soon

I am currently working on function in Excel that will display the status of an activity based on the due date provided.
This function would display:
"Overdue" if Today()> Due Date;
"Due Soon" If the Due date was within one week
"Due Later" if Today() < Due Date +7
Below is an example of what I was able to muster up:
Function Status_of_Date()
If Sheets("Issue_Log").Range("Due_Date").Value < Date Then
Sheets("Issue_Log").Range("Date_Status").Value = "Overdue" 'overdue
ElseIf Sheets("Issue_Log").Range("Due_Date").Value < 7 + Date Then
Sheets("Issue_Log").Range("Date_Status").Value = "Due Later" ' Due Soon
ElseIf Sheets("Issue_Log").Range("Due_Date").Value > 7 + Date Then
Sheets("Issue_Log").Range("Date_Status").Value = "Due Later" ' Due Later
Else
End If
End Function
Codeless Solution
Add a column to your table, to count the days left - since anything negative is overdue anyway, make all negatives -1:
Use a table formula to calculate it:
=IF([#[Due Date]]-TODAY()<0,-1,[#[Due Date]]-TODAY())
Next, have another table to hold the status given a number of days:
Since you have 3 statuses, and they're really ranges of values, to achieve the values you're after you'll need:
A row with -1 for everything Overdue
A row with 0 for everything due Soon
A row with 7 for everything due Later
Now your "Date Status" column can be a simple VLOOKUP formula:
Again, a table formula is used; note the "approximate match" last parameter:
=VLOOKUP([#Days],tblStatusLookup,2,TRUE)
Adjust tblStatusLookup to whatever you've named your lookup table.
Look 'ma, not a single line of code!
Then you can hide the [Days] column if you don't need it shown, and the lookup table can be anywhere you want - and if the thresholds need to change, or if new statuses need to be added, you just tweak the lookup table (important: keep the [Days] sorted ascending, that's how approximate match VLOOKUP works!)
Bugs in OP
Your function needs to know what row to work with. That should be a parameter; change the signature to accept one - or even better, change it to accept a DueDate parameter - then you simply don't need to care about anything other than the date you're given:
Public Function GetDateStatus(ByVal dueDate As Date) As String
If dueDate - Date < 0 Then
GetDateStatus = "Overdue"
ElseIf dueDate - Date < 7 Then
GetDateStatus = "Due Soon"
Else
GetDateStatus = "Due Later"
End If
End function
And then in your table the formula would be:
=GetDateStatus(#[Due Date])
No need to be bothered with ranges and the nitty-gritty details of how and where every value is coming from - code gets much, much simpler when you work at the right abstraction level!
Note that a worksheet function is not allowed to change other cells' values: it calculates a value.

Match Dates with Time Periods

I have transaction data which includes a trade date. I want to be able to match the trade date of the transaction with the matching time period.
I have a table with 5 different time periods like so:
Period 1: 1/1/2000 - 3/31/2000
Period 2: 4/4/2001 - 6/6/2001
Period 3: 10/10/2002 - 12/31/2002
etc.
I want to be able to match the dates from the transaction data with their matching period for further calculation purposes.
The only solution I could thing of was nested if formulas but those are always ugly and depending on how many different periods I have not usable.
Thanks for the help!
Try this:
Public Sub RangeChecker()
Dim date1, date2, myDate As Date
Dim myDateStatus As String
date1 = CDate("January 1, 2000")
date2 = CDate("June 1, 2000")
myDate = CDate("May 1, 2000")
If (myDate > date1 And myDate < date2) Then
myDateStatus = "The date is inside the range"
Else
myDateStatus = "The date is outside the range"
End If
MsgBox (myDateStatus)
End Sub
You should only need one if statement per date range.
It's difficult to answer when you don't specify enough the layout of your data, which thing is in which column etc. Supposing the periods are defined in columns A, B and C, and the date for which you want to find the period is F2, you can use this CSE formula:
=INDEX($A$2:$A$7,MATCH(1,($B$2:$B$7<=F2)*(F2<=$C$2:$C$7),0))
' enter then press Ctrl+Shift+Enter

Resources