VBA : copier-coller 2 colonnes d'un classeur vers 1 seule dans un autre

Bonjour,

Novice en VBA, je cherche à copier coller des données d'un classeur "source" à un classeur "destination".

Jusqu'à présent mon code fonctionnait très bien puisque je copiais des colonnes dans d'autres colonnes : basique.

MAIS : nouveau cas de figure : J'ai deux colonnes différentes dans le classeur "source" qui doivent finir dans une seule colonne dans le classeur "destination".

Pour chaque ligne :

si la colonne CJ est différente de vide alors la coller dans la colonne F dans le classeur 2,

sinon placer le curseur dans la colonne DD, si elle est différente de vide alors la coller dans la colonne F du classeur 2

Précisions : dans le classeur "source" le nombre de ligne évolue c'est donc aussi le cas dans le classeur "destination"

J'imagine que c'est très simple pour des initiés mais j'ai déjà beaucoup cherché et je manque de temps.

Je crois qu'il faut que je fasse une boucle avec deux conditions, ainsi qu'une variable qui compte le nombre de ligne ; intuitions surement fausses et que si même bonnes je n'arrive pas à mettre en oeuvre...

Merci d'avance,

Bonjour,

Une proposition à coller dans un module VBA dans ton classeur Source (à enregistrer au format ".xlsm") :

Sub CopieSpeciale()

Dim Lig As Long, LigMax As Long, Source As Worksheet, Destination As Worksheet

Set Source = ThisWorkbook.ActiveSheet
Set Destination = Workbooks("Classeur1").Sheets("Feuil1")

With Source
    LigMax = .Range("CJ" & Rows.Count).End(xlUp).Row 'Détermine la dernière ligne
    For Lig = 2 To LigMax 'Boucle sur les lignes
        If Not IsEmpty(.Range("CJ" & Lig)) Then 'Si "CJ" <> vide
            Destination.Range("F" & Lig) = .Range("CJ" & Lig) 'reporter la valeur
        ElseIf Not IsEmpty(.Range("DD" & Lig)) Then Destination.Range("F" & Lig) = .Range("DD" & Lig) 'Sinon si DD <> vide, reporter la valeur
        End If
    Next Lig
End With

End Sub

PS : le nom du classeur et de la feuille de destination est à adapter

Bonjour,

Novice en VBA

Ta description de l'opération le montre ! Tu indiques ce que tu ferais manuellement, pas la façon dont VBA peut faire :

tu dois parcourir ton tableau ligne par ligne... eh bien d'abord tu le prélèves en tableau pour l'examiner hors Excel :

    aa = ActiveSheet.Range("A1").CurrentRegion.Value

on suppose que ton tableau commence bien en A1 et qu'il comporte une ligne d'en-tête, et que ce n'est pas un tableau Excel (sans quoi on procèderait différemment !).

Pour parcourir les lignes une boucle :

    For i = 2 To UBound(aa)

Pour chaque ligne on teste les 2 cellules concernées, et si contiennent une valeur on prélève pour placer dans un tableau résultat :

        If aa(i, 88) <> "" Then
            Redim Preserve Tbl(n)
            Tbl(n) = aa(i, 88) : n = n + 1
        End If
        If aa(i, 108) <> "" Then
            Redim Preserve Tbl(n)
            Tbl(n) = aa(i, 108) : n = n + 1
        End If

Et quand c'est fini, on n'a plus qu'à ajouter les données prélevées dans la feuille cible.

