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

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.

Related

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

To many if statements to handle

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)

Check for day range and no

I have the following data sheet:
As you can see I have a date and a no which is a string.
Now I want to filter out all dates which have the same number in a +-20 day intervall around the date. So for example:
If the 12.2.2014 has the value a then it gets a 1 and if the 3.2.2014 has the value a it gets also a 1. In contrast if the value 15.1.2014 has the value a it gets a 0 because it is not in the +-20 day range. If there exists two rows like in the example below with 10.07.2002 and value d then it gets a 0 because there is no other day in a 20 day intervall around it.
My implementation idea is: Calculate for each value and date the difference of the dates and if it is less or equal than 20 and greater and equal to 1 then give out a 1 else a 0.
Can this be done in excel?
I really appreciate any suggestions
PS.: I hope that I showed the problem clearly!
UPDATE
Using this formula I get:
=COUNTIFS($B$2:$B$32;B2;$A$2:$A$32;">"&(A2-20);$A$2:$A$32;"<"&(A2+20))-1
see col E.
Something like this (adjust the $B$2:$B$32 etc to your actual data range):
=COUNTIFS($B$2:$B$32,B2,
$A$2:$A$32,">" & (A2-20),
$A$2:$A$32,"<" & (A2+20))-1
-1 is to avoid counting the row the formula is on.
To give only 0 or 1:
=MIN(COUNTIFS($B$2:$B$32,B2,
$A$2:$A$32,">" & (A2-20),
$A$2:$A$32,"<" & (A2+20))-1,1)

comparing dates with sharepoint

I am trying to compare the date of my Last B Service + Service interval months to todays date in Sharepoint. But it is giving me an error.
=IF(DATE(YEAR([Last B Service]),
MONTH([Last B Service])+[B Service Monthly Interval],
DAY([Last B Service])),"D")) >= NOW(), 0, 1)
I add B Service Monthly Interval to the Months section in the Date variable, then try and compare it to NOW() (todays date) to make this example easier, i have changed the result to 0 and 1 (i ahve also tested this and it returns an error)
Can you see whats wrong with that code?
I don't know what the "D" is doing in your formula as all the parentheses around that area make the formula invalid (you actually tried to close the IF after "D".
I don't know if it makes sense, but the following formula would work:
=IF(DATE(YEAR([Last B Service]);MONTH([Last B Service])+[B Service Monthly Interval];DAY([Last B Service])) >= NOW();0;1)
Here comes the trick: SharePoint calculated columns formula are largely compatible to Excel! What I actually did to try this out:
Open a new sheet
Write "4/14/13" into A1 (the last service)
Write "3" into B2 (the service interval)
Create the formula in C3: =IF(DATE(YEAR(A1);MONTH(A1)+B1;DAY(A1)) >= NOW();0;1)
Profit

Lotus Notes: Displaying days of a month, following the weekdays of it

