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 :

Dupliquer une ligne d'une listbox / base de donnée


Sujet :

Macros et VBA Excel

  1. #1
    Membre à l'essai
    Homme Profil pro
    Chargé de projet
    Inscrit en
    Novembre 2019
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Chargé de projet
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2019
    Messages : 14
    Points : 11
    Points
    11
    Par défaut Dupliquer une ligne d'une listbox / base de donnée
    Bonjour,

    Je souhaite dupliquer (copier et coller) une ligne de ma listbox mais je n’arrive pas à la coller ou je le souhaite.
    En effet avec mon code, ma ligne se colle à la deuxième ligne de ma base de donnée (juste en dessous de mes entêtes) alors que je voudrais qu'elle se colle soit après ma ligne sélectionnée soit en bas de ma base de donnée.

    Ma listbox est "listbox1" et elle se trouve sur l'userform "Form6Combos"
    Ma base de donnée est "BD matériel"
    Mon boutton pour la duplication est "B_dup"

    J'aimerais sélectionner une ligne dans ma listbox et quand j’appuie sur le bouton de duplication, j'obtienne une deuxième ligne identique.

    Voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Private Sub B_dup_Click()
     For numlignevide = 2 To Range("A" & Rows.Count).End(xlUp).row
            If Cells(numlignevide, 1) = "" Then
                Exit For
            End If
        Next
        For i = 1 To 11
            Sheets("BD matériel").Cells(numlignevide, i).Value = Me.ListBox1.List(ListBox1.ListIndex, i - 1)
    Next
    UserForm_Initialize
    End sub
    Voila mon soucis, en espérant que quelqu'un puisse m'aider.

    Je vous souhaite de bonnes fêtes de fin d'année.

    Quentin

  2. #2
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 124
    Points : 55 919
    Points
    55 919
    Billets dans le blog
    131
    Par défaut
    Salut.

    il faut travailler avec les tableaux structurés (Voir mon tuto)

    Le principe: La listbox commence à 0. Donc, l'indice de la ligne sélectionnée de la listbox est égal à la ligne du tableau structuré -1. Dès lors, on peut ajouter une listrow (une ligne de données) au tableau structuré puis lui passer les valeurs de la ligne sélectionnée de la listbox.

    Voici un exemple de tableau, nommé Tableau1

    Nom : 2019-12-30_174747.png
