How to convert a custom date to date for a camparison? - vba

I need to convert a custom date data from Spreadsheet 1 to make a comparison with a date data from Spreadsheet 2. The custom date data has this format: 21/02/2014 08:09:21 a.m., and will be stored in variable Date1. And the date data is: 21/02/2014, and stored in Date2. I need to compare only the dates (without the time parameter) with the instruction "if", e.g.
If Date1=Date2 Then
'Instruction
End If
I have most of the code, so I basically just need the way to convert the custom date data to date data, store in the variables and compare them.

VBA solution:
Sub timeCompare()
date1 = Application.WorksheetFunction.Text([A1], "d/m/yyyy")
date2 = Application.WorksheetFunction.Text([A2], "d/m/yyyy")
If date1 = date2 Then
MsgBox ("match")
Else
MsgBox ("no match")
End If
End Sub
OR
Sub timeCompare()
date1 = Int([A1])
date2 = Int([A2])
If date1 = date2 Then
MsgBox ("match")
Else
MsgBox ("no match")
End If
End Sub
Results:
Formula solution:
=IF(TEXT(A1,"d/m/yyyy")=TEXT(A2,"d/m/yyyy"),"Match","No Match")
Or
=IF(INT(A1)=INT(A2),"Match","No Match")

Related

Check if the day is between two given days using VBA in Excel

I've limited knowledge in coding with VBA in Excel and have run into a problem. I'm trying to write a code where it does something based on what day of the week it is.
I'm extracting the day of the week as string and then using a IF...ELSE bit. Code is attached below:
Sub Schedule()
Dim Today As String
Today = Format(Date, "dddd")
If Today >= "Monday" And Today <= "Thursday" Then
'code to do something
ElseIf Today = "Friday" Then
'code to do something
ElseIf Today >= "Saturday" And Today <= "Sunday" Then
'code to do something
End If
End Sub
Kindly advise.
A Select Case ... is fine for this - and do use constants, not magic numbers:
Sub Schedule()
Select Case Weekday(Date)
Case vbMonday To vbThursday
' Code to do something.
Case vbFriday
' Code to do something else.
Case vbSaturday, vbSunday
' Code to do some fun.
End Select
End Sub
Use WeekDay() to extract an integer representing the current day of the week:
Dim Today As VbDayOfWeek
Today = Weekday(Date)
If Today >= vbMonday And Today <= vbThursday Then
....
You cannot apply comparison operands (> or <) to strings so you will need to use the .WeekDay() function instead of formatting to string.
Here is the documentation: WeekDay please note the second optional parameter.
Here is the code:
Dim Today as Long
Today = WeekDay(Date)
If Today >= 2 And Today <= 5 Then
'do something
ElseIf Today = 6 Then
'do something
ElseIf Today = 7 Or Today = 1 Then
'do something
End If

Getting all the dates between two selected dates

Good afternoon, I'm new to programming and I'm working with VB.NET.
I need to get the difference between two dates and then list all the intermediate dates in listbox1. I tried the following code but it doesn't work.
Private Sub breaks()
Dim date1 As Date = DateTimePicker1.Value.ToString("dd/MM/yyyy")
Dim date2 As Date = DateTimePicker2.Value.ToString("dd/MM/yyyy")
While date1 <= date2
Dim result = date1
ListBox1.Items.Add(result)
Dim term = 1
date1 = DateTimePicker1.Value.AddDays(term)
End While
End Sub
The function is called within a button. When executed it only shows the sidebars but is blank.
The image shows start date 03/10/2020 and end date 03/16/2020, however the result (listbox) does not return anything.
I expected my result to come:
03/10/2020
03/11/2020
03/12/2020
03/14/2020
03/15/2020
03/16/2020
the interval between them.
Can anyone tell me what's wrong?
You can use some linq for a simple solution
ListBox1.DataSource =
Enumerable.Range(0, 2 + DateTimePicker2.Value.Subtract(DateTimePicker1.Value).Days).
Select(Function(offset) DateTimePicker1.Value.AddDays(offset)).
ToList()
It generates a list of numbers to act as the offset from the initial date, then adds them the specified number of times (different between the dates in days) to create all the dates. No loop required.
Credit to this answer
Edit:
This can also be similarly applied to a DataGridView, but in order to make a single column, we would need to select an anonymous type.
DataGridView1.DataSource =
Enumerable.Range(0, 2 + DateTimePicker2.Value.Subtract(DateTimePicker1.Value).Days).
Select(Function(offset) New With {.Date = DateTimePicker1.Value.AddDays(offset)}).
ToList()
You should avoid using strings for datetimes until they need to be text.
The variable date1 can be used for all the dates, like this:
Dim date1 As Date = DateTimePicker1.Value
Dim date2 As Date = DateTimePicker2.Value
While date1 <= date2
ListBox1.Items.Add(date1.ToString("MM/dd/yyyy"))
Dim term = 1
date1 = date1.AddDays(term)
End While
Also, you should make sure to set Option Strict On as the default for new projects, and set it for the current project.

