XL 2019 Trouver le numéro de ligne d'un item sélectionné dans une listbox

Bana XIII

XLDnaute Nouveau
J’ai une listbox qui charge les données d’un tableau de 9 colonnes et plusieurs centaines de lignes. Et bien sûr pour me retrouver, je procède à des filtres suivant 3 critères afin de réduire le nombre de données à charger dans la listbox. Ensuite je choisi un item dans la listbox et les données choisis sont renvoyées dans les textbox pour des éventuelles modifications. Tout va bien jusque-là.

Mon souci c’est comment retrouver la ligne du tableau correspondant à l’item sélectionné dans la listbox pour procéder à la modification !

Cordiales salutations!
 

mapomme

XLDnaute Barbatruc
Bonsoir,

Une astuce : quand vous chargez la listbox, ajoutez y une colonne (de largeur 0 donc invisible) qui contient le numéro de ligne (de la feuille excel) des items filtrés. Vous aurez ainsi une lecture directe de la ligne de l'item sélectionné au sein de la listbox. Cette astuce permet aussi de distinguer dans la listbox des lignes doublons dans les données (puisque leurs numéros de ligne dans la dernière colonne invisible sont différents).

Une autre riche idée : Joignez un fichier avec les données et le code que vous avez déjà écrit.
 
Dernière édition:

mapomme

XLDnaute Barbatruc
Bonjour @cathodique :),

@mapomme : Stp, à quoi sert la variable booléenne 'ok'?
A ne pas exécuter le code de ListBox2_Click(), mais pourquoi ?

Quand on initialise le UserForm, quand on sélectionne un item dans ListBox1, on touche à ListBox2 avec diverses instructions du type : Listbox2.list = t ou bien ListBox2.ListIndex = -1, ...

Ces instructions qui affectent ListBox2 déclenchent l'évènement ListBox2_Click. Or je ne désire exécuter le code de ListBox2_Click() uniquement lorsque l'utilisateur sélectionne lui-même un élément de ListBox2 et non pas quand l'évènement se déclenche de manière "indirecte" ou "en cascade".

Pour cela j'utilise la variable OK. En début de procédure pouvant déclencher de manière inopportune l'évènement ListBox2_Click (selon ma propre logique de codage), on met OK à False bloquant ainsi l’exécution du code de ListBox2_Click(). A la fin de la procédure, on remet bien sûr OK à True pour permettre à nouveau l'exécution normale et justifiée de l'entièreté du code de ListBox2_Click() par la suite.

Cette utilisation de la variable OK ne bloque pas l'évènement ListBox2_Click qui se produit malgré tout et qui entraine le branchement à la procédure évènementielle ListBox2_Click(). Le test de cette variable empêche simplement la poursuite ou non de l'exécution du code.

Si ce n'est pas clair, me re-demander.
 
Dernière édition:

cathodique

XLDnaute Barbatruc
Bonjour @cathodique :),


A ne pas exécuter le code de ListBox2_Click(), mais pourquoi ?

Quand on initialise le UserForm, quand on sélectionne un item dans ListBox1, on touche à ListBox2 avec diverses instructions du type : Listbox2.list = t ou bien ListBox2.ListIndex = -1, ...

Ces instructions qui affectent ListBox2 déclenchent l'évènement ListBox2_Click. Or je ne désire exécuter le code de ListBox2_Click() uniquement lorsque l'utilisateur sélectionne lui-même un élément de ListBox2 et non pas quand l'évènement se déclenche de manière "indirecte" ou "en cascade".

Pour cela j'utilise la variable OK. En début de procédure pouvant déclencher de manière inopportune l'évènement ListBox2_Click (selon ma propre logique de codage), on met OK à False bloquant ainsi l’exécution du code de ListBox2_Click(). A la fin de la procédure, on remet bien sûr OK à True pour permettre à nouveau l'exécution normale et justifiée de l'entièreté du code de ListBox2_Click() par la suite.

Cette utilisation de la variable OK ne bloque pas l'évènement ListBox2_Click qui se produit malgré tout et qui entraine le branchement à la procédure évènementielle ListBox2_Click(). Le test de cette variable empêche simplement la poursuite ou non de l'exécution du code.

Si ce n'est pas clair, me re-demander.
Rebonjour @mapomme,

Merci beaucoup, tes explications sont très claires.

Bonne journée.
 

patricktoulon

XLDnaute Barbatruc
re
Bonjour @mapomme
pour ne pas déclencher le code de l'event click d'une listebox en la remplissant ou modifiant ou autre il suffit simplement de mettre le code de l'event dans ce "IF"
if activecontrol.name="nom de ta listbox" then
'code de l'event
end if

