简体   繁体   中英

Excel VBA convert Date with time

I have 2 cells with time data that format as follows:

"A1" = Sep 01 2018 00:01:33.707 
"A2" = Sep 01 2018 00:01:49.917

I need to create a button and method within excel VBA that will set "A3" cell to true if the time "A2" is more than "A1" by 90 seconds. This is what i have so far but it does not work:

Sub Macro2()
    Dim str1 As String, str2 As String

    With Worksheets("sheet5")

        str1 = .Cells(1, "A").Text
        str2 = .Cells(2, "A").Text

        'greater than 90m seconds in A3
        .Cells(3, "A") = CBool(Abs((DateValue(Left(str1, 6) & "," & Mid(str1, 7, 5)) + _
                                    TimeValue(Mid(str1, 13, 8)) + TimeSerial(0, 0, 1) * CDbl(Right(str1, 4))) - _
                                   (DateValue(Left(str2, 6) & "," & Mid(str2, 7, 5)) + _
                                   TimeValue(Mid(str2, 13, 8)) + TimeSerial(0, 0, 1) * CDbl(Right(str2, 4)))) > _
                                   TimeSerial(0, 0, 90))
        'actual absolute difference in A4
        .Cells(4, "A") = Abs((DateValue(Left(str1, 6) & "," & Mid(str1, 7, 5)) + _
                                    TimeValue(Mid(str1, 13, 8)) + TimeSerial(0, 0, 1) * CDbl(Right(str1, 4))) - _
                                   (DateValue(Left(str2, 6) & "," & Mid(str2, 7, 5)) + _
                                    TimeValue(Mid(str2, 13, 8)) + TimeSerial(0, 0, 1) * CDbl(Right(str2, 4))))
    End With End Sub

The above gives error because Date functions works with system Locale, which in my case is Hebrew, while the Data is in English.

Another way that could help is to convert all the column "A" (which holds the dates) to a system local date that can be used with Date and time functions on VBA (don't know how to do that).

Please help

I have split your task into 3 functions.

a) a helper function converts the 3 characters of the month into an integer. It looks a little clumsy, there might be other approaches but the advantage of using a large Select Case is it is easy to understand and easy to adapt if month names in a different language arise:

Function getMonthFromName(monthName As String) As Integer

    Select Case UCase(monthName)
        Case "JAN": getMonthFromName = 1
        Case "FEB": getMonthFromName = 2
        Case "MAR": getMonthFromName = 3
        Case "APR": getMonthFromName = 4
        (...)
        Case "SEP": getMonthFromName = 9
        (...)
    End Select

End Function

b) a function that converts the string into a date. It assumes the date format in the form you provided, but it is easily adapted if the format changes (for simplicity, the seconds are rounded)

Function GetDateFromString(dt As String) As Date

    Dim tokens() As String
    tokens = Split(Replace(dt, ":", " "), " ")

    Dim day As Integer, month As Integer, year As Integer
    month = getMonthFromName(CStr(tokens(0)))
    day = Val(tokens(1))
    year = Val(tokens(2))

    Dim hour As Integer, minute As Integer, second As Double
    hour = Val(tokens(3))
    minute = Val(tokens(4))
    second = Round(Val(tokens(5)), 0)

    GetDateFromString = DateSerial(year, month, day) + TimeSerial(hour, minute, second)
End Function

c) A function that calculated the difference of the 2 dates in seconds. A date in VBA (and many other environments) is stored as Double , where the Date-Part is the integer part and the date is the remainder. This makes it easy to calculate with Date values.

Function DateDiffInSeconds(d1 As String, d2 As String) As Long
    Dim diff As Double
    diff = GetDateFromString(d2) - GetDateFromString(d1)
    DateDiffInSeconds = diff * 24 * 60 * 60
End Function

Update to deal with milliseconds: Change the GetDateFromString -function. In that case, DateDiffInSeconds should return a double rather than a long .

Function GetDateFromString(dt As String) As Date

    Const MillSecPerHour As Long = 24& * 60 * 60 * 1000

    Dim tokens() As String
    tokens = Split(Replace(Replace(dt, ".", " "), ":", " "), " ")

    Dim day As Integer, month As Integer, year As Integer
    month = getMonthFromName(CStr(tokens(0)))
    day = Val(tokens(1))
    year = Val(tokens(2))

    Dim hour As Integer, minute As Integer, second As Integer, milli As Integer
    hour = Val(tokens(3))
    minute = Val(tokens(4))
    second = Val(tokens(5))
    milli = Val(tokens(6))

    GetDateFromString = DateSerial(year, month, day) _
                      + TimeSerial(hour, minute, second) _
                      + milli / MillSecPerHour
End Function

I think you are over-complicating it, try this to get an idea how to do it:

Sub Macro2()
    Dim str1 As String, str2 As String

    With Worksheets("sheet5")

        .Range("b1:e1") = Split(Range("A1"), " ")
        .Range("B2:e2") = Split(Range("A2"), " ")


End Sub

For your information, I've done what you are doing in a slightly different (and easier) way:

In cell B2, I put the value 13/11/2018 11:44:00 .
In cell B3, I put the value 13/11/2018 11:45:01 .
(For both cells, the cell formatting has been set to d/mm/jjjj u:mm:ss ).

In another cell, I put following formula:

=IF((B3-B2)*86400>90;TRUE;FALSE)

The formula is based on the idea that a datetime value is set, based on the idea that one day equals 1, and there are 86400 seconds in one day.

Like this, you can calculate time differences without needing VBA.

Use UDF.

Sub Macro2()
    Dim str1 As String, str2 As String
    Dim mySecond As Double, t1 As Double, t2 As Double, t3 As Double
    mySecond = TimeSerial(0, 0, 90)

    With Worksheets("sheet5")
        str1 = .Cells(1, "A").Text
        str2 = .Cells(2, "A").Text
        t1 = ConvertTime(str1)
        t2 = ConvertTime(str2)
        t3 = t2 - t1
        .Cells(3, "a") = Abs(t3) >= mySecond
    End With

End Sub
Function ConvertTime(s As String)
    Dim vS
    vS = Split(s, " ")
    ConvertTime = DateValue(vS(0) & "-" & vS(1) & "-" & vS(2)) + TimeValue(Split(vS(3), ".")(0))
End Function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM