banner for Ms Access Gurus

Sort String Array by any column using VBA

Got an array of information you want to sort? Sort by one (BubbleSort) or two dimensions. Pass the array and it will be changed. This example uses a string array. (If I recall correctly, there was an issue using a variant array and all strings worked). For numbers in a 2D string array, perhaps make 2 columns to store them; one to show with formatting for display to users and the other padded with zeros for sorting.

Since this is pure VBA code and not application specific, it will work with Access as well as other applications like Excel, Word, PowerPoint, and Visio.

For performance, there's a counter for number of swaps so that VBA will stop the loop for comparing if there's nothing else to sort.

UPDATE Sep 2026

Sort Ascending or Descending

The Main procedure is to sort an array with 2-dimensions. It also works with one dimension (but is more complex than the simple BubbleSort example).

Sort2DStringArray

Pass an array to changed by sorting. Optionally, send a column number to sort by. Optionally send a boolean to sort descending instead of ascending (default).

The code checks the column number sent to ensure it's valid and if not, makes a logical choice.

There are additional procedures, for testing

use VBA to Sort 2-Dimensional Array by any column using VBA

Quick Jump

Goto the Very Top  


Download

Download zipped BAS file that you can import with a function to sort one or two dimensional array. Also contains simple Bubble Sort for one dimension and test procedures. bas_Array_Sort_s4p.zip

If you have trouble with the downloads, you may need to unblock the ZIP file, aka remove Mark of the Web, before extracting the file. Here are steps to do that: https://msaccessgurus.com/MOTW_Unblock.htm

Goto Top  

Video

watch on YouTube: How does Bubble Sort work? (5:50)

Goto Top  

Test Results

test2DSort

	INITAL ARRAY: Dim asArray(1 To 5, 1 To 3) As String
	-------------------------
	 1    Butch; Dog; 07
	 2    Midnight; Cat; 15
	 3    Tweety; Bird; 85
	 4    Fred; Fish; 02
	 5    Sylvester; Cat; 79
	-------------------------
	Sort2DStringArray(asArray), 1st column Ascending
	-------------------------
	 1    Butch; Dog; 07
	 2    Fred; Fish; 02
	 3    Midnight; Cat; 15
	 4    Sylvester; Cat; 79
	 5    Tweety; Bird; 85
	-------------------------
	Sort2DStringArray(asArray, 2), 2nd column ascending
	tie in sort column is then by the last sort
	-------------------------
	 1    Tweety; Bird; 85
	 2    Midnight; Cat; 15
	 3    Sylvester; Cat; 79
	 4    Butch; Dog; 07
	 5    Fred; Fish; 02
	-------------------------
	Sort2DStringArray(asArray, 2, True), 2nd column descending
	tie in sort column is broken by same initial Name sort
	-------------------------
	 1    Fred; Fish; 02
	 2    Butch; Dog; 07
	 3    Midnight; Cat; 15
	 4    Sylvester; Cat; 79
	 5    Tweety; Bird; 85
	-------------------------
	Sort2DStringArray(asArray, 1, True), 1st column Descending
	-------------------------
	 1    Tweety; Bird; 85
	 2    Sylvester; Cat; 79
	 3    Midnight; Cat; 15
	 4    Fred; Fish; 02
	 5    Butch; Dog; 07
	-------------------------
	Sort2DStringArray(asArray, 3, True), 3rd column descending
	-------------------------
	 1    Tweety; Bird; 85
	 2    Sylvester; Cat; 79
	 3    Midnight; Cat; 15
	 4    Butch; Dog; 07
	 5    Fred; Fish; 02
	-------------------------

testBubbleSort

	INITAL ARRAY
	-------------------------
	 0    Title
	 1    Subject
	 2    Author
	 3    Keywords
	 4    Comments
	 5    Last author
	 6    Revision number
	 7    Application name
	 8    Manager
	 9    Company
	-------------------------
	SORTED ARRAY, Ascending
	-------------------------
	 0    Application name
	 1    Author
	 2    Comments
	 3    Company
	 4    Keywords
	 5    Last author
	 6    Manager
	 7    Revision number
	 8    Subject
	 9    Title
	-------------------------
	SORTED ARRAY, Descending
	-------------------------
	 0    Title
	 1    Subject
	 2    Revision number
	 3    Manager
	 4    Last author
	 5    Keywords
	 6    Company
	 7    Comments
	 8    Author
	 9    Application name
	-------------------------

Goto Top  

VBA

Standard module

Option Compare Text  'Ignore Case
Option Explicit  'variables must be declared

'*************** Code Start ***************************************************
' module: bas_Array_Sort_s4p
'
' Purpose  : Pass a string array you want to sort
'              -- it will be changed.
'              1- or 2-dimensional string array
'              Optionally, designate a column index to sort by
'              default column=0 and will be adjusted to lowest if not sent
'              Optionally, indicate descending order
' Author   : crystal (strive4peace)
' this code: https://msaccessgurus.com/VBA/Array_Sort2D.htm
' LICENSE  :
'   You may freely use and share this code, but not sell it.
'   Keep attribution. Mark your changes. Use at your own risk.
'------------------------
' PROCEDURES
'     Sort2DStringArray
'     BubbleSort
'------------------------
'     testBubbleSort
'     test2DSort
'     WriteBubbleArray2Debug
'     Write2DArray2Debug
'--------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'           Sort2DStringArray
'-------------------------------------------------------------------------------
Public Sub Sort2DStringArray(ByRef psArray() As String _ 
         ,Optional ByVal piSortColumnIndex As Integer = 0 _ 
         ,Optional ByVal pbDescending As Boolean = False _ 
               ) 
' Sort a 2-dimensional string array by specified column
'  based on bubble-sort code by Brent Spaulding
' 260906 UPDATED to specify descending sort pbDescending, bSwap,
' 240520 strive4peace,... 240714 stop if done,260820

   'PARAMETERs
   '  psArray -- string array you want to sort
   '             1 or 2 dimensions will be considered
   
   '  piSortColumnIndex is the column index (2nd dimension)
   '        in the array to sort by
   '        if not specified or lower, will be by the first column
   '        if higher than last, will be by the last column
   '  pbDescending is True for descending sort. Default=False

   On Error GoTo Proc_Err 
            
   Dim asCurrentValue() As String 
   
   ' pbDescending calculated True=Descending, False=Ascending (default)
   Dim iColumn As Integer _ 
      ,iColumn1 As Integer _ 
      ,iColumn2 As Integer _ 
      ,iRow As Integer _ 
      ,iRow1 As Integer _ 
      ,iRow2 As Integer _ 
      ,iRows As Integer _ 
      ,iLastRow As Integer _ 
      ,iCountSwap As Integer _ 
      ,sValue1 As String _ 
      ,sValue2 As String _ 
      ,bSwap As Boolean 
   
   iRow1 = LBound(psArray,1)  'first row
   iRow2 = UBound(psArray,1)  'last row
   iRows = iRow2 - iRow1 + 1   'calculate number of rows
   
   iColumn1 = LBound(psArray,2)  'first column
   iColumn2 = UBound(psArray,2)  'last column
   
   iCountSwap = 0   'haven't swapped anything yet

   If piSortColumnIndex < iColumn1 Then 
      'sort by first column if lower number specified
      'default is 0
      piSortColumnIndex = iColumn1 
   End If 
   If piSortColumnIndex > iColumn2 Then 
      'sort by last column if higher number specified
      piSortColumnIndex = iColumn2 
   End If 
   
   'array with current values -- works with 1D arrays too
   ReDim asCurrentValue(iColumn1 To iColumn2) 

   'Bubble sort the array if more than 1 row
   If iRows > 1 Then 
      'set the last row to compare
      iLastRow = iRow2 
      Do Until iLastRow = iRow1 
         iCountSwap = 0  'no swaps yet for this pass
      
         'loop from first row to next to last row
         For iRow = iRow1 To iLastRow - 1 
            'store current value and next value, in Sort Column
            sValue1 = psArray(iRow,piSortColumnIndex) 
            sValue2 = psArray(iRow + 1,piSortColumnIndex) 
            
            bSwap = False 
            'is comparison ascending or descending?
            If pbDescending <> False Then  'True - descending
               If sValue1 < sValue2 Then 
                  'sort descending
                  bSwap = True 
               End If 
            Else 
               'ascending
               If sValue1 > sValue2 Then 
                  bSwap = True 
               End If 
            End If  
   
            'swap values
            If bSwap <> False Then 
               'save current value for each column in array
               For iColumn = iColumn1 To iColumn2 
                  asCurrentValue(iColumn) = psArray(iRow,iColumn) 
               Next iColumn 
               
               'swap value in each column
               For iColumn = iColumn1 To iColumn2 
                  'assign current values to next row values
                  psArray(iRow,iColumn) = psArray(iRow + 1,iColumn) 
                  'assign next row values to saved values
                  psArray(iRow + 1,iColumn) = asCurrentValue(iColumn) 
               Next iColumn 
               
               'count how many swaps made for this pass
               iCountSwap = iCountSwap + 1 
            
            End If   'values swapped
            
         Next iRow 
         
         'stop the loop if no swaps were made
         If Not iCountSwap > 0 Then 
            'all done!
            Exit Do 
         End If 
         
         iLastRow = iLastRow - 1   'decrement last row
         iCountSwap = 0   'reset swap counter
         
      Loop    ' Until iLastRow = iRow1
   End If 
                      