Affichages : 839
Taille : 3,0 Ko




    Voici le code qui charge la listbox d'un userform avec les données du tableau.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Sub Test()
      With UserForm1
        .ListBox1.List = Range("tableau1").Value
        .Show
      End With
    End Sub
    Voici le code du userform. Sur clic du bouton, on insère une ligne dans le tableau après la ligne sélectionnée dans la listbox et on transfère les valeurs. Après, il faut rafraîchir la listbox
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Private Sub btnDuplicate_Click()
      DuplicateListRow
    End Sub
     
    Sub DuplicateListRow()
      Dim r As Range
     
      Set r = Range("tableau1").ListObject.ListRows.Add(ListBox1.ListIndex + 2).Range
      Range("tableau1").ListObject.ListRows(ListBox1.ListIndex + 1).Range.Copy r
      ListBox1.List = Range("tableau1").Value
    End Sub
    Tu dis que tu souhaites insérer la ligne à la suite de la ligne copiée OU en bas du tableau, mais tu ne nous dis pas quand tu souhaites l'un et quand tu souhaites l'autre. Je précise que, normalement et sauf cas particuliers (plages de valeurs, listes en cascade, etc), l'ordre des données dans un tableau structuré n'a aucune importance et ne peut avoir aucune incidence sur les formules s'appuyant sur le tableau (un des 7 péchés capitaux d'Excel)


    J'ai posté cette contribution qui modélise les échanges entre un userform et un tableau structuré. Si tu souhaites systématiser ton approche, tu pourrais t'en inspirer...

  3. #3
    Membre chevronné
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    1 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 1 369
    Points : 2 156
    Points
    2 156
    Par défaut
    Bonjour,

    Voici un exemple de duplication de l'enregistrement actif. L'enregistrement est ajouté à la BD.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Private Sub B_duplique_Click()
      Me.Enreg = Range(NomTableau).Rows.Count + 1
      B_valid_Click
    End Sub
    Boisgontier

  4. #4
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 124
    Points : 55 919
    Points
    55 919
    Billets dans le blog
    131
    Par défaut
    Citation Envoyé par boisgontierjacques Voir le message
    [...]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Private Sub B_duplique_Click()
      Me.Enreg = Range(NomTableau).Rows.Count + 1
      B_valid_Click
    End Sub
    [...]

    Perso, c'est le signe d'une mauvaise architecture qu'un code événementiel appelle un autre code événementiel. Si, pour une raison x, le code de B_valid_Click est modifié, il va falloir mesurer les impacts de cette modification sur les codes qui appellent cet évènement. Je déconseille très fortement cette architecture.

    Les codes événementiels ne peuvent rien faire d'autre que d'appeler des procédures/fonctions et éventuellement avertir l'utilisateur par msgbox. Le chainage de codes événementiels est le meilleur moyen de se casser la gu*** lors d'une prochaine évolution de code.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Chargé de projet
    Inscrit en
    Novembre 2019
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Chargé de projet
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2019
    Messages : 14
    Points : 11
    Points
    11
    Par défaut
    Bonjour à vous deux,

    Tout d’abord je vous remercie pour vos réponses et pour le temps que vous y avez consacré.

    Pierre, je vais étudier ta proposition et la mettre en pratique. Celle-ci m'a l'air tout à fait adaptable et correspondre à ce que je cherche. Je reviendrais vers toi si tu le veux bien pour d'éventuelles questions.

    Boisgontier, merci pour cette solution rapide et efficace qui fonctionne parfaitement et qui allège le code.

    Enfaîte mon formulaire de base est une matrice générique que Boisgontier a réalisé. Il m'a beaucoup aidé sur le projet et il connaît bien mon excel.
    Le fait d'appeler la procédure du bouton de validation est une simplification car la duplication de ligne (avec le bouton dupliqué) revient au même que d'en recrée une (avec le bouton de validation) avec les informations de la saisie qui lui sont propres.
    Après il est clair que si le code vient à évoluer il faudra le prendre en compte afin qu'il remplisse toujours sa fonction souhaitée.

    Je vous remercie pour vos travaux et vous souhaite de bonnes fêtes de fin d'année.

    Quentin

  6. #6
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 124
    Points : 55 919
    Points
    55 919
    Billets dans le blog
    131
    Par défaut
    Citation Envoyé par Tintin88 Voir le message
    [...]
    Le fait d'appeler la procédure du bouton de validation est une simplification[...]
    Je comprends bien que le fait d'appeler la procédure du bouton semble être une simplification, mais qui amènera des problèmes le jour où le code de ce bouton évoluera.

    Regarde la structure suivante, dans laquelle tout fonctionne bien, pour l'instant.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Private Sub CommandButton1_Click()
      ...
      ...
      ...
    End Sub
     
    Private Sub CommandButton2_Click()
      CommandButton1_Click
      ...
      ...
      ...
    End Sub
    Maintenant, tu te dis que le bouton 1 devrait envoyer un message à l'utilisateur pour dire qu'il a fini son boulot. Au moment d'ajouter la ligne de code, tu "oublies" évidemment que le bouton 2 appelle le bouton 1... Et donc, en plein milieu du process du bouton 2, tu te prends le message (bloquant) du bouton 1 et tu dois intervenir en validant le message pour que Bouton2 continue son job... Pas bon La mauvaise architecture amène des problèmes de maintenance ^^
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Private Sub CommandButton1_Click()
      ...
      ...
      ...
      MsgBox "Terminé"
    End Sub
     
    Private Sub CommandButton2_Click()
      CommandButton1_Click
      ...
      ...
      ...
    End Sub

    Regarde maintenant la bonne architecture, qui ne coûte pas plus cher à mettre en place dès le début de ton projet.
    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
    Sub Action1()
      ...
      ...
      ...
    End Sub
     
    Sub Action2()
      ...
      ...
      ...
    End Sub
     
    Private Sub CommandButton1_Click()
      Action1
    End Sub
     
    Private Sub CommandButton2_Click()
      Action1
      Action2
    End Sub

    Si maintenant tu te dis qu'il faut que Bouton1 alerte l'utilisateur de la fin de son action, tu ajoutes simplement un msgbox dans l'événement du bouton1 (Pas à la fin de Action1), et tu n'as pas à te tracasser de qui appelle quoi, car tu n'as pas chainé tes événements. Ton Bouton2 continue à faire son job sans être perturbé par la modif sur Bouton1. CQFD
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Private Sub CommandButton1_Click()
      Action1
      MsgBox "Terminé"
    End Sub
     
    Private Sub CommandButton2_Click()
      Action1
      Action2
    End Sub
    De plus, une architecture professionnelle du code devrait exiger une gestion d'erreur sur les événements "au cas où". Dès lors, il se pourrait bien que les gestions d'erreurs des boutons 1 et 2 se téléscopent si on chaîne les procédures événementielles.


    Conclusion:
    Un code événementiel ne peut JAMAIS appeler un autre code événementiel. De l'observation de cette règle d'architecture découle une maintenance et une évolution du code aisée

    Bonnes fêtes de fin d'année

  7. #7
    Membre à l'essai
    Homme Profil pro
    Chargé de projet
    Inscrit en
    Novembre 2019
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Chargé de projet
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2019
    Messages : 14
    Points : 11
    Points
    11
    Par défaut
    Re,

    Ah oui d'accord, expliquer comme cela je comprend tout à fait l'importance de faire comme vous me le dites.

    Et comme vous le dites ça ne prend pas plus de temps de faire cela dès le début.

    Je vous remercie pour votre très claire et précise explication. J'aurais appris beaucoup de chose aujourd'hui. Merci d'avoir passer du temps la-dessus.

    Je vous souhaite de bonnes fêtes,

    Quentin

  8. #8
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 124
    Points : 55 919
    Points
    55 919
    Billets dans le blog
    131
    Par défaut
    J'ai développé mon propos dans ce billet de blog, pour détailler et compléter ma réponse, notamment en abordant la notion de contrat entre fonction, ainsi que la gestion des erreurs

    Bonnes fêtes également, et bonne année 2020

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 21/06/2010, 23h29
  2. Réponses: 2
    Dernier message: 16/11/2005, 13h41
  3. [MySQL] Backup d'une grosse base de données (60MB)
    Par MiJack dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 01/11/2005, 18h22
  4. Calcul de la taille d'une future base de données
    Par Kuma25 dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 17/08/2005, 09h54
  5. copier une table vers une autre base de données
    Par Herveg dans le forum Oracle
    Réponses: 3
    Dernier message: 11/01/2005, 14h20

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