2014-08-27 10 views
-3

Je reçois le temps comme 23300000, c'est-à-dire hhMMssmm format comme chaîne et je veux calculer la différence de ces deux valeurs.Calcul du temps dans Excel VBA

Ici, hh est les heures, MM est les minutes, ss les secondes et mm est la 60e de seconde. Utilisation de VBA pour Excel 2003

+0

comment prévoyez-vous de calculer la différence entre une date qui se répète le jour suivant? C'est à dire. 23h30 et 1h30 le lendemain? –

+0

Non, les valeurs seront du même jour. donc 1h30 ne sera jamais là. Il sera toujours maximum comme '24000000' –

+0

bien, vous avez besoin d'une certaine logique if-else pour que cela fonctionne, spécialement la partie' mm'. pourquoi ne pas nous montrer ce que vous avez essayé et dire ce qui ne fonctionne pas et puis nous pouvons vous aider –

Répondre

1

Cette UDF renverra la valeur absolue de la différence de secondes

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 
+0

Je soupçonne l'OP voudrait que la valeur retournée soit également une chaîne dans le même format que l'entrée un;) –

+1

@mehow j'étais incertain de la forme ou du format du résultat. J'ai posté une option. Si * Rohit * aimerait un autre format, je mettrai à jour ma réponse en conséquence. –

1

Que diriez-vous quelque chose comme ceci:

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 

Les ToSeconds() La fonction convertit votre nombre en secondes, et vous pouvez faire vos calculs en fonction de cela.

+0

Assez juste - édité la fonction pour retourner le nombre de secondes écoulées depuis minuit à la place. – Bogey

+0

bien fait ++ pour la mise à jour –

0

Bien que cette solution ne soit pas aussi courte que les autres, je crois que c'est très facile à comprendre. Tout ne peut pas être nécessaire ici, mais vous pourrez en trouver quelques-unes utiles à l'avenir.

La sous-routine run vous permet d'exécuter la fonction test avec vos valeurs spécifiées. La fonction test teste la logique timeDiff & timeSum.
La fonction timeDiff trouve le décalage horaire entre t1 et t0.
La fonction timeSum trouve la somme de temps de t1 et t0.
La fonction asDuration supprime le suffixe AM/PM d'une valeur temporelle. La fonction asMilitary convertit le format 12 heures au format 24 heures.
La fonction concat que j'ai créée pour concaténer plus facilement les chaînes.

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