I have the date and time in the following format:
7/12/2012 3:41
I want to keep only the date from this. I have tried to write a function to do this, but excel will only recognise this as a string so I am having difficulty editing the entry. If some one could help me with a function or direction to spilt off only the date portion of this it would be greatly appreciated.
My intended application is something along the lines of
Public Function Change(X As Variant)
'
If X > Application.WorksheetFunction.Now() Then
Change = 1
End If
'
End Function
Depends whether you are looking for a Date or a String as the output. Here's how to do both.
Dim strDateTime As String
Dim strDate As String
Dim s() As String
Dim pureDate As Date
strDateTime = "7/12/2012 3:41"
strDate = Split(strDateTime, " ")(0) ' "7/12/2012"
pureDate = CDate(strDate) ' 7 Dec 2012 (in my locale)
' ... results may be ambiguous depending on your locale
'Another way to get a Date, not blindly using CDate:
s = Split(strDate, "/")
' if date in day/month/year format:
pureDate = DateSerial(CInt(s(2)), CInt(s(1)), CInt(s(0))) ' 7 Dec 2012
' or, if date in month/day/year format:
pureDate = DateSerial(CInt(s(2)), CInt(s(0)), CInt(s(1))) ' 12 July 2012
Use the Format function like this:
Public Function Change(DateExp) As Date
'Format function lets you transform most data in your desired format.
'CDate handles any Date Expression conversion to Date data type.
'CStr handles any expression conversion to String data type
If IsMissing(ReturnType) Then
'Return as Date, default when ReturnType is not supplied
Change = Format(CDate(DateExp), "m/d/yyyy")
Else
If ReturnType = True Then
'Return as Date
Change = Format(CDate(DateExp), "m/d/yyyy")
ElseIf ReturnType = False Then
Change = Format(CDate(DateExp), "m/d/yyyy")
'Return as String
Change = CStr(Change)
Else
'Error out any values other than TRUE or FALSE
Change = CVErr(xlErrValue)
End If
End If
End Function
But if you are really interested with returning just the date, use Today() Function instead of Now() (for WS).
Equivalent functionality in VBA is Date Function which return your systems current date.
Same
Related
I am trying to convert the date format of my cells as the csv format they are delivered in shows a date but excel doesn't recognize it as a date (it shows "Standard" as format and the dates are aligned on the left, hence not dates in excel).
Dim lr11 As Integer
Dim dates11 As Date
lr11 = WS1.Cells(WS1.Rows.Count, "C").End(xlUp).row
For dates11 = 2 To lr11
WS1.Cells(dates11, 3).Value = CDate(Cells(dates11, 3).Value)
Next dates11
The above code sometimes works in a Test Sub() but when used in my main Sub, I always get "12:00:00 AM" in all cells instead of dates.
What am I doing wrong?
Thanks!
If you have strings that look like dates in the format DD.MM.YYYY you can split them and create a numeric date using DateSerial like below:
Option Explicit
Public Function ConvertStringDDMMYYYYtoDate(ByVal InputString As String) As Date
Dim RetVal As Date
Dim Parts() As String
Parts = Split(InputString, ".")
If UBound(Parts) = 2 Then
RetVal = DateSerial(Parts(2), Parts(1), Parts(0))
If Not Format$(RetVal, "DD.MM.YYYY") = InputString Then
MsgBox "Input String is not a real date", vbCritical
RetVal = 0
End If
End If
ConvertStringDDMMYYYYtoDate = RetVal
End Function
Then use it like
For dates11 = 2 To lr11
WS1.Cells(dates11, 3).Value = ConvertStringDDMMYYYYtoDate(WS1.Cells(dates11, 3).Value)
WS1.Cells(dates11, 3).NumberFormat = "DD.MM.YYYY" ' format it however you like it to look like
Next dates11
I am iterating through dates in a loop to execute different snippets of code.The following piece of code in the loop gives me a
runtime error '6' Overflow
when assigning the cell's value to dateClaim:
Dim dateClaim As Date
Dim rngDateClaimeMade As Range
Set rngDateClaimeMade = dfensCSheet.Range("AC7") 'AC contains dates in format dd.mm.yyyy
dateClaim = rngDateClaimeMade.value
dateClaimMonth = Format(Month(dateClaim), "00")
dateClaimYear = Year(dateClaim)
Any ideas/ help is very much appreciated!
So that looks like 24.12.2020 is a text not a date in that cell and therefore it cannot be converted automatically.
If your dates are always in this format dd.mm.yyyy you can convert it like below:
Option Explicit
Public Sub Example()
Dim TextDate As String ' this is a text looking like a date (but is not a date just a string)
TextDate = "24.12.2020" ' instead read your cell value here
' test if the string has a format that we can convert
If Not TextDate Like "??.??.????" Then
MsgBox "Date was not in expected format dd.mm.yyyy"
Exit Sub
End If
' split text into 3 parts by dot as delimiter
Dim SplitDate() As String
SplitDate = Split(TextDate, ".")
' reorder the 3 parts to make a real numeric date
Dim NumericDate As Date
NumericDate = DateSerial(SplitDate(2), SplitDate(1), SplitDate(0))
' this numeric date is now a real date that can be formatted as desired
Debug.Print Format$(NumericDate, "yyyy-mm-dd") 'returns 2020-12-24
End Sub
You can then use
Dim dateClaim As Date
dateClaim = DateSerial(SplitDate(2), SplitDate(1), SplitDate(0))
Dim dateClaimMonth As String
dateClaimMonth = Format$(dateClaim , "mm")
Dim dateClaimYear As String
dateClaimYear = Format$(dateClaim , "yyyy")
if you need month and year as text! If you need them numeric don't use Format$()!
VBA cannot convert text dates with dots directly. So try:
dateClaim = DateValue(Replace(rngDateClaimeMade.Value, ".", "/"))
dateClaimMonth = Month(dateClaim)
dateClaimYear = Year(dateClaim)
Apply the format 00 where the month is to be displayed.
I am processing a .txt file in VBA.
Amongst other tasks, I need to read in a string representing a date and display the actual date in Excel.
A date string in the .txt file looks like "190223"
This represents 23/02/2019
My challenge is to get this done.
What I have done so far is:
' ... loop
With ActiveWorkbook.Worksheets(1)
' Other statements here
' Event date time
.Range("N" & i).Value = StrReverse(Mid(.Range(keyword.Offset(0, 4).Address), 1, 2) & _
"/" & Mid(.Range(keyword.Offset(0, 4).Address), 3, 2) & _
"/" & Mid(.Range(keyword.Offset(0, 4).Address), 5, 2))
End With
But I get the undesired output:
32/20/91 ' For a date string 190223 the desired output should be 23/02/19
Any help would be much appreciated.
Thanks in advance.
Convert it into a real date
You must extract year, month and day of that string and then convert this into a real date.
Then you can format the date to what ever date format you like. The value that is saved in the cell is then a real date value (not a string!) so you can calculate with it.
I highly recommend to read How Dates Work in Excel – The Calendar System Explained + Video to understand the background and why real dates are so important.
Here is an example:
Option Explicit
Public Sub ConvertDateExample()
Const InputStr As String = "190223"
Dim InputYear As Integer
Dim InputMonth As Integer
Dim InputDay As Integer
'extract year, month and day
InputYear = Left(InputStr, 2)
InputMonth = Mid(InputStr, 3, 2)
InputDay = Right(InputStr, 2)
'put it together to a real date
Dim RealDate As Date
RealDate = DateSerial(InputYear, InputMonth, InputDay)
'write the date into a cell
Range("A1").Value = RealDate
'format that cell to your desired format
Range("A1").NumberFormat = "dd/mm/yyyy"
End Sub
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
Windows 10 Pro, Regional Settings to UK English.
In Excel VBA I have a string "02/05/2017 16:30"
That, in the UK, means "02 May 2017 16:30"
But VBA turns this to US format somehow and in the cell puts "05/02/2017 16:30"
The VBA code is like this
Dim sField As String
sField = "02/05/2017 16:30"
ws.Cells(1,1) = sField
I can use CDate to get around this but CDate but that requires extra code to determine which cells are dates and which aren't, whereas the implicit conversion works for all types.
Use a Date variable instead, and always provide your date in MDY in VBA.
Dim sField As Date
sField = #05/02/2017 16:30#
ws.Cells(1,1) = sField
AFAIK in VBA you must always work the 'American way', with dates MDY. It does NOT follow regional settings. Which is good, because that enables running the same code on heterogeneous environments.
This is some workaround in the VBA code:
Sub Main()
Dim myInput As String
Dim splitMe As Variant
Dim outputDate As Date
myInput = "02/05/2017 16:30"
splitMe = Split(myInput, "/")
outputDate = DateSerial(Left(splitMe(2), 4), splitMe(1), splitMe(0))
Debug.Print Format(outputDate, "DD-MMM-YY")
Debug.Print Format(outputDate, "DD-MM-YYYY")
End Sub
It takes the date as a string and it splits it by /. Then it takes the year, the month and the day and it builds a new date with the help of DateSerial(). DateSerial MSDN.
In cases like this, make sure that you are passing the correct date to excel and there you may change the format through something as easy as this:
Range("A1").NumberFormat = "m/d/yyyy"
To make sure, that you are passing the correct date, simply try Month(YourDate) over the date or Day(YourDate).
I rather use the built-in VBA functions DateSerial(year, month, day) and TimeSerial(hour, min, sec).
Dim myDateTime as date
mydateTime = DateSerial(2017, 5, 2) + TimeSerial(16, 30, 0)
ws.Cells(1,1) = myDateTime
You can then set the number formatting on the Excel cell to your liking.
I assume this is faster because there is not need to translate any string beforehand. More importantly for me as a programmer, the parameters are explicit. I don't have to worry about different regional setting.
I solved a related problem. My workbook is for use only in the UK. It has a sheet for entering details of cash collected at various venues. The user has two single-cell fields to identify each venue; typically a location and a date, but sometimes the "date" field will contain an extended location name instead.
Dates should be entered as dd/mm/yy, but almost anything recognisable is accepted except mm/dd/yy.
The details are stored in memory, then later copied to formatted worksheets for printing. I verified the storage in memory. But after the workbook had been in use for a few months, I found that if the user entered a valid date in a cell in the format dd/mm/[yy]yy (e.g. 05/11/17), and its interpretation as mm/dd/[yy]yy would also give a valid date, then the date would obscurely be printed as 11-Mar instead of 05-Nov.
Some code snippets:
'Data structure:
Public Type BkItem 'An item of income, for banking.
ItemName As String 'The first field, just a text name.
ItemDate As Date 'The second field, interpreted as a date.
ItemDateNumber As Long 'The date as internally stored as an integer.
ItemDateString As String 'Re-formatted string, e.g. "05-Nov-17".
' ...
End Type 'BkItem.
'Input validation:
BankData = Range(.Cells(BankFirstRow, BankFirstCol), _
.Cells(BankLastItemLastRow, BankLastCol))
With BankItem(BankTotalItems)
.ItemName = IName
.ItemDateString = BankData(<row>, <col>)
.ItemDateNumber = DateToLong(.ItemDateString)
End With
'Utility routine. "Paper" is a 2-dimensional array of all the data to be printed
'on one or more pages; "Dest" is a global range.:
Sub OutputDataToSheet(ByVal Size As Long, ByRef CurrentSheet As String, _
ByRef Paper() As Variant)
Worksheets(CurrentSheet).Activate
Set Dest = Worksheets(CurrentSheet).Range((Cells(1, 1)), _
(Cells(Size, LastCol)))
Dest.Value = Paper 'Copy data to final sheet for printing.
End Sub 'OutputDataToSheet.
'As we build the array "Paper", it helps to format those cells on the final
'printout worksheet which are going to contain dates.
.Range(Cells(CurRow, L15c01), Cells(CurRow, L15c01)).NumberFormat = "dd-Mmm-yyyy"
'For the item date.
.Range(Cells(CurRow, L15c01), Cells(CurRow, L15c01)).HorizontalAlignment = xlCenter
If IsDate(BankItem(item).ItemDateString) Then
Paper(<row>, <col>) = BankItem(item).ItemDateNumber
'Date as a number, so OutputDataToSheet preserves UK date format.
Else
Paper(<row>, <col>) = BankItem(item).ItemDateString
'Extension of name.
End If 'IsDate(.ItemDateString).