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 :

Supprimer une ou les lignes d’un tableau structuré en fonction des Items sélectionnés dans une ListBox


Sujet :

Macros et VBA Excel

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 788
    Points : 182
    Points
    182
    Par défaut Supprimer une ou les lignes d’un tableau structuré en fonction des Items sélectionnés dans une ListBox
    Bonjour,

    Je voudrais supprimer une ou les lignes d’un tableau structuré en fonction des Items sélectionnés dans une ListBox alimenté par un autre tableau.

    N'ayant pas trouvé de réponse claire sur le net, je m'adresse encore une fois à vous.

    Voici mon code mais qui ne fonctionne pas comme je le souhaiterai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Dim I As Integer
    'boucle sur les éléments sélectionnés de la ListBox d'un tableau et supprimer lignes correspondantes dans un autre tableau
    For I = 0 To Source.ListCount - 1
         If Source.Selected(I) = True Then
             Range("ZoneSaisieBCAchats[Réf]").Find(What:=Source.List(I),SearchOrder:=xlByRows).ListObject.ListRows(1).Delete
         End If
    Next I
    C'est certainement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ListObject.ListRows(1).Delete
    qui ne convient pas ?

    Avez-vous une sujétion, merci d'avance pour votre aide.

  2. #2
    Rédacteur
    Avatar de Philippe Tulliez
    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    Janvier 2010
    Messages
    12 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur, développeur et consultant Excel, Access, Word et VBA

    Informations forums :
    Inscription : Janvier 2010
    Messages : 12 910
    Points : 28 886
    Points
    28 886
    Billets dans le blog
    53
    Par défaut
    Bonjour,
    Plusieurs syntaxes possibles pour un tableau nommé t_Montableau se trouvant dans la feuille nommée Translation dont on supprime la ligne 10

    Syntaxe 1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Worksheets("Translation").ListObjects("t_Montableau").ListRows(10).Delete
    Syntaxe 2 si le tableau est le seul dans la feuille
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Worksheets("Translation").ListObjects(1).ListRows(10).Delete
    Syntaxe 3
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Range("t_MonTableau").ListObject.ListRows(10).Delete
    Pour les syntaxes 1 et 2, il est toujours préférable d'ajouter le parent de la feuille (le classeur). Syntaxes à privilégier si plusieurs classeurs sont ouverts et que l'on n'est pas certain que le tableau se trouve dans le classeur actif.
    Pour la syntaxe 3, c'est obligatoirement le tableau nommé t_Montableau du classeur actif qui est concerné.

    Petite précision : Le numéro de ligne définit dans l'argument de la collection ListRows concerne le numéro de ligne de la partie des données (DataBodyRange). Ne pas oublié que les lignes d'un ListBox ou ComboBox commence à l'indice 0
    Philippe Tulliez
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
    Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
    Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
    Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 788
    Points : 182
    Points
    182
    Par défaut
    Bonjour Philippe Tulliez et merci pour votre réponse,

    Aucun souci pour supprimer une ligne précise par exemple la 10 dans la feuille où se trouve le premier tableau.

    Une petite précision mon tableau "ZoneSaisieBCAchats[Réf]" peut contenir tout ou partie de l'autre tableau qui alimente la ListBox qui contient toutes lignes de la RowSource.

    C'est à partir de cette Listbox que je veux supprimer une ou les lignes du tableau ""ZoneSaisieBCAchats[Réf]" en fonction des Items sélectionnés.

    J'ai l'impression ListObject.ListRows(1).Delete supprime toujours la première ligne du tableau "ZoneSaisieBCAchats[Réf]"

    @+

  4. #4
    Membre chevronné Avatar de mfoxy
    Homme Profil pro
    Automation VBA
    Inscrit en
    Février 2018
    Messages
    752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Automation VBA
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2018
    Messages : 752
    Points : 1 971
    Points
    1 971
    Par défaut
    Bonjour Modus,

    Ne sachant pas comment est remplie ta ListBox (données filtrées, au autre), je trouve que ton souhait de récupérer la ligne dans le tableau structuré, par Matching, est la façon dont il faut travailler. Il est possible que l'index (-1) de ta liste ne soit peut-être pas l'index de la listRow de ton tableau structuré.

    Ta manière de travailler, via le find, t'assures de conserver le même code : que tes données soit oui ou non filtrée dans ton listbox.

    Pierre Fauconnier, donne Ici, une fonction qui pourrait être utile pour récupérer l'index de la ligne que tu ajouterais au lieu de ton 1 dans le .delete de Philippe (perso je préfère la version 3).


    Attention que cela s'arrêtera à la première valeur identique de ton tableau, donc s'il y a des doublons...
    La clef devrait donc pour bien faire être un identifiant unique dans la base.

    Bat,
    Michaël

    Si mon aide/avis vous a été profitable , n'hésitez pas à cliquer sur , ça fait toujours plaisir...
    _________________________________________________________________________________________________________________

    "Tout le monde est un génie. Mais si on juge un poisson sur sa capacité à grimper à un arbre, il passera sa vie à croire qu'il est stupide..."
    Albert Einstein

  5. #5
    Expert éminent

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 108
    Points : 9 917
    Points
    9 917
    Billets dans le blog
    5
    Par défaut
    Bonjour,

    pour éviter d'aller chercher la ligne concernée, il serait plus pratique d'ajouter une colonne masquée dans ta listbox, contenant le numéro de ligne (ligne de la feuille OU mieux : ligne du databodyrange).

    Ainsi, à la sélection d'un élément, il suffit d'utiliser le numéro de ligne dans la commande de suppression (syntaxe 1 à 3 de Philippe)

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 788
    Points : 182
    Points
    182
    Par défaut
    Bonjour et merci à mfoxy & joe.levrai pour vos réponses.

    mfoxy j'ai été sur lien que vous indiquez, je n'ai pas trouvé la réponse et pas compris comment utiliser la fonction qui pourrait être utile pour récupérer l'index de la ligne.

    Dans mon cas comment récupérer et indiquer le numéro de la ligne dans ListObject.ListRows(?).Delete.

    @+

  7. #7
    Rédacteur
    Avatar de Philippe Tulliez
    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    Janvier 2010
    Messages
    12 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur, développeur et consultant Excel, Access, Word et VBA

    Informations forums :
    Inscription : Janvier 2010
    Messages : 12 910
    Points : 28 886
    Points
    28 886
    Billets dans le blog
    53
    Par défaut
    Bonjour,
    Code de la procédure qui charge le ListBox. En première colonne, le n° d'enregistrement (N° de la ligne dans la liste)
    La variable Rng de type Range représente l'objet DataBodyRange
    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
    Private Sub LoadListBox(LookupValue As String)
      ' Argument
      '   LookupValue  Valeur à filtrer
      Dim r As Long
      Me.ListBox1.Clear
      With rng_Data
       For r = 1 To .Rows.Count   ' Nbre de lignes de la liste de données
        If LCase(Left(.Cells(r, 2).Value, Len(LookupValue))) = LCase(LookupValue) Then
         Me.ListBox1.AddItem r    ' N° de l'enregistrement
         Me.ListBox1.List(Me.ListBox1.ListCount - 1, 1) = .Cells(r, 2).Value
         Me.ListBox1.List(Me.ListBox1.ListCount - 1, 2) = .Cells(r, 3).Value
        End If
       Next r
      End With
    End Sub
    Code de la procédure événementielle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Private Sub ListBox1_Click()
     Dim RowNumber As Long
     With Me.ListBox1
       RowNumber = .List(.ListIndex, 0)
       MsgBox "N° de la ligne sélectionnée " & RowNumber
     End With
    End Sub
    donc pour supprimer la ligne sélectionnée ListObject.ListRows(RowNumber).DeleteCe code n'est valable que pour une seule sélection.
    Il y a lieu de l'adapter si la propriété MultiSelect du ListBox a pour valeur la constante fmMultiSelectMulti
    Philippe Tulliez
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
    Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
    Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
    Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 788
    Points : 182
    Points
    182
    Par défaut
    Bonsoir Philippe Tulliez,

    J'ai du mal à intégrer votre code et procédure évènementielle dans mon projet.

    Voici ma ListBox pour faire une sélection ou une multi sélection :

    Nom : ListBox.jpg