Proc_Exit: 
   Exit Sub 

Proc_Err: 
   MsgBox Err.Description _ 
       ,, "ERROR " & Err.Number _ 
        &  "   Sort2DStringArray"
   
   Resume Proc_Exit 
   Resume 
End Sub 

'-------------------------------------------------------------------------------
'           BubbleSort -- simple example
'-------------------------------------------------------------------------------
Public Sub BubbleSort(ByRef psArray() As String _ 
         ,Optional ByVal pbDescending As Boolean = False _ 
   ) 
' 240714 strive4peace
' 260904 descending sort: pbDescending=True, bSwap
' Sort a single dimension string array
'  based on bubble-sort code originally written by Brent Spaulding

   ' PARAMETERS
   '   psArray -- string array to sort
   '   pbDescending = True to sort descending. Default=False=sort ascending
   
   On Error GoTo Proc_Err 
   
   Dim iRow As Integer _ 
      ,iRow1 As Integer _ 
      ,iRow2 As Integer _ 
      ,iRows As Integer _ 
      ,iLastRow As Integer _ 
      ,iCountSwap As Integer _ 
      ,sValue1 As String _ 
      ,sValue2 As String _ 
      ,bSwap As Boolean 
      
   iRow1 = LBound(psArray,1)  'first row
   iRow2 = UBound(psArray,1)  'last row
   iRows = iRow2 - iRow1 + 1  'calculate number of rows

   iCountSwap = 0  'haven't swapped anything yet
   
   'Bubble sort the array if more than 1 row
   If iRows > 1 Then 
      'set the last row to compare
      iLastRow = iRow2 
      'loop until last row is the first row
      Do Until iLastRow = iRow1 
         
         'loop from first row to next to last row
         For iRow = iRow1 To iLastRow - 1 
            'store current value and next value
            sValue1 = psArray(iRow) 
            sValue2 = psArray(iRow + 1) 

            bSwap = False 
            'is comparison Ascending or Descending?
            If pbDescending <> False Then 
               'sort descending
               'if current is less than next, then swap
               If sValue1 < sValue2 Then 
                  bSwap = True 
               End If 
            Else 
               'sort ascending
               'if current is greater than next, then swap
               If sValue1 > sValue2 Then 
                  bSwap = True 
               End If 
            End If 
   
            'swap values
            If bSwap <> False Then 
               'save current value for each column in array
               'set current row value = next value
               psArray(iRow) = sValue2 
               'set next value = saved current value
               psArray(iRow + 1) = sValue1 
               'count how many swaps made for this pass
               iCountSwap = iCountSwap + 1 
            End If 
            
         Next iRow 

         'stop the loop if no swaps were made
         If Not iCountSwap > 0 Then 
            'all done!
            Exit Do 
         End If 
         
         iLastRow = iLastRow - 1  'decrement last row
         iCountSwap = 0  'reset swap counter
         
      Loop   ' Until iLastRow = iRow1
   End If 
                      
