如果我理解正確,您需要的是索引排序。許多語言都將索引排序作爲標準函數提供。 VBA既沒有標準排序也沒有索引排序。
使用傳統的數組排序,值在數組內排序。例如:假設我有值的數組:
A D B E C
如果我傳遞數組排序,則返回:
A B C D E
但有時你可以在陣列不排序。在你的情況下,數組是一系列的列標題。您無法對這些標題進行排序,因爲它們屬於它們的列。您必須對列進行排序,因爲列的順序意味着某些內容,所以最好不切實際並且可能不可接受。
有了一個索引排序,您創建陣列按鍵和指標:
Keys A D B E C
Indices 1 2 3 4 5
這兩個數組傳遞給葉鍵不變,排序排序指標給:
Indices 1 3 5 2 4
隨着定期排序,您可以按Array(1)
訪問排序的條目。 Array(2)
等。使用索引排序,您可以訪問排序條目Array(Indices(1))
。 Array(Indices(2))
等。
通過索引來獲取排序條目可能有點難以理解,毫無疑問,直接進入源數組無疑是件小事。
下面我給你一個索引插入排序。插入排序簡單易懂,但對於大量條目而言速度很慢。你只有五個條目進行排序,所以它的性能是可以接受的。查看「插入排序」的Wiki條目,瞭解它的工作原理。
宏DemoSortColumnHeadings
顯示瞭如何使用排序以及如何訪問列標題。我用名稱ColHeads
而不是Keys
和ColNums
而不是Indices
,因爲我相信這會使DemoSortColumnHeadings
更易於理解。排序的ColNums
包含您需要的順序中的列號。排序後,不再需要數組ColHeads
。
最後一點。 VBA是我所知道的唯一一種允許指定數組下限和上限的語言。大多數語言都要求下限爲零。我利用這個來定義數組的維數爲(2至6)而不是(0至4)。這就是爲什麼數組ColNums
中的值是列號。對於大多數語言,我需要ColNums(N)+2來獲取列號。
Option Explicit
Sub DemoSortColumnHeadings()
Const ColFirst As Long = 2 ' Column B = column 2
Const ColLast As Long = 6 ' Column F = column 6
Dim ColCrnt As Long
Dim ColNums() As Long
Dim InxColNum As Long
Dim ColHeads() As String
With Worksheets("Test data")
ReDim ColHeads(ColFirst To ColLast)
ReDim ColNums(ColFirst To ColLast)
For ColCrnt = ColFirst To ColLast
ColHeads(ColCrnt) = .Cells(1, ColCrnt).Value
ColNums(ColCrnt) = ColCrnt
Next
Debug.Print "Initial sequence"
Debug.Print "|";
For ColCrnt = ColFirst To ColLast
Debug.Print .Cells(1, ColCrnt).Value & "|";
Next
Debug.Print
Call InsertionSort(ColNums, ColHeads)
Debug.Print "Final sequence"
Debug.Print "|";
For InxColNum = LBound(ColNums) To UBound(ColNums)
ColCrnt = ColNums(InxColNum)
Debug.Print .Cells(1, ColCrnt).Value & "|";
Next
Debug.Print
End With
End Sub
Public Sub InsertionSort(ByRef Indices() As Long, ByRef Keys() As String)
Dim Found As Boolean
Dim I As Long
Dim InxIFwd As Long
Dim InxIBack As Long
For InxIFwd = LBound(Indices) + 1 To UBound(Indices)
I = Indices(InxIFwd) ' Save value of current entry in Indices
' Find first entry back, if any, such that Keys(I) >= Keys(Indices(InxIBack))
' If Keys(I) < Keys(Indices(InxIBack)), set Indices(InxIBack+1) to
' Indices(InxIBack). That is move indices for keys greater that Keys(I) down
' Indices leaving a space for I nearer the beginning.
Found = False
For InxIBack = InxIFwd - 1 To LBound(Indices) Step -1
If Keys(I) >= Keys(Indices(InxIBack)) Then
' Keys(I) belongs after Keys(Indices(InxIBack))
Indices(InxIBack + 1) = I
Found = True
Exit For
End If
Indices(InxIBack + 1) = Indices(InxIBack)
Next
If Not Found Then
' Insertion point for I not found so it belongs at beginning of Indices
Indices(LBound(Indices)) = I
End If
Next
End Sub
請從您的方法發佈代碼。 – Limak