Affichages : 3518
Taille : 25,7 Ko

    Et le tableau dans lequel la ou les lignes sélectionnées seront supprimées :

    Nom : Tableau.jpg
Affichages : 3490
Taille : 11,0 Ko

    Finalement j'ai trouvé la solution en m'inspirant d'une veille discussion de ce forum :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    For I = 0 To Source.ListCount - 1
            If Source.Selected(I) = True Then
                Range("ZoneSaisieBCAchats[Réf]").Find(What:=Source.List(I), SearchOrder:=xlByRows).Select
                With Sheets("BC achats").ListObjects("ZoneSaisieBCAchats")
                    If .Active Then Ligne = ActiveCell.Row - .Range.Row
                    MsgBox "La cellule active est dans le tableau à la ligne " & Ligne
                End With
                Range("ZoneSaisieBCAchats[Réf]").ListObject.ListRows(Ligne).Delete
            End If
        Next I
    Le seul petit bémol c'est le Select, mais bon ça fonctionne.

    Si vous avez une meilleure idée, je suis preneur.

    @+

  9. #9
    Expert éminent

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 108
    Points : 9 917
    Points
    9 917
    Billets dans le blog
    5
    Par défaut
    Bonjour,

    pourquoi "rechercher" une valeur qu'on connait déjà afin d'en récupérer une information ?

    Comme je l'avais suggéré, et comme Philippe l'a partiellement expliqué (il fallait un peu d'adaptation) :

    1) une procédure (dans un module standard) pour charger le listbox, avec en première colonne le stockage de la ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Sub ChargeListBox(MonTablo As ListObject, MonListBox As MSForms.ListBox)
    Dim i As Long
        With MonListBox
            .Clear
            For i = 1 To MonTablo.DataBodyRange.Rows.Count
                .AddItem i
                .List(.ListCount - 1, 1) = MonTablo.DataBodyRange.Cells(i, 1)
                .List(.ListCount - 1, 2) = MonTablo.DataBodyRange.Cells(i, 2)
            Next i
        End With
    End Sub
    2) Dans le userform, la procédure d'initialisation qui va préparer le listbox

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Private Sub UserForm_Initialize()
        With Me
            .ListBox_ARTICLES.ColumnCount = 3
            .ListBox_ARTICLES.ColumnWidths = "0;80;80"
            ChargeListBox ThisWorkbook.Worksheets("Feuil1").ListObjects("ZoneSaisieBCAchats"), .ListBox_ARTICLES
        End With
    End Sub
    3) La procédure du commandbutton, après avoir sélectionné l'item souhaité, on clique dessus (on peut se passer d'un bouton et utiliser les évènements du listbox) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Private Sub CommandButton_VALIDER_Click()
        With Me.ListBox_ARTICLES
            ThisWorkbook.Worksheets("Feuil1").ListObjects("ZoneSaisieBCAchats").ListRows(.List(.ListIndex, 0)).Delete
            ChargeListBox ThisWorkbook.Worksheets("Feuil1").ListObjects("ZoneSaisieBCAchats"), Me.ListBox_ARTICLES
        End With
    End Sub

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 788
    Points : 182
    Points
    182
    Par défaut
    Bonsoir Jo Levrai,

    Je crains qu'on se soit mal compris.

    Votre solution consiste à initialiser la ListBox avec les données du tableau "ZoneSaisieBCAchats" et après avoir sélectionné l'Item souhaité, on clique dessus ou sur le bouton "Valider" pour supprimer la ligne dans le tableau.

    Il me parait plus simple dans ce cas de sélectionner la ou les lignes et de la ou les supprimées du tableau manuellement ?

    Hors comme j'essaye de l'expliquer dans mon précédent post, ma ListBox multi-sélection est alimentée par un autre tableau.

    Dans l'UseForm le bouton "Efface transfert" supprime une ou les lignes du tableau "ZoneSaisieBCAchats[Réf]" en fonction de l'Item ou les Items sélectionnés dans la ListBox.

    Le bouton "Transfert sélection" permet d'ajouter une ou des lignes dans le tableau "ZoneSaisieBCAchats[Réf]" en fonction de l'Item ou les Items sélectionnés dans la ListBox.

    Le tableau qui alimente la ListBox et le tableau "ZoneSaisieBCAchats[Réf]" ne sont pas sur les même feuilles

  11. #11
    Rédacteur
    Avatar de Philippe Tulliez
    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    Janvier 2010
    Messages
    12 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur, développeur et consultant Excel, Access, Word et VBA

    Informations forums :
    Inscription : Janvier 2010
    Messages : 12 910
    Points : 28 886
    Points
    28 886
    Billets dans le blog
    53
    Par défaut
    Bonjour,
    Il doit y avoir forcément une clé unique qui relie les deux tables donc faites un "Print screen" partiel des deux tables en indiquant trois, quatre lignes sélectionnées dans le ListBox en mettant en évidence les lignes à supprimer dans la table en question. je pense que ce sera plus parlant.
    Philippe Tulliez
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
    Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
    Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
    Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 788
    Points : 182
    Points
    182
    Par défaut
    Bonjour Philippe Tulliez,

    Voici le "Print screen" partiel de la table "BD produits"

    Nom : BD produits.jpg