et on a plus de soucis avec l’éventuelle mise a jour de la variable booléenne puisqu'elle n'est plus nécessaire

;)
 

Bana XIII

XLDnaute Nouveau
Bonjour la Pomme
Excuse moi le retard, j'ai dû retravailler mon fichier de base pour enlever les informations sensibles.
Voici en gros dans mon classeur EXEMPLE joint ce sur quoi je travaille. En attendant vos réactions, je continuer de tester vos différentes contributions.
Cordiales salutations!
 

Pièces jointes

  • EXEMPLE.xlsm
    34.5 KB · Affichages: 19

cathodique

XLDnaute Barbatruc
re
Bonjour @mapomme
pour ne pas déclencher le code de l'event click d'une listebox en la remplissant ou modifiant ou autre il suffit simplement de mettre le code de l'event dans ce "IF"
if activecontrol.name="nom de ta listbox" then
'code de l'event
end if

et on a plus de soucis avec l’éventuelle mise a jour de la variable booléenne puisqu'elle n'est plus nécessaire

;)
Merci @patricktoulon , bien que tu t'adresses à @mapomme, je me suis implicitement concerné car la question venait de moi.
Je t'avoue que je n'ai pas vraiment compris comment procéder. Aurais-tu sous le main un exemple stp.

Merci.
 

patricktoulon

XLDnaute Barbatruc
dans le userform 2 listbox
VB:
Private Sub ListBox1_Click()
    With ListBox1
        ListBox2.List = Cells(1, .Value).Resize(4).Value
        ListBox2.ListIndex = 2
    End With
End Sub


Private Sub ListBox2_Click()
    If ActiveControl.Name = "ListBox2" Then
        'tout le code de l'event doit etre dans ce  if
        MsgBox ListBox2.ListIndex
    End If
End Sub

Private Sub UserForm_Activate()
    ListBox1.List = Array(1, 2, 3)
End Sub

demo avec le if je selection un index en meme temps que je change la liste2
demo7.gif


démo sans le IF et pareille je selectionne un index en même temps que je change la liste2


demo7.gif
 

cathodique

XLDnaute Barbatruc
dans le userform 2 listbox
VB:
Private Sub ListBox1_Click()
    With ListBox1
        ListBox2.List = Cells(1, .Value).Resize(4).Value
        ListBox2.ListIndex = 2
    End With
End Sub


Private Sub ListBox2_Click()
    If ActiveControl.Name = "ListBox2" Then
        'tout le code de l'event doit etre dans ce  if
        MsgBox ListBox2.ListIndex
    End If
End Sub

Private Sub UserForm_Activate()
    ListBox1.List = Array(1, 2, 3)
End Sub

demo avec le if je selection un index en meme temps que je change la liste2
Regarde la pièce jointe 1107385

démo sans le IF et pareille je selectionne un index en même temps que je change la liste2


Regarde la pièce jointe 1107386
C'est parfait. T'es vraiment très fort. Merci pour ton partage, j'apprécie vraiment.

@Bana XIII : Toutes mes excuses d'avoir interféré dans ta discussion.

1000Mercis.
 

mapomme

XLDnaute Barbatruc
if activecontrol.name="nom de ta listbox" then
'code de l'event
end if
Bonjour @patricktoulon ;),

Tu as raison. Mais les goûts et les couleurs...:D

En général, je préfère l'indicateur au niveau UserForm. Mais pourquoi donc, qu'est-ce?

Quand on a des codes un peu longs, avec la méthode de la variable globale, je suis certain que, quoiqu'il se produise dans ma procédure, jamais celle liée à l’événement ne sera exécutée même en cas d'évènement impromptu (un changement de contrôle actif par exemple). De plus le code de ma procédure est indépendante du nom de mes contrôles.
Certes, il faut remettre l'indicateur à la bonne valeur en fin de procédure. Il faudrait même pour blinder, gérer une éventuelle erreur pour remettre l'indicateur à la bonne valeur (tout comme, pour les feuilles Excel, quand on utilise EnableEvents, il faut prévoir, en cas d'erreur, la réactivation après le Application.EnableEvents=False).

Ton idée est bonne 👍. Je ne l'avais jamais croisée (ton astuce) ;).
 

patricktoulon

XLDnaute Barbatruc
re
@mapomme
j'ai commencé a utiliser cette astuce
quand j'ai commencé a coder des classe control il y a quelques années
c'est simple et ça demande aucune mise a jour
et les events sont bien bridés a la seule action sur les controls eux même
et surtout c'est valable pour tout les controls ;)
notamment pour les checkbox en série par exemple
 
Dernière édition:

Discussions similaires

Statistiques des forums

Discussions
315 132
Messages
2 116 584
Membres
112 797
dernier inscrit
zouzou50