Verify date format in textbox entry - excel

I wish to provide a textbox in excel vba to enter the date. Permissible date formats are d-m-yy or yyyy, dd-mm-yy or yyyy, d/m/yy or yyyy, dd/mm/yy or yyyy. But the output format should be dd-mm-yyyy. I just don't know where to start. I know how to write the data to the required except worksheet but no idea about this code.Please guide
If IsDate(Me.TextBox2.Value) = False Then.
MsgBox "Enter a valid date format." & vbNewLine _
& "Valid Date Formats are:" & vbNewLine & vbNewLine _
& "D/M/YY" & vbNewLine _
& "DD/MM/YYYY" & vbNewLine _ & "D-M-YY" & vbNewLine _
& "DD-MM-YYYY", vbExclamation, "Date Format ERROR"
TextBox2.Activate
Exit Sub
End If
'This works perfect
Worksheets("PURCHASE").Range("B" & newrow) = CDate(TextBox2.Text)
Worksheets("PURCHASE").Range("B" & newrow).NumberFormat = "dd-mm-yyyy"

There is a VBA Range.IsDate function that attempts to resolve a valid date as true and an invalid date as false.
In Windows, the range of valid dates is January 1, 100 A.D., through December 31, 9999 A.D.; the ranges vary among operating systems.
That doesn't explain the Excel 1900 date system but it does explain the Excel 1904 date system. Blame Lotus 1-2-3 for the inequality.
Whatever algorithm is used in IsDate, I can say that I've had marginally more success when using it than a CDate conversion over a wide variety of system locales both on the source and target end.
Ultimately I've found the SQL standard YYYYMMDD an efficient storage and delivery method as well as raw long integers. The latter would simply require cell formatting in Excel to show a real human being that the value is a date.
If your code accepts the string date input as verified by CDate or IsDate then you may be transferring a string date into your cell. Dates are numeric and may need to be formatted in order for a human being to see them as dates and not a number like 43453.
Worksheets("PURCHASE").Range("B" & newrow) = cdate(TextBox2.Text)
Worksheets("PURCHASE").Range("B" & newrow).numberformat = "dd/mm/yyyy"

An option would be to, after the user entered a string into the textbox, to check whether it is possible to format the date. If not, a nonsense-date has been added and the user can be notified of the issue
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Dim nwdate As String
If Len(TextBox1.Value) < 6 Then GoTo falsedate
nwdate = Format(TextBox1.Value, "dd-mm-yyyy")
If nwdate = TextBox1.Value And Format(nwdate, "dd-mmmm-yyyy") = nwdate Then
GoTo falsedate
Else
TextBox1.Value = nwdate
End If
Exit Sub
falsedate:
MsgBox "Enter a valid date before proceeding", vbExclamation, "Error"
TextBox1.Value = ""
End Sub

Related

Day(Now) displaying January, 1900?

For whatever reason, everytime I try to use the Day(Now) function in VBA, it keeps displaying "1/9/1900". The Date function displays correctly, so I'm not sure what the issue here is.
Sub Test()
Dim datDay As Date
datDay = Day(Now)
MsgBox datDay
End Sub
Here's an image of the error.
The Day will be an integer somewhere between 1 and 31, depending on, well, the "day" part of the date returned by the DateTime.Now function.
The way dates are stored, they're essentially Double values, with the integer part being a number of days, and the decimal part being the time of day.
Debug.Print Format(CDate(0), "yyyy-mm-dd")
Output: 1899-12-30
We are June 10th, so the date value of 10 corresponds to January 9, 1900.
You want to store the value returned by Day, Month, and Year functions, into Long integer variables; not Date.
Dim datDay As Long
datDay = DateTime.Day(DateTime.Date) ' datDay is 10 because DateTime.Date is 2019-06-10.
Note: while unqualified Day, Date, Month, and Year (and others) functions work perfectly fine, it's probably a good idea to qualify them with the module they are declared in (VBA.DateTime), to avoid potentially confusing ambiguities, e.g. Date is both the name of a property of the DateTime module, and it's also a data type (Dim foo As Date), and the two have very different meanings.
Try:
Option Explicit
Sub Test()
Dim datDay As Date
datDay = Date
MsgBox "Whole date: " & datDay & vbNewLine & _
"Month: " & Month(Date) & " (" & Format(Date, "mmmm") & ")" & vbNewLine & _
"Day: " & Day(Date) & " (" & Format(Date, "dddd") & ")"
End Sub
Result:
Replace
datDay = Day(Now)
with
datDay = Day(Now())
Not sure if this will fix the problem, but =Day(Now()) works correctly when typed directly into a cell.
Your problem is datDay is typed as a Date. =Day(Now()) returns just 10, as today is June 10th. As a full Date value, this is 1/10/1900, since Excel indexes day 0 as 1/0/1900.