Affichages : 3457
Taille : 20,6 Ko

    Table "BD producteurs"

    Nom : BD producteurs.jpg
Affichages : 3448
Taille : 18,2 Ko

    ListBox exemple multi-sélection des lignes à supprimer dans le tableau "ZoneSaisieBCAchats"

    Nom : ListBox.jpg
Affichages : 3450
Taille : 38,0 Ko

    Tableau "ZoneSaisieBCAchats"

    Nom : Tableau ZoneSaisieBCAchats .jpg
Affichages : 3436
Taille : 12,3 Ko

    @+

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 788
    Points : 182
    Points
    182
    Par défaut
    Bonjour,

    Voici mon code modifié qui fonctionne bien sans Select :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        For I = 0 To Source.ListCount - 1
            If Source.Selected(I) = True Then
                Set ChercheLigne = Range("ZoneSaisieBCAchats[Réf]").Find(What:=Source.List(I), SearchOrder:=xlByRows)
                If Not ChercheLigne Is Nothing Then
                    Ligne = ChercheLigne.Address
                    Sheets("BC achats").Range(Ligne).EntireRow.Delete
                Else
                    MsgBox "Le produit ne figure pas dans le bon de commande !"
                End If
            End If
        Next I

Discussions similaires

  1. Réponses: 4
    Dernier message: 30/03/2020, 08h34
  2. Supprimer des lignes d’un tableau Excel avec une limite
    Par PASCAL9210 dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 28/12/2018, 12h05
  3. [XL-2016] Remplir une cellule en fonction des items sélectionnés dans une ListBox
    Par Manre dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 10/07/2018, 15h36
  4. Afficher les données d’une ligne d’un tableau après un click
    Par Bano dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 14/11/2017, 18h33
  5. supprimer les lignes d´un fichier.
    Par maeva87 dans le forum C#
    Réponses: 19
    Dernier message: 07/03/2014, 12h49

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