IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Bouton pour transférer des données d'un fichier Excel vers un autre


Sujet :

Macros et VBA Excel

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 61
    Points : 27
    Points
    27
    Par défaut Bouton pour transférer des données d'un fichier Excel vers un autre
    Bonjour à tous,

    Je souhaiterai insérer, sur une page excel, un bouton qui me permette de transférer des données vers un autre fichier SI certaines cellules sont remplies.
    En effet, j'ai deux fichiers et je dois recopier bcp de données du fichier1 vers le fichier2 avec les risques d'erreur que cela comporte. Je voudrais donc automatiser la copie des données.

    Ex. :
    Si la cellule G15 de mon fichier1 est remplie et que j'appuie sur mon bouton "transfert de données", les données contenues dans les cellules A15, C15, D15 du fichier1 sont envoyées dans les cellulles A1, C1, D1 de mon fichier2.

    Est-ce que vous pourriez m'aider à faire la macro s'il vous plait ? Je ne suis pas du tout experte en VB...

    Un grand merci par avance pour votre aide.

    Cordialement,

    Alfred

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 207
    Points : 251
    Points
    251
    Par défaut
    On ne refusera pas de t'aider mais on n'est pas là non plus pour te cracher le code directement.

    Pour commencer tu peux utiliser l'enregistreur de macros (Outils->Macro->Nouvelle Macro...) pour générer automatiquement un code des actions que tu veux réaliser.

    Après Outils->Macro->Macros... (ou Alt+F8), tu sélectionnes la macro que tu viens d'enregistrer et tu cliques sur 'Modifier'.

    Essaie alors de modifier la macro pour l'adapter à tes besoins et reviens demander de l'aide ici quand tu coinces (en décrivant ce qui ne va pas, où ça se produit, dans quelles circonstances...).

    Bon courage!

  3. #3
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 61
    Points : 27
    Points
    27
    Par défaut
    Bonjour,

    J'ai dû mal m'exprimer parce que je n'attendais pas que vous me "crachiez le code directement".
    Excusez moi.

    Je voulais surtout, dans un premier temps, savoir si ce que je voulais faire était possible et comment faire pour mettre des conditions.

    Je vais continuer à chercher.

    Cordialement,
    Alfred

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 207
    Points : 251
    Points
    251
    Par défaut
    C'est tout à fait faisable et même pas bien sorcier en VBA.

    Pour le bouton: Affichage -> Barres d'outils -> Boîte à outils Contrôles, puis dans cette barre d'outil, sélectionne un contrôle "bouton de commande" (l'icône est un rectangle gris) que tu places où tu veux sur ta feuille.

    De l'autre côté tu peux écrire une macro qui teste le contenu de tes cellules (avec des structures du style If [condition] Then [action1] Else [action 2] End If) et qui copie tes cellules.

  5. #5
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 61
    Points : 27
    Points
    27
    Par défaut
    Bonjour,

    Et merci pour vos réponses.

    J'étais exactement en train de faire ce que vous dites, mais j'ai vraiment du mal.

    Je ne suis pas certain de placer les instructions au bon endroit...

    En fait, j'ai bien mis un bouton sur la feuille, mais comme je voulais ajouter une condition, je suis un peu perdu...

    Pour l'instant, je n'ai pas encore copié les données des cellules, je fais juste des tests avec une message box.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Private Sub Worksheet_change(ByVal Target As Range)
     
    If Target.Column = 14 Then
     
          MsgBox "Vous venez de modifier la cellule " & Target.Address & " (" & Target.Value & ")"
     
     
    End If
     
     
    End Sub
    Ça fonctionne bien, mais je n'arrive pas à relier ça au bouton. Quand je fais : "affecter la macro > nouvelle" ça m'ouvre un module. Or, le code ci-dessus ne se trouve pas dans ce module.

    Autre question, sans doute idiote, mais bon... Il faut bien débuter... Est-ce qu'on peut imbriquer les Sub ?

    Merci d'avance.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 33
    Points : 105
    Points
    105
    Par défaut
    Bonjour,

    Vous ne pouvez pas attribuer la procédure que vous avez écrite au bouton car vous avez écrit votre code dans une procédure associé à un événement possédant un paramètre (Target).

    Pour associer une macro directement à un bouton de type formulaire que vous semblez avoir crée, il faut que la procédure soit sans paramètre et doit être publique.
    (il y a aussi l'option du bouton en ActiveX et la rédaction de la procédure évenementielle _onClick)

    quand à imbriquer des Sub, j'avoue ne pas bien comprendre ou vous voulez en venir...

    Cordialement.

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 207
    Points : 251
    Points
    251
    Par défaut
    Citation Envoyé par Alfred23 Voir le message

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Private Sub Worksheet_change(ByVal Target As Range)
     
    If Target.Column = 14 Then
     
          MsgBox "Vous venez de modifier la cellule " & Target.Address & " (" & Target.Value & ")"
     
     
    End If
     
     
    End Sub
    Ça fonctionne bien, mais je n'arrive pas à relier ça au bouton. Quand je fais : "affecter la macro > nouvelle" ça m'ouvre un module. Or, le code ci-dessus ne se trouve pas dans ce module.
    -> En fait pour affecter ta macro au bouton de contrôle, désactive le mode Création dans la barre d'outils contrôles (l'icône avec une équerre, une règle et un crayon; si le mode est activé l'arrière plan de cette icône est en orange) et double-clique sur ton bouton.
    Normalement ça devrait automatiquement te placer dans la procédure correspondant à l'évènement "clic sur ce bouton". Il ne te reste alors plus qu'à taper ta procédure à cet endroit et elle sera exécutée lorsque tu cliques sur le bouton.



    Citation Envoyé par Alfred23 Voir le message
    Autre question, sans doute idiote, mais bon... Il faut bien débuter... Est-ce qu'on peut imbriquer les Sub ?
    C'est pas du tout idiot comme question. La réponse est oui et non!

    En fait, toutes les procédures (sub) et fonctions (function) sont déclarées séparément mais tu peux ensuite appeler n'importe laquelle depuis une autre.

    Exemple schématique:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    Sub procédurePrincipale()
     
    [...]
     
    procédureSecondaire() 'Appel de la procédure secondaire au sein de la procédure principale
     
    [...]
     
    End Sub
     
     
     
    Sub procédureSecondaire()
     
    [...]
     
    End Sub
    Explication: chaque procédure est déclarée séparément (entre Sub machin() et End Sub).

    Au sein de ma procédure principale, j'appelle ma procédure secondaire. A ce moment là, l'exécution de la procédure principale est "mise en pause", la procédure secondaire est appelée, exécutée et une fois qu'elle s'est terminée l'exécution de la procédure principale reprend.

    Il est très fortement recommandé d'utiliser ce genre de structure car cela améliore grandement la clarté du code et permet souvent d'en réduire la longueur (si la procédure secondaire est appelée au moins 2 fois à des endroits différents dans la procédure principale).

    J'espère avoir été assez clair...n'hésite pas à demander des éclaircissements sur ce que tu ne comprends pas.

  8. #8
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 61
    Points : 27
    Points
    27
    Par défaut
    Merci pour vos réponses : elles m'éclairent bien !

    C'est super clair pour les sub "imbriquées", j'ai bien compris ! Je vais faire des petits tests pour voir j'arrive à passer de la théorie à la pratique.

    Bonjour,

    J'ai à nouveau besoin de votre aide...

    Pour m'en sortir, j'ai procédé par étapes. J'ai donc fait des petites macros en me disant qu'une fois que ça fonctionnerait je pourrais "fusionner" les macros.

    J'ai donc deux macros qui fonctionnent bien... séparément mais je voudais en faire 1 seule avec les deux et je n'y arrive pas...

    La macro 1 récupère bien les données de la cellule modifiée et la copie dans un autre fichier mais uniquement dans une cellule donnée.
    En plus, je n'arrive pas à affecter cette macro à un bouton...

    La macro 2 colle bien les cellules copiées dans la première ligne vide, mais je n'arrive à copier qu'une cellule donnée et non un cellule modifiée comme dans la macro 1.

    Avez vous des pistes à me donner ?

    Merci d'avance pour votre aide.

    Alfred

    Macro 1 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Sub Worksheet_change(ByVal Target As Range)
     
    If Target.Column = 12 Then
     
    Workbooks.Open ThisWorkbook.Path & "\Fichier1.xls"
    Sheets("Feuil1").Range("A1") = Target.Value
     
    End If
     
    End Sub
    Macro 2 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Sub EnvoiDonnees()
     
    'Copie des données des cellules B10 à D10 de la feuille 1 du Fichier2
    Workbooks("Fichier2.xls").Sheets("Feuil1").Range("b10:d10").Copy
    'Ouverture du fichier de destination
    Workbooks.Open ThisWorkbook.Path & "\Fichier1.xls"
    'Collage, dans le fichier de destination, sur la première ligne libre
    With Sheets("Feuil1").UsedRange: NoDeLaDernLig = .Cells(.Rows.Count, .Columns.Count).Row: End With
    Sheets("Feuil1").Cells(NoDeLaDernLig + 1, 1).Select
    ActiveSheet.Paste
    'Enregistrement des données copiées et fermeture du fichier de destination
    ActiveWorkbook.Save
    ActiveWorkbook.Close
     
    End Sub

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 207
    Points : 251
    Points
    251
    Par défaut
    Bonjour,

    En ce qui concerne ta Macro1, comme l'a déjà expliqué casanabo un peu plus haut, le problème vient du fait que ta macro est associé à l'évènement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Worksheet_change(ByVal Target As Range)
    Explication:

    VBA permet de réaliser des programmes "interactifs" en gérant les évènements affectant les objets sur lesquels on travaille. Par exemple, lorsque le contenu d'une cellule change, que l'on clique sur un bouton...etc.
    Dans ce cas précis, l'évènement Worksheet_change désigne un changement d'état d'une feuille de calcul et, en prime, envoie également une copie (ByVal) de l'objet ayant changé (Target As Range).
    Donc chaque fois qu'une cellule ou une plage de cellule est modifiée dans ta feuille de calcul, la Sub Worksheet_change(ByVal Target As Range) est exécutée.

    Problème:

    Ta macro utilise justement la plage retournée par l'évènement et en est donc dépendante. Si tu essaies de l'affecter à un bouton de contrôle, ça ne marchera plus car tu ne pourras pas récupérer 'Target' de la même façon.

    Solution:

    Utilise la même procédure sur l'évènement 'Click' de ton bouton de contrôle et à la place de Target utilise:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ActiveSheet.ActiveCell    'il faut que le bouton de contrôle se truve sur la même feuille pour que cela fonctionne.
    Et si tu veux changer la cellule de destination, il te suffit de changer Range("A1") pour la cellule que tu veux.


    En ce qui concerne la Macro2, j'avoue ne pas comprendre ton problème.

  10. #10
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 61
    Points : 27
    Points
    27
    Par défaut
    Bonjour Sclarckone, et merci pour ta réponse.

    Entre temps, j'avais modifié la macro :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    Sub Worksheet_change(ByVal Target As Range)
     
    'On déclare les variables ligneLong et ligneCourt
    Dim ligneLong, ligneCourt
     
    If Target.Column = 12 Then
        'On récupère l'adresse de la ligne modifiée
        ligneLong = Target.Address
        'On coupe l'adresse pour ne garder que le numéro de la ligne
        ligneCourt = Mid(ligneLong, 4)
        'On copie les cellules dont on a besoin dans la ligne précédement sélecionnée
        Range("D" & ligneCourt & ",E" & ligneCourt & ",F" & ligneCourt & ",O" & ligneCourt).Copy
     
        'On ouvre le fichier dans lequel on veut coller les données copiées
        Workbooks.Open ThisWorkbook.Path & "\Fichier1.xls"
        'On sélectionne la première ligne libre (sans données)
        With Sheets("Feuil1").UsedRange: NoDeLaDernLig = .Cells(.Rows.Count, .Columns.Count).Row: End With
        Sheets("Feuil1").Cells(NoDeLaDernLig + 1, 3).Select
     
        'On colle les données dans la page active
        'ActiveSheet.Paste
       Selection.PasteSpecial Paste:=xlPasteAllExceptBorders
     
        'On enregistre et on ferme la page active
        ActiveWorkbook.Save
        ActiveWorkbook.Close
     
    End If
     
    End Sub
    J'ai toujours deux problèmes :
    • Je réussi à coller les données dans la ligne qui me convient (la première disponible) mais je n'arrive pas à les coller dans différentes colonnes . Ex: ce qui est copié en D10 du premier fichier est collé en B15 du second fichier et ce qui est copié en F10 du premier fichier est collé en G15 du second fichier. J'arrive seulement à coller en B15 et C15.
    • J'ai toujours le problème du bouton que je voudrais associer à cette macro. J'ai lu tes explications, mais si je fais ça, la condition "si une cellule de la colonne 'O' est modifiée, on copie les données des colonnes D, E, F de la même ligne" ne tient plus, si ?


    Merci d'avance pour ton aide.

    Alfred

  11. #11
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 207
    Points : 251
    Points
    251
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Sheets("Feuil1").Cells(NoDeLaDernLig + 1, 3).Select
     
    'On colle les données dans la page active
    'ActiveSheet.Paste
    Selection.PasteSpecial Paste:=xlPasteAllExceptBorders
    La colonne dans laquelle tu colles est définie ici (en l'occurence la colonne 3 donc la colonne C). Si tu veux coller dans une autre colonne, il suffit de changer le numéro.


    Au passage, il est inutile de sélectionner ta cellule de destination et de faire le collage sur la cellule de destination. C'est ce que fait l'enregistreur de macro (vu que tu cliques sur la cellule avant de coller) mais en VBA ça peut se raccourcir comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Sheets("Feuil1").Cells(NoDeLaDernLig + 1, 3).PasteSpecial Paste:=xlPasteAllExceptBorders


    Pour ton problème d'évènement modification de cellules/clic sur bouton, il n'y a évidemment pas d'évènement correspondant dans VBA (qui ne gère que des évènements ponctuels sur un seul élément pour ce que j'en sais).

    Une solution à ton problème est de déclarer un tableau de taille dynamique avec une portée globale qui va contenir les valeurs des cellules modifiées (par exemple, mais si tu veux copier plusieurs cellules, il vaudra mieux stocker directement les 'Range' si c'est possible):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Public monTableau() As Variant    'si le contenu de tes cellules est toujours du même type (chaine de caractères, entiers, flottants) adapte le type en conséquence, c'est plus propre
    Redim monTableau(0 To 0)   'je choisis d'indicer à partir de 0 mais en VBA tu peux choisir ce que tu veux

    Avec ce tableau accessible depuis n'importe quelle objet, tu peux décomposer le problème en 2 parties:

    1°/ Sur l'évènement 'Worksheet_change", rajouter un élément au tableau:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Redim Preserve monTableau (0 To UBound(monTableau)+1) 'si tu as choisi d'indicer les éléments en démarrant de 0, UBound() est une fonction renvoyant le plus grand indice du tableau
    et stocke la valeur de la cellule modifiée

    2°/Sur l'évènement 'CommandButton_Click', tu copies une à une toutes les valeurs stockées dans le tableau en n'oubliant pas d'effacer le contenu du tableau une fois que c'est fini:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    For i=0 To UBound(monTableau)
        Sheets("Feuil1").Cells(...).Value=monTableau(i)
    Next i
     
    Erase monTableau

  12. #12
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 61
    Points : 27
    Points
    27
    Par défaut
    Merci beaucoup Sclarckone ! J'apprécie ton aide. Je suis en train de devenir dingue avec cette macro !

    Je vais essayer de faire ce que tu me conseilles et je reviens vers toi.

    Alfred.

    Bonjour Sclarckone,

    Je suis désolé, mais je ne m'en sort pas du tout avec les tableaux...

    Le code suivant, tout simple, fonctionne (sur le modèle que tu m'as donné mais sans tableau) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    Sub Worksheet_change(ByVal Target As Range)
     
    'On déclare les variables ligneLong et ligneCourt
    Dim ligneLong, ligneCourt
     
    If Target.Column = 12 Then
        'On récupère l'adresse de la ligne modifiée
        ligneLong = Target.Address
        'On coupe l'adresse pour ne garder que le numéro de la ligne
        ligneCourt = Mid(ligneLong, 4)
        'On copie les cellules dont on a besoin dans la ligne précédement sélecionnée
        Range("D" & ligneCourt & ",E" & ligneCourt & ",F" & ligneCourt & ",O" & ligneCourt).Copy
     
    End If
     
    End Sub
     
     
    Sub CommandButton_Click()
     
        'On ouvre le fichier dans lequel on veut coller les données copiées
        Workbooks.Open ThisWorkbook.Path & "\Fichier1.xls"
     
        'On colle les données copiées dans Worksheet_change()
        With Sheets("Feuil1").UsedRange: NoDeLaDernLig = .Cells(.Rows.Count, .Columns.Count).Row: End With
        Sheets("Feuil1").Cells(NoDeLaDernLig + 1, 3).PasteSpecial Paste:=xlPasteAllExceptBorders
     
    End Sub
    Si je modifie le code pour essayer d'utiliser un tableau, j'obtiens un message d'erreur "incompatibilité de type" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    Sub Worksheet_change(ByVal Target As Range)
     
    'On déclare un tableau de taille dynamique et de portée globale.
    'Il contiendra les données des cellules à coller dans le second fichier.
    Dim Tableau() As Variant
    'On indice le tableau à partir de 0.
    ReDim Tableau(0 To 0)
     
    'On déclare les variables ligneLong et ligneCourt
    Dim ligneLong, ligneCourt
     
    If Target.Column = 12 Then
        'On récupère l'adresse de la ligne modifiée
        ligneLong = Target.Address
        'On coupe l'adresse pour ne garder que le numéro de la ligne
        ligneCourt = Mid(ligneLong, 4)
        'On copie les cellules dont on a besoin dans la ligne précédement sélecionnée
        'Range("D" & ligneCourt & ",E" & ligneCourt & ",F" & ligneCourt & ",O" & ligneCourt).Copy
     
        'On ajoute un élément au tableau et on stocke la valeur de la cellule modifiée.
        ReDim Preserve Tableau(0 To UBound(Tableau) + 1)
     
     
    End If
     
    End Sub
     
     
    Sub CommandButton_Click()
     
        'On ouvre le fichier dans lequel on veut coller les données copiées
        Workbooks.Open ThisWorkbook.Path & "\Fichier1.xls"
     
        For i = 0 To UBound(Tableau)
            Sheets("Feuil1").Cells(3, 3).Value = Tableau(i)
        Next i
     
        Erase Tableau
     
    End Sub
    Je ne suis pas du tout certain de bien me servir du tableau...
    J'ai essayé de faire des macros juste pour comprendre le fonctionnement des tableaux mais peine perdue, je ne comprends pas !

    Merci d'avance de m'aider encore un peu !

    Cordialement,
    Alfred

  13. #13
    Membre expert
    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2011
    Messages
    1 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 858
    Points : 3 974
    Points
    3 974
    Par défaut
    Bonjour,

    Si j’ai bien compris, tu cherches à effectuer une copie de certaines cellules d’un classeur vers un autre classeur, cette copie étant exécutée via un CommandButton.
    Les cellules à copier sont dans le classeur actif, colonnes D, E, F et O (à adapter si nécessaire).
    Elles doivent être « collées » dans le classeur Fichier1.xls, colonnes A, B, C et D (à adapter si nécessaire), dans la première ligne vide.
    Les lignes correspondant aux cellules à copier sont marquées dans la colonne L (à adapter si nécessaire).

    Voici un code qui pourra te servir de fil conducteur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    Sub CommandButton1_Click()
    'On déclare la variable qui contiendra la référence du classeur cible
    Dim Wbc As Workbook
    'On déclare la variable qui contiendra la référence de la feuille source
    Dim Ws As Worksheet
    'On déclare la variable qui contiendra la référence de la feuille cible
    Dim Wc As Worksheet
    'On déclare la variable qui contient le numéro de la ligne modifiée
    Dim LigneMod As Long
    'On déclare la variable qui contient le numéro de la ligne où seront copiées les données
    Dim LigneAjout As Long
    'On déclare la plage de la colonne L qui porte le marquage des lignes à copier
    Dim MaPlage As Range
        'On déclare la feuille source
        Set Ws = ActiveSheet
        'On relève le numéro de la dernière ligne renseignée dans la colonne L
        DerLg = Ws.Range("L" & Rows.Count).End(xlUp).Row
        'Si au moins une ligne est renseignée,
        'Remarque :  s'il y a une ligne d'en-tête, il faudra modifier le code avec DerLg > 2
        If DerLg > 1 Then
            'on déclare la plage à examiner sinon on sort de la procédure.
            ' Remarque :  s'il y a une ligne d'en-tête, il faudra modifier le code avec "L2:L" & DerLg
            Set MaPlage = Ws.Range("L1:L" & DerLg)
            'On ouvre le fichier dans lequel on veut coller les données copiées
            Set Wbc = Workbooks.Open(ThisWorkbook.Path & "\Fichier1.xls")
            'On déclare le fichier cible
            Set Wc = Wbc.Worksheets("Feuil1")
        Else
            Exit Sub
        End If
        'On balaye la colonne L dans la plage renseignée
        For Each cel In MaPlage
            'Si la cellule est renseignée
            If cel <> "" Then
                'On récupère le numéro de la ligne correspondante
                LigneMod = cel.Row
                'On recherche la ligne de l'ajout en colonne A (à adapter)
                LigneAjout = Wc.Range("A" & Wc.Rows.Count).End(xlUp).Row + 1
                'On copie les cellules (à adapter)
                Wc.Range("A" & LigneAjout) = Ws.Range("D" & LigneMod)
                Wc.Range("B" & LigneAjout) = Ws.Range("E" & LigneMod)
                Wc.Range("C" & LigneAjout) = Ws.Range("F" & LigneMod)
                Wc.Range("D" & LigneAjout) = Ws.Range("O" & LigneMod)
            End If
        Next
        'On ferme le classeur Fichier1.xls après l'avoir enregistré.
        Wbc.Close SaveChanges:=True
        'On libère les ressources
        Set MaPlage = Nothing
        Set Wc = Nothing
        Set Ws = Nothing
        Set Wbc = Nothing
    End Sub
    Cordialement.

  14. #14
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 61
    Points : 27
    Points
    27
    Par défaut
    Merci beaucoup gFZT82

    J'apprécie beaucoup votre aide à tous parce que, bien que je me démène, je ne m'en sort pas et moralement c'est pas facile !

    Je vais étudier le code que tu me donnes, et je te donne des nouvelles. En plus, c'est super bien commenté, ça va beaucoup m'aider !

    Cordialement,
    Alfred

  15. #15
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 207
    Points : 251
    Points
    251
    Par défaut
    Citation Envoyé par Alfred23 Voir le message
    Je ne suis pas du tout certain de bien me servir du tableau...
    J'ai essayé de faire des macros juste pour comprendre le fonctionnement des tableaux mais peine perdue, je ne comprends pas !
    Effectivement le problème réside en partie dans l'utilisation du tableau.

    Mais d'abord il y a un problème de "portée"...
    On parle de portée d'une variable ou d'un objet pour désigner l'espace dans lequel cette variable existe. Pour bien comprendre prenons le cas le plus courant: la déclaration au sein d'une procédure avec Dim:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Private Sub main()
     
    Dim maVariable As Smthng
     
    End Sub
    Dans ce cas la variable 'maVariable' n'existe qu'au sein de ma procédure 'main()' (je ne peux donc pas m'en servir dans une autre procédure) et est détruite à la fin de la procédure.

    Pour empêcher la variable d'être détruite à la fin de la procédure on peut utiliser le mot clé 'Static' à la place de 'Dim', mais la variable n'est toujours pas accessible depuis d'autres procédures/fonctions.

    De façon similaire, peut déclarer des variables pour tout un module, cela se fait tout en "haut" du module, avant la première procédure/fonction. On a alors 2 portées possibles:

    - 'Private': la variable est accessible à toutes les procédures/fonctions du modules mais pas depuis un autre module

    - 'Public' la variable est accessible depuis tous les modules du projet

    Dans l'explorateur de projet, tu peux voir le projet de ton fichier en cours (normalement: VBA Project (nom_de_ton_fichier.xls)) et chaque module de ce projet: le classeur a un module ainsi que chaque feuille (plus des userforms indépendants et des modules persos si tu en utilises).

    Pour en revenir à nos moutons, il faut donc que tu déclares ton tableau dans ton module (qui, j'imagine, contient tes 2 procédures vu que tu travailles sur une seule feuille) en portée au moins 'Private' (mais utilise 'Public'; comme ça, si tu as besoin d'utiliser ce tableau dans d'autres feuilles, ce sera possible).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Public Tableau() As Long   'Pour stocker des numéros de lignes, un type entier est adapté
     
    Sub Worksheet_change(ByVal Target As Range)
    Et plus loin dans ton code, il ne faut pas te contenter d'ajouter une case au tableau mais il faut aussi remplir cette case:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ReDim Preserve Tableau(0 To UBound(Tableau) + 1)
    Tableau(UBound(Tableau)) = Target.Row    'Utiliser la propriété Row d'un objet Range est beaucoup plus concis et efficace que d'extraire la chaine de caractères correspondant à la ligne à partir de l'adresse!
    Le tableau contient donc maintenant tous les numéros des lignes à copier...je te laisse essayer d'écrire le bout de code pour copier les données nécessaires connaissant les numéros des lignes à copier

    Surtout, ne te contente pas de recopier le code que l'on te donne mais efforce-toi de le comprendre et n'hésite pas à poser des questions si besoin.

    Bon courage

  16. #16
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 61
    Points : 27
    Points
    27
    Par défaut
    Merci beaucoup Sclarckone,

    Surtout, ne te contente pas de recopier le code que l'on te donne mais efforce-toi de le comprendre et n'hésite pas à poser des questions si besoin.
    Je te promets que c'est ce que je fais !! Je passe des heures à faire des essais pour comprendre, mais j'ai vraiment du mal... Excusez moi.
    J'avoue que ça me démoralise de ne pas y arriver, mais bon, il faut garder espoir...

    Pour ce qui est du reste de ton mail, je vais m'y atteller tout de suite...

    A bientôt.
    Encore merci

Discussions similaires

  1. [XL-2007] Envoyer des données d'un fichier excel vers un autre fichier
    Par Langelusyfaire dans le forum Excel
    Réponses: 24
    Dernier message: 22/04/2014, 11h19
  2. [XL-2002] Recuperer des données d'un fichier excel vers un autre
    Par labinocle81 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 13/08/2009, 11h36
  3. copier des données d'un Fichier Excel à un a autre automatiquement
    Par meuah dans le forum Macros et VBA Excel
    Réponses: 36
    Dernier message: 21/05/2008, 10h45
  4. Importer des données d'un fichier Excel vers Javascript
    Par rafiq25 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 25/01/2008, 15h30
  5. Réponses: 1
    Dernier message: 14/05/2007, 14h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo