Lister en-têtes de colonne et/ou de ligne pour chaque cellule identique

Bonjour,

Je ne sais pas si le titre est suffisamment clair, mais je vais tenter d'étayer la chose.

J'écoute beaucoup de musique, et pour se faire, j'utilise une playlist avec beaucoup de groupes et d'artistes associés.

Avec le temps, je me suis adonné à un petit rituel, qui est de trouver à chaque morceau écouté le nom du groupe et (si ma mémoire est bien disposée) le ou les artistes associés.

Comme cela ne me suffisait pas, je me suis dit qu'il serait intéressant (pour moi en tout cas) de disposer d'une sorte de base de données qui me permettrait de connaitre les liaisons entre groupes et artistes.

Pour se faire, j'ai donc créé un fichier Excel (2007: car je ne dispose que d'Excel 2007) en .xlsm. Fichier pour base de travail diminué du nombre d'artiste et de groupe.

En colonne B à partir de la ligne 5 se trouve les noms des groupes.

En ligne 4 à partir de la colonne C se trouve les noms d'artistes.

Pour chaque liaison entre groupe et artiste, je mets un x majuscule dans la cellule à l'intersection du groupe et de l'artiste concernés.

Du coup, je souhaiterai comme le montre le fichier "exemple image" joint à ce post:

En rouge, pouvoir trouver le nom du ou des groupes associé(s) à l'artiste et en bleu, le nom du ou des artistes associé(s) au groupe.

J'ai déjà avancé un peu sur mon fichier, car j'ai créé un UserForm sur lequel j'ai disposé 2 ComboBox que je réussi à remplir avec les noms des artistes pour ComboBox1 et les noms des groupes pour ComboBox2.