Converting from dd.mm.yyyy to dd/mm/yyyy

I am currently using Excel 2010 and I have a column that contains date in such format (dd.mm.yyyy). I would like to change the dots to slash (/). I have tried using rng.Cells(1, 6) = WorksheetFunction.Substitute(rng.Cells(1, 6), ". ", "/")
However, when I do that, the result I get is different from my original date. For example, 02.11.2011 will become 11/02/2011.
The column that contains (dd.mm.yyyy) is in a date format
May I know why is that or is there another way of doing?
Is the column formatted as a date? If so, you can try
rng.Cells(1, 6) = Format(CDate(rng.Cells(1, 6)), "dd/MM/yyyy")
If it's an actual date value, then use NumberFormat
Range("B1").NumberFormat = "d/m/yyyy"
Range("B2").NumberFormat = "m/d/yyyy"
Range("B3").NumberFormat = "m-d-yyyy"
Im using this
splR = Split(oRange.Value, ".")
If UBound(splR) = 2 Then oRange.Value = Format(DateSerial(splR(2), splR(1), splR(0)), RegionalDateFormat) Else oRange.Value = oRange.Value
Function RegionalDateFormat(Optional outS As String)
Dim DateOrder As String
Dim DateSeparator As String
With Application
DateSeparator = .International(xlDateSeparator)
Select Case .International(xlDateOrder)
Case Is = 0
DateOrder = "mm" & DateSeparator & "dd" & DateSeparator & "yyyy"
Case Is = 1
DateOrder = "dd" & DateSeparator & "mm" & DateSeparator & "yyyy"
Case Is = 2
DateOrder = "yyyy" & DateSeparator & "mm" & DateSeparator & "dd"
Case Else
DateOrder = "Error"
End Select
End With
If outS = "Sep" Then outputS = DateSeparator Else outputS = DateOrder
RegionalDateFormat = outputS
End Function
Let's clarify that an Excel spreadsheet does not have a "date" data type per se. Excel's approach to dates is to store an integer, which you can choose to format as a date. So, for example, 43467 is the integer representing Jan 2 2019. (And the decimal part represents time during that day, so 43467.333.. represents Jan 2 2019 8:00 am.)
Try entering a date, then right-click > "Format cells" to format that cell as a number, to observe what I'm talking about.
In the same way, you can cause Excel to render that cell in the date format you want using the same method: select the cell > right-click > "Format cells", choose Custom, and enter a custom format, like dd.mm.yyyy.
Once you see that works, then your remaining task is simply to perform that same action from VBA, which would be with a statement like:
Range("B1").NumberFormat = "dd.mm.yyyy"
... as pointed out by others.
Now, if your initial attempt to get Excel to format your date cell as a number fails (it maintains its date appearance) then the date you see in the cell is actually stored as a string, and won't function as a date (for example to do date arithmetic). So you'll need to decide how to proceed -- perhaps convert these strings to "dates" (ie: numbers formatted as dates).

Excel VBA - remove weekends from automatic timesheet print

I slightly amended some code I found online.
Purpose:
Click on a 'Print with Dates' button, then enter start date, and have Excel automatically generate/print a months worth of timesheets (much better than the previous spreadsheet having 6 weeks of pages to print, and you had to edit every date manually).
Issues:
It prints weekends, which wastes paper. Is there a way it can refer to a list of dates (weekends, public holidays), and not generate those for printing?
You'll see the date format is m/d/yyyy in the code, which strangely prints as dd/mm/yyyy (which is what I wanted). When the code was dd/mm/yyyy it was printing correctly (20/03/2019), but if it goes to the following month it was switching to American format m/d/yyyy (04/20/2019). I know it doesn't seem to make sense, but having it as m/d/yyyy actually prints as dd/mm/yyyy across any start/end dates. I'd like to know why, and also have dd/mm/yyyy in the code correctly printing across any date range.
CODE:
Sub PrintSheet()
Dim s As String
Dim d As Date
s = InputBox(Prompt:="Please enter the start date")
If Not IsDate(s) Then
MsgBox "Incorrect date", vbExclamation
Exit Sub
End If
For d = CDate(s) To DateAdd("m", 1, CDate(s)) - 1
Range("F2").Value = Format(d, "dddd")
Range("I2").Value = "" & Format(d, "m/d/yyyy")
ActiveSheet.PrintOut
Next d
End Sub
Cheers in advance :)
You can use the weekday function. It returns a number from 1 to 7. You can filter for 1-5 only for weekdays.
Sub PrintSheet()
Dim s As String
Dim d As Date
s = InputBox(Prompt:="Please enter the start date")
If Not IsDate(s) Then
MsgBox "Incorrect date", vbExclamation
Exit Sub
End If
For d = CDate(s) To DateAdd("m", 1, CDate(s)) - 1
If Weekday(d, vbMonday) < 6 Then
Range("F2").Value = Format(d, "dddd")
Range("I2").Value = "" & Format(d, "m/d/yyyy")
'MsgBox ("printing ") 'for testing
ActiveSheet.PrintOut
End If
Next d
End Sub