I have a not so nice question. I've been thinking about this for like a month now and read a couple of books but can seem to find an answer or how to execute this. As you all know, I'm making this application that generates date. I have one combobox it has months in it, starting january to december, two column table, first colum displays the day and the second one displays the weekdays, on selecting month combobox, it must display the days in that month on first column and weekdays on 2nd column, by row. example: I choose january, on the first column it will display the days of that month, 1st row is 1, 2nd row is 2, and so on, and same as weekdays. I'm kinda new to LN. Can you give me an idea for it? Hope you can help me out.
This is a solution based on Notes #Formula. Only a few lines of code are necessary to achieve the result.
First we need the form
The formula for Days is
_days :=1:2:3:4:5:6:7:8:9:10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31;
_numberDays := #Day(#Adjust(#Adjust(#Date(#ToNumber(Year); #ToNumber(Month); 1); 0; 1; 0; 0; 0; 0); 0; 0; -1; 0; 0; 0));
#Subset(_days; _numberDays)
and the formula for Weekday is
_weekdays := #Transform( #ToNumber(Days); "day";
#Weekday(#Date(#ToNumber(Year); #ToNumber(Month); day)));
#Replace(#Text(_weekdays);
"1":"2":"3":"4":"5":"6":"7";
"Sunday":"Monday":"Tuesday":"Wednesday":"Thursday":"Friday":"Saturday")
That's it.
The fields Month and Year have to have the property "Refresh fields on keyword change".
The fields Days and Weekday need "Computed for display", "Allow multiple values" and "New Line" as separate values.
The result will look like this
Truly dynamic tables are difficult. In this case it's definitely possible because you have a defined number of rows, but it's still somewhat messy.
I'm not aware of anything built in that will easily tell you how many days there are in each month. I'd probably just create a config doc with year, month, and numberOfDays fields, and hidden view that you can use for lookups. You're going to need this in many places, and you don't want to do the lookup each time, so do it in a hidden computed field that comes after your dropdown but before your table. (Be sure to set properties so the field is recomputed after the value in the dropdown is changed.) Call the field something like daysInSelectedMonth.
Obviously the first column is easy: just create your table and enter the numbers 1 through 31, and apply a hide-when formula to the cells for rows 29 through 31 so that they only show up if daysInSelectedMonth is the right number of days. You don't need the hide when in the other rows.
For the second column, you will need to use computed for display fields. I would strongly suggest naming them something like weekday_1, weekday_2,... weekday_31 so that you can use #ThisName and some simple string manipulation to extract the number from the field name. That will tell you what row the formula is in, and it is your day number. The benefit of doing it this way is that your formula can be exactly the same in every one of the fields -- just a cut-and-paste into the other fields after you get it right once.
I would suggest starting to work on the formula in the weekday_31 field, and when you get it right (showing the correct weekday in a month that does have 31 days, and blank in a month that does not), then you can copy the formula to the rest of the fields. You will need to use an #If to detect whether the month has the correct number of days -- this is easy, except for leap year. I'm going to leave that part up to you. Just make it return "" if the month does not have the right number of days, and then have the final clause of the #f use #Date to build the value for the date that you are working on and then use the #Weekday function to display the value.
It all depends on a few things:
Web application or Notes client application?
What is the end result of the exercise, i.e. what is the table intended to be used for? Display purposes only?
Making some assumptions (Notes client application, and table used only for display), I see two ways to do this.
An easy way to do this is to create the table with 31 rows and 2 columns.
In the cells you create fields: Day1, Weekday1, Day2, Weekday2, etc.
You also need a year field, unless it is always current year.
Set a hide-when formula on rows 29-31, to hide if the Day field for that row is blank.
On the advanced properties tab for the combobox where you select month, set "Run Exiting/OnChange events after value change".
In the Exiting event for the combobox, write some Lotusscript that populate the fields with days and weekdays, based on selected year and month. Something like this (untested:
Sub Exiting(Source As Field)
Dim session As New NotesSession
Dim ws As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim monthName As String
Dim YYYY As String
Dim firstDate As NotesDateTime
Dim lastDate As NotesDateTime
Dim n As Double
Dim i As Integer
Dim dayname(1 To 7) As String
dayname(1) = "Sunday"
dayname(2) = "Monday"
dayname(3) = "Tuesday"
dayname(4) = "Wednesday"
dayname(5) = "Thursday"
dayname(6) = "Friday"
dayname(7) = "Saturday"
Set uidoc = ws.CurrentDocument
YYYY = uidoc.FieldGetText("Year")
monthName = uidoc.FieldGetText("Month")
Set firstDate = New NotesDateTime("1 " & monthName & ", " & YYYY)
Set lastDate = New NotesDateTime(firstDate.DateOnly)
Call lastDate.AdjustMonth(1)
Call lastDate.AdjustDay(-1)
i = 0
For n = Cdbl(firstDate.LSLocalTime) To Cdbl(lastDate.LSLocalTime)
i = i + 1
Call uidoc.FieldSetText("Day" & i, Cstr(i))
Call uidoc.FieldSetText("Weekday" & i, dayname(Weekday(Cdat(n))))
Next
Call uidoc.Refresh()
End Sub
Another way to create a truly dynamic table, is the method I blogged about here:
http://blog.texasswede.com/dynamic-tables-in-classic-notes/
The benefit is that it is more flexible, and you can create a nicer layout without needing to create a large number of fields.

Resources