OVH Cloud OVH Cloud

tri dans une listbox

3 réponses
Avatar
Ticker
Bonsoir à tous
Je viens d'avoir un doute affreux, est ce qu'il est possible que les petits
gars de chez Microsoft aient oublié de mettre une fonction de tri dans les
listbox dans VBA. Je crois que en VB, il y a une fonction ("sort", je
crois), mais je ne l'ai pas vu dans VBA. Suis je donc obligé de passer par
des cellules ?
Merci de me répondre (j'espère que je me trompe)

3 réponses

Avatar
Denis Michon
Bonsoir Ticker,

************ PREMIER EXEMPLE****************

Voici un exemple comment trier par ordre croissant le contenu
d'un combobox avec l'aide d'une fonction

Si tu utilises ceci, tu ne dois pas utiliser la propriété "RowSource"
du combobox pour définir le contenu.

Tu dois adapter le nom de la feuille et la plage de cellules définies
dans cette exemple selon ton projet.

'---------------------------------------------------------------
Private Sub UserForm_Initialize()

Dim Rg As Range, Tblo As Variant

Set Fichier = ThisWorkbook

With Worksheets("Denis")
Set Rg = Range("A1:A" & .Range("A65536").End(xlUp).Row)
Tblo = Rg
End With

Me.ComboBox1.List = BubbleSort(Tblo)

Set Rg = Nothing

End Sub
'---------------------------------------------------------------

' À copier dans un Module Standard

Public Function BubbleSort(List As Variant)

Dim First As Integer, Last As Integer
Dim i As Integer, j As Integer
Dim Temp

First = LBound(List)
Last = UBound(List)
For i = First To Last - 1
For j = i + 1 To Last
If List(i, 1) > List(j, 1) Then
Temp = List(j, 1)
List(j, 1) = List(i, 1)
List(i, 1) = Temp
End If
Next j
Next i
BubbleSort = List
End Function
'---------------------------------------------------------------


************ DEUXIÈME EXEMPLE****************

À l'aide d'une fonction utilisant ADO (activex data objet), il est
possible de combiner plusieurs opérations dans la même :

A ) Éliminer les doublons
B ) Trier les items du combobox par ordre croissant
C ) Éliminer les lignes(entrées) vides si il y en a dans la plage de cellules.

Pour ce faire, ajouter la bibliothèque suivante à ton projet :
"Microsoft Activex Data Object 2.0 Librairy"

Le nom de la feuille et la plage de cellules doivent être adapté
selon ton projet.

Selon que ta plage de cellules a une étiquette de colonne tu devras
utiliser dans cette ligne de code qui fait référence à une fonction différente...

Me.ComboBox1.List = MaListe(Rg, Fichier) 'Avec étiquette

OU

Me.ComboBox1.List = MaListe1(Rg, Fichier) 'Sans étiquette


à copier dans le module du formulaire
'---------------------------------------------
Private Sub UserForm_Initialize()

Dim Rg As Range, Fichier As Workbook

Set Fichier = ThisWorkbook

With Worksheets("Denis")
Set Rg = Range("A1:A" & .Range("A65536").End(xlUp).Row)
End With

Me.ComboBox1.List = MaListe(Rg, Fichier)

Set Fichier = Nothing: Set Rg = Nothing

End Sub
'---------------------------------------------

'à copier dans un modules standard
'Si ta plage de cellules CONTIENT une étiquette de colonne, utilise ceci :
'---------------------------------------------
Public Function MaListe(Rg As Range, Fichier As Workbook)

Dim Conn As ADODB.Connection, Rst As New ADODB.Recordset
Dim Requete As String, NomColonne As String

Rg.Name = Rg(1, 1).Text
NomColonne = Fichier.Names(Rg(1, 1).Text).Name

Requete = "SELECT " & NomColonne & " From " & NomColonne & "" _
& vbCrLf & "Where " & NomColonne & " <> Null " & vbCrLf & _
"Group By " & NomColonne & " ORDER By " & NomColonne & ""

Set Conn = New ADODB.Connection
Conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & Fichier.FullName & ";" & _
"Extended Properties=""Excel 8.0;HDR=Yes;"""

Rst.Open Requete, Conn, adOpenForwardOnly, adLockOptimistic

MaListe = Application.Transpose(Rst.GetRows)
ThisWorkbook.Names(Rg(1, 1).Text).Delete
Rst.Close: Conn.Close
Set Rst = Nothing: Set Conn = Nothing

