VBA format date to get the previous month - excel

I am fairly new at VBA and this seems like an easy task. I am just trying to get the current date substituting the current month for the previous one and a day constant as 21 so the result will have to be yyyy - (m-1) - 21
so far I had a couple of ideas and they work partially
Sub Test_Date()
Dim x As String
Dim p As String
p = Format(Date, "mm") - 1
x = Format(Date, "yyyy-" p "-21")
End Sub
if I MsgBx "p" comesback as what I want but, I dont know the correct syntax to concatenate them into one string
also
Sub Test_Date()
Dim x As String
x = Format(Date, "yyyy-(Format(Date, "mm") - 1)-21")
End Sub

You could also try this:
Function LastMonth() As Date
Dim d As Date
d = DateAdd("m", -1, Date)
LastMonth = DateSerial(Year(d), Month(d), 21)
End Function
Edit:
Format the returned date as needed:
Sub Test()
MsgBox Format(LastMonth, "yyyy-mm-dd")
End Sub

You could use DateSerial.
This accepts a year, month and day as its input and kicks out the date based on that.
So, DateSerial(2017,9,22) will give todays date.
To get the 21st of last month you'd use
DateSerial(Year(Date), Month(Date) - 1, 21)
Year(Date) returns 2017, Month(Date) returns 9.

