Dans un ListBox, ne garder que les lignes sélectionnées

Bonjour à toutes et à tous,

J'ai un ListBox alimenté par plusieurs feuilles (je ne peux pas utiliser AddItem), j'utilise donc

ListBox1.RowSource = "Feuil1!A1:D1000"

ou ListBox1.List = Range("A1:D1000").Value

Dans ce ListBox, je veux procéder à des sélections en cascade afin de ne conserver et pouvoir étudier que les lignes restantes (les colonnes sont triées par ailleurs pour regrouper les valeurs identiques).

Il s'agit donc de faire des suppressions multiples et progressives des lignes non sélectionnées. Je sais faire ligne à ligne par différentes méthodes, mais c'est bien bien trop long. Depuis 15 jours, recherches infructueuses sur Internet.

Dans l'exemple joint, j'utilise un code de MFerrand (merci à lui) qui me permet de supprimer ligne à ligne.

Merci d'avance à celle ou celui qui voudra bien se pencher sur le problème.

Cordialement

28classeur1.xlsm (26.39 Ko)

Bonjour

Votre fichier en retour.

J'ai désactivé la ligne Unload USF pour que vous voyez le résultat. Si vous la laissez, vous pouvez enlever ces trois lignes à la fin du code

With Feuil1
    dlg = .Range("A" & .Rows.Count).End(xlUp).Row
    ListBox1.List = .Range("A1:E" & dlg).Value
End With

Et la déclaration de variable, dim dlg as integer au début du code.

Si ok, et terminé, merci de cloturer le fil lors de votre réponse en cliquant sur le petit v en haut à droite

Cordialement

42classeur1.xlsm (25.07 Ko)

Bonjour et merci pour cette réponse rapide,

je crains de ne pas avoir été très clair dans ma demande.

Dans le fichier joint, le but serait de sélectionner par exemple toutes les personnes correspondant au caractère 4 de la deuxième colonne et ne garder que celles-là ; puis parmi les restantes de sélectionner toutes celles qui correspondent au suivi 3 de la 4ème colonne et ne garder que celles-là, puis toutes celles qui correspondent au lundi de la troisième colonne, etc...

Par ailleurs, le bouton supprimer devrait plutôt s'appeler sélectionner, puisqu'il ne faut garder que les lignes sélectionnées.

Vous avez bien compris le problème :

Dans le classeur que vous m'avez retourné, la sélection ne garde bien que le même nombre de lignes que celles sélectionnées, mais malheureusement, chez-moi, elles ne correspondent pas aux lignes sélectionnées.

Encore merci Dan,

Quand je veux appliquer le code proposé à mon projet, il se produit l'erreur "L'indice n'appartient pas à la sélection", sans indiquer un mot précis (le nom de la feuille est bien précisé avant).

Dans le projet, la Feuil1 récolte les données appelées par des ComboBox à partir de plusieurs autres feuilles.

Dans la pratique, le meilleur affichage dans le ListBox se fait en utilisant ListBox1.RowSource = "Feuil1!A1:E1000" et je sais que ça peut poser problème.

RE

Quand je veux appliquer le code proposé à mon projet, il se produit l'erreur "L'indice n'appartient pas à la sélection", sans indiquer un mot précis (le nom de la feuille est bien précisé avant).

Ce serait mieux de voir le vrai fichier...

Le message apparait à l'ouverture du fichier ?

Quel est le nom exact de la feuille où les données doivent être supprimées ?

Oubliez les Row.source, c'est mieux.

Le fichier original contient des données d'identité...

Je vais essayer de supprimer tout ce qui n'est pas indispensable et je l'envoie.

merci encore

Re

Pouvez-vous tester en remplaçant le code CommandButton1_Click dans l'USF par celui ci-dessous

Private Sub CommandButton1_Click()
Dim i As Integer, dlg As Integer
Application.ScreenUpdating = False
If ListBox1.ListIndex = -1 Then Exit Sub
For i = Range("A" & Rows.Count).End(xlUp).Row To 1 Step -1
   If ListBox1.Selected(i - 1) = False Then Rows(i).Delete
Next i
With Feuil1
    dlg = .Range("A" & .Rows.Count).End(xlUp).Row
    ListBox1.List = .Range("A1:E" & dlg).Value
End With
Application.ScreenUpdating = True
'Unload UserForm1
End Sub

Cordialement

Bonsoir Dan

Ca marche parfaitement dans le fichier test !!!

Je vais essayer demain de le transposer dans mon projet.

Je vous tiendrai au courant

Merci encore

Bien cordialement

Bonjour Dan,

Ci-joint le UserForm concerné par mon projet et malheureusement l'affichage dans le ListBox ne se fait que si son on l'alimente avec ListBox1.RowSource et c'est bien dommage parce que si l'on sélectionne et supprime des lignes (vides dans le ListBox) on voit bien qu'elles disparaissent dans la feuille RAPPORTS.

Comment faire ?

Bien cordialement

35projet-tri.xlsm (113.99 Ko)