End Function
'---------------------------------------------

'à copier dans un modules standard
'Si ta plage de cellules NE CONTIENT PAS d'étiquette de colonne, utilise ceci :
'---------------------------------------------
Public Function MaListe1(Rg As Range, Fichier As Workbook)

Dim Conn As ADODB.Connection, Rst As New ADODB.Recordset
Dim Requete As String

Rg.Name = "NomColonne"

Requete = "SELECT f1 From NomColonne " & vbCrLf & _
"Where f1 <> Null " & vbCrLf & _
"Group By f1 ORDER By f1"

Set Conn = New ADODB.Connection
Conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & Fichier.FullName & ";" & _
"Extended Properties=""Excel 8.0;HDR=No;"""

Rst.Open Requete, Conn, adOpenForwardOnly, adLockOptimistic

MaListe1 = Application.Transpose(Rst.GetRows)
Fichier.Names("NomColonne").Delete

Rst.Close: Conn.Close
Set Rst = Nothing: Set Conn = Nothing

End Function
'---------------------------------------------



Salutations!







"Ticker" a écrit dans le message de news:
Bonsoir à tous
Je viens d'avoir un doute affreux, est ce qu'il est possible que les petits
gars de chez Microsoft aient oublié de mettre une fonction de tri dans les
listbox dans VBA. Je crois que en VB, il y a une fonction ("sort", je
crois), mais je ne l'ai pas vu dans VBA. Suis je donc obligé de passer par
des cellules ?
Merci de me répondre (j'espère que je me trompe)
Avatar
Denis Michon
Bonsoir Thicker,

Peut être que tu préfères travailler avec DAO

Tu ajoutes la bibliothèque suivante ;
"Microsoft DAO 3.51 Objects Librairy"

ATTENTION : Vous allez éprouver des difficultés si les données
de la plage n'appartiennent pas au même type comme par
exemple du Numérique avec du texte. La liste ne contiendra
qu'un type de données...

2 Procédures selon que ta colonne a une étiquette de colonnes ou non.

Si ta plage de cellules a une étiquette de colonne
L'étiquette ne fera pas parti de la liste du combobox

'-------------------------------------------
Private Sub UserForm_Initialize()
'Avec Étiquettes de colonnes
Dim bd As Database, Rst As Recordset, Rg As Range
Dim Requete As String, Titre As String

With Worksheets("Denis")
Set Rg = .Range("A1:A" & .Range("A65356").End(xlUp).Row)
Rg.Name = "NomColonne"
Titre = Rg(1, 1).Text
End With

Set bd = OpenDatabase(ThisWorkbook.Name, False, False, "excel 8.0")

Requete = "SELECT " & Titre & " From NomColonne " & vbCrLf & _
"Where " & Titre & " <> Null " & vbCrLf & _
"Group By " & Titre & " ORDER By " & Titre & ""

Set Rst = bd.OpenRecordset(Requete)
Rst.MoveLast
Rst.MoveFirst
Rst.MoveNext

Do Until Rst.EOF
Me.ComboBox1.AddItem Rst(0)
Rst.MoveNext
Loop

Rst.Close
bd.Close
Set Rg = Nothing
Set Rst = Nothing
Set bd = Nothing

End Sub
'-------------------------------------------


Sans étiquettes de colonne, la première cellule de la plage signifiée
dans la procédure doit être vide. Avec DAO, on ne peut spécifier
explicitement comme ADO que l'étiquette est absente. Pour DAO,
la première donnée est résevée au nom du champ.

'--------------------------------------------
Private Sub UserForm_Initialize()

'Sans étiquettes de colonnes

Dim bd As Database, Rst As Recordset, Rg As Range
Dim Requete As String

With Worksheets("Denis")
.Range("A1:A" & .Range("A65356").End(xlUp).Row).Name = "NomColonne"
End With

Set bd = OpenDatabase(ThisWorkbook.Name, False, False, "excel 8.0")

Requete = "SELECT F1 From NomColonne " & vbCrLf & _
"Where F1 <> Null " & vbCrLf & _
"Group By F1 ORDER By F1"

Set Rst = bd.OpenRecordset(Requete)
Rst.MoveLast
Rst.MoveFirst

Do Until Rst.EOF
Me.ComboBox1.AddItem Rst(0)
Rst.MoveNext
Loop

Rst.Close 'ferme le recordset
bd.Close
'Libère la mémoir des objets
Set Rst = Nothing
Set bd = Nothing
Set Rg = Nothing

End Sub
'--------------------------------------------


Salutations!
















"Ticker" a écrit dans le message de news:
Bonsoir à tous
Je viens d'avoir un doute affreux, est ce qu'il est possible que les petits
gars de chez Microsoft aient oublié de mettre une fonction de tri dans les
listbox dans VBA. Je crois que en VB, il y a une fonction ("sort", je
crois), mais je ne l'ai pas vu dans VBA. Suis je donc obligé de passer par
des cellules ?
Merci de me répondre (j'espère que je me trompe)
Avatar
Ticker
Merci pour les multiples réponses, je pense que je vais utiliser la première
solution car c'est la seule dont je comprend parfaitement le code. Mais je
garde les autres sous le coude car je pense que lorsque j'en aurai fini avec
VBA, je vais passer à VB tout court (quand mes finances se porteront mieux
:o))) )



