5

I am trying to convert a date into long using VBA script. Below is the code snippet

Sub test()
    Dim str as string
    Dim d as variant
    str="1/1/2016"
    d=cdate(str)
end sub

The above snippet runs fine on windows but is giving me type mismatch error on MAC. Is there any turnaround to convert a valid string in a date.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Rohit Saluja
  • 1,517
  • 2
  • 17
  • 25

6 Answers6

2

Your regional settings are the root cause.

Can you try modify them?

defaults write NSGlobalDomain AppleICUDateFormatStrings -dict 1 dd/MM/yyyy
Jeandey Boris
  • 743
  • 4
  • 9
1

Your code did work on my local OS X machine with Excel. I have different region settings, though. I would suggest try using the international date format ("YYYY-mm-dd").

Sub Main
    Dim str as String
    Dim d as Variant
    str = "2016-01-01"
    d = CDate(str)
End Sub

Alternatively, you could try "Jan/1/2016".


P.S.: You can see your date & time settings in OS X under System Preferences -> Language & Region -> Advanced -> Dates:

OS X language & region date settings

1

Many different answer, so I may as well throw this way of doing it it into the ring,

Sub test()
    Dim str As String
    Dim d As Variant
    str = "1/1/2016"
    d = CDate(Format(str, "dd/MM/yyyy"))
    Debug.Print d
End Sub
KyloRen
  • 2,691
  • 5
  • 29
  • 59
0

Maybe try removing the "/" before converting? I do not have a Mac to test:

Public Sub test()
    Dim str As String
    Dim d As Long 'should be Date, but your question states Long
    str = "1/1/2016"
    d = CDate(Replace(str, "/", ""))
    Debug.Print d
End Sub

Also, have you tried checking for missing references? Date for VBA not working in Excel 2011?

Community
  • 1
  • 1
Jennifer
  • 27
  • 4
0

You could use the IsDate() function to check if it is a date before converting. Otherwise use a workaround:

Sub test()
    Dim str as string
    Dim d as variant
    str = "1/1/2016"

    If IsDate(str) then
       d = CDate(str)
    Else
       Dim aDateParts() as String
       aDateParts() = Split(str, "/")

       ' DateSerial(Year, Month, Day)
       d = DateSerial(CInt(aDateParts(2)), CInt(aDateParts(0)), CInt(aDateParts(1)))
    End If
end sub
  • So far the only answer providing a possible workaround, however I'm not sure does `IsDate(str)` prevent the str being validated as a date although assigning `d` might fail. Also if the date string is something funny like "1/32/2017" we get to the else part where bad things start to happen. – Han Soalone Jan 26 '17 at 13:04
  • I was going to do this with a left/mid/right for the day month year, your answer is better with the split function. In my view this could be improved by putting it into a: Function ConDate(InputDate as string) as date – Preston Jan 26 '17 at 17:39
  • @HanSoalone This code was more a proof of concept than a working solution, it should be refined if that's an acceptable solution. Tom, thanks, it seems like a good idea! What's the best practice here? Should I upvote your solution? – sebifeixler Jan 30 '17 at 15:02
  • @sebifeixler I understood that and it is a good concept, I just wanted to point out the problems this approach might bring. Likely the solution will work ok, if added some error checking etc. – Han Soalone Jan 31 '17 at 06:46
  • It is sure a nice workaround but just want to let you guys know one thing, DateSerial is not working on my Mac – Rohit Saluja Jan 31 '17 at 08:54
0

I didn't post this originally, because I felt it didn't address the root of the problem, however, if you want a workaround, you can use the below function in a similar way as you would use a CDate, by calling ConDate("12/12/2016").

This is is the way I approached the problem:

Sub MainTest()
    Dim InputString As String, OutputDate As Date

    InputString = "01/12/2016"
    OutputDate = ConDate(InputString)

    Debug.Print OutputDate, TypeName(OutputDate)
End Sub

Function ConDate(ByRef InputString As String) As Date
    Dim Day As Long, Month As Long, year As Long
    'mmddyyyy format
    Month = CLng(Left(InputString, InStr(1, InputString, "/", vbTextCompare) - 1))
    Day = CLng(Mid(InputString, InStr(1, InputString, "/", vbTextCompare) + 1, InStrRev(InputString, "/", , vbTextCompare) - InStr(1, InputString, "/", vbTextCompare) - 1))
    year = CLng(Right(InputString, 4))
    ConDate = DateSerial(year, Month, Day)
End Function

Not wanting to plagerise sebifeixler's answer I kept my original left/mid/right to separate the day/month/year, but I feel it's much neater to use his split function to separate the date by "/". A combination of the two would be a good workaround.

Preston
  • 7,399
  • 8
  • 54
  • 84