简体   繁体   中英

Runtime Error on a 2D Bubblesort in Excel VBA array

I have been banging my head (and a few other heads as well on other Excel programming sites) to get a Combobox in a Userform to sort the rows (coming from two columns in the source spreadsheet) in alpha order.

Ideally, I want a 2 dimensional sort, but at this point, will settle for ONE that works.

Currently, the Combobox, when dropped down, reads in part (minus the bullet points, which do NOT appear and are not needed):

  • Zoom MRKPayoutPlan
  • Chuck PSERSFuture
  • Chuck PSERSCurrent

What I want is:

  • Chuck PSERSCurrent
  • Chuck PSERSFuture
  • Zoom MRKPayoutPlan

The first order is derived from the order in which the rows appear in the source worksheet.

At this point, I am getting a Runtime Error '13', Type Mismatch error. Both fields are text fields (one is last name, the other is a classification code- I want to sort first by name).

Below are the two relevant sections of the VBA code. If someone can help me sort this out, I'll buy at least a virtual round of beers. Excel VBA is not my most comfortable area- I can accomplish this in other apps, but the client spec is that this all must run in Excel alone. Thanks in advance.

Private Sub UserForm_Initialize()
   fPath = ThisWorkbook.Path & "\"
   currentRow = 4

   sheetName = Sheet5.Name
   lastRow = Sheets(sheetName).Range("C" & Rows.Count).End(xlUp).Row


    Dim rngUID As Range
    Dim vList

    Set rngUID = Range("vUID")

    With rngUID
        vList = Application.Index(.Cells, .Parent.Evaluate("ROW(" & .Address & ")"), Array(7, 1))
    End With
   vList = BubbleSort2D(vList, 2, 1)

    With ComboBox1
        .ColumnCount = 2
        .ColumnWidths = "100;100"
        .List = vList
    End With

   PopulateControls
End Sub

Public Function BubbleSort2D(Strings, ParamArray SortColumns())
    Dim tempItem
    Dim a                     As Long
    Dim e                     As Long
    Dim f                     As Long
    Dim g                     As Long
    Dim i                     As String
    Dim j                     As String
    Dim m()                   As String
    Dim n
    Dim x As Long
    Dim y As Long
    Dim lngColumn As Long


    e = 1
    n = Strings
    Do While e <> -1

        For a = LBound(Strings) To UBound(Strings) - 1
            For y = LBound(SortColumns) To UBound(SortColumns)
                lngColumn = SortColumns(y)
                i = n(a, lngColumn)
                j = n(a + 1, lngColumn)
                f = StrComp(i, j)
                If f < 0 Then
                    Exit For
                ElseIf f > 0 Then
                    For x = LBound(Strings, 2) To UBound(Strings, 2)
                        tempItem = n(a, x)
                        n(a, x) = n(a + 1, x)
                        n(a + 1, x) = tempItem
                    Next x
                    g = 1
                    Exit For
                End If
            Next y
        Next a
        If g = 1 Then
            e = 1
        Else
            e = -1
        End If

        g = 0
    Loop
    BubbleSort2D = n
End Function

Here is a bubble sort in VBA source .

Public Sub BubbleSort(ByRef sequence As Variant, _
        ByVal lower As Long, ByVal upper As Long)

    Dim upperIt As Long
    For upperIt = upper To lower + 1 Step -1

        Dim hasSwapped As Boolean
        hasSwapped = False

        Dim bubble As Long
        For bubble = lower To upperIt - 1

            If sequence(bubble) > sequence(bubble + 1) Then

                Dim t as Variant
                t = sequence(bubble)

                sequence(bubble) = sequence(bubble + 1)
                sequence(bubble + 1) = t
                hasSwapped = True

            End If

        Next bubble

        If Not hasSwapped Then Exit Sub

    Next upperIt

End Sub

Note that using variable names that specify what they are and do instead of single letters makes it easier to read.

As for the 2D sort. Don't. Sort each array individually then sort the array of arrays using the same method. You will need to provide an abstraction to compare the columns. Do not try to sort them both at the same time. I can't think of a scenario where that is a good idea. If for some reason elements can change their sub array in the 2D array, then flatten it into 1 array, sort that and split it back into a 2D array.

Honestly from what I am understanding of you specific problem. You are going from 1D sequence to a 1D sequence so I think 2D arrays are and unnecessary complication.

Instead use a modified bubble sort routine with the comparison statement,

 If sequence(bubble) > sequence(bubble +1) Then '...

replaced with a custom comparison function

ComboBoxItemCompare(sequence(bubble), sequence(bubble + 1))

that will return True if the first argument should be swapped with the second.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM