Solved

# How to sort numbers in a Listbox in desending order using an array and bubblesort

Posted on 2004-10-04
1,067 Views
I want to make a program that will sort the users inputed numbers in a desending order.  On my form I  have a listbox ,a texrbox and two cmdButtons.
The user enters a several numbers  (anywhere from a value of 1 to a million or so) example: 2; 25; 1,794; 4,009,546 etc.  They then click one of the cmdButtons and this number is added to the listbox and I am guessing to an array.  Once the user has entered all the numbers they need sorted., they click the other cmdButton and the  numbers in the listbox are sorted.  I am not familiar with sorting(bubble, quick) or arrays (how to populate them in real time)so any code on how to accomplish this would be greatly appreciated.  Also I guess I would need a third button  to clear listbox and the array (ReDim?) so the user could enter a new set of numbers to be sorted from least to greatest.
0
Question by:ucla11
• 3
• 2
• 2

LVL 4

Accepted Solution

cachedVB earned 250 total points
'This is the code to sort the listbox

Dim splt
splt = split(text1.text)
Dim num as integer
Dim i as integer
dim x as integer

for i = 0 to list1.listcount - 1
for x = i to list1.listcount - 1
if (val(list1.list(i)) > val(list1.list(x))) then
num = val(list1.list(i))
list1.list(i) = list1.list(x)
list1.list(x) = num
end if
next x
next i

To clear the listbox, just use list1.clear
0

LVL 4

Expert Comment

oops... the one above is in ascending order, to make it descending, make the line
if (val(list1.list(i)) < val(list1.list(x))) then
if (val(list1.list(i)) > val(list1.list(x))) then
0

LVL 85

Expert Comment

Private Sub Command1_Click()
Dim values() As Long
Dim tempValues As Variant
Dim i As Integer
Dim j As Integer
Dim temp As Long

' build an array of your values
tempValues = Split(Text1.Text, ";")
ReDim values(UBound(tempValues))
For i = LBound(tempValues) To UBound(tempValues)
values(i) = CLng(tempValues(i))
Next i

' bubble sort the values in descending order
For i = (UBound(values) - 1) To 0 Step -1
For j = 0 To i
If values(j) < values(j + 1) Then
temp = values(j)
values(j) = values(j + 1)
values(j + 1) = temp
End If
Next j
Next i

' populate the listbox with the sorted values
List1.Clear
For i = LBound(values) To UBound(values)
Next i
End Sub
0

LVL 18

Expert Comment

If you set the .Sorted property of the listbox to true at design time the list will be sorted alphabeticaly.
To make an alphabetic sort work on numberd you have to left pad the numbers with spaces as you add then to the list view. This is easy if you know the maximum length of your numbers.

Try the following code with the .Sorted property set to True and then false at design time.
e.g.

Private Sub Command1_Click()
Dim i As Long
Dim sNumber As String
With List1
For i = 1 To 10000
sNumber = Format(Fix(Rnd() * i + 1), "#,##0")
.AddItem Space(10 - Len(sNumber)) & sNumber
Next i
End With
End Sub

0

LVL 85

Expert Comment

But that will sort ascending not descending.  You would still have to create some kind of temp array, collection, or another listbox to hold the values temporarily so you can reverse the order of the items.

~IM
0

LVL 18

Expert Comment

IM,
You're quite right. It's me not reading the question properly. I just have an aversion to ever using a bubble-sort due to its order n^2 time, though they are probably fine for 100 items or less as in this requirement.
JR

Just for interest here's a version that uses QuickSort to sort 32,000 items in the listbox and also a bubble-sort to sort the same items. It demonstrates why you should never use a bubble-sort when n gets large.

Option Explicit

Private Sub Command1_Click()

'Populate the listbox with random numbers
Dim i As Long
Dim sNumber As String
With List1
.Clear
For i = 1 To 32000
sNumber = Format(Fix(Rnd() ^ 2 * 10000), "#,##0")
Next i
End With

End Sub

Private Sub Command2_Click()

'Quick-sort the listbox descending
SortNumericListBox List1, False

End Sub

Private Sub Command3_Click()
'Slow bubble-sort the listbox
Dim i As Long
Dim j As Long
Dim Arr() As String
Dim sTemp As String
With List1
ReDim Arr(.ListCount - 1) As String
For i = 0 To .ListCount - 1
Arr(i) = .List(i)
Next i

For i = LBound(Arr) To UBound(Arr)
For j = 0 To i
If CDbl(Arr(j)) < CDbl(Arr(j + 1)) Then
sTemp = Arr(j)
Arr(j) = Arr(j + 1)
Arr(j + 1) = sTemp
End If
Next j
Next i

.Clear
For i = LBound(Arr) To UBound(Arr)
Next i
End With

End Sub

Public Function SortNumericListBox(objListBox As ListBox, Optional Ascending As Boolean = True)
'Sorts a listbox containing numeric values
Dim MyArray() As String
Dim i As Long
With objListBox
ReDim MyArray(0 To .ListCount - 1)
For i = LBound(MyArray) To UBound(MyArray)
MyArray(i) = .List(i)
Next i
QuickSortArray LBound(MyArray), UBound(MyArray), MyArray
.Clear
If Ascending Then
For i = LBound(MyArray) To UBound(MyArray)
Next i
Else
For i = UBound(MyArray) To LBound(MyArray) Step -1
Next i
End If
End With

End Function

Private Function QuickSortArray(ByVal LowBound As Long, ByVal HighBound As Long, Array2Sort() As String)

Dim intX As Long
Dim intY As Long
Dim MidBound As String
Dim tmpElement As String
Dim iCount As Long
On Error GoTo PROC_ERR
' If there is data to sort
If HighBound > LowBound Then
' Calculate the value of the middle array element
MidBound = Array2Sort((HighBound + LowBound) \ 2)
intX = LowBound
intY = HighBound
' Split the array into halves
Do While intX <= intY
If CDbl(Array2Sort(intX)) >= CDbl(MidBound) And CDbl(Array2Sort(intY)) <= CDbl(MidBound) Then
'Begin Swap
tmpElement = Array2Sort(intX)
Array2Sort(intX) = Array2Sort(intY)
Array2Sort(intY) = tmpElement
'End Swap
intX = intX + 1
intY = intY - 1
Else
If CDbl(Array2Sort(intX)) < CDbl(MidBound) Then
intX = intX + 1
End If
If CDbl(Array2Sort(intY)) > CDbl(MidBound) Then
intY = intY - 1
End If
End If
Loop
'Sort the lower half of the array
QuickSortArray LowBound, intY, Array2Sort
'Sort the upper half of the array
QuickSortArray intX, HighBound, Array2Sort
End If

PROC_EXIT:

Exit Function

PROC_ERR:

Beep
MsgBox "Error: " & Err.Number & ". " & Err.Description, vbExclamation
Resume PROC_EXIT

End Function
0

LVL 85

Expert Comment

I quite agree.  Only use Bubble Sort for small data sets.

~IM
0

## Featured Post

I’ve seen a number of people looking for examples of how to access web services from VB6.  I’ve been using a test harness I built in VB6 (using many resources I found online) that I use for small projects to work out how to communicate with web serv…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…