Sorting ListBoxes with VBA

I received a question from a reader recently, who wanted to sort a Listbox using VBA.  As this seemed like a common problem which many users could face, I decided to dedicate a bit of time to create a more reusable solution.

In this post, we will look at two different types of Listboxes:

  • UserForm Listboxes for custom VBA solutions
  • Form Control Listboxes for worksheet based solutions
Sort ListBoxes with VBA

This post may seem like a lot of VBA code, but are comments inserted into the code to understand what is happening.  Within the text I included my thought process, to illustrate how I approached the scenario.  Whether my approach is right or wrong, it’s how I think about VBA.

There are four sort methods covered in this post:

  • Standard order (the order the elements are added to the list box)
  • Reverse order (the reverse of the standard order)
  • A-Z sort
  • Z-A sort

Download the example file: Join the free Insiders Program and gain access to the example file used for this post.

File name: 0172 Sort ListBox after load.zip

Re-usable code

One of the key principles of this little task was for the code to be as re-usable as possible.  Therefore in approaching this I sought to apply the following principles:

  • The code which performs the main actions is contained within a standard module
  • The code contained within the UserForm module intercepts the events (i.e. button clicks) then calls a macro from the standard module
  • The variables used for the macros within the standard module are passed as arguments when calling the macro
  • The list is re-created each time it is sorted, no matter which sort method is selected.  This ensures the list is updated for any changes whenever it is sorted.  The piece of reusable code which clears and re-creates the list I am calling the “resetMacro”.

Listboxes on UserForms

The screenshot below shows the UserForm, it contains:

  • a ListBox
  • four buttons for the different sort options
  • a close button
Sort ListBoxes - UserForm

VBA code included in a standard module

The following is the code to include in the standard module, which performs the main actions.

Display the UserForm

The first code, will simply display the UserForm when a button is clicked.

Sub ShowUserForm()

'Show the user form
frmListBoxExample.Show

End Sub

Populate the ListBox

The following code will list all the worksheets in a ListBox.  A variable referencing the specific ListBox is passed to the macro at run-time, therefore the code can be used with any ListBox.  In our example, this VBA code is used:

  • when the UserForm is initialized
  • when the btnStandard button is clicked
  • within all the other sort macros to recreate the list.
Sub UserFormList(myListBox As MSForms.ListBox)

'Create an object variable to hold worksheet as an object
Dim ws As Worksheet

'Clear the listBox
myListBox.Clear

'Loop through each worksheet add to listBox
For Each ws In ThisWorkbook.Worksheets

    myListBox.AddItem ws.Name

Next ws

End Sub

Reverse the items in the ListBox

The following code will first call the “resetMacro” to refresh the ListBox, then sort it in reverse order.

Sub UserFormReverseList(myListBox As MSForms.ListBox, Optional resetMacro As String)

'Create variables
Dim ListArray() As String
Dim i As Integer

'Reset the listBox into standard order
If resetMacro <> "" Then
    Run resetMacro, myListBox
End If

'Resize the Array variable
ReDim ListArray(0 To myListBox.ListCount - 1)

'Loop through the listBox and reverse the order into an Array
For i = 0 To myListBox.ListCount - 1

    ListArray(i) = myListBox.List(myListBox.ListCount - 1 - i)

Next i

'Clear the listBox
myListBox.Clear

'Fill the list box with the Array
myListBox.List = ListArray

End Sub

A-Z sort the List Box

The following code will first call the “resetMacro” to refresh the ListBox, then sort it in A-Z order using the Bubble sort method.

Sub UserFormSortAZ(myListBox As MSForms.ListBox, Optional resetMacro As String)

'Create variables
Dim j As Long
Dim i As Long
Dim temp As Variant

'Reset the listBox into standard order
If resetMacro <> "" Then
    Run resetMacro, myListBox
End If

'Use Bubble sort method to put listBox in A-Z order
With myListBox
    For j = 0 To .ListCount - 2
        For i = 0 To .ListCount - 2
            If LCase(.List(i)) > LCase(.List(i + 1)) Then
                temp = .List(i)
                .List(i) = .List(i + 1)
                .List(i + 1) = temp
            End If
        Next i
    Next j
End With

End Sub

