Excel VBA中的时间计算

Posted

技术标签:

【中文标题】Excel VBA中的时间计算【英文标题】:Time Calculation in Excel VBA 【发布时间】:2014-08-27 11:13:20 【问题描述】:

我将时间设置为 23300000hhMMssmm 格式为字符串 我想计算这两个值的差异。

这里 hh 是小时,MM 是分钟,ss 是秒,mm 是 60 秒。 在 Excel 2003 中使用 VBA

【问题讨论】:

您打算如何计算第二天的日期之间的差异? IE。 23:30和次日1:30? 否,值将是同一天。所以 1:30 永远不会出现。它总是最大为24000000 好吧,您需要一些 if-else 逻辑才能使其工作,特别是 mm 部分。您为什么不向我们展示您尝试过的方法并告诉我们哪些方法不起作用,然后我们可以为您提供帮助 相关:***.com/questions/939230/… 【参考方案1】:

这个UDF将返回以为单位的差的绝对值

Public Function tDiff(s1 As String, s2 As String) As Double
'
'   calculates the absolute value of the differences
'   returns the answer in seconds
'
    Dim hrs As Double, mins As Double, secs As Double, sixt As Double
    Dim tVal1 As Double, tVal2 As Double

    hrs = CDbl(Mid(s1, 1, 2)) * 60 * 60
    mins = CDbl(Mid(s1, 3, 2)) * 60
    secs = CDbl(Mid(s1, 5, 2))
    sixt = CDbl(Mid(s1, 7, 2)) / 60
    tVal1 = hrs + mins + secs + sixt

    hrs = CDbl(Mid(s2, 1, 2)) * 60 * 60
    mins = CDbl(Mid(s2, 3, 2)) * 60
    secs = CDbl(Mid(s2, 5, 2))
    sixt = CDbl(Mid(s2, 7, 2)) / 60
    tVal2 = hrs + mins + secs + sixt

    If tVal1 > tVal2 Then
        tDiff = tVal1 - tVal2
    Else
        tDiff = tVal2 - tVal1
    End If
End Function

【讨论】:

我怀疑 OP 希望返回的值也是与输入格式相同的字符串;) @mehow 我不确定结果的形式或格式。我发布了一个选项。如果 Rohit 想要其他格式,我会更新我的答案以适应。【参考方案2】:

这样的事情怎么样:

Public Sub test()
    Dim ms1 As Double
    Dim ms2 As Double

    ms1 = ToSeconds(23142700)
    ms2 = ToSeconds(23311500)

    Debug.Print "Difference between dates in seconds: " & ms2 - ms1
End Sub


Public Function ToSeconds(number As Long) As Double
    Dim hh As Long
    Dim mm As Long
    Dim ss As Long
    Dim ms As Long

    ms = (number Mod (100 ^ 1)) / (100 ^ 0)
    ss = (number Mod (100 ^ 2) - ms) / (100 ^ 1)
    mm = (number Mod (100 ^ 3) - ss * (100 ^ 1) - ms) / (100 ^ 2)
    hh = (number Mod (100 ^ 4) - mm * (100 ^ 2) - ss * (100 ^ 1) - ms) / (100 ^ 3)

    ToSeconds = ms * 1 / 60 + ss + mm * 60 + hh * 60 * 60
End Function

ToSeconds() 函数将您的数字转换为秒,您可以据此进行计算。

【讨论】:

很公平 - 编辑函数以返回自午夜以来经过的秒数。【参考方案3】:

虽然这个解决方案可能不像其他解决方案那么短,但我相信它很容易理解。并非此处的所有内容都可能是必需的,但您可能会发现其中一些在将来很有用。

run 子例程允许您使用指定的值运行 test 函数。test 函数测试 timeDifftimeSum 逻辑。timeDiff 函数查找 t1t0 之间的时间差。timeSum 函数求 t1t0 的时间和。asDuration 函数从时间值中删除 AM/PM 后缀。asMilitary 函数将 12 小时格式转换为 24 小时格式。 我创建的concat 函数可以更轻松地连接字符串。

Sub Main() 'Run Test
    MsgBox Test("0:29:0", "23:30:0")
End Sub

Function Test(startT As Date, endT As Date) 'Test timeDiff & timeSum logic
    Dim nextShift As Date, prevShift As Date, hours As Date

    hours = timeDiff(endT, startT)
    prevShift = timeDiff(startT, "0:30:0")
    nextShift = timeSum("0:30:0", endT)        

    Test = concat("Start -", startT, "", "End - ", endT, "", "Duration -", asDuration(hours), "", "Next Shift: ", nextShift, "", "Prev Shift: ", prevShift)
End Function


Function timeDiff(t1 As Date, t0 As Date) As Date 'Return Time1 minus Time0
    Dim units(0 To 2) As String

    units(0) = Hour(t1) - Hour(t0)
    units(1) = Minute(t1) - Minute(t0)
    units(2) = Second(t1) - Second(t0)

    If units(2) < 0 Then
        units(2) = units(2) + 60
        units(1) = units(1) - 1
    End If

    If units(1) < 0 Then
        units(1) = units(1) + 60
        units(0) = units(0) - 1
    End If

    units(0) = IIf(units(0) < 0, units(0) + 24, units(0))
    timeDiff = Join(units, ":")
End Function


Function timeSum(t1 As Date, t0 As Date) As Date 'Return Time1 plus Time0
    Dim units(0 To 2) As String

    units(0) = Hour(t1) + Hour(t0)
    units(1) = Minute(t1) + Minute(t0)
    units(2) = Second(t1) + Second(t0)

    If units(2) >= 60 Then
        units(2) = units(2) Mod 60
        units(1) = units(1) + 1
    End If

    If units(1) >= 60 Then
        units(1) = units(1) Mod 60
        units(0) = units(0) + 1
    End If

    units(0) = IIf(units(0) >= 24, units(0) Mod 24, units(0))
    timeSum = Join(units, ":")
End Function


Function asDuration(time As Date) As String 'Display as duration; Remove AM/PM suffix from time
    time = asMilitary(time)
    asDuration = Left(time, Len(time))
End Function


Function asMilitary(time As Date) As String 'Convert 12-hour format to 24-hour-format
    asMilitary = Hour(time) & ":" & Minute(time) & ":" & Second(time)
End Function


Function concat(ParamArray var() As Variant) As String 'Return arguments of function call concatenated as a single string
    For Each elem In var()
        concat = IIf(elem <> "", concat & elem & " ", concat & vbNewLine)
    Next
End Function

【讨论】:

以上是关于Excel VBA中的时间计算的主要内容,如果未能解决你的问题,请参考以下文章

在 Excel 的 VBA 代码中计算 %

Excel VBA:SendKeys 在某些计算机上失败

如何向/从具有 VBA 宏计算的 Excel 文件发送和接收信息

VBA:更新后无法自动重新计算 Excel 公式 - 需要手动交互

使用 excel vba 计算每行中的重复值和报告重复数

需要帮助使用 VBA 在 excel 中将超链接插入到我计算机上的指定图片