...Suite, je me suis rendu compte avec le fichier test qu'il était plus logique de supprimer ce qui est sélectionné et non pas l'inverse, surtout si la sélection dépasse les limites visibles du listbox.

Donc, s'il est possible de faire en sorte...

RE

...Suite, je me suis rendu compte avec le fichier test qu'il était plus logique de supprimer ce qui est sélectionné et non pas l'inverse, surtout si la sélection dépasse les limites visibles du listbox.

Probablement mais dans le fichier test cela fonctionnait.

Les Row.source... A éviter avec les codes VBA et cela n'a pas de sens que cela ne fonctionne pas sans ces Row.source

Je ne vois pas pourquoi cela ne fonctionne pas dans votre projet et bien dans le fichier test

L'usfrapports prends les infos où ? dans la feuille Rapport ou dans la feuille Base ?

Dans votre fichier, il n'y a rien dans la feuille Rapports.

Pouvez-vous remettre le fichier avec des données dans la feuille Rapport et me dire si c'est dans la feuille rapports que l'on supprime ou dans la feuille Base ??

Bonjour Dan,

merci pour cette réponse toujours aussi rapide.

Evidemment, un bout de programme envoyé comme ça sans autre explication n'est pas très clair .

Il n'y a rien dans la feuille rapport, elle est alimentée par les 4 Combobox en haut du Userform. Elle permet de recueillir les données que l'on veut analyser. On n'est pas obligé d'alimenter toutes les colonnes (Dans la réalité, il y en a même 6 avec d'autres fonctions).

Donc on choisit en général le nom puis les différents critères à analyser. Ensuite on fait un tri sur la colonne à analyser. On supprime ce qui ne correspond pas au critère de sélection. Sur ce qui reste, on peut faire un tri sur un autre critère, etc... Bien entendu, on ne peut pas rajouter de colonne après avoir fait un tri, ça ne correspondrait plus à rien. Dans ce cas on réinitialise et on peut recommencer.

La feuille RAPPORTS permet ainsi de refaire indéfiniment des analyses sans toucher aux données de la BASE qui ne doivent en aucun cas être modifiées (en tous cas pas de cette façon : elle est elle-même alimentée par d'autres Userform).

Bonne journée.

Cordialement

Bonjour Dan,

après de très nombreux essais, j'ai enfin trouvé la solution en plaçant la relation entre la feuille et le LisBox :

Me.ListBox1.List = .Range("A1:D" & .[A65000].End(xlUp).Row).Value, non pas dans l'initialisation de l'Userform, mais à la fin de chaque requête de ComboBox. Dans ce cas, l'affichage dans le ListBox se fait normalement et la suppression des lignes sélectionnées aussi.

Une question cependant : quel avantage a-t-on à utiliser

Range("A1:D" & .[A65000].End(xlUp).Row).Value, plutôt que Range("A1:D1000".Value ?

Est-ce une question d'utilisation de la mémoire ? et si oui, ai-je intérêt à modifier aussi :

If CbRapport1.Value = "Nom" Then

.Range("A1:A100").Value = Sheets("BASE").Range("A2:A100").Value en .Range("A1:A" & .[A65000].End(xlUp).Row).Value ?

Merci d'avoir pris le temps de me répondre et merci pour vos conseils.

Cordialement

Bonjour

Une question cependant : quel avantage a-t-on à utiliser

Range("A1:D" & .[A65000].End(xlUp).Row).Value, plutôt que Range("A1:D1000".Value ?

L'avantage de faire le code est d'aller chercher vraiment la plage utilisée et surtout d'éviter de louper une donnée si par exemple la dernière ligne est la ligne 1001 ou plus bas.

Dans votre ligne vous partez de la ligne 65000. Faites plutôt ceci --> .Range("A1:D" & .Range("A" &.rows.count).End(xlUp).Row).Value

Avec cette ligne vous êtes sûr de toujours partir de la dernière ligne de votre feuille excel. Pour mémoire le 65000 était souvent utilisé pour pour excel 2003. Dans les versions excel récentes les feuilles ont plus de lignes.

Attention toutefois que j'ai supposé que la colonne A est toujours complétée à chaque ligne. d'où le "range("A" & rows.count)..."

Est-ce une question d'utilisation de la mémoire ? et si oui, ai-je intérêt à modifier aussi :

If CbRapport1.Value = "Nom" Then

.Range("A1:A100").Value = Sheets("BASE").Range("A2:A100").Value en .Range("A1:A" & .[A65000].End(xlUp).Row).Value ?

A ce niveau là, non cela n'a pas vraiment d'importance sur la mémoire. Par contre en pratiquant de la sorte vous n'aurez pas de données vides dans la combo. Comme dit avant vous pouvez aussi mettre ceci -> .Range("A1:A" & .range("A" & .rows.count).End(xlUp).Row).Value

Si besoin n'hésitez pas.

Cordialement

Bonsoir Dan,

Merci pour ces infos. Je vais les mettre en pratique...

Bien cordialement

Rechercher des sujets similaires à "listbox garder que lignes selectionnees"