VBA - Cumuler Copier/coller en boucle avec une formule

Bonsoir à tous !!

ça faisait longtemps que je n'étais pas venu ici, et du coup longtemps que je n'ai pas pratiqué excel par la même occasion

du coup j'ai perdu toutes notions de VBA, même si elles étaient déjà légères à la base.

j'ai un petit soucis, j'ai créé un fichier qui me sers de vérification, il va piocher dans un classeur (1) puis un classeur (2) et vérifie les données manquantes du classeur 1 dans le classeur 2 et vice versa.

J'ai très bien réussi à faire cette fonction via une formule dans une cellule , (index+equiv) présente dans le fichier

mais j'aimerais la coupler avec un copier-coller en boucle avec condition (si cellule non VIDE) , afin qu'il ne me laisse pas de "blanc"

Je vous joint en pièce jointe l'idée. car c'est toujours compliqué d'expliquer il y a 2 fichiers N et N1 qui sont l'équivalent de mes fichiers de données à traiter.

et mon fichier synthèse ou il y a un tableau avec ma formule qui va piocher dans N et N1 mais qui bien évidement n'est pas "rangé". car juste une formule étendue à d'autres cellules.

je n'ai pas mis de "début de macro" car même mon "copié collé en boucle si cellule non vide" était bancale

un grand merci d'avance pour votre aide.

11recherche.zip (19.30 Ko)

Bonjour,

Une piste :

Sub Test()

    Dim Cls_N As Workbook
    Dim Cls_N1 As Workbook
    Dim PlgN As Range
    Dim PlgN1 As Range
    Dim CelN As Range
    Dim CelN1 As Range
    Dim TN() As String
    Dim TN1() As String
    Dim I As Long
    Dim Trouver As Boolean

    On Error Resume Next
    Set Cls_N = Workbooks("N.xls")
    If Err.Number <> 0 Then MsgBox "Le classeur 'N.xls' est fermé !": Exit Sub
    Err.Clear

    Set Cls_N1 = Workbooks("N+1.xls")
    If Err.Number <> 0 Then MsgBox "Le classeur 'N+1.xls' est fermé !": Exit Sub

    With Cls_N.Worksheets("Feuil1"): Set PlgN = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)): End With
    With Cls_N1.Worksheets("Feuil1"): Set PlgN1 = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)): End With

    'recherche de l'un dans l'autre...
    For Each CelN In PlgN

        If CelN <> "" Then

            Set CelN1 = PlgN1.Find(CelN.Value, , xlValues, xlWhole)

            If CelN1 Is Nothing Then

                I = I + 1: ReDim Preserve TN1(1 To I)
                TN1(I) = CelN.Value

            End If
        End If

    Next CelN

    I = 0

    '...et vice versa
    For Each CelN1 In PlgN1

        If CelN1 <> "" Then

            Set CelN = PlgN.Find(CelN1.Value, , xlValues, xlWhole)

            If CelN Is Nothing Then

                I = I + 1: ReDim Preserve TN(1 To I)
                TN(I) = CelN1.Value

            End If
        End If

    Next CelN1

    'résultat dans le classeur synthèse où doit se trouver ce code !
    With ThisWorkbook.Worksheets("Feuil1")

        For I = 1 To UBound(TN)

            .Cells(I + 2, 2).NumberFormat = "@"
            .Cells(I + 2, 2).Value = TN(I)

        Next I

        For I = 1 To UBound(TN1)

            .Cells(I + 2, 1).NumberFormat = "@"
            .Cells(I + 2, 1).Value = TN1(I)

        Next I

    End With

End Sub

Wow, ha oui, je m'attendais a quelque chose de plus simple.

Ça marche parfaitement. Un grand merci à toi !

Il faut que j'arrive à comprendre un peu ce code.

A quoi correspond les variables TN et TN1 ?

Et aussi comment fonctionne la variable PlgN avec les fameux roms count et x1up.

J'en vois souvent dans des exemples mais je ne comprends pas.