Proc_Exit: 
   On Error GoTo 0  'reset
   Exit Sub 

Proc_Err: 
   MsgBox Err.Description _ 
       ,, "ERROR " & Err.Number _ 
        &  "   BubbleSort"
   
   Resume Proc_Exit 
   Resume 
   
End Sub 

'-------------------------------------------------------------------------------
'           testBubbleSort
'-------------------------------------------------------------------------------
Sub testBubbleSort() 
'270414 s4p, for testing, 260904 descending
'make an array with string values
' write the original values to the Debug (Immediate) window, Ctrl-G
' show how the array changes
' for Ascending and Descending sorting
   'CALLs
   '  BubbleSort
   '  WriteBubbleArray2Debug
   
   Dim asArray() As String 
   'define test array by splitting a string at each comma
   asArray = Split( _ 
       "Title" _ 
      &  ",Subject" _ 
      &  ",Author" _ 
      &  ",Keywords" _ 
      &  ",Comments" _ 
      &  ",Last author" _ 
      &  ",Revision number" _ 
      &  ",Application name" _ 
      &  ",Manager" _ 
      &  ",Company" _ 
      , ",") 
   
   Debug.Print  "INITAL ARRAY"
   Call WriteBubbleArray2Debug(asArray) 
   
   'sort the array
   Call BubbleSort(asArray) 
   
   Debug.Print  "SORTED ARRAY, Ascending"
   Call WriteBubbleArray2Debug(asArray) 
   
   'sort the array in descending order
   Call BubbleSort(asArray,True) 
   
   Debug.Print  "SORTED ARRAY, Descending"
   Call WriteBubbleArray2Debug(asArray) 
      
End Sub 

'-------------------------------------------------------------------------------
'           test2DSort
'-------------------------------------------------------------------------------
Sub test2DSort() 
'260904 s4p, for testing
'make a 2-dimensional array with string values
' write the original values to the Debug (Immediate) window, Ctrl-G
' and show how the array changes
' depending on how it is sorted

   'CALLs
   '  Sort2DStringArray
   '  Write2DArray2Debug
   
   Dim asArray(1 To 5,1 To 3) As String 
   'define test array
   'Name, species, age
   'Tweety and Sylvester first appeared together in 1947
   asArray(1,1) =  "Butch": asArray(1,2) =  "Dog": asArray(1,3) =  "07"
   asArray(2,1) =  "Midnight": asArray(2,2) =  "Cat": asArray(2,3) =  "15"
   asArray(3,1) =  "Tweety": asArray(3,2) =  "Bird": asArray(3,3) =  "85"
   asArray(4,1) =  "Fred": asArray(4,2) =  "Fish": asArray(4,3) =  "02"
   asArray(5,1) =  "Sylvester": asArray(5,2) =  "Cat": asArray(5,3) =  "79"
   
   Debug.Print  "INITAL ARRAY: Dim asArray(1 To 5, 1 To 3) As String"
   Call Write2DArray2Debug(asArray) 
   
   'sort the array by first column
   Call Sort2DStringArray(asArray) 
   
   Debug.Print  "Sort2DStringArray(asArray), 1st column Ascending"
   Call Write2DArray2Debug(asArray) 
   
   'sort the array by 2nd column
   Call Sort2DStringArray(asArray,2) 
   
   Debug.Print  "Sort2DStringArray(asArray, 2), 2nd column ascending"
   Debug.Print  "tie in sort column is then by the last sort"
   Call Write2DArray2Debug(asArray) 
   
   'sort the array by 2nd column, descending
   Call Sort2DStringArray(asArray,2,True) 
   
   Debug.Print  "Sort2DStringArray(asArray, 2, True), 2nd column descending"
   Debug.Print  "tie in sort column is broken by same initial Name sort"
   Call Write2DArray2Debug(asArray) 
   
   'sort the array by first column, descending
   Call Sort2DStringArray(asArray,1,True) 
   
   Debug.Print  "Sort2DStringArray(asArray, 1, True), 1st column Descending"
   Call Write2DArray2Debug(asArray) 
   
   'sort the array by 3rd column in descending order
   Call Sort2DStringArray(asArray,3,True) 
   
   Debug.Print  "Sort2DStringArray(asArray, 3, True), 3rd column descending"
   Call Write2DArray2Debug(asArray) 

