VBA_Copier sur la base des entêtes

Résolu/Fermé
senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020 - 14 avril 2015 à 23:48
via55 Messages postés 14040 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 5 février 2023 - 23 juil. 2015 à 10:23
Bonjour,
J'ai un fichier excel avec deux onglets (source et cible).
Je souhaiterais copier des données de l'onglet source vers cible en se référant des entêtes de mes données.
La macro doit récupérer les données de l'onglet source et les coller dans l'onglet cible après avoir fait la correspondance entre le noms des colonnes entre les deux onglets.
Je sais faire une macro qui copie et colle une plage mais ce je souhaite ici c'est que quelques soit la disposition des onglets entre les deux onglets que ma macro soit capable de copier et de coller les données aux bonnes colonnes dans l'onglet cible.
Je vous joint via le lien ci-dessous un exemple simplifié.
https://www.cjoint.com/c/EDpabmmEeeH
Merci beaucoup pour votre aide

4 réponses

via55 Messages postés 14040 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 5 février 2023 2 550
15 avril 2015 à 01:16
Bonsoir senecatour

Macro selon ton exemple :
https://www.cjoint.com/?0DpbDwN45rQ

Cdlmnt
Via
0
senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020 3
15 avril 2015 à 15:51
Bonjour Via 55
Merci beaucoupo via 55. C'est super! c'est exactement ce que je voulais.
Cependant, il y a une chose dont j'aimerais comprendre dans le code de la macro.
que signifie les espace (, , , , , ) dans la ligne suivante?
ligne = Sheets("Source").Columns(2).Find("*", , , , xlByColumns, xlPrevious).Row

J'aimerais bien comprendre ce code.
Merci d'avance pour tes explications.

Cordialement,
0
via55 Messages postés 14040 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 5 février 2023 2 550 > senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020
15 avril 2015 à 16:01
0
senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020 3
16 avril 2015 à 17:18
Bonjour Via55,
Merci pour votre aide.

J'ai retravaillé votre code en essayant de l'adapter à mon besoin.
Cette fois -ci, je dois copier les données depuis un autre classeur Excel appelé (source)
L'idée est la suivante:
en lançant ma macro depuis contenu dans l'onglet cible, j'exécute les tâches suivantes:
-J'ouvre le classeur source grâce à un lien contenu dans l'onglet "parametre" du classeur cible
-Je sélectionne l'onglet souhaité qui porte le même nom que l'onglet actif de mon classeur cible
-Je copie les données depuis le classeur source vers le classeur cible et ceci en utilisant la méthode que tu m'avais proposée.

J'ai essayé d'adapter mon code mais je n'y arrive pas.
Je vous joins les deux fichiers d'exemple (source et cibe) avec les codes dans le classeur cible.
https://www.cjoint.com/c/EDqrErbQWYY
https://www.cjoint.com/c/EDqrFFRTglR

Si vous pouvez vraiment m'aider à résoudre ce problème, ce sera Top.

Je vous remercie beaucoup pour votre aide.
0
via55 Messages postés 14040 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 5 février 2023 2 550 > senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020
17 avril 2015 à 02:04
Bonsoir Senecartour

1) Tu avais enregistré le code en tant que fonction (Function) et non en tant que macro dans un module (Sub)
2) des erreurs dans certaines lignes comme le nom de variable de feuille entre guillemets
3) Pour travailler avec 2 classeurs en même temps il faut clairement les identifier (WBsource et WBcible dans ma macro) et adapter la macro (pas possible d'utiliser activeworkbook, activesheet etc)
4) J'ai revu la macro :
Pour la lancer d'une feuille de Cible tu peux utiliser le raccourci que je lui ai donné : CTRL + i ou depuis Macros dans onglet Developpeur du Ruban
Mais avant il faut indiquer le chemin complet de Source dans la feuille parametre

https://www.cjoint.com/?0DrcsjAYgNx

Cdlmnt
Via
0
senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020 3
21 avril 2015 à 23:30
Bonsoir Via55,

Je n'ai pas pu répondre à votre message car j'étais en vacance. Votre méthode fonctionne mais cela ne correspond pas exactement à ce que je souhaite.

mon souhait, c'est de créer une fonction qui permet de copier et de coller les données sur la base des entêtes. Après je pourrais utiliser cette fonction dans une procédure Sub.

L'avantage pour cette solution, c'est que je n'aurais pas à définiri à chaque fois les noms des onglets sources et cibles. Car je peux avoir jusqu'à 15 onglets dans les classeurs source et cible.

Le nom de mon onglet source est défini par rapport à celui de l'onglet cible dans le quel je me place.

Autrement dit, si je me place par exemple dans mon classeur cible dans un onglet nommé "Batiment" et que je lance ma macro, cette dernière doit ouvrir l'onglet "Batiment" dans le classeur source et copier les données.
C'est exactement mon souhait.

