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,
Related
I have some issue with my VBA code. I got Date variable that stored as dd/mm/yyyy but when I write the date to a specific cell the format change to mm/dd/yyyy, I have been trying many options but none of them worked for me, I also check that the variable know what is the current day, month and year.
The code:
Sheets("report_orders").Select
Range("A1").Value = customerName
Range("A2").Value = "äæîðä " & orderID
Range("A3").Value = "äæîðä ì÷åç " & orderPo
'Range("B2").Value = orderDate
Range("B2").Value = Day(orderDate) & "/" & Month(orderDate) & "/" & Year(orderDate)
Debug.Print "year " & Year(orderDate)
Debug.Print "month " & Month(orderDate)
Debug.Print "day " & Day(orderDate)
but the result is :
When you put a date into a cell, you can format it using .NumberFormat. Ensure that you format the cell before entering the value. For example
Range("B2").NumberFormat = "mm/dd/yyyy"
Range("B2").Value = orderDate
You can read more about the .NumberFormat in Range.NumberFormat property (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
I can't get the current month.
It seems very simple to get the current year and day, as tested with the following:
MsgBox Year(Date)
MsgBox Day(Date)
MsgBox Year(Now)
MsgBox Day(Now)
How is it possible to show the current month as either a number (1, 2 etc.) or a full name?
I could use TODAY() in a cell and convert that in VBA with something like CurrentMonth = MonthName(Month(Sheet1.Range("A1"))) but I would like to do this directly in VBA for Excel.
Try,
debug.print Format(Date, "mmm") 'Mar
debug.print Format(Date, "mmmm") 'March
debug.print Format(Date, "m") '3
debug.print Format(Date, "mm") '03
Month(Now)
Returns the index number associated with the current month.
Jeeped's code below is the most compact, but to give you an idea of how indexes work, the following code will return the month name based on the index returned:
Dim months(11) As String
months(0) = "Jan"
months(1) = "Feb"
months(2) = "Mar"
months(3) = "Apr"
months(4) = "May"
months(5) = "Jun"
months(6) = "Jul"
months(7) = "Aug"
months(8) = "Sep"
months(9) = "Oct"
months(10) = "Nov"
months(11) = "Dec"
Dim nowMonth As Integer
nowMonth = Month(Now)
For i = 0 To 11
If nowMonth = (i + 1) Then
MsgBox (months(i))
End If
Next
Found an easier solution to get the current Month Name
Just use MonthName(Month(Now)) and assign it to a string.
Month(Now) gives you the month number and MonthName() uses that number to display the current month
A really helpful and simple way is to combine the format function together with date.
Examples (assuming today is Oct 23, 2019):
To get current month as a number as in original question:
MsgBox Format(Date, "mm")
^ Will return: 10
To get current month as short text:
MsgBox Format(Date, "mmm")
^ Will return: Oct
To get current month with full text:
MsgBox Format(Date, "mmmm")
^ Will return: October
You can combine these with days and years as well.
Additional examples:
MsgBox Format(Date, "dd-mmm-yyyy")
^ Will return 23-Oct-2019
MsgBox Format(Date, "dddd-mmmm-dd-yyyy")
^ Will return: Wednesday-October-23-2019
This is creating a custom format, so you can rearrange the dd, mm, yyyy areas as you see fit, such as:
MsgBox Format(Date, "yyyy/mm/dd")
^ Will return: 2019/23/10
Here is the best way I have found to do it:
Sub getMonth()
'MsgBox DatePart("m", Date)
'MsgBox Evaluate("MONTH(""" & Date & """)")
'MsgBox VBA.DateTime.Month(Date)
MsgBox Format(Date, "mmmm")
End Sub
Below is how I found the previous month based on the current month name, the assignment to monthNum is the piece needed to solve your question.
month = "February"
'****'
monthNum = Application.Evaluate("=MONTH(1&" & Chr(34) & month & Chr(34) & ")") 'Returns month #
'****'
If monthNum = 1 Then
monthNum = 12
Else
monthNum = monthNum - 1
End If
month = MonthName(monthNum) 'Returns January
I am using DateTime.Now in my Excel Macro to show the current timestamp.
It shows timestamp in "dd-MM-yyyy hh:mm:ss" format.
Instead, how can I get the timestamp in "yyyy-MM-dd hh:mm:ss" format?
Try with: format(now(), "yyyy-MM-dd hh:mm:ss")
DateTime.Now returns a value of data type Date. Date variables display dates according to the short date format and time format set on your computer.
They may be formatted as a string for display in any valid date format by the Format function as mentioned in aother answers
Format(DateTime.Now, "yyyy-MM-dd hh:mm:ss")
Format(Now(), "yyyy-MM-dd hh:mm:ss")
If some users of the code have different language settings format might not work. Thus I use the following code that gives the time stamp in format "yyymmdd hhMMss" regardless of language.
Function TimeStamp()
Dim iNow
Dim d(1 To 6)
Dim i As Integer
iNow = Now
d(1) = Year(iNow)
d(2) = Month(iNow)
d(3) = Day(iNow)
d(4) = Hour(iNow)
d(5) = Minute(iNow)
d(6) = Second(iNow)
For i = 1 To 6
If d(i) < 10 Then TimeStamp = TimeStamp & "0"
TimeStamp = TimeStamp & d(i)
If i = 3 Then TimeStamp = TimeStamp & " "
Next i
End Function
this worked best for me:
Cells(partcount + 5, "N").Value = Date + Time
Cells(partcount + 5, "N").NumberFormat = "mm/dd/yy hh:mm:ss AM/PM"
Copy and paste this format yyyy-mm-dd hh:MM:ss in format cells by clicking customs category under Type
Timestamp in saving workbook path, the ":" needs to be changed. I used ":" -> "." which implies that I need to add the extension back "xlsx".
wb(x).SaveAs ThisWorkbook.Path & "\" & unique(x) & " - " & Format(Now(), "mm-dd-yy, hh.mm.ss") & ".xlsx"
It can work as easy as this, choose the location you want, in this case I choose D3
Sheets("Put your Sheet's name here").Range("D3") = Now
Example, my sheet is called Sources
Sheets("Sources").Range("D3") = Now
Use the Format function.
Format(Date, "yyyy-mm-dd hh:MM:ss")
this code does not seem to work well always when copying currency data from another sheet:
Dim myprice As String
myprice = othersheet.Range("H" & c.Row).Value
ws.Range("C" & r).Value = myprice
ws.Range("C" & r).Style = "Currency"
sometimes cells have a warning that "this number is formatted as text"
Excel's "Number Stored as Text" issue can be a bit vexing.
The Help recommendation is to perform a conversion operation by multiplying the value by 1. In practice, however, you're probably better off checking that myprice is numeric and then proceeding accordingly.
For instance:
Dim myprice As String
myprice = othersheet.Range("H" & c.Row).Value
If IsNumeric(myprice) Then
myprice = CCur(myprice)
Else
'Catch non-numeric accordingly
myprice = "Couldn't convert to number"
End If
ws.Range("C" & r).Value = myprice
ws.Range("C" & r).Style = "Currency"
HTH
Try declaring myprice as a Currency.
Have you tried using NumberFormat of the cell
ws.Range("C" & r).NumberFormat = "$#,##0.00"
This is working for me:
For Each myprice In __your target range here__
myprice.Value = CDec(myprice.Value)
myprice.NumberFormat = "0.00" 'or whatever format you wish
Next myprice
This code worked for me, to convert cells depending on their contents. It ran fairly quickly for a worksheet with >800,000 cells containing numbers stored as text, with 32-bit Excel 2013 running on a Windows 8.1 machine. It did the job in less than 2 minutes.
For Each aCell In ThisWorkbook.Sheets("Working data").UsedRange.Cells
If aCell.Errors.Item(xlNumberAsText).Value Then
aCell.Formula = aCell.Text
End If
Next aCell