+ Reply to Thread
Results 1 to 4 of 4

Sorting a Multi-Dimensional Array by Value, Highest to Lowest [Excel, VBA Only]

Hybrid View

  1. #1
    Forum Contributor
    Join Date
    03-22-2012
    Location
    OR, USA
    MS-Off Ver
    Excel 14/2010
    Posts
    273

    Sorting a Multi-Dimensional Array by Value, Highest to Lowest [Excel, VBA Only]

    So I have a table of values:

    Col A Col B Col C
    Row 1 23410 7000.00 6939.45
    Row 2 23397 15000.00 11244.51
    Row 3 27060 4000.00 3524.78

    I need to be able to sort the values (up to 10 eventually) using an multidimensional array by Column B. The code will eventually be in a UserForm (and thus cannot rely on a spreadsheet sort).

    The following code works on two conditions: 1. Only 3 rows of data (need up to 10) & 2. If it is in the order as shown (needs to be any order)

    Option Explicit
    
    Sub valueSortTest()
    
        '***SETTING VARIABLES***
        Dim readForm As Worksheet, cpt(1 To 3) As String, charges(1 To 3) As Double, fsValue(1 To 3) As Double
        Dim MaxSort(1 To 3, 1 To 3), x As Integer, sortValue(1 To 3, 1 To 3)
        
        '***IDENTIFYING WORKSHEET TO BE USED***
        Set readForm = ActiveWorkbook.Worksheets("Sheet1")
        
        '***READING DATA INTO AN ARRAY***
        For x = 1 To 3
            cpt(x) = readForm.Range("A" & x).Value
            charges(x) = readForm.Range("B" & x).Value
            fsValue(x) = readForm.Range("C" & x).Value
            sortValue(1, x) = cpt(x)
            sortValue(2, x) = charges(x)
            sortValue(3, x) = fsValue(x)
        Next x
        
         '***SORTING ARRRAY [FIRST TIME]***
        For x = 1 To 3
            If sortValue(3, x) > MaxSort(3, 1) Then
                MaxSort(1, x) = MaxSort(1, 1)
                MaxSort(2, x) = MaxSort(2, 1)
                MaxSort(3, x) = MaxSort(3, 1)
                MaxSort(1, 1) = sortValue(1, x)
                MaxSort(2, 1) = sortValue(2, x)
                MaxSort(3, 1) = sortValue(3, x)
            Else
                MaxSort(1, x) = sortValue(1, x)
                MaxSort(2, x) = sortValue(2, x)
                MaxSort(3, x) = sortValue(3, x)
            End If
        Next x
         
            '***PLACE SORTED VALUES INTO SPREADSHEET/FORM***
        For x = 1 To 3
            readForm.Range("E" & x).Value = MaxSort(1, x)
            readForm.Range("F" & x).Value = MaxSort(2, x)
            readForm.Range("G" & x).Value = MaxSort(3, x)
        Next x
    
    End Sub

  2. #2
    Forum Expert
    Join Date
    01-23-2013
    Location
    USA
    MS-Off Ver
    Microsoft 365 aka Office 365
    Posts
    3,863

    Re: Sorting a Multi-Dimensional Array by Value, Highest to Lowest [Excel, VBA Only]

    Hi lloydgodin,

    I have approached problems like this by converting all the numbers to strings, all having the same number of digits before and after the decimal point.

    You might want to try something like the following:
    Option Explicit
    
    Sub QuickAndDirtySortBCA()
    
      Dim s() As String
      Dim z() As String
    
      Dim i As Long
    
      Dim a As Double
      Dim b As Double
      Dim c As Double
      
      Dim sData As String
      
      
      ''''''''''''''''''''''''''
      'Create raw data by converting numbers to strings
      'This simulates reading data from a spreadsheet
      ''''''''''''''''''''''''''
      a = 23410
      b = 7000#
      c = 6939.45
    
      ReDim s(1 To 1)
      s(1) = Format(b, "00000000.0000000") & " " & Format(c, "00000000.0000000") & " " & Format(a, "00000000.0000000")
    
      a = 23397
      b = 15000#
      c = 11244.51
    
      ReDim Preserve s(1 To 2)
      s(2) = Format(b, "00000000.0000000") & " " & Format(c, "00000000.0000000") & " " & Format(a, "00000000.0000000")
    
    
      a = 27060
      b = 4000#
      c = 3524.78
    
      ReDim Preserve s(1 To 3)
      s(3) = Format(b, "00000000.0000000") & " " & Format(c, "00000000.0000000") & " " & Format(a, "00000000.0000000")
    
      Debug.Print "'''''''''''''''"              'Output in Immediate Window (CTRL G in Debugger)
      Debug.Print "Data Before Sorting:"
      Debug.Print s(1)
      Debug.Print s(2)
      Debug.Print s(3)
      
      ''''''''''''''''''''''''''
      'Sort the strings in the arbitrary order 'b c a'
      ''''''''''''''''''''''''''
      Call LjmBubbleSortStringDescending(s)
    
    
      Debug.Print "'''''''''''''''"
      Debug.Print "Data After Sorting:"
      Debug.Print s(1)
      Debug.Print s(2)
      Debug.Print s(3)
      
      
      ''''''''''''''''''''''''''
      'Convert the sorted string back to numberic 'a b c'
      ''''''''''''''''''''''''''
      
      Debug.Print "'''''''''''''''"
      Debug.Print "Data After Decoding the Srings:"
      
      For i = 1 To 3
      
        sData = s(i)
        Call LjmParseString(sData, z)
        
        b = CDbl(z(0))
        c = CDbl(z(1))
        a = CDbl(z(2))
        
        Debug.Print "Line " & i, a, b, c
      
      Next i
    
      Debug.Print "'''''''''''''''"
    
    End Sub
    
    Sub LjmBubbleSortString(ByRef myArray() As String)
      'This sorts a string array in ascending order using a 'Bubble Sort' algorithm
         
      Dim iFirst As Integer
      Dim iLast As Integer
      Dim i As Integer
      Dim j As Integer
      Dim sTemp As String
         
      'Get the start and end indices
      iFirst = LBound(myArray)
      iLast = UBound(myArray)
        
      'Sort
      For i = iFirst To iLast - 1
        For j = i + 1 To iLast
          If myArray(i) > myArray(j) Then
            sTemp = myArray(j)
            myArray(j) = myArray(i)
            myArray(i) = sTemp
          End If
       Next j
     Next i
         
    End Sub
    
    Sub LjmBubbleSortStringDescending(ByRef myArray() As String)
      'This sorts a string array in descending order using a 'Bubble Sort' algorithm
         
      Dim iFirst As Integer
      Dim iLast As Integer
      Dim i As Integer
      Dim j As Integer
      Dim sTemp As String
         
      'Get the start and end indices
      iFirst = LBound(myArray)
      iLast = UBound(myArray)
        
      'Sort
      For i = iFirst To iLast - 1
        For j = i + 1 To iLast
          If myArray(i) < myArray(j) Then
            sTemp = myArray(j)
            myArray(j) = myArray(i)
            myArray(i) = sTemp
          End If
       Next j
     Next i
         
    End Sub
    
    Function LjmParseString(InputString As String, ByRef sArray() As String) As Integer
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '
    ' This parses a space delimited string into an array of tokens.
    ' Leading and trailing spaces are stripped from the string in the process.
    '
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    
      Dim i As Integer
      Dim LastNonEmpty As Integer
      Dim iSplitIndex As Integer
    
     'Initialization
      LastNonEmpty = -1
      
      'Split the string into tokens
      sArray = Split(InputString)
      iSplitIndex = UBound(sArray)
    
     'Remove the null tokens
      For i = 0 To iSplitIndex
    
        If sArray(i) <> "" Then
           'Get rid of all the whitespace
            LastNonEmpty = LastNonEmpty + 1
            sArray(LastNonEmpty) = sArray(i)
        End If
      Next i
    
    
     'Return the number of indices
      LjmParseString = LastNonEmpty
      
    End Function
    Lewis
    Last edited by LJMetzger; 03-23-2015 at 04:08 PM. Reason: Changed sort from ascending to descending; Lewis can't read.

  3. #3
    Forum Contributor
    Join Date
    03-22-2012
    Location
    OR, USA
    MS-Off Ver
    Excel 14/2010
    Posts
    273

    Re: Sorting a Multi-Dimensional Array by Value, Highest to Lowest [Excel, VBA Only]

    Lewis,

    Sorry for the late reply. I was out of the office yesterday. I took the code you used to sort and was able to get it to work. I was able to do it without converting the numbers. Here is a copy of the working code:

    Sub valueSortTest()
    
        '***SETTING VARIABLES***
        Dim readForm As Worksheet, cpt(1 To 10) As String, charges(1 To 10) As Double, fsValue(1 To 10) As Double
        Dim MaxSort(1 To 3), x As Integer, sortValue(1 To 3, 1 To 10), iFirst As Integer, iLast As Integer
        Dim j As Integer
        
        
        '***IDENTIFYING WORKSHEET TO BE USED***
        Set readForm = ActiveWorkbook.Worksheets("Sheet1")
        iFirst = LBound(charges)
        iLast = UBound(charges)
        
        '***READING DATA INTO AN ARRAY***
        For x = iFirst To iLast
            cpt(x) = readForm.Range("A" & x).Value
            charges(x) = readForm.Range("B" & x).Value
            fsValue(x) = readForm.Range("C" & x).Value
            sortValue(1, x) = cpt(x)
            sortValue(2, x) = charges(x)
            sortValue(3, x) = fsValue(x)
        Next x
        
         '***SORTING ARRRAY [FIRST TIME]***
        
        For x = iFirst To iLast - 1
            For j = x + 1 To iLast
                If sortValue(3, x) < sortValue(3, j) Then
                    MaxSort(1) = sortValue(1, j)
                    MaxSort(2) = sortValue(2, j)
                    MaxSort(3) = sortValue(3, j)
                    sortValue(1, j) = sortValue(1, x)
                    sortValue(2, j) = sortValue(2, x)
                    sortValue(3, j) = sortValue(3, x)
                    sortValue(1, x) = MaxSort(1)
                    sortValue(2, x) = MaxSort(2)
                    sortValue(3, x) = MaxSort(3)
                End If
            Next j
        Next x
                 
        '***PLACE SORTED VALUES INTO SPREADSHEET/FORM***
        For x = iFirst To iLast
            readForm.Range("E" & x).Value = sortValue(1, x)
            readForm.Range("F" & x).Value = sortValue(2, x)
            readForm.Range("G" & x).Value = sortValue(3, x)
        Next x
    
    End Sub
    Thank you so very much for your help.
    Last edited by lloydgodin; 03-25-2015 at 09:25 AM. Reason: forgot to post my gratitude

  4. #4
    Forum Expert mikerickson's Avatar
    Join Date
    03-30-2007
    Location
    Davis CA
    MS-Off Ver
    Excel 2011
    Posts
    6,229

    Re: Sorting a Multi-Dimensional Array by Value, Highest to Lowest [Excel, VBA Only]

    You could use something like this.
    Note that getting the array from and writing it to a worksheet is just for testing purposes. The array can be gotten any way (as long as it is a 1-based two dimensional array).

    The keyColumn and Descending arguments can be adjusted to your liking.
    This uses a bubble sort but the "sort row numbers" approach can be used with any kind of sort.
    The "build SortedArray using arrRows as a guide" explains the concept behind this.

    Sub test()
        Dim unSortedArray As Variant
        Dim SortedArray As Variant
        Dim Descending As Boolean
        Dim arrRows As Variant, rowCount As Long
        Dim keyColumn As Long
        Dim i As Long, j As Long, temp As Long
        
        unSortedArray = Range("A1:C3").Value: Rem get a 2-D array
        
        Descending = True: Rem adjust
        keyColumn = 2: Rem adjust
        
        rowCount = UBound(unSortedArray, 1)
        
        Rem make arrRows = {1, 2, 3, ..., rowCount}
        ReDim arrRows(1 To rowCount)
        For i = 1 To rowCount: arrRows(i) = i: Next i
        
        Rem sort arrRows
        For i = 1 To rowCount - 1
            For j = i + 1 To rowCount
                If (unSortedArray(arrRows(j), keyColumn) < unSortedArray(arrRows(i), keyColumn)) Xor Descending Then
                    temp = arrRows(i)
                    arrRows(i) = arrRows(j)
                    arrRows(j) = temp
                End If
            Next j
        Next i
    
        Rem build SortedArray using arrRows as a guide
        ReDim SortedArray(1 To rowCount, 1 To UBound(unSortedArray, 2))    
        For i = 1 To rowCount
            For j = 1 To UBound(unSortedArray, 2)
                SortedArray(i, j) = unSortedArray(arrRows(i), j)
            Next j
        Next i
        
        Rem output somewhere (testing)
        Range("E1").Resize(rowCount, UBound(SortedArray, 2)).Value = SortedArray
    End Sub
    Last edited by mikerickson; 03-25-2015 at 09:46 AM.
    _
    ...How to Cross-post politely...
    ..Wrap code by selecting the code and clicking the # or read this. Thank you.

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. [SOLVED] Sorting an Array by Highest to Lowest [Excel 14, VBA Only]
    By lloydgodin in forum Excel Programming / VBA / Macros
    Replies: 2
    Last Post: 03-25-2015, 09:26 AM
  2. Set up a multi-dimensional array
    By penfold1992 in forum Excel Programming / VBA / Macros
    Replies: 5
    Last Post: 07-04-2013, 04:28 AM
  3. [SOLVED] Load excel range into multi dimensional array
    By Rishi Dhupar in forum Excel Programming / VBA / Macros
    Replies: 1
    Last Post: 01-26-2006, 11:55 AM
  4. [SOLVED] Multi-Dimensional Array Let & Get
    By Trip in forum Excel Programming / VBA / Macros
    Replies: 0
    Last Post: 09-21-2005, 04:05 PM
  5. [SOLVED] Re : Excel Sorting a 2-Dimensional Array
    By tkt_tang@hotmail.com in forum Excel Programming / VBA / Macros
    Replies: 11
    Last Post: 05-03-2005, 12:06 PM

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1