If you notice there is a -2 in the code, which appears odd.  So why is it there and what does it do?

  • Using the Bubble Sort method, the last item does not need to be sorted.  If every other item in the list is sorted correctly, then the last item must also be in the correct place (so that is the first -1).
  • The first item in a UserForm ListBox is item 0, rather than 1.  Therefore, as the list starts at zero, we can -1 from the count to ensure we loop through all the items once.

Note: When using a Form Control list box, the first list position is 1, so the Form Control VBA code further down the post only has -1, rather than -2.

Z-A sort the ListBox

The following code will first call the “resetMacro” to refresh the ListBox, then sort it in Z-A order using the Bubble sort method.

Sub UserFormSortZA(myListBox As MSForms.ListBox, Optional resetMacro As String)

'Create variables
Dim j As Long
Dim i As Long
Dim temp As Variant

'Reset the listBox into standard order
If resetMacro <> "" Then
    Run resetMacro, myListBox
End If

'Use Bubble sort method to put listBox in Z-A order
With myListBox
    For j = 0 To .ListCount - 2
        For i = 0 To .ListCount - 2
            If LCase(.List(i)) < LCase(.List(i + 1)) Then
                temp = .List(i)
                .List(i) = .List(i + 1)
                .List(i + 1) = temp
            End If
        Next i
    Next j
End With

End Sub

VBA code included in the UserForm code module

The following sections of code are all included within the UserForm module.  The code here is primarily to call the macros in the standard module, which we covered in the section above.

The name of the ListBox in the example is lstListBox.

Initialize the UserForm

When the UserForm first opens the UserForm_Initialize code executes.  In our example, when the UserForm opens it calls the UserFormList macro, passing the lstListBox as an object variable into the macro.

Private Sub UserForm_Initialize()

Call UserFormList(Me.lstListBox)

End Sub

Clicking the btnClose Button

The close button with Unload the UserForm.

Private Sub btnClose_Click()

Unload Me

End Sub

Clicking the btnStandard button

The first button calls the macro to return the list to its original order.  The code UserFormList is called, passing the lstListBox as an object variable.

Private Sub btnStandard_Click()

Call UserFormList(Me.lstListBox)

End Sub

Clicking the btnReverse button

The second button calls the macro to reverse the order of the list.  In our example, the code UserFormReverseList is called.  Two arguments are passed (1) the ListBox object (2) the name of the resetMacro.

Private Sub btnReverse_Click()

Call UserFormReverseList(Me.lstListBox, "UserFormList")

End Sub

Clicking the btnAZ button

The third button calls the macro to sort the list in A-Z order.  The code UserFormSortAZ is called.  Two arguments are passed (1) the ListBox object (2) the name of the “resetMacro”.

Private Sub btnAZ_Click()

Call UserFormSortAZ(Me.lstListBox, "UserFormList")

End Sub

Clicking btnZA button

The fourth button calls the macro to sort the list in Z-A order.  The code UserFormSortZA is called.  Two arguments are passed (1) the ListBox object (2) the “resetMacro”.

Private Sub btnZA_Click()

Call UserFormSortZA(Me.lstListBox, "UserFormList")

End Sub

That now completes the code used to sort a ListBox contained within a UserForm.

Form Control Listboxes on the worksheet

The code in this section is for use with a Form Control ListBox.

Sort ListBoxes -FormControl

Each button is assigned to a macro requiring arguments, as a result they do not appear within the Assign Macro box.  Click here to learn more about this technique.

The macros assigned to each button is as follows:

  • Standard sort: FormControlList “lstListBox”‘
  • Reverse sort: FormControlReverse “lstListBox”, “FormControlList”‘
  • A-Z sort: FormControlSortAZ “lstListBox”, “FormControlList”‘
  • Z-A sort: FormControlSortZA “lstListBox”, “FormControlList”‘

VBA code included in a standard module

The following code is all included in the standard module.

Populate the ListBox

The code below will list all the worksheets in a ListBox.  The specific ListBox is passed to the macro as an argument, therefore this can be used with any ListBox.  This macro is called:

  • when the btnStandard button is clicked
  • within all the other sort macros to recreate the list (i.e. the “resetMacro”).
Sub FormControlList(myListBoxName As String)

'Create Object variable to hold the listBox
Dim myListBox As Object

'Set the variable to the worksheet and listBox called
Set myListBox = ActiveSheet.ListBoxes(myListBoxName)

'Create an object variable to hold worksheet as an object
Dim ws As Worksheet

'Clear the listBox
myListBox.RemoveAllItems

