Private Sub Worksheet_SelectionChange(ByVal r As Range)
Dim derlig&, liste, ub&, d As Object, tablo, i&, j&, x$
derlig = Range("H" & Rows.Count).End(xlUp).Row
If derlig < 4 Then Range("H4:I" & Rows.Count).Delete xlUp: Exit Sub
Set r = Intersect(r, Range("H4:H" & derlig))
If r Is Nothing Then Exit Sub
Application.ScreenUpdating = False
Range("H4:H" & Rows.Count).Interior.ColorIndex = xlNone 'RAZ
Range("I4:I" & Rows.Count) = "" 'RAZ
'---stockage en colonne J (masquée)---
[J:J] = "" 'RAZ
If r.Count > 100 Then 'limite
Set r = Range("H4:H" & derlig) 'on sélectionne tout
Else
r.Copy [J1]
liste = [J1].Resize(r.Count, 2) 'matrice, plus rapide, au moins 2 éléments
ub = UBound(liste)
End If
r.Interior.ColorIndex = 44 'orange
Set d = CreateObject("Scripting.Dictionary")
d.CompareMode = vbTextCompare 'la casse est ignorée
'---tableau source---
tablo = Range("A4:C" & Range("A" & Rows.Count).End(xlUp).Row + 3) 'matrice, plus rapide
For i = 1 To UBound(tablo)
If tablo(i, 1) <> "" And tablo(i, 2) <> "" And tablo(i, 3) <> "" Then
If ub Then
For j = 1 To ub
If tablo(i, 2) = liste(j, 1) Then
x = tablo(i, 1) & Chr(1) & liste(j, 1) 'concaténation avec séparateur
d(x) = d(x) + tablo(i, 3) 'somme
End If
Next j
Else
x = tablo(i, 1)
d(x) = d(x) + tablo(i, 3) 'somme
End If
End If
Next i
'---tableau des résultats---
With Range("G4:I" & Range("G" & Rows.Count).End(xlUp).Row + 3)
tablo = .Value 'matrice, plus rapide
For i = 1 To UBound(tablo)
If ub Then
For j = 1 To ub
x = tablo(i, 1) & Chr(1) & liste(j, 1) 'concaténation avec séparateur
If d.exists(x) Then tablo(i, 3) = tablo(i, 3) + d(x)
Next j
Else
x = tablo(i, 1)
If d.exists(x) Then tablo(i, 3) = d(x)
End If
Next i
.Columns(3) = Application.Index(tablo, , 3) 'restitution en colonne I
End With
End Sub