Private Sub Worksheet_Change(ByVal Target As Range)
Dim tablo, d As Object, i&, x$, v, a(), n&, nn&
tablo = [Tableau1].Value2 '1er tableau structuré, matrice, plus rapide
Set d = CreateObject("Scripting.Dictionary")
d.CompareMode = vbTextCompare 'la casse est ignorée
For i = 1 To UBound(tablo)
x = tablo(i, 1): v = tablo(i, 2)
If x <> "" And IsNumeric(v) Then
If Not d.exists(x) Then
d(x) = n 'mémorise la ligne
ReDim Preserve a(2, n) 'base 0, 3 colonnes transposées
a(1, n) = x
n = n + 1
End If
nn = d(x)
a(0, nn) = a(0, nn) + v 'calcul du total
a(2, nn) = nn 'mémorise la ligne
End If
Next i
tablo = Empty
If n Then
tri a, 0, n - 1
ReDim tablo(n - 1, 2) 'base 0, 3 colonnes
For i = 0 To n - 1
tablo(i, 0) = a(1, i): tablo(i, 1) = a(0, i): tablo(i, 2) = a(2, i)
Next i
End If
'---restitution---
Application.ScreenUpdating = False
Application.EnableEvents = False 'désactive les évènements
With [Tableau2] '2ème tableau structuré
.Resize(, 3) = tablo
If n < .Rows.Count Then .Rows(n + 1).Resize(.Rows.Count - n).ClearContents 'RAZ en dessous
If n Then .Sort .Columns(2), xlDescending, .Columns(3), , xlAscending, Header:=xlYes 'tri sur 2 colonnes
.ListObject.Resize .ListObject.Range.Resize(, 2) 'redimensionne le tableau
.Columns(3).EntireColumn.ClearContents
End With
Application.EnableEvents = True 'réactive les évènements
End Sub
Sub tri(a, gauc, droi) ' Quick sort
Dim ref, g, d, temp
ref = a(0, (gauc + droi) \ 2)
g = gauc: d = droi
Do
Do While a(0, g) > ref: g = g + 1: Loop
Do While ref > a(0, d): d = d - 1: Loop
If g <= d Then
temp = a(0, g): a(0, g) = a(0, d): a(0, d) = temp
temp = a(1, g): a(1, g) = a(1, d): a(1, d) = temp
temp = a(2, g): a(2, g) = a(2, d): a(2, d) = temp
g = g + 1: d = d - 1
End If
Loop While g <= d
If g < droi Then Call tri(a, g, droi)
If gauc < d Then Call tri(a, gauc, d)
End Sub