问题
I am using the below code to sot my Listbox data numerically. I use the following IF statement to check if data is numeric (some data is not):
If IsNumeric(.List(i, 4)) And IsNumeric(.List(j, 4)) Then
My Listbox data is sorted correctly. However because of the above IF statement the sorting process ignores non-numeric data. I need to sort the non numeric data to the bottom of the Listbox.
Public Sub BubbleSort()
Dim i As Long
Dim j As Long
Dim Temp4 As Variant, Temp3 As Variant, Temp2 As Variant, Temp1 As Variant, Temp0 As Variant
With Plybooks.ListBox1
For i = 0 To .ListCount - 2
For j = i + 1 To .ListCount - 1
If IsNumeric(.List(i, 4)) And IsNumeric(.List(j, 4)) Then
If CLng(.List(i, 4)) > CLng(.List(j, 4)) Then
Temp4 = CLng(.List(j, 4))
.List(j, 4) = .List(i, 4)
.List(i, 4) = Temp4
Temp3 = .List(j, 3)
.List(j, 3) = .List(i, 3)
.List(i, 3) = Temp3
Temp2 = .List(j, 2)
.List(j, 2) = .List(i, 2)
.List(i, 2) = Temp2
Temp1 = .List(j, 1)
.List(j, 1) = .List(i, 1)
.List(i, 1) = Temp1
Temp0 = .List(j, 0)
.List(j, 0) = .List(i, 0)
.List(i, 0) = Temp0
End If
End If
Next j
Next i
End With
End Sub
回答1:
Your list is not sorted correctly because when one of the two values is not numeric, your sort routine doesn't do anything.
Common solution when sorting a list of values (objects) that are not directly comparable is to write a custom function that compares two values. The sort function calls this function every time it needs to compare two values.
For your case, the function could look like this:
Function IsLarger(v1 As Variant, v2 As Variant) As Boolean
' Compare 2 values and return
' True if first value is larger
' False if second value is larger
' Comparing:
' When v1 and v2 are numeric, compare the values
' When only one of those values is numeric, that value is considered a smaller
' When both values are non-numeric, make a string compare
If IsNumeric(v1) And IsNumeric(v2) Then
IsLarger = (Val(v1) > Val(v2))
ElseIf IsNumeric(v1) Then
IsLarger = False
ElseIf IsNumeric(v2) Then
IsLarger = True
Else
IsLarger = (UCase(v1) > UCase(v2))
End If
End Function
You can replace the two nested if-statements in your Sort-Routine simply with
If IsLarger(.List(i, 4), .List(j, 4)) Then
来源:https://stackoverflow.com/questions/64535875/excel-vba-sort-listbox-data-if-not-numeric-to-bottom