Excel VBA конвертировать дату со временем - PullRequest
0 голосов
/ 13 ноября 2018

У меня есть 2 ячейки с данными времени, которые форматируются следующим образом:

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

Мне нужно создать кнопку и метод в Excel VBA, который установит для ячейки «A3» значение true, если время «A2»больше, чем «А1» на 90 секунд.Это то, что у меня есть, но оно не работает:

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

Выше приведено сообщение об ошибке, потому что функции Date работают с системой Locale, которая в моем случае - иврит, а данные - на английском.

Другой способ, который может помочь, - преобразовать весь столбец «А» (который содержит даты) в системную локальную дату, которую можно использовать с функциями даты и времени в VBA (не знаю, как это сделать).

Пожалуйста, помогите

Ответы [ 4 ]

0 голосов
/ 13 ноября 2018

Использовать 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
0 голосов
/ 13 ноября 2018

Для вашей информации, я сделал то, что вы делаете, немного другим (и более простым) способом:

В ячейку B2 я поместил значение 13/11/2018 11:44:00.
В ячейку B3,Я поместил значение 13/11/2018 11:45:01.
(Для обеих ячеек форматирование ячеек было установлено на d/mm/jjjj u:mm:ss).

В другую ячейку я поместил следующую формулу:

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

Формула основана на идее, что установлено значение даты / времени, на основе идеи, что один день равен 1, а в одном дне 86400 секунд.

Таким образом, вы можете вычислять разницу во времени безнуждающийся в VBA.

0 голосов
/ 13 ноября 2018

Я разделил вашу задачу на 3 функции.

a) вспомогательная функция преобразует 3 символа месяца в целое число.Это выглядит немного неуклюже, могут быть и другие подходы, но преимущество использования большого Select Case в том, что его легко понять и легко адаптировать, если появляются названия месяцев на другом языке:

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) функция, которая преобразует строку в дату.Предполагается, что формат даты указан в предоставленной вами форме, но он легко адаптируется, если формат изменяется (для простоты, секунды округлены)

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) Функция, которая рассчитала разницу между двумя датами.в секундахДата в VBA (и многих других средах) хранится как Double, где Date-Part является целочисленной частью, а date является оставшейся частью.Это позволяет легко рассчитать с помощью значений даты.

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

Обновление для работы с миллисекундами: измените функцию GetDateFromString.В этом случае DateDiffInSeconds должен вернуть double, а не 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
0 голосов
/ 13 ноября 2018

Я думаю, что вы слишком усложняете это, попробуйте это, чтобы понять, как это сделать:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...