VBA: How to make an IF statement on a DateDiff function

In a VBA project i'm working on, I need to count the number of lines where the difference between two dates is inferior to X hours.
My idea was to go through all the lines and check for each line, like this:
Dim count as Integer
if DateDiff("h", date1, date2) < 24 then
count = count + 1
End If
The problem is that I get an incompatibility type error (execution error 13).
Is it possible to make IF statements on a DateDiff function? Or is it maybe possible to make a filter with DateDiff as the condition?
Thanks for the help and sorry for my poor english as it's not my main language!
I have tested it like this without any errors.
Dim date1 As Date
Dim date2 As Date
date1 = "14/10/2015 19:00:00"
date2 = "14/10/2015 16:28:43"
If DateDiff("h", date1, date2) < 24 Then
count = count + 1
End If
The VBA conversion function CDate can apply a little of the overhead you constantly pay for to correct the dates. With that said, it is best to correct the data to begin with and not rely upon error controlled conversion functions.
Dim date1 As Date, date2 As Date, n As Long
date1 = CDate("14/10/2015 19:00:00")
date2 = CDate("14/10/2015 16:28:43")
Debug.Print date1 & " to " & date2
If IsDate(date1) And IsDate(date2) Then
If DateDiff("h", date1, date2) < 24 Then
n = n + 1
End If
'alternate
If date2 - date1 < 1 Then
n = n + 1
End If
End If
Given that 24 hours is a day and a day is 1, simple subtraction should be sufficient for this base comparison.
Your DMY format may cause problems with the EN-US-centric VBA in date conversion. If an ambiguous date string is found (e.g. "11/10/2015 16:28:43") you may find that you are interpreting it as MDY.

Get the last day of month

