excel vba string to date - string

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).

Related

Convert date to Date Function

I want to convert a date in a cell to the date function so it is a formula. How do I get the date (using VBA), any date, say, 13 Jun 2020 to =DATE(2020, 6, 13) using variables for the year, month, and day. My code I have tried but won't work. The activecell shows 13-Jun-2020 as a date but appears in the function box as 13/06/2020
Sub ConvertDateToDateFunction()
Dim mvDay, mvMth, mvYr As Integer
mvDay = Left(ActiveCell, 2)
mvMth = Mid(ActiveCell, 4, 2)
mvYr = Right(ActiveCell, 4)
ActiveCell.Value = "=DATE(mvYr, mvMth, mvDay)"
End Sub
You have two problems. Here is the solution to the smaller one. The code below would do what you intend. It would convert a text string in the ActiveCell to a function of similar value and insert it in the cell below the ActiveCell.
Sub ConvertDateToDateFunction()
' if you don't say what it's supposed to be it'll be a Variant
Dim mvDay As String, mvMth As String, mvYr As String
mvDay = Left(ActiveCell.Value, 2)
mvMth = Mid(ActiveCell.Value, 4, 2)
mvYr = Right(ActiveCell.Value, 4)
ActiveCell.Offset(1).Formula = "=DATE(" & mvYr & "," & mvMth & "," & mvDay & ")"
End Sub
It's not entirely easy to insert a date as a text string in Excel because Excel will try to recognize a date for a date. Observe that any part of a string is a string, not an integer.
Now about your much bigger problem which is that you don't understand how Excel handles dates. It is such a big problem because you are trying to create a date in Excel in various ways and you run into all sorts of trouble. Read up on the subject here.
To give you a taste of what you will learn: what you see displayed in a cell isn't what the cell contains. There might be a formula in it and you see a number. And there might be a date and you see a string. What you see is determined by the cell's format. I think Chip Pearson's article will cover that topic. If you need to know more, look for "Cell formatting" on the web.
Your macro won't work because the date is a "real date" and not a string.
Try the following to convert the contents of cells containing a real date to a formula which will return the same date:
Option Explicit
Sub dtToFormula()
Dim R As Range, C As Range
Dim vDateParts(2)
Set R = [a1:a10]
'Set R = ActiveCell 'or Selection whatever range you want to convert
For Each C In R
If IsDate(C) And Not C.HasFormula Then
vDateParts(0) = Year(C.Value2)
vDateParts(1) = Month(C.Value2)
vDateParts(2) = Day(C.Value2)
C.Formula = "=DATE(" & Join(vDateParts, ",") & ")"
End If
Next C
End Sub

How to display sub string in reverse order but read from left to right in VBA

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

VBA code to filter sheet by exact date using InputBox

We are trying to get this code working to filter sheet by exact date but still can't figure it out, any ideas what is wrong? Date is formatted in sheet as mm/dd/yyyy
Sub FilterDate()
Dim ap, dt As Date, dt1 As Date, lr&: lr = ActiveSheet.UsedRange.SpecialCells(11).Row
With ActiveSheet.[a1].CurrentRegion.Resize(lr, 10)
ap = Application.InputBox("get date")
dt = CDate(ap)
.AutoFilter 10, "=" & dt
End With
End Sub
File sample
Thank you for pointing out that declaration problem, I did changes in excel tools but code seems to have another issue,any date input leaves only top row...
You are missing to declaring variables!! Using Option Explicit will make your life much easier since you can't run code without declared variables.
In the VBA editor go to: "Tools" -> "Options" -> "Require Variable Declaration".
Sub FilterDate()
Dim ap As Date, dt As Date, dt1 As Date
Dim lr As Long
lr = ActiveSheet.UsedRange.SpecialCells(11).Row
With ActiveSheet.[a1].CurrentRegion.Resize(lr, 10)
ap = Application.InputBox("get date")
dt = CDate(ap)
'dt = CDate("2018-10-26")
.AutoFilter 10, Criteria1:=">=" & dt, _
Operator:=xlAnd, Criteria2:="<" & dt + 1
End With
End Sub
EDIT:
Yes, since you have date you need to filter in an interval, rather than one "=" criteria (two criteria where your date is between those two criteria), don't forget to make a header since the header values always is present (Code is updated). Example below is with date 2018-10-26.

how to search a string for a date after 3 letters and determine if it falls into a date range