End Sub 

'-------------------------------------------------------------------------------
'           WriteBubbleArray2Debug -- for testing
'-------------------------------------------------------------------------------
Public Sub WriteBubbleArray2Debug( _ 
   ByRef psArray() As String _ 
   ,Optional pbShowIndex As Boolean = True) 
'270414 s4p, for testing,260905
' iterate the passed single dimension string array
' Write the array index and its values
'  to the debug (Immediate) window

   ' PARAMETERs
   '   psArray -- single dimension string array
   '  pbShowIndex = true to show element index
   
   Dim i As Integer 
   
   Debug.Print String(25, "-") 
   For i = LBound(psArray) To UBound(psArray) 
      If pbShowIndex Then 
         Debug.Print i; Tab(7); 
      End If 
      Debug.Print psArray(i) 
   Next i 
   Debug.Print String(25, "-") 

End Sub 

'-------------------------------------------------------------------------------
'           Write2DArray2Debug -- for testing
'-------------------------------------------------------------------------------
Public Sub Write2DArray2Debug( _ 
   ByRef psArray() As String _ 
   ,Optional pbShowIndex As Boolean = True) 
'270414 s4p, for testing,260905
' iterate the passed 2-dimensional string array
' Write the array index and values for each column
'  to the debug (Immediate) window

   ' PARAMETERs
   '   psArray -- 2D string array (also work with 1D?)
   '  pbShowIndex = true to show element index in output
   
   Dim iRow As Integer _ 
      ,iCol As Integer _ 
      ,vString As Variant 
   
   Debug.Print String(25, "-") 
   For iRow = LBound(psArray) To UBound(psArray) 
      vString = Null 
      If pbShowIndex Then 
         Debug.Print iRow; Tab(7); 
      End If 
      For iCol = LBound(psArray,2) To UBound(psArray,2) 
         vString = (vString +  "; ") & psArray(iRow,iCol) 
      Next iCol 
      Debug.Print vString 
   Next iRow 
   Debug.Print String(25, "-") 

End Sub 
'*************** Code End *******************************************************
' Code was generated with colors using the free Color Code add-in for Access

Goto Top  

Reference

Microsoft Learn

Help: LBound function

Help: UBound function

Help: Exit statement

Help: String function

Help: ByRef, ByVal

Goto Top  

Backstory

Maybe instead of saving values to a table, you're using an array that only exists in memory?

Bubble Sort

BubbleSort is a fairly simple version of sorting a string array. It was based on code originally written by Brent Spaulding. It sorts by one dimension. How it works is explained in:

YouTube video: How does Bubble Sort work? (5:50)

Until I wrote intermediate arrays to Debug, for Bubble Sort video visuals, it didn't occur to me to stop comparing ... hence a new thing to keep track of — iCountSwap — number of swaps so looping and comparing will stop if there's nothing more to do.

Sort2DStringArray

Sort2DStringArray works with 2 dimensions like an Excel spreadsheet. Whenever data is swapped, so are corresponding values in related columns.

If no particular column is specified, array will be sorted by the first column. This could be expanded for more than 2 dimensions.

Goto Top  

Share with others

Here's the link for this page in case you want to copy it and share it with someone:

https://msaccessgurus.com/VBA/Array_Sort2D.htm

or in old browsers:
http://www.msaccessgurus.com/VBA/Array_Sort2D.htm

Goto Top