Avec en prime le défilement des ComboBox avec la molette de la souris.(Merci aux contributeurs des différents forums que j'ai pu "éplucher").

J'ai également placé 2 ListBox.

ListBox1 sous la ComboBox1 qui doit recevoir la liste du ou des groupes associé(s) à l'artiste sélectionné.

ListBox2 sous la ComboBox2 qui doit recevoir la liste du ou des artistes associé(s) au groupe sélectionné.

Et c'est là que je cale !!!!

Je ne parviens pas à trouver comment faire pour que lorsque je sélectionne un artiste dans la ComboBox1, mon code puisse lire tous les "X" se trouvant dans la colonne concernée de l'artiste et que pour chaque ligne trouvée il me renvoi les noms des groupes dans la ListBox1.

Même question dans l'autre sens, en sélectionnant un groupe dans la ComboBox2 pour afficher les artistes dans la ListBox2.

Sur les ListBox, je n'ai pas créé le moindre bout de code, car pour moi, c'est la panne sèche.

Ça fait 15 jours que je cherche, mais là j'en peux plus!!!!

D'avance un grand merci aux personnes qui pourront m'orienter sur la bonne voie.

Cdlt Rv.

17exemple-image.zip (341.68 Ko)
16liked-copie.zip (335.47 Ko)

Bonjour

Déjà un premier point dans votre fichier. Cela râme avec les codes au sujet de la souris qui sont placés dans le module 2.
Ces codes là qui n'aident en rien pour la fluidité de votre fichier.
Je ne comprenais pas pourquoi ma souris s'arrêtait par moment puis là après plantage complet, j'ai pigé l'histoire.

Pour votre usf :
1. Supprimez le code Private Sub UserForm_Activate()
2. Remplacez le code Initialize par ceci

Private Sub UserForm_Initialize() 'a l'initialisation du UserForm
Dim i As Integer 'déclaration de la variable i utilisée pour remplir la ComboBox2 (liste des groupes)
Dim dcl As Integer, dlg As Integer
Dim plage

With Sheets("Feuil2")
    dcl = .Cells(4, Columns.Count).End(xlToLeft).Column
    dlg = .Range("B" & Rows.Count).End(xlUp).Row

    Set plage = .Range(.Cells(4, 3), .Cells(4, dcl))
    ComboBox1.List = Application.Transpose(plage.Value)
    ComboBox2.List = .Range("B5:B" & dlg).Value
End With
End Sub

3. remplacez le code Combobox1_change par celui ci-dessous

Private Sub ComboBox1_Change() 'Survient lors de la modification de la propriété Value
Dim prem As String
Dim c As Range
Dim col As Integer

ListBox1.Clear
If ComboBox1.Value = vbNullString Then Exit Sub

With Sheets("Feuil2")
    col = .Rows("4:4").Find(ComboBox1.Value, LookIn:=xlValues, lookat:=xlWhole).Column

    Set c = .Columns(col).Find("X", LookIn:=xlValues, lookat:=xlWhole)
    If Not c Is Nothing Then
        prem = c.Address
        Do
            If UCase(.Cells(c.Row, col)) = "X" Then
                With ListBox1
                    .AddItem
                    .List(.ListCount - 1, 0) = Sheets("Feuil2").Cells(c.Row, col).Offset(0, -1).Text
                End With

            End If
            Set c = .Columns(col).FindNext(c)
        Loop While Not c Is Nothing And c.Address <> prem
    End If
End With
End Sub

Au final, dans votre userform vous devez juste avoir 3 codes. Les deux ci-dessus et le code pour la listbox2 à venir

Cordialement

Bonjour Dan,

Merci pour ton retour, j'apprécie grandement.

J'ai suivi tes deux premiers conseils, à savoir:

Suppression du code "Private Sub UserForm_Activate()" et remplacement du code "Private Sub UserForm_Initialize()" par le tiens.

Code que je me suis permis de commenter afin que je puisse plus facilement m'y retrouver avec mon propre 'charabia'.

Si au passage, tu vois que mes commentaires ne sont pas vraiment cohérent ou pas trés judicieux par rapport au code, n'hésites pas à me reprendre.

Ceci dit, ton code est court et plus efficace que le mien, donc l'adoption n'en est que plus naturel.

Pour le conseil 3, je l'ai suivi également.

Il fonctionne très bien lorsque je sélectionne le premier artiste en colonne C.

Mais lorsque je sélectionne le deuxième artiste en colonne D, la listbox1 me donne les valeurs de la colonne immédiatement à gauche (donc la c) et ainsi de suite.

Donc il faut que je trouve le moyen pour que quelque soit la colonne de l'artiste sélectionné, le retour soit toujours donné par rapport aux lignes correspondantes de la colonne B ce qui correspondrai bien aux noms des groupes.

Je joint l'évolution du fichier (Liked - Copie numéro 2.xlsm) ou j'ai modifié les codes et mis mes commentaires.

Les X de liaisons (groupes <--> artistes) de Feuil2 peuvent êtres modifiés comme on veut pour les besoin de tests, j'ai les vraies données à l'abri sur un autre fichier.

Donc maintenant, je vais essayer de résoudre ce problème de décalage de colonne pour l'affichage de ListBox1.

Je pense que cette ligne de code pour ComboBox1:

.List(.ListCount - 1, 0) = Sheets("Feuil2").Cells(c.Row, col).Offset(0, -1).Text

à quelque chose à y voir.

Ensuite, je me pencherai sur le code de la ListBox2.

Il y a des chances pour que j'appelle à nouveau "au secours" mais avant, je vais me triturer un peu les méninges.

Je crois, que c'est la seule est vrais façon d'avancer.

Merci encore Dan.

Re,

Ok pour le fichier. Vous avez bien modifié et vous avez constaté que c'est nettement plus fluide lors de l'exécution.
Les commentaires sont corrects (bien que long... mais bon le principal est de s'y retrouver pour vous et c'est une bonne méthode)


Mais lorsque je sélectionne le deuxième artiste en colonne D, la listbox1 me donne les valeurs de la colonne immédiatement à gauche (donc la c) et ainsi de suite.

Oui erreur de ma part
Dans le code Private Sub ComboBox1_Change(), vous avez cette ligne --> .List(.ListCount - 1, 0) = Sheets("Feuil2").Cells(c.Row, col).Offset(0, -1).Text
Il faut modifier la ligne comme ceci :

.List(.ListCount - 1, 0) = Sheets("Feuil2").Cells(c.Row, 2).Text

Voici le code pour la listbox2

Private Sub ComboBox2_Change() 'Survient lors de la modification de la propriété Value
Dim prem As String
Dim c As Range
Dim dlg As Integer, lig As Integer

ListBox2.Clear
If ComboBox2.Value = vbNullString Then Exit Sub

With Sheets("Feuil2")
    dlg = .Range("B" & Rows.Count).End(xlUp).Row
    lig = Range("B5:B" & dlg).Find(ComboBox2.Value, LookIn:=xlValues, lookat:=xlWhole).Column + 3

    Set c = .Rows(lig).Find("X", LookIn:=xlValues, lookat:=xlWhole)
    If Not c Is Nothing Then
        prem = c.Address
        Do
            If UCase(.Cells(lig, c.Column)) = "X" Then
                With ListBox2
                    .AddItem
                    .List(.ListCount - 1, 0) = Sheets("Feuil2").Cells(4, c.Column).Text
                End With
            End If
            Set c = .Rows(lig).FindNext(c)
        Loop While Not c Is Nothing And c.Address <> prem
    End If
End With
End Sub

Je vous laisse faire pour les commentaires mais si besoin et souci, je peux vous les ajouter

NB : Petit conseil, ajouter ceci tout en haut de vos codes --> Option Explicit (cette instruction sert à ne pas oublier de déclarer les variables)

Dites - moi pour la suite

Bonjour Dan,

Merci pour ta correction sur ComboBox1 car sans cela, j'aurai eu du mal à trouver je pense.

Pour l'instant, ce ne sont pas mes compétences réelles avec VBA qui me permettent de vraiment avancer en la matière, mais plutôt des tâtonnements successifs en essayant au mieux de comprendre le langage.

Syntaxe, construction du code e.t.c...

C'est pourquoi les commentaires de lignes de codes sont très importants pour moi, cela me permet de "fixer" l'information personnelle recueillie afin de pouvoir revenir dessus si besoin et créer d'autres lignes de code pour d'autre fichier.

Une sorte de bibliothèque pour mes neurones en quelque sorte. (Ben oui !!! l'âge n'aidant pas, il faut bien trouver une parade).

Pour le code de ComboBox2, mes tâtonnements m'ont permis de modifier la ligne suivante:

lig = Range("B5:B" & dlg).Find(ComboBox2.Value, LookIn:=xlValues, lookat:=xlWhole).Column + 3

en

lig = Range("B5:B" & dlg).Find(ComboBox2.Value, LookIn:=xlValues, lookat:=xlWhole).Row

Car 'Column +3' ne permet de lire que la ligne 5 de Feuil2 quelque soit le groupe recherché dans ComboBox2

Que t'inspires cette modification ?

Mais là, je n'ai pas vraiment tout compris.

Peux-tu m'aider à commenter cette portion de code de ComboBox1

Do
            If UCase(.Cells(c.Row, col)) = "X" Then
                With ListBox1
                    .AddItem
                    .List(.ListCount - 1, 0) = Sheets("Feuil2").Cells(c.Row, 2).Text
                End With
            End If
            Set c = .Columns(col).FindNext(c)
        Loop While Not c Is Nothing And c.Address <> prem

et celle ci pour ComboBox2

Do
            If UCase(.Cells(lig, c.Column)) = "X" Then
                With ListBox2
                    .AddItem
                    .List(.ListCount - 1, 0) = Sheets("Feuil2").Cells(4, c.Column).Text
                End With
            End If
            Set c = .Rows(lig).FindNext(c)
        Loop While Not c Is Nothing And c.Address <> prem

Je joints la dernière version du fichier.

Cdlt Rv.

Bonjour

Pour l'instant, ce ne sont pas mes compétences réelles avec VBA qui me permettent de vraiment avancer en la matière, mais plutôt des tâtonnements successifs en essayant au mieux de comprendre le langage....
C'est pourquoi les commentaires de lignes de codes sont très importants pour moi...

C'est une bonne méthode pour comprendre plutôt que de prendre sans rien piger et donc vous avez bien raison d'ajouter les commentaires.
Cela devient "une bibliothèque" comme vous le précisez.. et comme vous l'écrivez "l'age n'aide pas..."... idem pour moi
N'oubliez par que vous disposez de la touche F8 sur votre clavier pour faire du mode pas à pas dans les codes. Un passage du pointeur de la souris sur les instructions où vous êtes arrêté permet de voir la valeur des variables mais aussi de voir ce que se passe dans la feuille ou l'USF.


Pour le code de ComboBox2, mes tâtonnements m'ont permis de modifier la ligne suivante:
lig = Range("B5:B" & dlg).Find(ComboBox2.Value, LookIn:=xlValues, lookat:=xlWhole).Column + 3
...
Que t'inspires cette modification ?

Juste !. désolé je n'avais pas vérifié plus loin l'exactitude des infos renvoyées. J'avais fait un copier coller du premier code combobox1_change qui définissait une colonne. Cette instruction lig=...n'a pas de sens dans le cas Combobox2. Mais vous avez bien vu en remplaçant column par ROW.


Peux-tu m'aider à commenter cette portion de code de ComboBox1

Voici ci-dessous

        Do 'Instruction pour debuter une boucle
            If UCase(.Cells(c.Row, col)) = "X" Then 'verifier si la cellule de la ligne variable 'C' et de la colonne variable 'Col' contient X (Ucase = Majuscule)
                With ListBox1
                    .AddItem 'instruction pour pouvoir ajouter dans la listbox
                    .List(.ListCount - 1, 0) = Sheets("Feuil2").Cells(c.Row, 2).Text 'ajout du groupe trouve en cellule(ligne, colonne) --> ligne = variable c et colonne = 2 (Listcount pour compter le nombre de ligne dans la listbox, 0 pour la premiere colonne)
                End With
            End If
            Set c = .Columns(col).FindNext(c) 'on cherche la valeur X suivante dans la colonne variable 'col'
        Loop While Not c Is Nothing And c.Address <> prem 'on relance l'excution 'DO' si 'c' n est pas rien et que l'adresse de la cellule trouvee est differente de celle definie dans la variable 'prem"

NB : je ne mets pas volontairement les accents dans les commentaires. Avec VBA le mieux est de penser anglais car quelque fois les caractères sont transformés. Par exemple lorsque vous portez un fichier entre excel windows et excel MAC.

Pas besoin de reposter un fichier car j'ai votre dernière version

Si besoin d'infos dites-moi mais si vous en avez terminé pensez à cloturer le fil

Crdlt

Bonsoir Dan,

Un grand merci pour ton aide, car même si j'arrive a avancer un peu, sans toi, je serai encore bien loin du but.

Il ne faut pas être désolé pour le code de ComboBox2, car en ce qui me concerne, je ne m'occupe que de mon fichier pour l'instant, ce qui me laisse le temps et l'énergie pour avancer.

Mais je pense que pour toi ce doit être différent, tu dois avoir plusieurs 'gamelle' sur le feu comme on dit, ce qui fait que l'erreur est bien plus facile même avec de meilleures compétences.

Pour les commentaires c'est super, merci je vais pouvoir annoter complétement mon code.

Je clôture le sujet donc en espérant qu'il sera utile à d'autres personnes.

Au plaisir de "refaire affaire avec toi" Dan.

Bonne soirée.

A+

Rechercher des sujets similaires à "lister tetes colonne ligne chaque identique"