Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim an%, preced1 As Worksheet, preced2 As Worksheet, PlageFormule As Range, formule$, i&, j&, zone As Range, tablo, n&, lig&, r As Range, a, b, k%
an = Val(Sh.Name)
If an = 0 Then Exit Sub
Set Target = Intersect(Target, Sh.Range("D3:D" & Sh.Rows.Count), Sh.UsedRange)
If Target Is Nothing Then Exit Sub
Application.ScreenUpdating = False
Application.EnableEvents = False 'désactive les évènements
On Error Resume Next
Set preced1 = Sheets(an - 1 & "_" & an)
Set preced2 = Sheets(an - 2 & "_" & an - 1)
Set PlageFormule = Intersect(Sh.Columns(13), Target.EntireRow) 'colonne M
formule = PlageFormule(1).FormulaR1C1 'mémorise
PlageFormule = False 'supprime les formules
For Each zone In Intersect(Target.EntireRow, Sh.Columns(5).Resize(, 10)).Areas 'colonnes E à N
tablo = zone 'matrice, plus rapide
n = 0
For Each r In zone.Rows
n = n + 1
i = 0: j = 0: lig = r.Row
i = Application.Match(r.Cells(1, 0), preced1.Columns(4), 0)
j = Application.Match(r.Cells(1, 0), preced2.Columns(4), 0)
a = "": b = ""
a = preced1.Range(Replace(r.Address, lig, i))
b = preced2.Range(Replace(r.Address, lig, j))
For k = 1 To 10
If IsEmpty(tablo(n, k)) Then tablo(n, k) = a(1, k): If IsEmpty(tablo(n, k)) Then tablo(n, k) = b(1, k)
Next k, r
zone = tablo 'restitue le tableau modifié
Next zone
PlageFormule = formule 'restitue les formules
Application.EnableEvents = True 'réactive les évènements
End Sub