Code dans le module Option Explicit

Sub MAJ_Facturation()

    Dim wsBL As Worksheet, wsSynAchat As Worksheet, wsSynAutres As Worksheet
    Dim lastRowBL As Long, lastRowAchat As Long, lastRowAutres As Long
    Dim i As Long, found As Range
    Dim key As String, facture As String, depot As String
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")

    ' Feuilles
    Set wsBL = ThisWorkbook.Sheets("BL_a_facturer")
    Set wsSynAchat = ThisWorkbook.Sheets("Synthese_A_l_achat")
    Set wsSynAutres = ThisWorkbook.Sheets("Synthese_Autres")

    Application.ScreenUpdating = False

    ' Dernières lignes
    lastRowBL = wsBL.Cells(wsBL.Rows.Count, "A").End(xlUp).Row
    lastRowAchat = wsSynAchat.Cells(wsSynAchat.Rows.Count, "A").End(xlUp).Row
    lastRowAutres = wsSynAutres.Cells(wsSynAutres.Rows.Count, "A").End(xlUp).Row

    ' --- Étape 1 : Identifier visuellement les doublons dans BL_a_facturer ---
    wsBL.Range("A2:Z" & lastRowBL).Interior.ColorIndex = xlNone
    For i = 2 To lastRowBL
        key = Trim(wsBL.Cells(i, "C").Value) & "|" & _
              Trim(wsBL.Cells(i, "D").Value) & "|" & _
              Trim(wsBL.Cells(i, "F").Value)
        If dict.exists(key) Then
            wsBL.Rows(i).Interior.Color = RGB(255, 230, 150)
            wsBL.Rows(dict(key)).Interior.Color = RGB(255, 230, 150)
        Else
            dict.Add key, i
        End If
    Next i

    ' --- Étape 2 : Copier ou mettre à jour dans les synthèses ---
    For i = 2 To lastRowBL
        key = Trim(wsBL.Cells(i, "C").Value) & "|" & _
              Trim(wsBL.Cells(i, "D").Value) & "|" & _
              Trim(wsBL.Cells(i, "F").Value)

        depot = Trim(wsBL.Cells(i, "E").Value)
        facture = Trim(wsBL.Cells(i, "K").Value)

        ' Si DEPOT = "ACHAT" => vers Synthese_A_l_achat
        If UCase(depot) = "ACHAT" Then
            Set found = wsSynAchat.Range("A:Z").Find(key, LookIn:=xlValues, lookat:=xlWhole)
            If found Is Nothing Then
                ' Nouvelle ligne
                lastRowAchat = wsSynAchat.Cells(wsSynAchat.Rows.Count, "A").End(xlUp).Row + 1
                wsSynAchat.Rows(lastRowAchat).Value = wsBL.Rows(i).Value
                If facture <> "" Then wsSynAchat.Cells(lastRowAchat, "K").Value = facture
            Else
                ' Déjà existante : mise à jour du n° de facture
                If facture <> "" Then wsSynAchat.Cells(found.Row, "K").Value = facture
            End If

        Else
            ' Sinon vers Synthese_Autres
            Set found = wsSynAutres.Range("A:Z").Find(key, LookIn:=xlValues, lookat:=xlWhole)
            If found Is Nothing Then
                lastRowAutres = wsSynAutres.Cells(wsSynAutres.Rows.Count, "A").End(xlUp).Row + 1
                wsSynAutres.Rows(lastRowAutres).Value = wsBL.Rows(i).Value
                If facture <> "" Then wsSynAutres.Cells(lastRowAutres, "K").Value = facture
            Else
                If facture <> "" Then wsSynAutres.Cells(found.Row, "K").Value = facture
            End If
        End If
    Next i

    ' --- Étape 3 : Supprimer les lignes facturées de BL_a_facturer ---
    For i = lastRowBL To 2 Step -1
        If Trim(wsBL.Cells(i, "K").Value) <> "" Then wsBL.Rows(i).Delete
    Next i

    Application.ScreenUpdating = True
    MsgBox "Mise à jour terminée (copie + suppression des lignes facturées)", vbInformation

End Sub

Code dans la feuille Lignes_BL

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo SafeExit

    ' Ignore les changements sur l'entête
    If Target.Row <= 1 Then Exit Sub

    ' Si des lignes sont ajoutées ou modifiées, on relance la mise à jour globale
    Application.EnableEvents = False
    Call MAJ_Facturation

SafeExit:
    Application.EnableEvents = True
End Sub


Code dans la feuille BL_a_facturer 

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo SafeExit
    Dim watchCol As Range
    Set watchCol = Me.Columns("K") ' colonne N° facture

    ' Vérifie si la modification concerne la colonne K
    If Not Intersect(Target, watchCol) Is Nothing Then
        ' Vérifie qu'on n'est pas dans les en-têtes
        If Target.Row > 1 Then
            Application.EnableEvents = False
            ' Lance la macro de mise à jour complète
            Call MAJ_Facturation
        End If
    End If

SafeExit:
    Application.EnableEvents = True
End Sub
 