'Loop through each worksheet add to listBox
For Each ws In ThisWorkbook.Worksheets

    myListBox.AddItem ws.Name

Next ws

End Sub

Reverse the items in the ListBox

The following code will first call the “resetMacro” to update the ListBox, then sort it in reverse order.

Sub FormControlReverse(myListBoxName As String, Optional resetMacro As String)

'Create variables
Dim ListArray() As String
Dim i As Integer
Dim myListBox As ListBox

'Set the variable to the worksheet and listBox called
Set myListBox = ActiveSheet.ListBoxes(myListBoxName)

'Reset the listBox into standard order
If resetMacro <> "" Then
    Run resetMacro, myListBoxName
End If

'Resize the Array variable
ReDim ListArray(1 To myListBox.ListCount)

'Loop through the listBox and reverse the order into an Array
For i = 1 To myListBox.ListCount

    ListArray(i) = myListBox.List(myListBox.ListCount - i + 1)

Next i

'Clear the listBox
myListBox.RemoveAllItems

'Fill the list box with the Array
myListBox.List = ListArray

End Sub

A-Z sort the List Box

The following code will first call the “resetMacro” to update the ListBox, then sort it in A-Z order using the Bubble sort method.

Sub FormControlSortAZ(myListBoxName As String, Optional resetMacro As String)

'Create variables
Dim j As Long
Dim i As Long
Dim temp As Variant
Dim myListBox As ListBox

'Set the variable to the worksheet and listBox
Set myListBox = ActiveSheet.ListBoxes(myListBoxName)

'Reset the listBox into standard order
If resetMacro <> "" Then
    Run resetMacro, myListBoxName
End If

'Use Bubble sort method to put listBox in A-Z order
With myListBox
    For j = 1 To .ListCount - 1
        For i = 1 To .ListCount - 1
            If LCase(.List(i)) > LCase(.List(i + 1)) Then
                temp = .List(i)
                .List(i) = .List(i + 1)
                .List(i + 1) = temp
            End If
        Next i
    Next j
End With

End Sub

Z-A sort the List Box

The following code will first call the “resetMacro” to update the ListBox, then sort it in Z-A order using the Bubble sort method.

Sub FormControlSortZA(myListBoxName As String, Optional resetMacro As String)

'Create variables
Dim j As Long
Dim i As Long
Dim temp As Variant
Dim myListBox As ListBox

'Set the variable to the worksheet and listBox
Set myListBox = ActiveSheet.ListBoxes(myListBoxName)

'Reset the listBox into standard order
If resetMacro <> "" Then
    Run resetMacro, myListBoxName
End If

'Use Bubble sort method to put listBox in A-Z order
With myListBox
    For j = 1 To .ListCount - 1
        For i = 1 To .ListCount - 1
            If LCase(.List(i)) < LCase(.List(i + 1)) Then
                temp = .List(i)
                .List(i) = .List(i + 1)
                .List(i + 1) = temp
            End If
       Next i
    Next j
End With

End Sub

Conclusion

In this post, we have seen two methods to sort ListBoxes using VBA using reusable code segments.  Obviously, to be useful this needs to be part of a bigger project.  Feel free to take this and adapt it as you need to.


Discover how you can automate your work with our Excel courses and tools.

Excel Academy

Excel Academy
The complete program for saving time by automating Excel.

Excel Automation Secrets

Excel Automation Secrets
Discover the 7-step framework for automating Excel.

Office Scripts Course

Office Scripts: Automate Excel Everywhere
Start using Office Scripts and Power Automate to automate Excel in new ways.

4 thoughts on “Sorting ListBoxes with VBA”

  1. I slightly modified the provided solution to allow for multiple columns and calling the sub for any listbox as I have several listboxes with varying columns in my userform.

    Private Sub sortlistbox(LB As Object)
    Dim cols As Long, temp() As Variant
    cols = LB.ColumnCount – 1
    ReDim temp(0 To cols)
    With LB
    For j = 0 To .ListCount – 2
    For i = 0 To .ListCount – 2
    If LCase(.List(i)) > LCase(.List(i + 1)) Then
    For c = 0 To cols
    temp(c) = .List(i, c)
    .List(i, c) = .List(i + 1, c)
    .List(i + 1, c) = temp(c)
    Next c
    End If
    Next i
    Next j
    End With
    End Sub

    Reply

Leave a Comment