爲了早期開發的目的,幾年前,我定製了一種「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在此問題的示例中,手動添加了邊框。但在現實生活中,有一種算法。在單元周圍應用邊框以強調在一段時間內沒有發生變化。應用邊界後,包含該值的列可能會被重新排序許多次,然後算法再次檢查更改。 –