XL 2010 [RESOLU] Listbox et Listobject

  • Initiateur de la discussion Initiateur de la discussion cathodique
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

cathodique

XLDnaute Barbatruc
Bonjour,

D'habitude pour alimenter une Listbox à partir d'un tableau structuré (ListObject), s'il se nomme Tb, le code suivant était suffisant pour alimenter le listbox
VB:
[Tb].value
En travaillant sur un fichier, je me suis rendu compte que ce code fonctionne si et seulement si, il y a au moins 2 lignes de données.
En effet, si le tableau a une ligne ou non vide le code plante. Je n'arrive pas à contourner ce problème.
Voici le code pour celles et ceux qui n'ouvrent jamais les fichiers joints.
Code:
Option Explicit

Private Sub UserForm_Initialize()
   Dim Tb1 As ListObject, Tb2 As ListObject, Tb3 As ListObject
   With Sheets("feuil1")
      Set Tb1 = .ListObjects("Tjeux1")
      Set Tb2 = .ListObjects("Tjeux2")
      Set Tb3 = .ListObjects("Tjeux3")
'tableau vide--------------------------------------------
      'ListBox1.List = Tb1.DataBodyRange.Value  'plante
      'ListBox1.List = [Tjeux1].Value           'plante

'tableau une seule ligne de données----------------------
      'ListBox2.List = Tb2.DataBodyRange.Value     'plante
      'ListBox2.List = [Tjeux2].Value              'plante

'tableau avec + de 2 lignes de données---------------------
      ListBox3.List = Tb3.DataBodyRange.Value     'fonctionne
      'ListBox3.List = [Tjeux3].Value               'fonctionne
   End With
   Set Tb1 = Nothing
   Set Tb2 = Nothing
   Set Tb3 = Nothing
End Sub
Merci par avance.
 

Pièces jointes

Solution
Bonsoir
bonsoir j'arrive après la bataille mais bon
VB:
Option Explicit

Private Sub UserForm_Initialize()
Dim r As Range, i&, lstBx As MSForms.ListBox
    For i = 1 To 3
        Set r = Range("Tjeux" & i)
        Set lstBx = Me.Controls("ListBox" & i)
        lstBx.Clear: If r.Rows.Count > 1 Then lstBx.List = r.Value Else lstBx.Column = r.Resize(, 2).Value
    Next
End Sub
j'explique ou pas le pourquoi du comment et l'astuce??
En remerciant celles et ceux qui auront consulter le fil. J'ai trouvé une solution.
VB:
Option Explicit

Private Sub UserForm_Initialize()
   Dim Tb1 As ListObject, Tb2 As ListObject, Tb3 As ListObject

   With Sheets("feuil1")
      Set Tb1 = .ListObjects("Tjeux1")
      Set Tb2 = .ListObjects("Tjeux2")
      Set Tb3 = .ListObjects("Tjeux3")
      'tableau vide--------------------------------------------
      If Tb1.DataBodyRange Is Nothing Then
         ListBox1.Clear
      ElseIf Tb1.ListRows.Count = 1 Then
         ListBox1.AddItem Tb1.DataBodyRange(1)
      Else
         ListBox1.List = Tb1.DataBodyRange.Value
      End If

      'tableau une seule ligne de données----------------------
      If Tb2.DataBodyRange Is Nothing Then
         ListBox2.Clear
      ElseIf Tb2.ListRows.Count = 1 Then
         ListBox2.AddItem Tb2.DataBodyRange(1)
      Else
         ListBox2.List = Tb2.DataBodyRange.Value
      End If

      'tableau avec + de 2 lignes de données---------------------
      If Tb3.DataBodyRange Is Nothing Then
         ListBox3.Clear
      ElseIf Tb3.ListRows.Count = 1 Then
         ListBox3.AddItem Tb3.DataBodyRange(1)
      Else
         ListBox3.List = Tb3.DataBodyRange.Value
      End If
      ListBox3.List = Tb3.DataBodyRange.Value     'fonctionne
   End With

   Set Tb1 = Nothing
   Set Tb2 = Nothing
   Set Tb3 = Nothing
End Sub
 
Bonjour,

Peut être comme ceci en utilisant non plus la propriété .List mais .RowSource

VB:
Private Sub UserForm_Initialize()
   Dim Tb1 As ListObject, Tb2 As ListObject, Tb3 As ListObject
   With Sheets("feuil1")
        Set Tb1 = .ListObjects("Tjeux1")
        Set Tb2 = .ListObjects("Tjeux2")
        Set Tb3 = .ListObjects("Tjeux3")
        
        xNbrTb1 = .Range("Tjeux1").Count: xAdrTb1 = .Range("Tjeux1").Address
        xNbrTb2 = .Range("Tjeux2").Count: xAdrTb2 = .Range("Tjeux2").Address
        xNbrTb3 = .Range("Tjeux3").Count: xAdrTb3 = .Range("Tjeux3").Address
    