Si vous pouvez m'aider à résoudre ce problème, vous me soulagez énormément, car, je n'arrive pas à trouver la solution.

Merci encore pour le temps que vous consacrez pour aider les gens.

Cordialement,
0
senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020 3
Modifié par senecartour le 25/06/2015 à 15:41
Bonjour via55,

Je reviens vers vous pour un petit réglage de la macro que vous m'aviez aidé à réaliser et qui me sert énormément. Merci encore une fois.

Le petit réglage dont je n'arrive pas à faire est le suivant:
J'ai deux fichier (source et cible). l'idée est de copier les données du fichier cible vers le fichier source et ceci en comparant les entête (jusqu'ici tout est nickel).

Sauf que lorsqu'il y a une entête dans le fichier cible qui n'existe pas dans le fichier source, la macro beug.

Mon souhait est le suivant:
Peu importe la nature ou le nombre d'entête dans mon fichier cible, l'idée c'est de récupérer toutes les données des colonnes du fichier source et de les coller dans des bonnes colonnes du fichier cible et ceci même s'il y a une entête présente dans le fichier cible mais absente dans le fichier source.

Je te joins les deux fichiers.
https://www.cjoint.com/c/EFznOKNGjea
https://www.cjoint.com/c/EFznO3wqqGa

Merci encore énormément,

Partager son savoir est la meilleure façon d'apprendre!
0
via55 Messages postés 14040 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 5 février 2023 2 550
25 juin 2015 à 17:43
Bonjour senecartour

Essaie de remplacer la macro dans cible par celle-ci :
Sub A_Import()

Application.DisplayAlerts = False
Application.ScreenUpdating = False

Dim lientetesource As Long, coentetesource As Integer, lientetecible As Long, coentetecible As Integer, WBsource As Workbook, WBcible As Workbook

If MsgBox("Voulez-vous importez les données?", vbYesNo, "Import") = vbNo Then
    Exit Sub
Else

Set WBcible = Workbooks(ActiveWorkbook.Name)
Set WBsource = Workbooks.Open(WBcible.Sheets("parametre").Cells(3, 2).Value)

ongletcible = ThisWorkbook.ActiveSheet.Name
' nom onglet source est le même que onglet cible sauf dans le cas de feuille Capital où c'est Pays
If ThisWorkbook.ActiveSheet.Name = "Gammes_Taches" Or ThisWorkbook.ActiveSheet.Name = "Gammes_MO" Then ongletsource = "Gammes" Else ongletsource = ongletcible

' derniere ligne remplie de source
ligentetesource = WBsource.Sheets(ongletsource).Columns(2).Find("*", , , , xlByColumns, xlPrevious).Row
'derniere colonne remplie de source
colentetesource = WBcible.Sheets(ongletcible).Rows(2).Find("*", , , , xlByRows, xlPrevious).Column
' boucle sur les colonnes de cible
  For n = 2 To colentetesource
' en tete de la colonne desource
      entetesource = WBsource.Sheets(ongletsource).Cells(2, n)
' colonne de cible correspondant à cet en tête
On Error GoTo suite
      coentetecible = WBcible.Sheets(ongletcible).Rows(2).Find(entetesource, , , xlWhole, xlByRows, xlPrevious).Column
      ' boucle sur les lignes
        For t = 7 To ligentetesource
        ' copie ligne source dans cible
        WBcible.Sheets(ongletcible).Cells(t + 3, coentetecible) = WBsource.Sheets(ongletsource).Cells(t, n)
        Next t
suite:
    Next n
End If
WBsource.Close

End Sub


On fait l'inverse, au lieu de boucler sur les colonnes de cible on boucle sur les colonnes de source et si l'en tête existe dans cible on copier les lignes

Cdlmnt
Via
0
senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020 3
25 juin 2015 à 19:44
Super via55,
ça fonctionne impeccablement!!
0
senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020 3 > senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020
26 juin 2015 à 15:10
Bonjour via55,

J'ouvre à nouveau le sujet suite à une remarque sur la macro que vous m'avez proposé.
La macro fonctionne dans un sens mais pas dans l'autre.
Autrement dit, si une entête est présente dans l'onglet cible mais absente dans l'onglet source, la copie se fait sans problème.
Par contre si une entête est présente dans l'onglet source mais absente dans l'onglet cible, la macro beug.
Pourriez-vous m'aider réaliser cette étape ?

En résumé, je souhaite que la macro fasse des recherches sur la base des entêtes et copier les données de l'onglet source vers l'onglet cible. Elle ne doit pas contrôler et ceci même si une entête est absente dans un onglet ou dans un autre.

Merci pour votre retour.
0
via55 Messages postés 14040 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 5 février 2023 2 550 > senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020
26 juin 2015 à 17:27
Bonjour

Oui j'ai fait une erreur dans la macro que je t'ai envoyé, oublié de rectifier une ligne, celle ci :
colentetesource = WBcible.Sheets(ongletcible).Rows(2).Find("*", , , , xlByRows, xlPrevious
la bonne ligne est en fait : colentetesource = WBcible.Sheets(ongletsource).Rows(2).Find("*", , , , xlByRows, xlPrevious

Cdlmnt
Via
0
senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020 3 > via55 Messages postés 14040 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 5 février 2023
27 juin 2015 à 14:04
Bonjour via55,
J'ai corrigé mais une nouvelle erreur à mon avis liée aux histoire des entêtes apparaît.
Je vous copie la macro ci-dessous
Merci et désolé pour cette sollicitation.
----------------------------------------------
Sub A_Import()

Application.DisplayAlerts = False
Application.ScreenUpdating = False

Dim lientetesource As Long, coentetesource As Integer, lientetecible As Long, coentetecible As Integer, WBsource As Workbook, WBcible As Workbook

If MsgBox("Voulez-vous importez les données?", vbYesNo, "Import") = vbNo Then
Exit Sub
Else

Set WBcible = Workbooks(ActiveWorkbook.Name)
Set WBsource = Workbooks.Open(WBcible.Sheets("parametre").Cells(3, 2).Value)

ongletcible = ThisWorkbook.ActiveSheet.Name

' derniere ligne remplie de source
ligentetesource = WBsource.Sheets(ongletsource).Columns(2).Find("*", , , , xlByColumns, xlPrevious).Row
'derniere colonne remplie de source

'colentetesource = WBcible.Sheets(ongletcible).Rows(2).Find("*", , , , xlByRows, xlPrevious).Column
colentetesource = WBcible.Sheets(ongletsource).Rows(2).Find("*", , , , xlByRows, xlPrevious).Column

' boucle sur les colonnes de cible
For n = 2 To colentetesource
' en tete de la colonne desource
entetesource = WBsource.Sheets(ongletsource).Cells(2, n)
' colonne de cible correspondant à cet en tête

On Error GoTo suite
coentetecible = WBcible.Sheets(ongletcible).Rows(2).Find(entetesource, , , xlWhole, xlByRows, xlPrevious).Column
On Error GoTo suite
' boucle sur les lignes
For t = 7 To ligentetesource
' copie ligne source dans cible
WBcible.Sheets(ongletcible).Cells(t + 3, coentetecible) = WBsource.Sheets(ongletsource).Cells(t, n)
Next t
suite:
Next n
End If
WBsource.Close
0
via55 Messages postés 14040 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 5 février 2023 2 550 > senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020
27 juin 2015 à 17:20
Bonjour

Pour mois ce fichier avec sa macro fonctionne sans erreur avec el fichier Source envoyé
http://www.cjoint.com/c/EFBprSJZQgx

Si tu as un fichier avec d'autres données dans Source et qui occasionne une erreur envoie moi le fichier en m'indiquant quelle ligne de la macro est concernée

Cdlmnt
Via
0
senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020 3
26 juin 2015 à 21:14
Sub A_Import()

Application.DisplayAlerts = False
Application.ScreenUpdating = False
Bonjour,
J'ai corrigé mais une nouvelle erreur à mon avis liée aux histoire des entêtes apparaît.
Je vous copie la macro ci-dessous
Merci et désolé pour cette sollicitation.


Sub A_copier
Dim lientetesource As Long, coentetesource As Integer, lientetecible As Long, coentetecible As Integer, WBsource As Workbook, WBcible As Workbook

If MsgBox("Voulez-vous importez les données?", vbYesNo, "Import") = vbNo Then
Exit Sub
Else

Set WBcible = Workbooks(ActiveWorkbook.Name)
Set WBsource = Workbooks.Open(WBcible.Sheets("parametre").Cells(3, 2).Value)

ongletcible = ThisWorkbook.ActiveSheet.Name

' derniere ligne remplie de source
ligentetesource = WBsource.Sheets(ongletsource).Columns(2).Find("*", , , , xlByColumns, xlPrevious).Row
'derniere colonne remplie de source

'colentetesource = WBcible.Sheets(ongletcible).Rows(2).Find("*", , , , xlByRows, xlPrevious).Column
colentetesource = WBcible.Sheets(ongletsource).Rows(2).Find("*", , , , xlByRows, xlPrevious).Column

' boucle sur les colonnes de cible
For n = 2 To colentetesource
' en tete de la colonne desource
entetesource = WBsource.Sheets(ongletsource).Cells(2, n)
' colonne de cible correspondant à cet en tête

On Error GoTo suite
coentetecible = WBcible.Sheets(ongletcible).Rows(2).Find(entetesource, , , xlWhole, xlByRows, xlPrevious).Column
On Error GoTo suite
' boucle sur les lignes
For t = 7 To ligentetesource
' copie ligne source dans cible
WBcible.Sheets(ongletcible).Cells(t + 3, coentetecible) = WBsource.Sheets(ongletsource).Cells(t, n)
Next t
suite:
Next n
End If
WBsource.Close
End Sub
0
senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020 3
21 juil. 2015 à 12:14
Bonjour Via55,
Pour information, j'ai reouvet le sujet pour pouvoir entrer en contact avec vous. Mais il s'agit d'un autre sujet.

En effet, n'ayant pas eu solution à mon problème après avoir posté ma demande sur le forum, je me permet de vous dresser directement ma demande en espérant avoir une réponse;
En résumé, je souhaite mettre en place un outil me permettant d'exporter les données dans un fichier csv avec séparateur "^3;
Mon souhait c'est de copier les données dans un tableau vba avec la fonction Redim et d'exporter les données ensuite dans un fichieur csv.

J'ai commencé à coder mais je suis bloqué sur la partie ou je dois affecter les données dans mon tableau après avoir redimensionner ce dernier avec la fonction Redim.
Je vous joins le fichier.
https://www.cjoint.com/c/EGvkoi2A7mc

Je vous remercie vraiament à l'avance car c'est outil devrait me servir énormément.
0
via55 Messages postés 14040 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 5 février 2023 2 550 > senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020
21 juil. 2015 à 14:43
Bonjour senecartour

Désolé, là je ne sais pas faire
Mais je pense qu'il faut redimensionner le tableau au départ
Ensuite incrémenter une variable de 1 à chaque tour de boucle pour remplir le tableau
Peut être :
'Redimensionnement de mon tableau
                  ReDim donnees(1 To lifin - 1)
'Boucle sur mes lignes de données
For licourante = 2 To lifin
        'Boucle sur mes colonnes de données
          For cocourante = 2 To cofin
          x=x+1
                  
     donnees(x) = Cells(licourante, cocourante) & " ^ "                                                                                                         
                                                                                                                                                   
         Next cocourante
Next licourante


Cdlmnt
Via
0
senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020 3 > via55 Messages postés 14040 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 5 février 2023
21 juil. 2015 à 16:22
Merci via 55 pour votre retour qui me donne de l'espoir

J'ai réussi à passer l'étape du tableau en codant à ma façon. Cependant je suis bloqué à l'étape de génération du fichier csv avec les données.
Pourriez-vous, s'il vous plaît, me rendre service en regardant le fichier (dernière version de mes codes via le lien ci-dessous).

https://www.cjoint.com/c/EGvovBKIASc

Je suis vraiment perdu malgré mes efforts.
0
via55 Messages postés 14040 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 5 février 2023 2 550 > senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020
21 juil. 2015 à 16:35
Oui la Sub Enregistrer fichier a des erreurs
Apparement le dim de chemin et feuille pose problème
Ensuite psLigneFichier n'est pas trouvé

mais n'ayant pas bâti cette macro et ne connaissant pas bien la procédure je ne saurais rectifier mais en reposant la question sur le forum tu vas bien trouver quelqu'un de compétent en csv pour corriger ça

Bon courage
Via
0
senecartour Messages postés 325 Date d'inscription dimanche 12 mai 2013 Statut Membre Dernière intervention 29 octobre 2020 3 > via55 Messages postés 14040 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 5 février 2023
23 juil. 2015 à 10:06
Bonjour via 55,
J'ai contourné le problème en adoptant ma solution par rapport à un code qui m'a été fourni.
Jai réussi à exporter les données en cvs, sauf que je souhaite ajouter des contrôles lors de l'export des données en scv.

1ere contrôle:
lorsqu'on a "Oui" à la ligne 7 d'une colonne, les données de la colonne doivent être concaténées avec les données de la colonne B.
J'ai déjà mis ce contrôle sauf qu'au lieu que le contrôle s'applique dans le fichier CSV généré, il est directement appliqué dans l'onglet lui même (ce que je ne souhaite pas)


2ème contrôle
lorsqu'on se situe dans l'onglet nommé "Division", le nombre de fichiers exportés dépendra des données dans la colonne "C". Autrement dit, les lignes de données ayant le même nombre doivent se retrouver dans le même fichier avec comme nom des fichiers (nom de l'onglet&N°)
Par exemple dans notre cas: on doit avoir trois fichiers nommées respectivement (Division1, Division2, Division3).

Je vous joins le fichier en question.
https://www.cjoint.com/c/EGxifXIB6kc


Merci pour votre aide.
0