Use the dateadd function (https://www.techonthenet.com/excel/formulas/dateadd.php):
DateAdd( interval, number, date )
or
DateAdd("m", 5, "22/11/2003")

Try
Sub Test_Date()
Dim d As Date
d = "22-09-2017"
d = DateSerial(Year(d), Month(d) - 1, 21)
End Sub

Related

Excel VBA not reading Date data the way I want

I have a program that is supposed to read the date from a cell. In that cell, I have given it the value of =NOW() just by typing it into the cell outside of VBA. The cell is formatted as a date and the format is: dd-month (for example; 28-Jan). When VBA reads the cell, it reads it as mm/dd/yyy 00:00:00 AM/PM. Is there a way to make my code read the month from the format I set? A section of my code is below:
dashpos = InStr(1, ThisWorkbook.Worksheets("Main").Cells(2, 15), "-")
curmonth = Right(ThisWorkbook.Worksheets("Main").Cells(2, 15).Value, dashpos + 1)
The cell containing the date is Cell(2,15). I then go on to use the three letters on the month to determine the following month using a Select Case curmonth.
If your format is mm/dd/yyy 00:00:00 AM/PM in the worksheet, then the month will always have two digits. Therefor:
curmonth = CLng(Left(ThisWorkbook.Worksheets("Main").Cells(2, 15).Text, 2))
Sub testDateExtraction()
'Next day in the format you use in the sheet (no matter, in fact...):
Debug.Print Format(ThisWorkbook.Worksheets("Main").Cells(2, 15).Value + 1, "dd-mmm")
'Next month
Debug.Print MonthName(Month(ThisWorkbook.Worksheets("Main").Cells(2, 15).Value) + 1, True)
'If you insists to use the string type data:
Dim strDate As String, strMonth As String
strDate = CStr(Format(ThisWorkbook.Worksheets("Main").Cells(2, 15).Value + 1, "dd-mmm"))
strMonth = Right(strDate, 3)
Debug.Print MonthName(Month(DateValue(Day(Date) & "-" & strMonth & "-2020")) + 1, True)
End Sub
I then go on to use the three letters on the month to determine the following month
If you want to determine the next month, you can just use DateAdd and Month. The cell format is irrelevant.
The following returns the month number:
Month(DateAdd("m", 1, Cells(2,15)))
If you want it as a three letter string, for some reason, then
Format(DateAdd("m", 1, Cells(2,15)), "mmm")

VBA Date Format For Variable

I need to turn content in a spreadsheet column from text to a date.
The cell format is text and the inputters were instructed to input a date as "ddmmyyyy".
Accidents happened and I found some content that would not parse as a date, including entries like "Unknown".
So I used a variable declared as a date and wrote an error handler to deal with content that would not parse.
Now for the bit I cannot work out.
If the date was 3rd March 2000 and someone input that as "03332000" that will not parse because "33" cannot be a month or a day; it is caught by the error handler as I wanted.
But if it was input as "03132000" I can't think of a way of preventing VBA converting that to a valid date as "13/03/2000".
Declaring a format for the date variable will not prevent VBA parsing the date.
I can write something that tests number range of the day and month part of the string but that is extra lines of code and I was hoping to do it just by the error handler.
I'd approach it a little differently and let Excel do the work.
Public Function ValidateDate(ByVal strDate As String) As Boolean
Dim intDay As Integer, intMonth As Integer, intYear As Integer, dtDate As Date
ValidateDate = True
On Error GoTo IsInValid
If Len(strDate) <> 8 Then GoTo IsInValid
If Not IsNumeric(strDate) Then GoTo IsInValid
intDay = Left(strDate, 2)
intMonth = Mid(strDate, 3, 2)
intYear = Right(strDate, 4)
dtDate = DateSerial(intYear, intMonth, intDay)
If DatePart("d", dtDate) <> intDay Then GoTo IsInValid
If DatePart("m", dtDate) <> intMonth Then GoTo IsInValid
If DatePart("yyyy", dtDate) <> intYear Then GoTo IsInValid
Exit Function
IsInValid:
ValidateDate = False
End Function
... this will ensure that anything related to leap years etc. will still work correctly and it will ensure that all entries are validated correctly.
If you place:
03332000
in cell A1 and run:
Sub CheckDate()
Dim s As String, d As Date
s = Range("A1").Text
d = DateSerial(CInt(Right(s, 4)), CInt(Mid(s, 3, 2)), CInt(Left(s, 2)))
MsgBox s & vbCrLf & d
End Sub
You will get:
So even though a valid month can only be in the range [1-12], Excel is trying to "help" you by interpreting the 33 as a projection of future date. For example, if the month was entered as 13, Excel will treat it as December of the following year!
You can't rely on error-handling for this. You need checks like:
Sub CheckDate2()
Dim s As String, d As Date
Dim dd As Integer, mm As Integer, yr As Integer
s = Range("A1").Text
yr = CInt(Right(s, 4))
mm = CInt(Mid(s, 3, 2))
dd = CInt(Left(s, 2))
If yr = 0 Or yr < 1900 Then
MsgBox "year is bad"
Exit Sub
End If
If dd = o Or dd > 31 Then
MsgBox "day is bad"
Exit Sub
End If
If mm = 0 Or mm > 12 Then
MsgBox "month is bad"
Exit Sub
End If
d = DateSerial(yr, mm, dd)
MsgBox s & vbCrLf & d
End Sub
You can also do other checks like looking at the length of the field, etc.

How do I validate a YYYYMMDD string is a date in Excel VBA?

The date is supplied as a string in the form: 20180503
The function is supposed to validate that the entry is:
in the form YYYYMMDD
a valid date
The following code does not do the trick:
Function formatDateYYYYMMDD(dateStr As String, dateFormat As String) As String
Dim strToDate As Date
strToDate = CDate(dateStr)
If IsDate(strToDate) Then
formatDateYYYYMMDD= format(dateStr, dateFormat)
Else
formatDateYYYYMMDD= "Not a date"
End If
End Function
Perhaps:
edit: original UDF changed as it would not flag certain invalid format dates.
Option Explicit
Function formatDateYYYYMMDD(dateStr As String, dateformat As String) As String
Dim strToDate As Date
On Error GoTo invalidDate
If Len(dateStr) = 8 And _
Left(dateStr, 4) > 1900 And _
Mid(dateStr, 5, 2) <= 12 And _
Right(dateStr, 2) <= 31 Then
formatDateYYYYMMDD = Format(CDate(Format(dateStr, "0000-00-00")), dateformat)
Exit Function
End If
invalidDate: formatDateYYYYMMDD = "Not a date"
End Function
The On Error will pick up invalid dates that otherwise meet the format criteria: eg Sep 31, Feb 30
Interesting idea for a function. I've rewritten your code below to do exactly what you said. Function returns "Not a date" for 2018101a, 20181033, 201810300, otherwise returns date in formatted string. Note that you need to provide a valid string format and I did not handle that error. I assume there are no spaces at the end?
Function formatDateYYYYMMDD(dateStr As String, dateFormat As String) As String
Dim strToDate As Date
Dim day As Integer
Dim month As Integer
Dim year As Integer
On Error Resume Next
year = Left(dateStr, 4)
month = Mid(dateStr, 5, 2)
day = Right(dateStr, 2)
strToDate = DateSerial(year, month, day)
If Err.Number <> 0 Or Len(dateStr) <> 6 Then
formatDateYYYYMMDD = "Not a date"
Err.Clear
On Error GoTo 0
Else
On Error GoTo 0
formatDateYYYYMMDD = Format(strToDate, dateFormat)
End If
End Function
I fiddled with the code getting some directions from the guy's suggestion and it works now. Thanks, guys for all your input.
This is what I did
sValue = frmForm.txtSearch.Value
If IsDate(sValue) Then
'do nothing
Else
sValue = Format(frmForm.txtSearch.Value, "DD-MM-YYYY")
End If
If the input date is always in this format(YYYYMMDD), you can write a custom code to convert it into a string that can be converted to date using CDATE.
Remember to convert month to name of the month, and year to four digit year. In this way you are explicitly defining the month, year and the remaining one as date, if you keep them as two digit numbers they may be interpreted differently on difference systems (when you convert them using CDATE)
I recommend this format DD-MMM-YYYY
In your code instead of
strToDate = CDate(dateStr)
You have to write a custom function
And in place of
formatDateYYYYMMDD= format(dateStr, dateFormat)
Return just the dateStr and set the format of the cell where it is returned to YYYYMMDD

Get the month and year from today's date

I am trying to get the month and year for today's date.
Sub automation()
Dim wsheet As Worksheet
Dim month As Integer
Dim year As Integer
Set wsheet = Application.Workbooks("try").Worksheets("try")
month = Application.WorksheetFunction.month(Date)
year = Application.WorksheetFunction.year(Date)
End Sub
My expected output is 5 for month and 2017 for year if today's date is 15/5/2017.
You may have some problem because you've shadowed some existing functions Month and Year with your variable names month and year. So, use different variable names:
Dim m As Integer
Dim y As Integer
And then either:
m = DatePart("m", Date)
y = DatePart("yyyy", Date)
Or:
m = month(Date)
y = year(Date)
In my Excel 2010 (not tested in 2013) while Month is a worksheet function, it's not exposed to VBA for some reason. If you want to use the WorksheetFunction instance of these, you can technically do it using the Application.Evaluate method, like so:
m = Evaluate("MONTH(""" & Date & """)")
y = Evaluate("YEAR(""" & Date & """)")
The built-in VBA.DateTime.Month and VBA.DateTime.Year functions, however, are available and that is what would be used in the second example above.
If you must for some reason retain the month and year variable names, then you need to fully qualify the function call to avoid error:
month = VBA.DateTime.Month(Date)
year = VBA.DateTime.Year(Date)
Change in your code like this:
Sub CurrentDate()
Dim currentMonth As Long
Dim currentYear As Long
currentMonth = Month(Date)
currentYear = Year(Date)
Debug.Print currentMonth; currentYear
End Sub
Month and Year are functions of the VBA.DateTime, do not use them for variable names.
In general, Application.WorksheetFunction does not have a function, related to current date, in contrast to VBA.DateTime.Month or VBA.DateTime.Year (or at least I did not find) any in the Excel Library.
dim this as date
this = Format(Date(), "yyyy")
this = Format(Date(), "mm")
Answering late but I wanted to reference the VBA documentation from microsoft's own page.
To get Month from date:
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/month-function
Sample snippet:
Dim MyDate, MyMonth
MyDate = #February 12, 1969# ' Assign a date.
MyMonth = Month(MyDate) ' MyMonth contains 2.
To get Year from date:
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/year-function
Sample snippet:
Dim MyDate, MyYear
MyDate = #February 12, 1969# ' Assign a date.
MyYear = Year(MyDate) ' MyYear contains 1969.
I like these answers, but I needed one that would contain both the month and year in the format (my use case is as an accountant). This was my solution:
Dim today As Date
today = Date ' Get the current date
Dim period As String
period = Format(today, "MM/YYYY") ' Convert the date to MM/YYYY

Excel VBA - compare date in cell to current date

(Excel 2010 VBA)
I have a cell (A1) containing a date in the format of mmm-yy ("Custom" category).
Foe example, if I enter 1/6/13 the cell shows June-13. That's fine.
In my VB macro I need to check this date whether the month is the current month and whether the year is the current year. I don't care about the day.
Does this help you:
Public Sub test()
d = Sheet1.Range("A1")
n = Now()
If Year(d) = Year(n) And Month(d) = Month(n) Then
MsgBox "It works"
End If
End Sub
Thanks to Dave and MiVoth I did :
Dim xdate As Date
xdate = Worksheets("sheet1").Range("A1")
If Month(Date) = Month(xdate) And Year(Date) = Year(xdate) Then
MsgBox "OK"
Else
MsgBox "not OK"
End If
That did the job!
Thank a lot to everyone,
Gadi
How about this:
Function MonthYear() As Boolean
MonthYear = False
If Not IsDate(Cells(1, 1)) Then Exit Function
If Month(Date) = Month(Cells(1, 1)) And Year(Date) = Year(Cells(1, 1)) Then
MonthYear = True
End If
End Function
The function returns true if month and year are the same as current date. If not it returns false.

Resources