Option Explicit
Sub CalculeDureeTotalSite()
Const Cible As String = "K2"
Dim LastLig As Long, i As Long, n As Long, Duree As Double
Dim M1 As Byte, M2 As Byte, MoisNum As Byte
Dim MonDico As New Scripting.Dictionary
Dim Str As String, LaCause As String
Dim Tb, Res()
Application.ScreenUpdating = False
With Feuil1
LastLig = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range(Cible).Resize(LastLig, 2).ClearContents
Tb = .Range("A2:E" & LastLig)
LaCause = .[Cause]
MoisNum = Application.Match(.[Mois], .[ListeMois], 0)
For i = 1 To UBound(Tb, 1)
If Tb(i, 5) = LaCause Then
M1 = Month(Tb(i, 2))
M2 = Month(Tb(i, 3))
If Entre(MoisNum, M1, M2) Then
If M1 < MoisNum Then Tb(i, 2) = DebMois(Tb(i, 2), MoisNum)
If M2 > MoisNum Then Tb(i, 3) = FinMois(Tb(i, 3), MoisNum)
Duree = Tb(i, 3) - Tb(i, 2)
Str = Tb(i, 1)
If Not MonDico.Exists(Str) Then
MonDico.Add Str, Duree
Else
MonDico(Str) = MonDico(Str) + Duree
End If
End If
End If
Next i
n = MonDico.Count
If n > 0 Then
ReDim Res(1 To n, 1 To 2)
For i = 0 To n - 1
Res(i + 1, 1) = MonDico.Keys(i)
Res(i + 1, 2) = MonDico.Items(i)
Next i
Set MonDico = Nothing
.Range(Cible).Resize(n, 2) = Res
.Range(Cible).Offset(0, 1).Resize(n, 1).NumberFormat = "dd ""jour(s)"" hh"" heure(s) ""mm"" minute(s)"""
.Range(Cible).Resize(n, 2).Sort Key1:=.Range(Cible), Order1:=xlAscending, Header:=xlNo
End If
End With
End Sub
Private Function Entre(ByVal M As Byte, ByVal Mi As Byte, ByVal Mf As Byte) As Boolean
Entre = M >= Mi And M <= Mf
End Function
Private Function DebMois(ByVal Dte As Long, ByVal M As Byte) As Long
DebMois = DateSerial(Year(Dte), M, 1)
End Function
Private Function FinMois(ByVal Dte As Long, ByVal M As Byte) As Double
FinMois = DateSerial(Year(Dte), M + 1, 1) - 1 / 1440
End Function