UserForm et combobox

Paladin

XLDnaute Junior
Bonjour le forum,

Quelqu'un saurait-il comment on remplit une Combobox par macro (en utilisant RowSource) ?
L'aide de VBA dit :

Combobox.RowSource = 'A2:G10'

Mais ça ne marche pas chez moi.
De plus, je veux mettre un nom défini et j'ai donc essayé :

Combobox.RowSource = 'Liste_Def_XLS'

Mais ça ne marche pas non plus. Je ne peux pas remplir à l'avance RowSource dans les propriétés de l'objet et il faut donc absolument que je passe par une macro.

Quelqu'un saurait-il le faire ?

Merci d'avance
 

Paladin

XLDnaute Junior
Mes excuses, en fait ça marche bien comme ça

Combobox.RowSource = 'Liste_Def_XLS'

L'erreur vient du test que je fais avant pour savoir si Liste_Def_XLS (nom défini sous Excel avec la fonction DECALER) est vide.

Euh, donc ma question porte plutôt sur : comment on teste pour savoir si un nom est vide ?
Pour des cellules, c'est comme ça je sais :

If Range('A2').Value <> '' then ...

Mais pour un nom on fait comment ?
Parce que comme ça, ça marche pas :

If Range('Liste_Def_XLS').Value <> '' then ...

Merci d'avance
 

Hervé

XLDnaute Barbatruc
Bonjour paladin, le forum

Pour savoir si une liste est vide, je bouclerai sur chaque élément de cette liste, si un élément de cette liste est vide, j'incrémente un compteur et enfin si le compteur est égale au nombre d'élement de la liste, c'est que celle-ci est vide.

En imaginant une liste nommée toto, ca pourrait donner ceci :

Sub Bouton3_QuandClic()
Dim c As Range
Dim compteur As Byte

For Each c In Range('toto')
&nbsp; &nbsp;
If c = '' Then compteur = compteur + 1
Next c

If compteur = Range('toto').Count Then
&nbsp; &nbsp; MsgBox 'la liste toto est vide.'
End If
&nbsp; &nbsp; &nbsp; &nbsp;
End Sub

Sinon, pour en revenir à ton souci de combobox

La méthode rowsource n'est pas très adapté aux userforms (problème de compatibilité mac, puis pénible à manoeuvrer lorsque tu veux enlever des éléments de la combobox)

je présume, aussi, que tu utilises une liste et la fonction décaler pour adapter ta liste aux nombres d'élément.

Je te propose donc une autre synthaxe en utilisant la méthode additem, et rendant par contre ta liste inutile :
Private Sub UserForm_Initialize()
Dim i As Integer

'pour i = 1 jusqu'a la derniere cellule non vide de la colonne A
For i = 1 To Range('a65536').End(xlUp).Row
&nbsp; &nbsp;
If Range('a' & i) <> '' Then 'si la cellule (A et i) n'est pas vide, alors ....
&nbsp; &nbsp; &nbsp; &nbsp; ComboBox1.AddItem Range('a' & i)
' on remplit la combobox de la valeur de (A et I)
&nbsp; &nbsp;
End If ' fin de condition
Next i ' incrémentation de I


End Sub

Code a placer dans le module de l'userform.

salut
 

Paladin

XLDnaute Junior
Sur les plus gros UserForm, j'ai une dizaine de combobox.
Au début, les listes sont vides donc ça va, mais au fur et à mesure de l'utilisation de l'outil (par le futur utilisateur), il devrait y avoir de nombreux éléments (je dirai, grosso modo, une centaine maxi par liste).
Et mon souci c'est que je ne sais pas sur quel genre de config je serai amener à mettre mon appli ... Sur un P4 2GHz, ça tourne pépère, mais si je dois aller sur de vieux 800 MHz ou moins, j'ai un peu peur ... (et l'objectif est aussi que la partie base de données de mon appli soit plus rapide que ce qui avait été fait par mon prédécesseur sous Access ... car ça ramait pas mal !).
 

Hervé

XLDnaute Barbatruc
re

OK

alors il existe une autre méthode, la roll royce de la vitesse, les tableaux :

si tu ne dois pas tester les cellules avant l'envoi dans la combobox, tu as ceci :

Private Sub UserForm_Initialize()
Dim tablo As Variant

tablo = Range('a1:a' & Range('a65536').End(xlUp).Row)

ComboBox1.List = tablo

End Sub

si tu dois tester :

Private Sub UserForm_Initialize()
Dim tablo As Variant
Dim i As Integer

tablo = Range('a1:a' & Range('a65536').End(xlUp).Row)

For i = 1 To UBound(tablo)
&nbsp; &nbsp;
If tablo(i, 1) <> '' Then
&nbsp; &nbsp; &nbsp; &nbsp; ComboBox1.AddItem tablo(i, 1)
&nbsp; &nbsp;
End If
Next i
&nbsp; &nbsp; &nbsp; &nbsp;
End Sub


sinon il y a aussi les boucles for each qui sont un poil plus rapide que les boucles for to (enfin, je crois)

salut
 

Paladin

XLDnaute Junior
La seule raison qui me poussait à faire les tests <> '', c'était que si j'envoyais une liste vide avec RowSource, j'avais une erreur.
En effet, je crois que je vais prendre ta première méthode.

Et en fait, j'ai trouvé tout seul un petit truc : comme la série se remplit toujours par le haut (A3 ne peut être remplit que si A2 a une valeur), je vais tester tout simplement A2.

Merci encore pour ton aide.
 

Paladin

XLDnaute Junior
tablo = Range('a1:a' & Range('a65536').End(xlUp).Row)

Je ne souhaite pas prendre en compte la première ligne alors j'ai essayé en remplaçant A1 par A2, mais ça ne marche pas (pas de message d'erreur, mais ça ne prend que la ligne 1 et 2 et pas les lignes suivantes).

Pourtant je connais le truc xlUp machin :p , et je vois pas d'où vient le problème.

Tu as une idée là dessus ?
 

Hervé

XLDnaute Barbatruc
re re re :)

Alors là on a un souci, parce que je vois pas d'autre synthaxe pour alimenter un tablo de la ligne 2 à la derniere cellule non vide.

pourrais-tu joindre ton code complet en expliquant bien quelles valeurs tu veux dans le tableau.

salut
 

Paladin

XLDnaute Junior
Re re re

Bon, alors là je comprends pas.

J'ai voulu continuer à travailler sur le reste du UserForm (changer la valeur des autres textbox et listbox dès qu'on sélectionne une donnée dans le combobox utilisé) et j'ai voulu faire un test ...

Boum ! Là ça marche nickel le 'tablo' !
Excel avait surement envie de faire des siennes ...

Pour info, voilà ce que donne mon code d'initialisation :

Code:
Private Sub UserForm_Initialize()
    If Sheets('Risques').Range('A2').Value <> '' Then
        Tablo_Temp = Sheets('Risques').Range('a2:a' & Range('a65536').End(xlUp).Row)
        Choix_RiskModif.List = Tablo_Temp
    End If
End Sub

Je cherche même pas à comprendre ...
 

Hervé

XLDnaute Barbatruc
re

content que tu te sois sorti de ton problème :)

une autre synthaxe en créant un bloc d'instruction with, plus élégant et ceci accèlere légèrement le code :

Private Sub UserForm_Initialize()
&nbsp; &nbsp;
With Sheets('Risques')
&nbsp; &nbsp; &nbsp; &nbsp;
If .Range('A2').Value <> '' Then
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Tablo_Temp = .Range('a2:a' & .Range('a65536').End(xlUp).Row)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Choix_RiskModif.List = Tablo_Temp
&nbsp; &nbsp; &nbsp; &nbsp;
End If
&nbsp; &nbsp;
End With
End Sub


Note bien les points . devant les ranges, très important, ils lient les instructions suivantes au blocs with.

de plus, en revenant sur ton souci pour vérifier si une liste est vide, je te donne une autre synthaxe soufflé par l'excellent didierMdf dans le creux de l'oreille :

If Not Application.CountA(Range('MaPlage')) > 0 Then MsgBox 'Plage vide'

c'est quand meme plus propre et plus court que mon bidule de boucle, non ? :)

Merci didier

salut
 

Discussions similaires

Statistiques des forums

Discussions
312 229
Messages
2 086 426
Membres
103 206
dernier inscrit
diambote