XL 2010 [RESOLU] Listbox et Listobject

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

  • Listbox_Listobject.xlsm
    20.4 KB · Affichages: 9
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??

ChTi160

XLDnaute Barbatruc
Bonjour le Fil
@patrick
J'ai remarqué que même si la ListBox n'a qu'une ou Zéro ligne de Données, le nombre de ligne (ListCount) est 2 (du au Resize(,2) ,je pense !)
Ça ne risque pas de poser un problème dans certains cas ?
Ce que j'ai mis comme procédure (Plus simpliste Lol)
VB:
Private Sub UserForm_Initialize()
Dim i As Byte

 With Range("Tjeux" & i).ListObject
    If Not .DataBodyRange Is Nothing And .ListRows.Count > 1 Then
          Controls("ListBox" & i).List = .DataBodyRange.Value 'plante
             ElseIf .ListRows.Count = 1 Then
           Controls("ListBox" & i).AddItem .ListRows(1).Range.Cells(1, 1) '
      End If
 End With
Next i
End Sub
Bonne Journée
Jean marie
 

patricktoulon

XLDnaute Barbatruc
re
Bonjour chti160
non le resize est de deux colonnes en effet dans le tableau 2 ca ajoute 2 lignes (la 2d vide) c'est étonnant

par contre pour le empty dans l 2d condition tu en met une autre
et là la listbox 1 sera réellement vide
VB:
Private Sub UserForm_Initialize()
    Dim r As Range, i&, lstBx As MSForms.ListBox
    For i = 1 To 3
        Set r = Range("Tjeux" & i)
        With Me.Controls("ListBox" & i)
            .Clear: If r.Rows.Count > 1 Then .List = r.Value Else If r.Value <> Empty Then .Column = r.Resize(1, 2).Value
        End With
    Next
End Sub
 

patricktoulon

XLDnaute Barbatruc
re
en transposant on a le résultat escompté
Code:
Private Sub UserForm_Initialize()
    Dim r As Range, i&, lstBx As MSForms.ListBox
    For i = 1 To 3
        Set r = Range("Tjeux" & i)
        With Me.Controls("ListBox" & i)
            .Clear: If r.Rows.Count > 1 Then .List = r.Value Else If r.Value <> Empty Then .Column = Application.Transpose(r.Resize(1, 2).Value)
        End With
    Next
End Sub
 

patricktoulon

XLDnaute Barbatruc
re
ben la première c'est si le ubound >1
et dans le else tu met si empty faire ceci ou cel
alors ca y est j'ai percuté
en fait c'est pas étonnant
quand je prend un resize 2 colonne sur une ligne plage.resize(1,2) j'obtient un array 1 dim il faut donc transposer
car en effet le .list accepte un array 1 dim donc pour le .column on devra transposer même si ça ne parait pas logique
tel que je le fait dans le post #19
 

patricktoulon

XLDnaute Barbatruc
re
j’irais même jusqu’à dire si l'on voudrait parfaire la chose conceptuellement parlant
ca n'a rien a faire dans le initialise ou l'activate
car a tout moment dans un userform on peut avoir besoins de mettre les liste a jour
VB:
Option Explicit

Private Sub UserForm_Initialize()
     Dim I&
     For I = 1 To 3
        reliste I
    Next
End Sub

Sub reliste(x)
 Dim r As Range
      Set r = Range("Tjeux" & x)
    With Me.Controls("ListBox" & x)
        If r.Rows.Count > 1 Then .List = r.Value Else If r.Value <> Empty Then .Column = Application.Transpose(r.Resize(1, 2).Value)
    End With
End Sub

ailleurs dans le code ou event des controls dans l'userform à tout moment on peut mettre a jour
un ou deux d'entre elles ou les 3
soit en appelant comme je le fait dans le initialise dans une boucle
soit unitaire en appelant simplement "reliste 1 ou 2 ou 3"
 

Discussions similaires

Réponses
6
Affichages
342

Statistiques des forums

Discussions
313 274
Messages
2 096 754
Membres
106 739
dernier inscrit
jcdu16