'tableau vide--------------------------------------------
        'ListBox1.List = Tb1.DataBodyRange.Value  'plante
        'ListBox1.List = [Tjeux1].Value           'plante
        If xNbrTb1 < 2 Then
            ListBox1.RowSource = xAdrTb1
        Else
            ListBox1.List = [Tjeux1].Value
        End If
'tableau une seule ligne de données----------------------
        'ListBox2.List = Tb2.DataBodyRange.Value     'plante
        'ListBox2.List = [Tjeux2].Value              'plante
        If xNbrTb2 < 2 Then
            ListBox2.RowSource = xAdrTb2
        Else
            ListBox2.List = [Tjeux2].Value
        End If
'tableau avec + de 2 lignes de données---------------------
        'ListBox3.List = Tb3.DataBodyRange.Value     'fonctionne
        'ListBox3.List = [Tjeux3].Value               'fonctionne
        If xNbrTb3 < 2 Then
            ListBox3.RowSource = xAdrTb3
        Else
            ListBox3.List = [Tjeux3].Value
        End If

    End With
    Set Tb1 = Nothing
    Set Tb2 = Nothing
    Set Tb3 = Nothing
End Sub

Du coup cela devrait le faire
@+ Lolote83
 
Bonjour
Effectivement, c'est pas tres clair!🤔
Tu peux contourner comme ceci
For Each i In Tb2.DataBodyRange.Rows
me.ListBox2.AddItem i
'ListBox2.List = [Tjeux2].Value 'plante
Next
Bonjour,

@sousou : Dans un userform, j'ai des listboxs et combobox alimentées à partir de tableaux structurés qui devraient être au préalable remplis via d'autres userforms. Il s'avère que certains sont vides ou n'ont qu'une seule ligne de valeurs. J'utilise par exemple Listbox1.list=[Tjeux1].value mais a plante lorsque le tableau Tjeux1 est vide ou n'a qu'une seule ligne de valeur.
J'espère que c'est plus clair. Pour info, j'ai essayé Listbox1.Column=[Tjeux1].value plante aussi.
Ne fonctionne que pour 2 lignes et plus.
 
Bonjour,

Peut être comme ceci en utilisant non plus la propriété .List mais .RowSource

VB:
Private Sub UserForm_Initialize()
   Dim Tb1 As ListObject, Tb2 As ListObject, Tb3 As ListObject
   With Sheets("feuil1")
        Set Tb1 = .ListObjects("Tjeux1")
        Set Tb2 = .ListObjects("Tjeux2")
        Set Tb3 = .ListObjects("Tjeux3")
       
        xNbrTb1 = .Range("Tjeux1").Count: xAdrTb1 = .Range("Tjeux1").Address
        xNbrTb2 = .Range("Tjeux2").Count: xAdrTb2 = .Range("Tjeux2").Address
        xNbrTb3 = .Range("Tjeux3").Count: xAdrTb3 = .Range("Tjeux3").Address
   
'tableau vide--------------------------------------------
        'ListBox1.List = Tb1.DataBodyRange.Value  'plante
        'ListBox1.List = [Tjeux1].Value           'plante
        If xNbrTb1 < 2 Then
            ListBox1.RowSource = xAdrTb1
        Else
            ListBox1.List = [Tjeux1].Value
        End If
'tableau une seule ligne de données----------------------
        'ListBox2.List = Tb2.DataBodyRange.Value     'plante
        'ListBox2.List = [Tjeux2].Value              'plante
        If xNbrTb2 < 2 Then
            ListBox2.RowSource = xAdrTb2
        Else
            ListBox2.List = [Tjeux2].Value
        End If
'tableau avec + de 2 lignes de données---------------------
        'ListBox3.List = Tb3.DataBodyRange.Value     'fonctionne
        'ListBox3.List = [Tjeux3].Value               'fonctionne
        If xNbrTb3 < 2 Then
            ListBox3.RowSource = xAdrTb3
        Else
            ListBox3.List = [Tjeux3].Value
        End If

    End With
    Set Tb1 = Nothing
    Set Tb2 = Nothing
    Set Tb3 = Nothing
End Sub

Du coup cela devrait le faire
@+ Lolote83
Bonjour,

@Lolote83 😉: je te confirme que ton code fonctionne aussi. Juste déclarer les variables que tu as ajouté.
Merci beaucoup. Je pointe ta proposition comme solution.
 
