Sorting data using VBA: Bubble Sort
2020-06-14 Sorting 3 173
BubbleSort: Sorting small one- or two-dimensional arrays (<= 1000 items):
The BubbleSort algorithm is suitable for sorting small arrays, usually with 1000 items or less.
BubbleSort is a stable sort method, something that might be important when you are sorting data with multiple columns.
When you use a stable sort method items with equal sort keys are returned in the same order in the sorted result as they had before being sorted.
BubbleSort can be painfully slow when sorting large arrays.
Use BubbleSort1 on one-dimensional arrays and BubbleSort on two-dimensional arrays.
BubbleSort can also be used to sort two-dimensional arrays that has a header row.
NOTE: The sorting algorithm in this document is adapted for use in VBA based on detailed descriptions found in Wikipedia.
See this post if you need information about how to read from and write to worksheet cells using array variables (including code for the Array_ReplaceErrors macro).
Sub BubbleSort1(varArray As Variant, Optional blnCompareText As Boolean = False, Optional blnSortAscending As Boolean = True) ' updated 2012-09-02 by OPE ' sorts a one-dimensional array in ascending or descending order ' fast on small arrays, slow on very large arrays (n^2 comparisons) ' example: BubbleSort1 varArrayVariable Dim n As Long, blnSwap As Boolean, i As Long, varTemp As Variant If Not IsArray(varArray) Then Exit Sub n = UBound(varArray, 1) - LBound(varArray, 1) + 1 If n < 2 Then Exit Sub Do blnSwap = False For i = LBound(varArray, 1) + 1 To UBound(varArray, 1) If blnSortAscending Then If blnCompareText Then blnSwap = StrComp(varArray(i - 1), varArray(i), vbTextCompare) > 0 Else blnSwap = varArray(i - 1) > varArray(i) End If Else If blnCompareText Then blnSwap = StrComp(varArray(i - 1), varArray(i), vbTextCompare) < 0 Else blnSwap = varArray(i - 1) < varArray(i) End If End If If blnSwap Then varTemp = varArray(i - 1) varArray(i - 1) = varArray(i) varArray(i) = varTemp End If If blnSwap Then Exit For Next i Loop Until Not blnSwap End Sub Sub BubbleSort(varArray As Variant, Optional lngSortColumn As Long = -1, Optional blnCompareText As Boolean = False, _ Optional blnHasHeaderRow As Boolean = False, Optional blnSortAscending As Boolean = True) ' updated 2012-09-02 by OPE ' sorts a two-dimensional array in ascending or descending order based on the content in column lngSortColumn ' lngSortColumn must be an integer number >= LBound(varArray, 2) and <= UBound(varArray, 2), uses LBound(varArray, 2) if lngSortColumn < 0 ' fast on small arrays, slow on very large arrays (n^2 comparisons) ' stable sort method, items with equal sort keys are returned in the same order in the sorted result as they had before being sorted ' example: BubbleSort varArrayVariable, 1 Dim n As Long, blnSwap As Boolean, i As Long, j As Long, varTemp As Variant, varCaption As Variant If Not IsArray(varArray) Then Exit Sub n = UBound(varArray, 1) - LBound(varArray, 1) + 1 If n < 2 Then Exit Sub If lngSortColumn < 0 Then lngSortColumn = LBound(varArray, 2) ' sort by the first column item If lngSortColumn < LBound(varArray, 2) Or lngSortColumn > UBound(varArray, 2) Then Exit Sub If blnHasHeaderRow Then i = LBound(varArray, 1) varCaption = varArray(i, lngSortColumn) ' save original column header If blnCompareText Then If blnSortAscending Then varArray(i, lngSortColumn) = Space(15) & varArray(1, lngSortColumn) Else varArray(i, lngSortColumn) = Replace(Space(15), " ", Chr(255)) & varArray(1, lngSortColumn) End If Else If blnSortAscending Then varArray(i, lngSortColumn) = -1E+16 ' use -1E+16 when sorting ascending Else varArray(i, lngSortColumn) = Replace(Space(15), " ", Chr(255)) & varArray(1, lngSortColumn) End If End If End If Do blnSwap = False For i = LBound(varArray, 1) + 1 To UBound(varArray, 1) If blnSortAscending Then If blnCompareText Then blnSwap = StrComp(varArray(i - 1, lngSortColumn), varArray(i, lngSortColumn), vbTextCompare) > 0 Else blnSwap = varArray(i - 1, lngSortColumn) > varArray(i, lngSortColumn) End If Else If blnCompareText Then blnSwap = StrComp(varArray(i - 1, lngSortColumn), varArray(i, lngSortColumn), vbTextCompare) < 0 Else blnSwap = varArray(i - 1, lngSortColumn) < varArray(i, lngSortColumn) End If End If If blnSwap Then For j = LBound(varArray, 2) To UBound(varArray, 2) varTemp = varArray(i - 1, j) varArray(i - 1, j) = varArray(i, j) varArray(i, j) = varTemp Next j End If If blnSwap Then Exit For Next i Loop Until Not blnSwap If blnHasHeaderRow Then i = LBound(varArray, 1) varArray(i, lngSortColumn) = varCaption ' restore original column header End If End Sub
Here are some of the options you can use to sort data in Excel using VBA:
- Sorting two-dimensional arrays: SORT worksheet function
- Sorting a worksheet range: RangeSort
- Sorting a worksheet table: TableSort
- Sorting small arrays (<= 1000 items): BubbleSort
- Sorting a large one-dimensional array (> 1000 items): QuickSort (might use a lot of memory)
- Sorting a large one-dimensional array (> 1000 items): ShellSort (uses less memory than QuickSort)
- Sorting a large two-dimensional array (> 1000 items): MergeSort
RangeSort, TableSort, BubbleSort, MergeSort and the SORT worksheet function are stable sort methods:
Items with equal sort keys are returned in the same order in the sorted result as they had before being sorted.
QuickSort and ShellSort are not stable sort methods and you would normally not want to use these with two-dimensional arrays.
See this post if you need information about how to read from and write to worksheet cells using array variables.