I am trying to write VBA for the first time in many years and I am having trouble getting started.
I am creating a form that users will fill out. There is no data until the user fills in the two columns. They will enter information first in column A and then in column B.
Then in each cell they can enter ABC followed by a date or XYZ followed by a date
I am trying write code that will do the following:
When a cell in column B is changed, I want to check to see if it contains the string "ABC" followed by a date (i.e. "ABC7/29/14" or "ABC 7/29/14").
Where the date format is inconsistent (i.e. sometimes it would be 07/29/2014, sometimes 7/29/14).
If the cell does contain ABC followed by a date, I want to check if that date falls within a specified date range (ie. 07/29/14 to 7/30/14). This date range will be hardcoded in.
If the date does fall within that range then I want to check the cell in the same row to the left (column A) to see if it contains the same string "ABC" followed by a date range.
If the second cell does contain ABC followed by a date I want to check if that date falls within a second specified date range (i.e. "ABC10/12/14" or "ABC 10/13/14").
If all these conditions are met I want to have a message box pop up.
Thank you so much in advance. I have written a few things for this and I am just not getting good results or even things that run correctly every time.
****EDIT****
I have updated my code to what I am currently working with. I am getting a compile Error: Object Required and it is highlighting my Set FirstPmtLDate line. Also the code is running as soon as any cell is changed. I really only want it to run when cells in B column are selected.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim SecondPmt As Range
Dim FirstPmt As Range
Dim FirstPmtLDate As Date
Dim FirstPmtUDate As Date
Dim SecondPmtLDate As Date
Dim SecondPmtUDate As Date
Set SecondPmt = ActiveCell
Set FirstPmtLDate = DateValue(7 / 29 / 2014)
Set FirstPmtUDate = DateValue(7 / 30 / 2014)
Set SecondPmtLDate = DateValue(10 / 12 / 2014)
Set SecondPmtUDate = DateValue(10 / 13 / 2014)
Application.EnableEvents = False
'If target cell is empty post change, nothing will happen
If IsEmpty(Target) Then
Application.EnableEvents = True
Exit Sub
End If
'Using If Not statement with the Intersect Method to determine if Target
'cell is within specified range
If Not Intersect(Target, Range("B2:B16")) Is Nothing Then
'Checks if cell contains ABC in any case
If InStr(SecondPmt.Value, "ABC", vbTextCompare) <> 0 Then
'Remove any spaces user may entered
SecondPmt = Replace(SecondPmt, " ", "")
'Finds date after ABC in any format
SecondPmt = Mid(SecondPmt, 4)
'Checks if it is 07/29/14 or 7/30/14
SecondPmtDate = DateValue(SecondPmt)
If SecondPmtDate = SecondPmtLDate Or SecondPmtDate = SecondPmtUDate Then
'Then if it does have one of those dates the cell to the left is selected
FirstPmt = SecondPmt.Offset(0, -1)
'Checks if new cell contains ABC in any case
If InStr(FirstPmt.Value, "ABC", vbTextCompare) <> 0 Then
'Remove any spaces user may entered
FirstPmt = Replace(FirstPmt, " ", "")
'Finds date after ABC in any format
FirstPmt = Mid(FirstPmt, 4)
'Checks if it is 10/12/14 or 10/13/14
FirstPmtDate = DateValue(FirstPmt)
If FirstPmtDate = FirstPmtLDate Or FirstPmtDate = FirstPmtUDate Then
'Then if it does have one of those dates Pop up message box
MsgBox "This is not a valid entry!"
End If
End If
End If
End If
End If
Application.EnableEvents = True
End Sub
Try this:
If InStr(s, "ABC") <> 0 Then
s = Mid(s, 4)
d = DateValue(s)
....
End If
where s is the string from your cell. Don't mind the spaces and additional zeros. The DateValue function will do it. Just check if the regional settings on your computer and in Excel are appropriate for the date format you want to use. (see the documentation)
Dont worry about the presence or not of leading zeroes in your date, the Format() function will manage that for you
dim strDate as string
dim strDateStart as string
dim strDateEnd as string
dim dtDate as date
dim dtStart as date
dim dtEnd as date
strDateStart = "07/29/2014"
strDateEnd = "07/30/2014"
' assuming your in the US and the locale date format of your system is mm/dd/aaaa as this is on what Cdate will operate on
' convert stribgs to dates
dtStart = Cdate(strDateStart)
dtEnd = Cdate(strDateEnd)
'assuming that FirstPmt contains ABCdateinanyformat
' we extract the date part (remove ABC) and we format the date
strDate = (Format( left(FirstPmt.value,4),"mm/dd/yyyy")
dtDate = Cdate(strDate)
' you can check if the date is within your range of dates like:
if dtDate >= dtStart) and (dtDate <= dtEnd) then
' do your stuff
end if

VB6, CDate(sheet.range("B", counter))

I've been looking and looking for a solution but without success.
I need to populate list-view by date criteria, I know how to fill it with simple criteria but date criteria has given me a lot of problems.
I have dates (dd.mm.yyyy) in B column in my Excel document and I need to convert them to date and compare with date which I choose from calendar control on the form. How can I set that default date in VB6 be dd.mm.yyyy?
I am beginner and I don't know where I am wrong, please help me. Thanks in advance.
Do Until .Cells(myCounter, 1) & "" = ""
strDate = listObj.Range("B" & myCounter)
myDate= CDate(strDate) >>>>>>>>>> Run-time error "13" Mismatch type
If myDate > Calendar1.Value Then
.........................
End If
myCounter =myCounter + 1
Loop
edit: This is my whole code
Dim excelObj As excel.Application
Dim wbObj As excel.Workbook
Dim sheetObj As Worksheet
Dim myCounter As Long
Set excelObj = New excel.Application
excelObj.Visible = False
Set wbObj = excelObj.Workbooks.Open(App.Path & "\excel_document.xlsx")
Set sheetObj = excelObj.Worksheets("Sheet1")
Dim L As ListItem
Dim myDateAs Date
Dim strDate As String
ListView1.ListItems.Clear
With sheetObj
myCounter = 2
Do Until .Cells(myCounter, 1) & "" = ""
strDate = sheetObj.Range("B" & myCounter)
myDate= CDate(strDate)
If myDate > Calendar1.Value Then
........
End If
myCounter = myCounter + 1
Loop
End With
excelObj.Quit
In excel document B column is formatted as Date - dd/mm/yyyy. I tried also not to do CDate but without success.
How did you declare strDate? Dim strDate As String? Variant? Not declared?
Given what you're trying to do, it really should be declared as either Variant or Date. It looks like you declared it as a String, and that you are also entering strings on the cells.
When you Enter the date values in Excel, you should enter them as dates instead of strings. It's easy; just make sure that the cells are formatted with "dd.mm.yyyy" and they will accept such dates correctly when you type them. When you retrieve the values from VB, they will be retrieved as Dates and you will be able to manipulate them as such.
If you really want to transform a string that comes in that format into a Date value, you can use this method: Parse finnish date string to Date Type in VB6

Resources