I want to get the last day of the month.
This is my code. If I want to debug it and compile it to the database it says it has an error in the syntax.
Public Function GetNowLast() As Date
Dim asdfh As Date
asdfh = DateValue("1." _
& IIf(Month(Date) + 1) > 12, Month(Date) + 1 - 12, Month(Date) + 1) _
&"."&IIf(Month(Date)+1)>12 , Year(Date)+1,Year(Date))
asdf = DateAdd("d", -1, asdf)
GetNowLast = asdf
End Function
GD Linuxman,
Let's focus on obtaining the result...:-)
See also: here
The comment by #Scott Craner is spot on ! Though strictly speaking there is no need to use the formatting. (Assuming you want to work with the 'Date' object)
To achieve what you want, setup the function as per below:
Function GetNowLast() as Date
dYear = Year(Now)
dMonth = Month(Now)
getDate = DateSerial(dYear, dMonth + 1, 0)
GetNowLast = getDate
End Function
You can call the function in your code as:
Sub findLastDayOfMonth()
lastDay = GetNowLast()
End Sub
Alternatively, and neater is likely:
Function GetNowLast(inputDate as Date) as Date
dYear = Year(inputDate)
dMonth = Month(inputDate)
getDate = DateSerial(dYear, dMonth + 1, 0)
GetNowLast = getDate
End Function
You can call that function and pass it an input parameter.
Sub findLastDayOfMonth()
lastDay = GetNowLast(Now()) 'Or any other date you would like to know the last day of the month of.
End Sub
See also this neat solution by #KekuSemau
Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim d1 As String
Set Rng = Range("A2")
d1 = Range("a2").Value2 'put a date in A2 Formatted as date(cell format)
Dim years
Dim months
Dim end_month
years = year(d1)
months = month(d1)
end_month = Day(DateSerial(years, months + 1, 1 - 1)) 'add one month and subtract one day from the first day of that month
MsgBox CStr(end_month), vbOKOnly, "Last day of the month"
End Sub
I realize this is a bit late into the conversation, but there is an already available worksheet function that gives the end of month date, EoMonth().
Pasting into the Immediate Window:
?Format(CDate(WorksheetFunction.EoMonth(Date, 0)), "dd")
Will return the last day of the month based on current date.
As a UDF, it makes sense to give it a default Argument:
Function LastDay(Optional DateUsed As Date) As String
If DateUsed = Null Then DateUsed = Date
LastDay = Format(CDate(WorksheetFunction.EoMonth(DateUsed, 0)), "dd")
Debug.Print LastDay
End Function
If you feed it Arguments, be sure that they are Date Literals (i.e. Enclosed with #s)
LastDay(#3/10#)
Result: 31
LastDay #2/11/2012#
Result: 29 '(A leap Year)
Note the output Data Type is String (not Date) and that the format of the date can be adjusted as needed (Ex: "mm/dd/yyyy" instead of "dd").
If the Date Data Type is needed, use:
Function LastDay(Optional DateUsed As Date) As Date
If DateUsed = 0 Then DateUsed = Date
LastDay = WorksheetFunction.EoMonth(DateUsed, 0)
Debug.Print CDate(LastDay)
End Function
I hope that helps someone.
In short, a great and straightforward approach is to find the first day of the following month and then move backward one day.
Make yourself a little function that does something like this:
Obtain the month and year in question (the one where you want the last day)
Use DateSerial to combine the month and the year, along with the day "1" to get the first day of the month in question.
Use DateAdd to add one month. This will get you the first day of the next month (which is one day after the date you really want).
Use DateAdd again to subtract (move back) one day. This will give you the last day of the month where you started.
Function eom(ByVal input_date As Date) As Date
' take the first day of the month from the input date, add one month,
' then back up one day
eom = DateAdd("d", -1, DateAdd("m", 1, DateSerial(Year(input_date), Month(input_date), 1)))
End Function
In Access VBA, you can call Excel's EOMonth worksheet function (or almost any of Excel's worksheet methods) is by binding to an Excel application object and a WorksheetFunction object, which can be accomplished in a few ways.
Calling Excel functions with an Late Bound object
The shortest method from Access VBA is with a single line of code using a late-bound object. This example returns the date of the last day of the current month:
MsgBox CreateObject("Excel.Application").WorksheetFunction.EOMonth(Now(), 0)
A more verbose method, as a function:
Function eoMonth_LateBound(dt As Date) As Date
Dim xl As Object
Set xl = CreateObject("Excel.Application")
eoMonth_LateBound = xl.WorksheetFunction.eomonth(dt, 0)
Set xl = Nothing
End Function
An issue with late-bound references is that VBA takes a second to bind the object each time the function is called. This can be avoided by using early binding.
Calling Excel functions with an Early Bound object
If the function is to be used repeatedly, it's more efficient to go with Early Binding and retain the object between calls, for example:
Go Tools > References and add a reference to "Microsoft Excel x.xx Object Library" (use whatever the newest version number is that you have installed).
Add this code in a new module:
Option Compare Database
Option Explicit
Dim xl As Excel.Application
Function eoMonth_EarlyBound(dt As Date) As Date
If xl Is Nothing Then Set xl = New Excel.Application
eoMonth_EarlyBound = xl.WorksheetFunction.eomonth(dt, 0)
End Function
Sub demo()
MsgBox eoMonth_EarlyBound(Now())
MsgBox eoMonth_EarlyBound("4/20/2001")
End Sub
Creating a WorksheetFunction object
If Excel's worksheet functions are to be used lots throughout your code, you could even create a WorksheetFunction object to simplify the calls. For example, this could be a simple way to join multiple strings with TEXTJOIN, or get a response from an API with WEBSERVICE:
Sub Examples()
'requires reference: "Microsoft Excel x.xx Object Library"
Dim xl As Excel.Application, wsf As Excel.WorksheetFunction
Set xl = New Excel.Application
Set wsf = xl.WorksheetFunction
'use EOMONTH to return last date of current month
Debug.Print CDate(wsf.eomonth(Now(), 0))
'use WEBSERVICE return your current IP address from a free JSON API
Debug.Print wsf.WebService("https://api.ipify.org")
'use TEXTJOIN to implode a bunch of values
Debug.Print wsf.TextJoin(" & ", True, "join", "this", , "and", , "that", "too")
'always tidy up your mess when finished playing with objects!
Set wsf = Nothing
Set xl = Nothing
End Sub
Note that these functions may require Excel 2016+ or Excel 365 (aka: Object Library 16.0+.)
Another method I used was:
nMonth = 2
nYear = 2021
lastDayOfMonth = DateSerial(nYear, nMonth + 1, 0)

how to compare time in vba

I want to write a macro that compares two times that is available in cells A1 and B1
I tried to use the following code BUT it gave me "type dismatch" at date1 = TimeValue(Range("A1"))
for example, the value at cell A1 like this 11/18/2011 10:11:36 PM
dim date1 as date
dim date2 as date
date1 = TimeValue(Range("A1"))
date1 = TimeValue(Range("B1"))
if date1 > date2 then
'do something
else
'do something else
end if
you need to use Range("A1").Value
Two things:
try changing the value in A1 to 11/10/2011 10:11:36 PM If things
now work you may have a Regional Settings mismatch
you've declared date1 and date2 but are assigning twice to date1 and never
assigning to date2
use application.worksheetfunction.mod( date value, 1 )
You ought to understand that date and time in excel is represented by a serial number, in which 1 equals to a day, and time is repredented by decimals or fractions.
All systems base their date from day zero which us January 1, 1900 = 1, and January 2, 1900 = 2 and so on.
On the excel worksheet you cab retrieve the current date snd time using today(). On vba you use Now instead. Todays date, in "0" or "General" number formatting should show a number that starts with 42..., which represents the number of days since January 1, 1900.
Since there are 24 hours within a day, if you wish to refer to 1 hour or 1:00 AM the fraction or decimal in the serial number is equalent to 1/24. 7:00 PM = 19/24
mod() is a formula or function that will return the remainder of a division. Remember that time is represented by decimals, you do not need the actual whole numbers.
You can use the mod() formula in vba by using "application.worksheetfunction." before any.
When you divide a date and time with 1 using mod() it will return the remainder which is the decimal portion of your date aka the time.
Comparing datevalue("1:00 PM") will not equal CDate("May 8, 2015 1:00 PM")
sub compare_dates()
dim date1 as date
dim date2 as date
dim str as string
str = activesheet.range("A1").value 'str = "11/18/2011 10:11:36 PM"
str = Left(str,Instr(str," ")-1) ' str = "11/18/2011"
date1 = str ' assign it to date1
str = activesheet.range("B1").value ' in the same way b1 cell value
str = left(str,instr(str," ")-1)
date2 = str
if date1 > date2 then
' do something
end if
end sub
Can't it be done by simply using .Text instead of .Value?
Dim date1 As Date
Dim date2 As Date
Dim date3 As Date
date1 = TimeValue(Range("A1").Text)
date2 = TimeValue(Range("B1").Text)
date3 = TimeValue(Range("C1").Text)
If date3 >= date1 And date3 <= date2 Then
'Yes!
Else
'No!
End If