Wenn ich richtig verstehe, was Sie brauchen, ist eine indizierte Sortierung. Viele Sprachen bieten eine indizierte Sortierung als Standardfunktion. VBA hat weder eine Sortierung noch eine indizierte Sortierung als Standard.
Bei einer konventionellen Array-Sortierung werden die Werte innerhalb des Arrays sortiert. Zum Beispiel: Angenommen, ich ein Array mit Werten haben:
A D B E C
Wenn ich das Array zu einer Art übergeben, wird es zurückgegeben, wie:
A B C D E
Aber manchmal können Sie das Array nicht sortiert werden. In Ihrem Fall ist das Array eine Reihe von Spaltenüberschriften. Sie können diese Überschriften nicht sortieren, weil sie zu ihren Spalten gehören. Sie müssten die Spalten sortieren, was bestenfalls unpraktisch und wahrscheinlich inakzeptabel ist, da die Reihenfolge der Spalten etwas bedeuten wird.
Mit einer indizierten Art erstellen Sie Arrays Keys und Indizes:
Keys A D B E C
Indices 1 2 3 4 5
Beide Arrays der Art geführt werden, die Schlüssel unverändert lässt und sortiert Indizes geben:
Indices 1 3 5 2 4
Mit dem Bei normaler Sortierung greifen Sie auf die sortierten Einträge als Array(1)
zu. Array(2)
und so weiter. Bei einer indizierten Sortierung greifen Sie auf die sortierten Einträge als Array(Indices(1))
zu. Array(Indices(2))
und so weiter.
Gehen über einen Index, um die sortierten Einträge zu bekommen, kann ein wenig schwierig zu verstehen sein, und es ist zweifellos fiedler, dass direkt auf das Quell-Array gehen.
Unten habe ich Ihnen eine indizierte Einfügungssortierung gegeben. Eine Einfügesortierung ist einfach und leicht zu verstehen, ist aber bei einer großen Anzahl von Einträgen langsam. Sie müssen nur fünf Einträge sortieren, damit die Leistung akzeptabel ist. Sehen Sie sich den Wiki-Eintrag für "Insertion Sort" für eine bildhafte Demonstration an, wie es funktioniert.
Makro DemoSortColumnHeadings
zeigt, wie Sie die Sortierung und den Zugriff auf die Spaltenüberschriften verwenden. Ich habe den Namen ColHeads
anstelle von Keys
und ColNums
anstelle von Indices
verwendet, weil ich glaube, dass dies DemoSortColumnHeadings
leichter verständlich macht.Die sortierte ColNums
enthält die Spaltennummern in der von Ihnen gewünschten Reihenfolge. Nach der Sortierung wird das Array ColHeads
nicht mehr benötigt.
Ein letzter Punkt. VBA ist die einzige Sprache, die ich kenne, mit der Sie sowohl die untere Grenze als auch die obere Grenze eines Arrays angeben können. Die meisten Sprachen verlangen, dass die untere Grenze Null ist. Ich habe das ausgenutzt, um die Dimensionen der Arrays als (2 bis 6) und nicht (0 bis 4) zu definieren. Aus diesem Grund sind die Werte im Array ColNums
Spaltennummern. Bei den meisten Sprachen hätte ich ColNums (N) +2 benötigt, um die Spaltennummer zu erhalten.
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
Bitte Code von Ihrem Ansatz eingeben. – Limak