Convert date to a number

I have written a macro which reads the cell content and opens corresponding files as per the cell value.
For example, if I provide 20140522 in a cell, it opens the file "C:\Files\20140522.csv".
However, instead of providing in the above format if I provide it as 22/05/2014 or more generally today's date, how can I convert it into above format in the vba script itself ?. This is because all my files are in the format shown in example only. Following is my macro code
Sub Open()
num=Cells(1,1).Value
ActiveWorkbook.Open(FileName:="C:\Files\" & num & ".csv")
End Sub
You can use Format:
num = Format(Cells(1,1).Value, "yyyymmdd")
Consider:
Sub dural()
Dim d As Date, sDate As String
d = Date
sDate = CStr(Year(d) & Format(Month(d), "00") & Format(Day(d), "00"))
ActiveWorkbook.Open Filename:="C:\Files\" & sDate & ".csv"
End Sub

Excel 2007 VBA CDate method accepted formats

I am developing a change event in VBA for specific cells in Excel 2007.
I want to convert dates (with time) with two different formats entered into these cells into one format (American).
Here is my code which checks if entered dates are in one of the two desired formats. crmdate is the String value of the ActiveCell:
If RegexServiceManager.test(crmdate) Then
outputDate = Format(CDate(crmdate), "MM/dd/yyyy hh:mm")
Application.EnableEvents = False
ActiveCell.Value = outputDate
ActiveCell.NumberFormat = "MM/dd/yyyy hh:mm"
Application.EnableEvents = True
ElseIf RegexSiebel.test(crmdate) Then
outputDate = CDate(crmdate)
Application.EnableEvents = False
ActiveCell.Value = outputDate
ActiveCell.NumberFormat = "MM/dd/yyyy hh:mm"
Application.EnableEvents = True
Else
MsgBox "Inapropriate date and time format"
End If
RegexServiceManager checks if date is in YYYY/MM/DD HH:MM:SS format and this works fine.
RegexSiebel checks if date is int DD-MMM-YYYY HH:MM format and this is where trouble begins.
I get a "Type mismatch" error on outputDate = CDate(crmdate) line. I have removed Format method like the one in the upper "If" to verfify that the error comes from CDate.
Could anyone advise on this? Maybe CDate does not recognize DD-MMM-YYYY (example: 01-Jan-2013) format? If so could anyone propose a workaround?
Target format is MM/DD/YYYY HH:MM.
Thank you & Best Regards,
Maciej
EDIT:
outputDate is of Date format!
I think I found the answer. It is a bit silly but the above code does not work with Polish regional settings. It works fine with American (and probably British too) regional settings.
I also changed the outputDate to Variant type.
I ended up with this:
If RegexServiceManager.test(crmdate) Then
MsgBox "otputDate: " & TypeName(outputDate) & vbCrLf & "crmdate: " & TypeName(crmdate)
outputDate = CDate(crmdate)
MsgBox "otputDate: " & TypeName(outputDate) & vbCrLf & "crmdate: " & TypeName(crmdate)
Application.EnableEvents = False
ActiveCell.Value = outputDate
ActiveCell.NumberFormat = "MM/dd/yyyy hh:mm"
Application.EnableEvents = True
ElseIf RegexSiebel.test(crmdate) Then
MsgBox "otputDate: " & TypeName(outputDate) & vbCrLf & "crmdate: " & TypeName(crmdate)
outputDate = CDate(crmdate)
MsgBox "otputDate: " & TypeName(outputDate) & vbCrLf & "crmdate: " & TypeName(crmdate)
Application.EnableEvents = False
ActiveCell.Value = outputDate
ActiveCell.NumberFormat = "MM/dd/yyyy hh:mm"
Application.EnableEvents = True
Else
MsgBox "Inapropriate date and time format"
End If
The Message Boxes are just for debugging purposes.
It is probably wise to detect regional settings at the beginning of the program, or write it in a better way to avoid this. :)
Hope this helps someone.
Thank you & Best Regards,

Resources