Re
J'avais bien compris ton problème, c'est pourquoi je te propose cette solution
@sousou 😎: C'est parfait. peu de ligne et efficace.
J'essaie d'apprendre à coder en utilisant les ListObjects. Tu n'as pas déclaré 'i', le code ne demande même de le déclarer malgré la présence de Option Explicit.
VB:
For Each i In Tb2.DataBodyRange.Rows
  Me.ListBox2.AddItem i
Next
Merci de m'éclairer.
 
bien sur pour la déclaration,
Pour le plantage, j'ai remarqué une chose,que je ne m'explique pas trop.
J'avais la même chose sur ton fichier.
excel ne détecte pas sur le tableau vide (tb1) les databodyrange, d’où une erreur
comme si le tableau n'avais pas été initialisé, à sa création.
Dans ton tableau vide tb1 , j'ai mis une valeur, puis je l'ai retirée, et c'est pour cela qu'il fonctionne.
Tu peu gérer ceci en utilisant le traitement d'erreur,
 
Dernière édition:
Bonsoir
bonsoir j'arrive après la bataille mais bon
VB:
Option Explicit

Private Sub UserForm_Initialize()
Dim r As Range, i&, lstBx As MSForms.ListBox
    For i = 1 To 3
        Set r = Range("Tjeux" & i)
        Set lstBx = Me.Controls("ListBox" & i)
        lstBx.Clear: If r.Rows.Count > 1 Then lstBx.List = r.Value Else lstBx.Column = r.Resize(, 2).Value
    Next
End Sub
j'explique ou pas le pourquoi du comment et l'astuce??
 
bien sur pour la déclaration,
Pour le plantage, j'ai remarqué une chose,que je ne m'explique pas trop.
J'avais la même chose sur ton fichier.
excel ne détecte pas sur le tableau vide (tb1) les databodyrange, d’où une erreur
comme si le tableau n'avais pas été initialisé, à sa création.
Dans ton tableau vide tb1 , j'ai mis une valeur, puis je l'ai retirée, et c'est pour cela qu'il fonctionne.
Tu peu gérer ceci en utilisant le traitement d'erreur,
Bonsoir,

Désolé pour le retard. Je remercie pour tes explications.

Bonne soirée et bon week-end
 
Bonsoir
bonsoir j'arrive après la bataille mais bon
VB:
Option Explicit

Private Sub UserForm_Initialize()
Dim r As Range, i&, lstBx As MSForms.ListBox
    For i = 1 To 3
        Set r = Range("Tjeux" & i)
        Set lstBx = Me.Controls("ListBox" & i)
        lstBx.Clear: If r.Rows.Count > 1 Then lstBx.List = r.Value Else lstBx.Column = r.Resize(, 2).Value
    Next
End Sub
j'explique ou pas le pourquoi du comment et l'astuce??
Bonsoir Patrick😉,

Tu sais bien que tes explications sont toujours les bienvenues.
J'essaie de comprendre la bête "ListObject" mais j'avoue que j'ai beaucoup de lacunes.
Je testerai demain ton code. Je suis crevé.
Bonne fin de soirée et bon week-end😎
 
Bonjour,

@patricktoulon : C'est un régale. Merci beaucoup, c'est très clair.
Je t'avoue que je ne fais pas autant d'effort que toi pour aller au bout du bout.
Quoique bien souvent j'essaie d'approfondir mais butant sur des difficultés de compréhension, j'abandonne.

Si j'ai bien compris, il est plus avantageux d'utiliser le Range que le ListObject pour "atteindre" un tableau structuré.

Tu m'as parfaitement démontrer comment solutionner mon problème en pratiquement une seule ligne de code. Évitant ainsi, la suite de If. Je connaissais l'utilisation du ListBox.Column en faisant des extractions de données d'une BD. Mais sans avoir bien compris le pourquoi du comment. Tu viens de me l'expliquer clairement.

à la fin de la vidéo, tu m'as montré qu'après le resize dans la listbox du tableau vide, qu'il y avait bien 2 lignes vides. Tu as dit que l'on pouvait lui appliquer un Clear. Si ce n'est abusé, je voudrais que tu me donnes ta solution.

En tout cas un grand bravo pour ta vidéo très pédagogique. Encore merci, pour ton partage et ta patience.

Bonne journée.

edit: J'ai téléchargé ta vidéo. Elle est dans ma "tirelire".
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Réponses
6
Affichages
544
Réponses
4
Affichages
446
Réponses
4
Affichages
954
Réponses
9
Affichages
1 K
Réponses
68
Affichages
8 K
Retour