Интервал между двумя датами в VBA - PullRequest
0 голосов
/ 07 января 2019

Время начала "08:58", время окончания "17:37". Ожидаемый результат - 8,39, что означает прошедшее время 8 часов и 39 минут. Я попробовал это:

Function UDF_datediff(d1 As Date, d2 As Date) As Double
    Dim hours As Integer
    Dim minutes As Integer

    hours = DateDiff("h", d1, d2)
    minutes = (DateDiff("n", d1, d2) Mod 60)

    UDF_datediff = hours + minutes / 100
End Function

Но он вычисляет неверные результаты по часам. Удивительно! Вы бы поделились каким-либо предложением подсчитать ожидаемые результаты?

Ответы [ 6 ]

0 голосов
/ 07 января 2019

Общий ответ таков:

      Format(CDate(d2-d1),"h:m")

В частности, для вашего времени начала и окончания это выражение будет давать результат "8:39".

Если вам нужно извлечь часы и минуты из этого, вы можете сделать это:

Dim sDuration as String
Dim iCol as Long
Dim sH as String
Dim sM as String
Dim iH as Long
Dim iM as Long

sDuration = Format(CDate(d2-d1),"h:m") ' the "8:39" in your case
iCol =InStr(sDuration, ":") 
sH = Left(sDuration, iCol - 1)
sM = Mid(sDuration, iCol + 1, 2) ' length of 2 or any longer
iH = CInt(sH)
iM = CInt(sM)

Вы всегда можете работать с «числами», преобразовывая десятичные дроби, умножая на 24 и на 60, округляя ... как в

iH = Int(CDate(d2-d1)*24) ' to get the hours

и т.д.. (немного сложнее с протоколом)

0 голосов
/ 07 января 2019
Function UDF_datediff(d1 As Date, d2 As Date) As Double
    Dim difference AS Double
    difference = d2 - d1
    UDF_datediff = Sgn(difference) * CDbl(Format(difference , "hh.mm"))
End Function

В вашем примере d2 - d1 - это DateTime, равный 1899-12-30 08:37:00 - отформатируйте его как Часы (2 цифры), десятичную точку, Минуты (2 цифры), затем преобразуйте в двойной и исправьте знак.

0 голосов
/ 07 января 2019

DateDiff на самом деле не совсем нужно. Вы можете использовать простой «минус», чтобы увидеть, что происходит:

Sub TestMe() 

    With Worksheets(1)
        Dim d1 As Date: d1 = 0.373611111111111 '08:58:00
        Dim d2 As Date: d2 = 0.734027777777778 '17:37:00
    End With
    Debug.Print UdfDatediff(d1, d2)            '08:39:00

End Sub

Function UdfDatediff(d1 As Date, d2 As Date) As Date

    UdfDatediff = Abs(d1 - d2)

End Function

Дата в VBA представлена ​​в виде двойного числа. Таким образом, если вы напишите 0.373611111111111 и отформатируете его в Date в VBA, вы получите:

?CDate(0.373611111111111)
08:58:00

Приведенные выше двойные значения получены путем записи следующего в Немедленное окно Ctrl + G :

?CDbl(TimeSerial(8,58,0))
 0,373611111111111 

В Excel дата также представляется в виде двойного числа, но в течение первых двух месяцев года 1900 она немного отличается от даты в VBA (см. Вопрос BillG здесь ).

0 голосов
/ 07 января 2019

Попробуйте

Sub test()
    Dim d1 As Date, d2 As Date
    Dim m As Double

    d1 = TimeValue("08:58")
    d2 = TimeValue("17:37")
    m = UDF_datediff(d1, d2)
    MsgBox m
    MsgBox Format(m / 24, "hh:mm")
End Sub

UDF

Function UDF_datediff(d1 As Date, d2 As Date) As Double

    UDF_datediff = (d2 - d1) * 24
End Function
0 голосов
/ 07 января 2019

Попробуйте это:

Sub Test()
    Dim minutes As Long
    Dim d1 As Date, d2 As Date
    d1 = "2018-01-01 08:58:00"
    d2 = "2018-01-01 17:37:00"
    minutes = DateDiff("n", d1, d2)
    ' Will print 8.39
    MsgBox Int(minutes / 60) & "." & minutes Mod 60
End Sub
0 голосов
/ 07 января 2019

альтернативно - учитывая, что время хранится в виде десятичных дробей дня

 Function UDF_datediff(d1 As Date, d2 As Date) As Double
    d2 = d2-int(d2) 'remove date portion
    d1= d1 - int(d1)
    UDF_datediff = (d2-d1)*24
  End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...