vbaexceldatereversing

Date Automatically Reversing VBA Excel


So, I'm having some problems with dates that are reversing themselves in VBA when assigned to a Date variable. It's simpler than it sounds, but it's really bugging me.

Code:

Dim InsertedDate as Date

On Error Resume Next

InsertedDate = Me.BoxDate.Value

If InsertedDate = 0 Then

     'Do Something

Else

     'Do Something Different

End If

So let's assume that user types a value like

12/18/2017

I'm brazilian, so that means the user typed the 12th day of the 18th month. Since there's no 18th month in the year, the user shouldn't be able to type that date and InsertedDate should be equal to 0, right? Or not? I mean, I'm not really sure how Excel work dates.

Anyway, what happens is: Excel automatically reverses the date to

18/12/2017       'InsertedDate Value

instead of InsertedDate being

12/18/2017       'InsertedDate Value

And the code goes to 'Do Something Different. So, how do I solve this? Notice that I haven't assigned the variable value to anything. The process of reversion happens automatically when assigning the value to the variable. I've already tried

Format(InsertedDate, "dd/mm/yyyy")    'Did not work

and

InsertedDate = CDate(Me.BoxDate.Value)  'Did not work

and I tried converting the values in other variables and stuff. So, I'm lost. If anyone could help me, I'd be extremely grateful. Thank you in advance.


Solution

  • If you choose data type as Date it will automatically convert dates to american format.
    My suggestion is to check the date format of the user and assume he uses the same (and it is not the safest assumption):

    If Application.International(xlMDY) then
         InsertedDate = Me.BoxDate.Value
    Else:
         Arr = Split(Me.BoxDate.Value,"/")
         InsertedDate = DateSerial(Arr(2),Arr(1),Arr(0))
    End if
    

    But it assumes that user has used "/" as a delimite - and there could be a lot of other scenarios. You can use a date picker instead or a function that will validate the date.

    EDIT: Actually here is a variation of function I use and its implementation in your code:

    Sub TestDate()
    If ConformDate(Me.BoxDate.Value) = "" Then
        MsgBox "Invalid Date!"
    Else
        MsgBox "" & ConformDate(Me.BoxDate.Value) & " is a valid date"
    End If
    End Sub
    
    Function ConformDate(DataToTransform As String) As String
    
    Dim DTT         As String
    Dim delim       As String
    Dim i           As Integer
    DTT = DataToTransform
    
    DTT = Trim(DTT)
    With CreateObject("VBScript.RegExp")
        .Pattern = "\s+"
        .Global = True
        DTT = .Replace(DTT, " ")
    End With
    Select Case True
       Case (DTT Like "*/*/*")
            delim = "/"
       Case (DTT Like "*-*-*")
            delim = "-"
       Case (DTT Like "*.*.*")
            delim = "."
       Case (DTT Like "* * *")
            delim = " "
       Case Else
            ConformDate = ""
            Exit Function
    End Select
    Arr = Split(DTT, delim)
    If UBound(Arr) < 2 Then
        ConformDate = ""
        Exit Function
    End If
    Dim Arrm(2) As String
    If Application.International(xlMDY) Then
        Arrm(0) = Arr(0)
        Arrm(1) = Arr(1)
        Arrm(2) = Arr(2)
    Else
        Arrm(0) = Arr(1)
        Arrm(1) = Arr(0)
        Arrm(2) = Arr(2)
    End If
    For i = LBound(Arrm) To UBound(Arrm)
        If Not IsNumeric(Arrm(i)) Then
            ConformDate = ""
            Exit Function
        End If
    Select Case i
            Case 0
                ' Month
                If Len(Arrm(i)) < 1 Or Len(Arrm(i)) > 2 Then
                    ConformDate = ""
                    Exit Function
                End If
                If Left(Arrm(i), 1) = "0" And Len(Arrm(i)) = 1 Then
                    ConformDate = ""
                    Exit Function
                End If
                If Left(Arrm(i), 1) = "0" Then Arr(i) = Right(Arrm(i), 1)
                If Arrm(i) > 12 Then
                    ConformDate = ""
                    Exit Function
                End If
            Case 1
                ' Day
                If Len(Arrm(i)) < 1 Or Len(Arrm(i)) > 2 Then
                    ConformDate = ""
                    Exit Function
                End If
    
                If Left(Arrm(i), 1) = "0" And Len(Arrm(i)) = 1 Then
                    ConformDate = ""
                    Exit Function
                End If
                If Left(Arrm(i), 1) = "0" Then Arrm(i) = Right(Arrm(i), 1)
                    If Arrm(i) > 31 Then
                    ConformDate = ""
                    Exit Function
                End If
                Case 2
                ' Year
                If Not (Len(Arrm(i)) = 2 Or Len(Arrm(i)) = 4) Then
                    ConformDate = ""
                    Exit Function
                End If
                If Len(Arrm(i)) = 2 Then Arrm(i) = Left(Year(Date), 2) & CStr(Arrm(i))
     End Select
    Next
    
    If Application.International(xlMDY) Then
        ConformDate = Format((DateSerial(CInt(Arrm(2)), CInt(Arrm(0)), CInt(Arrm(1)))), "dd/mm/yyyy")
    Else
         ConformDate = Format((DateSerial(CInt(Arrm(2)), CInt(Arrm(1)), CInt(Arrm(0)))), "dd/mm/yyyy")
    End If
    End Function