Private Sub Worksheet_Calculate()
Dim i As Variant
i = Application.Match(9 ^ 99, [A:A])
'---correction si le tableau est trié sur une autre colonne que la colonne A---
If Val(CStr(i)) > 4 Then If Evaluate("SUM(-(A3:A" & i - 1 & "<A4:A" & i & "))") _
And Evaluate("SUM(-(A3:A" & i - 1 & ">A4:A" & i & "))") Or [U3] = "" _
Then Worksheet_Change [A3]: Application.ScreenUpdating = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, [A:A,T:V,Y:AA,AD:AF,AI:AK,AN:AQ,AV:AV]) Is Nothing Then Exit Sub 'à adapter
Dim NlignesVides&, tablo As Range, styl$, i&, ColA As Range, n&, zoneA&(), celBaseF1
Dim plageF1 As Range, plageF2 As Range, plageF3 As Range, pas%, a(), b(), plageMoy$, deb&, fin&, f$
NlignesVides = 10 'nombre de lignes vides sous le tableau, à adapter
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
On Error Resume Next
With ListObjects(1) 'si un tableau Excel a été créé
Set tablo = .Range: styl = .TableStyle: .TableStyle = "": .Unlist
End With
ShowAllData 'si la feuille est filtrée
i = Application.Match(9 ^ 99, [A:A])
If i < 3 Then GoTo 1
'---détermination de ColA et épuration---
Set ColA = Range("A3.A" & i)
ColA.EntireRow.Sort ColA, xlAscending, Header:=xlNo 'tri de sécurité
If ColA.Count > 1 Then ColA.SpecialCells(xlCellTypeBlanks).EntireRow.Delete 'vides
If ColA.Count > 1 Then ColA.SpecialCells(xlCellTypeConstants, 2).EntireRow.Delete 'textes
'---mémorisation des lignes de début et de fin de zones en colonne A---
For i = 1 To ColA.Count
If ColA(i) <> ColA(i - 1) Then
n = n + 1
ReDim Preserve zoneA(1 To 2, 1 To n)
zoneA(1, n) = i
End If
zoneA(2, n) = i
Next i
'---initialisation des cellules de base et des plages des formules, à adapter éventuellement---
celBaseF1 = Array("H3", "J3", "L3", "N3", "P3") 'adresses (sans signe $)
Set plageF1 = Intersect(ColA.EntireRow, [T:T])
Set plageF2 = Intersect(ColA.EntireRow, [U:U])
Set plageF3 = Intersect(ColA.EntireRow, [V:V])
pas = 5 'décalage vers la droite
'---formules F1 F2 F3---
ReDim a(1 To ColA.Count, 1 To 1): b = a '2 tableaux auxiliaires pour accélérer
For i = 0 To UBound(celBaseF1)
Set plageF1 = plageF1.Offset(, pas * Sgn(i))
Set plageF2 = plageF2.Offset(, pas * Sgn(i))
Set plageF3 = plageF3.Offset(, pas * Sgn(i))
plageMoy = plageMoy & "," & plageF3(1).Address(0, 0) 'concaténation des adresses
plageF1 = "=" & celBaseF1(i) & "*" & plageF1(1, -1).Address(0, 0) & "+2*" & plageF1(1, 0).Address(0, 0)
For n = 1 To UBound(zoneA, 2)
deb = zoneA(1, n): fin = zoneA(2, n)
a(deb, 1) = "=MIN(" & plageF1(deb).Address(0, 0) & ":" & plageF1(fin).Address(0, 0) & ")"
f = "=13*" & plageF2(deb).Address(1, 0, ReferenceStyle:=xlR1C1, RelativeTo:=plageF3(deb)) _
& "/" & plageF1(deb).Address(0, 0, ReferenceStyle:=xlR1C1, RelativeTo:=plageF3(deb))
For deb = deb To fin
b(deb, 1) = f
Next deb, n
plageF2 = a: plageF3 = b 'restitution
Next i
'---dernières formules---
plageF3.Offset(, 1) = "=AVERAGE(" & Mid(plageMoy, 2) & ")"
plageF3.Offset(, 6) = "=SUM(" & plageF3(1, 2).Resize(, 5).Address(0, 0) & ")"
'---traitement des lignes sous le tableau---
i = Application.Match(9 ^ 99, [A:A]) 'dernière ligne du tableau
1 If i < 3 Then i = 3: Rows(3) = "" 'au moins une ligne pour conserver les formats
Rows(3).AutoFill Rows("3:" & i), xlFillFormats 'copie les formats
Rows(i + 1).Resize([V:V].Find("=13*/*", , xlFormulas, xlWhole, , xlPrevious).Row - i).Delete 'RAZ
n = 0: n = Rows(i + 1 & ":" & Rows.Count).Find("*", Cells(Rows.Count, 1), xlValues, , xlByRows, xlNext).Row
If n Then n = i + NlignesVides + 1 - n 'écart
If n > 0 Then Rows(i + 1).Resize(n).Insert: Rows(Rows.Count).Copy Rows(i + 1).Resize(n)
If n < 0 Then Rows(i + 1).Resize(-n).Delete
'---rétablit le tableau Excel avec son style---
i = 0: i = ColA.Count
ListObjects.Add(xlSrcRange, tablo.Resize(i + 1), , xlYes, , styl).Name = "Tableau1"
Application.ErrorCheckingOptions.InconsistentTableFormula = False 'efface les triangles verts des formules "incohérentes"
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
With UsedRange: End With 'actualise les barres de défilement
End Sub