为了早期开发的目的,几年前,我定制了一种“Quicksort”方法,以便为多列表进行快速排序。 为了您的目的,我定制了此例程的“排列组合”部分。它依赖于'复制'方法,因此在“大”多列表格上不会很快。 此代码不符合第2点的某些部分,因为代码已更改,但我希望您能找到有用的多列可能性。
Option Explicit
Option Compare Text
Option Base 1
Dim iRowFirst As Long, iRowLast As Long
Dim iBas As Long, iHaut As Long, iRowMid As Long
Dim sVarMid As String
Public Sub sort_test()
'declare table
Dim MCTable() As Variant
'declare key range and range to sort
Dim range_keyRange As Range
'key range is column A, rows 1 through 5
Set range_keyRange = Range("A1:A5")
ActiveWorkbook.Names.Add Name:="ToSort", RefersTo:="=" & range_keyRange.Address
' call "Temp" any cell not used
ActiveWorkbook.Names.Add Name:="Temp", RefersTo:="=$C$1"
MCTable() = Range("ToSort").Value
Application.ScreenUpdating = False
' call QuickSort1(Table which contains the values, # of the column sort key, "asce" or "desc")
Call QuickSort1(MCTable, 1, "desc")
Application.ScreenUpdating = True
Set range_keyRange = Nothing
End Sub
Public Sub QuickSort1(ByRef vList, iColK1 As Long, Sens As String, _
Optional ByVal pRowLeft As Long, Optional ByVal pRowRight As Long)
' iColK1 is the number of the column key for sorting.
iBas = LBound(vList, 2): iHaut = UBound(vList, 2)
If pRowRight = 0 Then
pRowLeft = LBound(vList, 1)
pRowRight = UBound(vList, 1)
End If
iRowFirst = pRowLeft
iRowLast = pRowRight
iRowMid = (pRowLeft + pRowRight) \ 2
sVarMid = vList(iRowMid, iColK1)
Do
'=====================================================================================
' Comparaison
'=====================================================================================
If LCase(Sens) Like "asce" Then
Do While sVarMid > vList(iRowFirst, iColK1) And iRowFirst < pRowRight
iRowFirst = iRowFirst + 1
Loop
Do While vList(iRowLast, iColK1) > sVarMid And iRowLast > pRowLeft
iRowLast = iRowLast - 1
Loop
ElseIf LCase(Sens) Like "desc" Then
Do While vList(iRowFirst, iColK1) > sVarMid And iRowFirst < pRowRight
iRowFirst = iRowFirst + 1
Loop
Do While sVarMid > vList(iRowLast, iColK1) And iRowLast > pRowLeft
iRowLast = iRowLast - 1
Loop
End If
'=====================================================================================
' Permutation
'=====================================================================================
If iRowFirst <= iRowLast Then
' Echange de positions
Call MoveRow(vList, iRowFirst, iRowLast, iBas, iHaut)
iRowFirst = iRowFirst + 1
iRowLast = iRowLast - 1
End If
'=====================================================================================
Loop Until iRowFirst > iRowLast
If pRowLeft < iRowLast Then QuickSort1 vList, iColK1, Sens, pRowLeft, iRowLast
If iRowFirst < pRowRight Then QuickSort1 vList, iColK1, Sens, iRowFirst, pRowRight
End Sub
Sub MoveRow(ByRef aList, iSour As Long, iDest As Long, iBas As Long, iHaut As Long)
Dim Temp() As String
Dim rTem As Range
Dim i As Long
Dim bGo As Boolean
For i = iBas To iHaut
ReDim Preserve Temp(i)
Range("ToSort")(iDest, i).Copy Range("Temp")
Temp(i) = aList(iDest, i)
Range("ToSort")(iSour, i).Copy Range("ToSort")(iDest, i)
aList(iDest, i) = aList(iSour, i)
Range("Temp").Copy Range("ToSort")(iSour, i)
aList(iSour, i) = Temp(i)
Next i
End Sub
希望它有帮助。
不幸的是我在想没有办法做到这一点。看起来,排序时不会移动边界,我也看不出任何方法来做到这一点。虽然你能否提供更多关于边界如何变化的细节?如何将他们放入(代码或手动?)以及如何决定哪些单元格获得边界?它背后有一个算法吗? – user1759942
继续我的评论我发现这个:“http://www.mrexcel.com/archive/Formatting/30503.html”,这证实了我的想法,即单元格没有被排序,但内部的数据。 – user1759942
@ user1759942在此问题的示例中,手动添加了边框。但在现实生活中,有一种算法。在单元周围应用边框以强调在一段时间内没有发生变化。应用边界后,包含该值的列可能会被重新排序许多次,然后算法再次检查更改。 –