"Denis Michon" a écrit dans le message de news:
4gJmb.12303$
Bonsoir Thicker,

Peut être que tu préfères travailler avec DAO

Tu ajoutes la bibliothèque suivante ;
"Microsoft DAO 3.51 Objects Librairy"

ATTENTION : Vous allez éprouver des difficultés si les données
de la plage n'appartiennent pas au même type comme par
exemple du Numérique avec du texte. La liste ne contiendra
qu'un type de données...

2 Procédures selon que ta colonne a une étiquette de colonnes ou non.

Si ta plage de cellules a une étiquette de colonne
L'étiquette ne fera pas parti de la liste du combobox

'-------------------------------------------
Private Sub UserForm_Initialize()
'Avec Étiquettes de colonnes
Dim bd As Database, Rst As Recordset, Rg As Range
Dim Requete As String, Titre As String

With Worksheets("Denis")
Set Rg = .Range("A1:A" & .Range("A65356").End(xlUp).Row)
Rg.Name = "NomColonne"
Titre = Rg(1, 1).Text
End With

Set bd = OpenDatabase(ThisWorkbook.Name, False, False, "excel 8.0")

Requete = "SELECT " & Titre & " From NomColonne " & vbCrLf & _
"Where " & Titre & " <> Null " & vbCrLf & _
"Group By " & Titre & " ORDER By " & Titre & ""

Set Rst = bd.OpenRecordset(Requete)
Rst.MoveLast
Rst.MoveFirst
Rst.MoveNext

Do Until Rst.EOF
Me.ComboBox1.AddItem Rst(0)
Rst.MoveNext
Loop

Rst.Close
bd.Close
Set Rg = Nothing
Set Rst = Nothing
Set bd = Nothing

End Sub
'-------------------------------------------


Sans étiquettes de colonne, la première cellule de la plage signifiée
dans la procédure doit être vide. Avec DAO, on ne peut spécifier
explicitement comme ADO que l'étiquette est absente. Pour DAO,
la première donnée est résevée au nom du champ.

'--------------------------------------------
Private Sub UserForm_Initialize()

'Sans étiquettes de colonnes

Dim bd As Database, Rst As Recordset, Rg As Range
Dim Requete As String

With Worksheets("Denis")
.Range("A1:A" & .Range("A65356").End(xlUp).Row).Name "NomColonne"
End With

Set bd = OpenDatabase(ThisWorkbook.Name, False, False, "excel 8.0")

Requete = "SELECT F1 From NomColonne " & vbCrLf & _
"Where F1 <> Null " & vbCrLf & _
"Group By F1 ORDER By F1"

Set Rst = bd.OpenRecordset(Requete)
Rst.MoveLast
Rst.MoveFirst

Do Until Rst.EOF
Me.ComboBox1.AddItem Rst(0)
Rst.MoveNext
Loop

Rst.Close 'ferme le recordset
bd.Close
'Libère la mémoir des objets
Set Rst = Nothing
Set bd = Nothing
Set Rg = Nothing

End Sub
'--------------------------------------------


Salutations!
















"Ticker" a écrit dans le message de
news:

Bonsoir à tous
Je viens d'avoir un doute affreux, est ce qu'il est possible que les
petits

gars de chez Microsoft aient oublié de mettre une fonction de tri dans les
listbox dans VBA. Je crois que en VB, il y a une fonction ("sort", je
crois), mais je ne l'ai pas vu dans VBA. Suis je donc obligé de passer par
des cellules ?
Merci de me répondre (j'espère que je me trompe)