PlgN = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)): End

.range(.cells(1,1) définit la cellule de départ?

.cells(rows.count,1) c'est l'équivalent d'une variable pour la ligne et 1 et constante en colonne 1?

Ha non sayez j'ai compris pour plgn et n1.

Du défini la plage de recherche dans chaque fichier en comptant le nombre de ligne rows count et le end x1up tu remonte après la dernière ligne vide ?

Par contre ça doit pas être exactement ça car comme je la lis, j'en comprend. Compte les lignes jusqu'à une cellule vide et remonte d'un cran.

Hors dans mon fichier il y a des trous, donc il devrait arrêter au premier trou rencontré hors c'est pas le cas.

Y'a un truc qui m'échappe.

Re

Ici, comme je pense que tu l'as compris on contrôle si les deux classeurs sont ouverts :

On Error Resume Next
Set Cls_N = Workbooks("N.xls")
If Err.Number <> 0 Then MsgBox "Le classeur 'N.xls' est fermé !": Exit Sub
Err.Clear

Set Cls_N1 = Workbooks("N+1.xls")
If Err.Number <> 0 Then MsgBox "Le classeur 'N+1.xls' est fermé !": Exit Sub

Ici, on défini les plages :

With Cls_N.Worksheets("Feuil1"): Set PlgN = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)): End With
With Cls_N1.Worksheets("Feuil1"): Set PlgN1 = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)): End With

La propriété End() permet, selon son argument, de remonter, descendre, aller vers la droite ou vers la gauche en partant de la cellule spécifiée pour trouver la première cellule qui ne soit pas vide. Dans mon code, la cellule spécifiée est la cellule la plus basse de la colonne(ici, la colonne A n° = 1), pour Excel < 2007, il y a 65536 lignes et Excel 2007 et plus 1048576 lignes. En partant du bas, on est certain de ne pas "oublier" des cellules ! "Cells(1, 1)" veux simplement dire ligne 1, colonne 1 donc A1 puisque c'est dans la colonne A que se trouvent les valeurs !

Ici, on effectue les recherches avec la méthode Find() qui elle parcours la plage mais comme le code est compilé, la méthode est bien plus rapide que si on demande au compilateur de le faire. Il faut savoir que le compilateur, celui qui interprète les lignes de code que nous écrivons, lit les lignes une par une de gauche à droite et de haut en bas, d'où le mot "code interprété". Donc, si la valeur est trouvée elle est stockée dans un tableau, pourquoi un tableau ? Mais tout simplement parce qu'il peut y avoir plusieurs valeurs qui se trouvent dans une plage et pas dans l'autre et vice versa. J'ai utilisé un tableau pour chaque plage, j'aurais pu en utilisé qu'un seul mais plus compliqué à comprendre car il aurait fallut définir des clés pour différencier les valeurs :

For Each CelN In PlgN

    If CelN <> "" Then

        Set CelN1 = PlgN1.Find(CelN.Value, , xlValues, xlWhole)

        If CelN1 Is Nothing Then

            I = I + 1: ReDim Preserve TN1(1 To I)
            TN1(I) = CelN.Value

        End If
    End If

Next CelN

Et ici, je ne fait que de lire les valeurs dans les tableaux et de les inscrire dans les cellules. .NumberFormat = "@" permet de mettre les cellules au format texte car tu as des valeurs de type code postal "02365" sinon, le zéro de début sauterait :

With ThisWorkbook.Worksheets("Feuil1")

    For I = 1 To UBound(TN)

        .Cells(I + 2, 2).NumberFormat = "@"
        .Cells(I + 2, 2).Value = TN(I)

    Next I

    For I = 1 To UBound(TN1)

        .Cells(I + 2, 1).NumberFormat = "@"
        .Cells(I + 2, 1).Value = TN1(I)

    Next I

End With

En espérant t'avoir éclairé

Rechercher des sujets similaires à "vba cumuler copier coller boucle formule"