On ira chercher la ligne à partir de laquelle insérer dans la colonne F de la feuille (inconnue), du classeur destinataire (dont on ignore le nom, et dont on ne sait s'il est déjà ouvert...).

Supposons i cette lignes d'insertion, dans la colonne F :

        .Cells(i, 6).Resize(n).Value = WorksheetFunction.Transpose(Tbl)

Et le tour sera joué. Mais on te fera ça à partir de classeurs modèles que tu n'as pas encore fournis...

Cordialement.

edit : Salut Pedro !

Merci beaucoup, je m'attendais pas à avoir une réponse si rapide !

J'ai testé le code, j'ai du faire me tromper car j'ai un message d'erreur

Une idée ?

Bonjour,

Une proposition à coller dans un module VBA dans ton classeur Source (à enregistrer au format ".xlsm") :

Sub CopieSpeciale()

Dim Lig As Long, LigMax As Long, Source As Worksheet, Destination As Worksheet

Set Source = ThisWorkbook.ActiveSheet
Set Destination = Workbook("Classeur1").Sheets("Feuil1")

With Source
    LigMax = .Range("CJ" & Rows.Count).End(xlUp).Row 'Détermine la dernière ligne
    For Lig = 2 To LigMax 'Boucle sur les lignes
        If Not IsEmpty(.Range("CJ" & Lig)) Then 'Si "CJ" <> vide
            Destination.Range("F" & Lig) = .Range("CJ" & Lig) 'reporter la valeur
        ElseIf Not IsEmpty(.Range("DD" & Lig)) Then Destination.Range("F" & Lig) = .Range("DD" & Lig) 'Sinon si DD <> vide, reporter la valeur
        End If
    Next Lig
End With

End Sub

PS : le nom du classeur et de la feuille de destination est à adapter

capture d ecran 2018 08 08 a 11 00 44

J'ai oublié un "s" à la fin de Workbooks

PS : le classeur destination doit être ouvert au préalable (sinon il faut changer le code)

Merci ; je comprends l'idée, je vais essayer par moi même...

Je ne suis pas en droit de fournir les dits classeurs, malheureusement. :/

Et le tour sera joué. Mais on te fera ça à partir de classeurs modèles que tu n'as pas encore fournis...

J'ai rajouté le "s" toujours une erreur sur la même ligne : "L'indice est en dehors des dimensions du tableau"

Ne faut il pas que je rajoute un ligne pour ouvrir le classeur de destination en indiquant le chemin d'accès ?

Workbooks.Open "/Users/aubrynina/Desktop/REPERTOIRE/ALL.xlsm"

Je ne suis pas en droit de fournir les dits classeurs, malheureusement. :/

Ceci est un argument qui ne sert qu'à se dispenser d'en fabriquer !

Pedro est de très bonne composition, mais cela démontre qu'en travaillant sur du vide on est obligé de reprendre à plusieurs fois...

bonjour à tous

Microsoft s'est rendu compte il y a 10 ans que les utilisateurs d'Excel géraient des données et ensuite voulaient les dispatcher dans d''autres feuilles ou classeurs

et il a bien travaillé.

il est résulté Power Query

ce module enfonce littéralement VBA pour ce genre de travail. Depuis 10 ans et il est très loin de se limiter aux xlsx

il sait lire toutes sortes de formats, même des qu'on ne connaît pas

il pré-traite les données, les digère et les affiche là où on veut !

c'est un ETL (voir Wiki)

en pratique, on ouvre le xlsx de destination,

menu Données Obtenir de Excel

et on plonge dans un monde merveilleux (déroutant au début, mais 1000 fois plus facile que VBA)

voir les tutos sur le web.

note générale : avant d'apprendre VBA, apprendre Excel et tous ses menus dont la richesse est géniale.

bonne journée à vous

PS : le classeur destination doit être ouvert au préalable (sinon il faut changer le code)

S'il n'est pas ouvert, alors oui, dans destination tu peux mettre l'instruction type Workbooks.Open. Si ta base de données à une dimension conséquente, il serait judicieux de s'orienter vers la proposition de @MFerrand

Oh, je suis vraiment désolée je n'avais pas vu la précision !

Merci beaucoup, je vérifie mais ça à l'air de fonctionner.

Base de donnée trop conséquente? à partir de quand c'est trop conséquent ? (6 861lignes pour 189 colonnes)

Une dernière question : est il possible d'appeler cette macro depuis ma macro générale qui est (je ne sais pas si ça se dit, je ne voudrais froisser personne) "dans mon classeur destination" / "rattachée à mon classeur destination" ?

Encore merci d'avoir pris le temps, de me répondre si vite, si gentiment et sans pourvoir voir les classeurs...

re

joins un fichier de départ exemple et un de destination exemple,tout avec des données fictives

je vais faire une soluce sans VBA et qui accepte 1 000 000 lignes sans sourciller

La solution précédente fonctionne presque et ça m'arrange que ça soit en VBA, en fait il le faut même puisque je dois programmée toute la macro pour qu'elle soit activée par quelqu'un d'autre dans deux mois

Je suis vraiment désolée...

Dernière question : Je réalise un filtre sur une autre colonne dans le classeur "source", je souhaite que la boucle soit donc réalisée sur ces lignes du classeur. J'ai donc légèrement modifié le code, c'est ok ça fonctionne. SAUF que quand les cellules sont collées elles le sont aux mêmes lignes quand dans le fichier source et non pas selon le filtre qui les met toutes à la suite...

Une dernière idée, svp ?

capture bis

Que disais-je ? Même sans jmd (Salut !) on aurait atteint une 2e page pour une question aussi simple !

Rechercher des sujets similaires à "vba copier coller colonnes classeur seule"