web-dev-qa-db-de.com

VBA-Array-Sortierfunktion?

Ich suche nach einer ordentlichen Sortierimplementierung für Arrays in VBA. Ein Quicksort wäre zu bevorzugen. Oder jeder andere Sortieralgorithmus außer Blasen oder Zusammenführen würde ausreichen.

Bitte beachten Sie, dass dies mit MS Project 2003 funktioniert. Vermeiden Sie daher die systemeigenen Funktionen von Excel und alle damit zusammenhängenden .net-Funktionen.

74
Mark Nold

Schau mal hier :
Edit: Die referenzierte Quelle (allexperts.com) ist seitdem geschlossen, aber hier sind die relevanten Autor Kommentare:

Im Web gibt es viele Algorithmen zum Sortieren. Der vielseitigste und normalerweise der schnellste ist der Quicksort-Algorithmus . Unten ist eine Funktion dafür. 

Rufen Sie es einfach auf, indem Sie ein Array von Werten (String oder numerisch; es spielt keine Rolle) mit der Lower Array Boundary (normalerweise 0) und der Upper Array Boundary (d. H. UBound(myArray).)

Beispiel: Call QuickSort(myArray, 0, UBound(myArray))

Wenn dies erledigt ist, wird myArray sortiert und Sie können machen, was Sie wollen.
(Quelle: archive.org )

Public Sub QuickSort(vArray As Variant, inLow As Long, inHi As Long)
  Dim pivot   As Variant
  Dim tmpSwap As Variant
  Dim tmpLow  As Long
  Dim tmpHi   As Long

  tmpLow = inLow
  tmpHi = inHi

  pivot = vArray((inLow + inHi) \ 2)

  While (tmpLow <= tmpHi)
     While (vArray(tmpLow) < pivot And tmpLow < inHi)
        tmpLow = tmpLow + 1
     Wend

     While (pivot < vArray(tmpHi) And tmpHi > inLow)
        tmpHi = tmpHi - 1
     Wend

     If (tmpLow <= tmpHi) Then
        tmpSwap = vArray(tmpLow)
        vArray(tmpLow) = vArray(tmpHi)
        vArray(tmpHi) = tmpSwap
        tmpLow = tmpLow + 1
        tmpHi = tmpHi - 1
     End If
  Wend

  If (inLow < tmpHi) Then QuickSort vArray, inLow, tmpHi
  If (tmpLow < inHi) Then QuickSort vArray, tmpLow, inHi
End Sub

Beachten Sie, dass dies nur mit eindimensionalen (auch "normalen"?) Arrays funktioniert. (Es gibt ein funktionierendes mehrdimensionales Array QuickSort hier .) 

89
Jorge Ferreira

Ich habe den "Fast Quick Sort" -Algorithmus in VBA konvertiert, falls es jemand anderes wünscht.

Ich habe es optimiert, um auf einem Array von Int/Longs zu laufen, aber es sollte einfach sein, es in ein Array umzuwandeln, das mit beliebigen vergleichbaren Elementen arbeitet.

Private Sub QuickSort(ByRef a() As Long, ByVal l As Long, ByVal r As Long)
    Dim M As Long, i As Long, j As Long, v As Long
    M = 4

    If ((r - l) > M) Then
        i = (r + l) / 2
        If (a(l) > a(i)) Then swap a, l, i '// Tri-Median Methode!'
        If (a(l) > a(r)) Then swap a, l, r
        If (a(i) > a(r)) Then swap a, i, r

        j = r - 1
        swap a, i, j
        i = l
        v = a(j)
        Do
            Do: i = i + 1: Loop While (a(i) < v)
            Do: j = j - 1: Loop While (a(j) > v)
            If (j < i) Then Exit Do
            swap a, i, j
        Loop
        swap a, i, r - 1
        QuickSort a, l, j
        QuickSort a, i + 1, r
    End If
End Sub

Private Sub swap(ByRef a() As Long, ByVal i As Long, ByVal j As Long)
    Dim T As Long
    T = a(i)
    a(i) = a(j)
    a(j) = T
End Sub

Private Sub InsertionSort(ByRef a(), ByVal lo0 As Long, ByVal hi0 As Long)
    Dim i As Long, j As Long, v As Long

    For i = lo0 + 1 To hi0
        v = a(i)
        j = i
        Do While j > lo0
            If Not a(j - 1) > v Then Exit Do
            a(j) = a(j - 1)
            j = j - 1
        Loop
        a(j) = v
    Next i
End Sub

Public Sub sort(ByRef a() As Long)
    QuickSort a, LBound(a), UBound(a)
    InsertionSort a, LBound(a), UBound(a)
End Sub
15
Alain

Erklärung auf Deutsch, aber der Code ist eine erprobte In-Place-Implementierung:

Private Sub QuickSort(ByRef Field() As String, ByVal LB As Long, ByVal UB As Long)
    Dim P1 As Long, P2 As Long, Ref As String, TEMP As String

    P1 = LB
    P2 = UB
    Ref = Field((P1 + P2) / 2)

    Do
        Do While (Field(P1) < Ref)
            P1 = P1 + 1
        Loop

        Do While (Field(P2) > Ref)
            P2 = P2 - 1
        Loop

        If P1 <= P2 Then
            TEMP = Field(P1)
            Field(P1) = Field(P2)
            Field(P2) = TEMP

            P1 = P1 + 1
            P2 = P2 - 1
        End If
    Loop Until (P1 > P2)

    If LB < P2 Then Call QuickSort(Field, LB, P2)
    If P1 < UB Then Call QuickSort(Field, P1, UB)
End Sub

So aufgerufen:

Call QuickSort(MyArray, LBound(MyArray), UBound(MyArray))
9
Konrad Rudolph

Ich habe etwas Code als Antwort auf eine verwandte Frage zu StackOverflow veröffentlicht:

Sortieren eines multidimensionalen Arrays in VBA

Die Codebeispiele in diesem Thread umfassen:

  1. Ein Vektorfeld Quicksort;
  2. Ein mehrspaltiges Array QuickSort;
  3. Ein BubbleSort.

Alains optimiertes Quicksort ist sehr glänzend: Ich habe gerade ein einfaches Split-and-Recurse durchgeführt, aber das obige Codebeispiel verfügt über eine Gating-Funktion, die redundante Vergleiche von doppelten Werten reduziert. Auf der anderen Seite programmiere ich für Excel, und es gibt noch einiges mehr für defensives Codieren - seien Sie gewarnt, Sie werden es brauchen, wenn Ihr Array die schädliche 'Empty ()' - Variante enthält, die Ihr While bricht. Wend-Vergleichsoperatoren und fangen Ihren Code in einer Endlosschleife ein.

Beachten Sie, dass Quicksort-Algorithmen - und jeder rekursive Algorithmus - den Stapel füllen und Excel zum Absturz bringen können. Wenn Ihr Array weniger als 1024 Mitglieder hat, würde ich einen rudimentären BubbleSort verwenden. 

 Public Sub QuickSortArray (ByRef SortArray als Variante, _ Optionales lngMin As Long = -1, _ Optionales lngMax As Long = -1, _ Optionales lngColumn As Long = 0) On Error Resume Next
'Sortiere ein zweidimensionales Array
' Verwendungsbeispiel: sort arrData nach dem Inhalt von Spalte 3 ' ' QuickSortArray arrData, 3
' 'Gepostet von Jim Rech 20.10.98 Excel.Programmierung
'Änderungen, Nigel Heffernan:
' "Vergleich mit leerer Variante fehlgeschlagen " 'Defensive Codierung: Eingaben prüfen
Dim i As Long Dim j As Long Dim varMid Als Variante Dim arrRowTemp As Variante Dim lngColTemp As Long

Wenn IsEmpty (SortArray) Dann Beenden Sie Sub Ende wenn
Wenn InStr (TypeName (SortArray), "()") <1 Dann ist 'IsArray () etwas defekt: Suchen Sie nach Klammern im Typnamen Beenden Sie Sub Ende wenn
Wenn lngMin = -1 Dann lngMin = LBound (SortArray, 1) Ende wenn
Wenn lngMax = -1 Dann lngMax = UBound (SortArray, 1) Ende wenn
Wenn lngMin> = lngMax Dann ist keine Sortierung erforderlich Beenden Sie Sub Ende wenn

i = lngMin j = lngMax
varMid = Leer varMid = SortArray ((lngMin + lngMax)\2, lngColumn)
'Wir senden' leere 'und ungültige Datenelemente an das Ende der Liste: Wenn IsObject (varMid). Dann beachten Sie, dass wir isObject (SortArray (n)) - varMid mightnicht prüfen, _ ein gültiges Standardmitglied oder eine gültige Eigenschaft. i = lngMax j = lngMin ElseIf IsEmpty (varMid) Dann i = lngMax j = lngMin ElseIf IsNull (varMid) Dann i = lngMax j = lngMin ElseIf varMid = "" Dann i = lngMax j = lngMin ElseIf varType (varMid) = vbError Then i = lngMax j = lngMin ElseIf varType (varMid)> 17 Dann i = lngMax j = lngMin Ende wenn

Während i <= j
Während SortArray (i, lngColumn) <varMid und i <lngMax i = i + 1 Wend
While varMid <SortArray (j, lngColumn) und j> lngMin j = j - 1 Wend

Wenn i <= j Dann
'Tauschen Sie die Zeilen aus ReDim arrRowTemp (LBound (SortArray, 2) nach UBound (SortArray, 2)) Für lngColTemp = LBound (SortArray, 2) nach UBound (SortArray, 2) arrRowTemp (lngColTemp) = SortArray (i, lngColTemp) SortArray (i, lngColTemp) = SortArray (j, lngColTemp) SortArray (j, lngColTemp) = arrRowTemp (lngColTemp) Nächstes lngColTemp ArrRowTemp löschen
i = i + 1 j = j - 1
Ende wenn

Wend
If (lngMin <j) Dann rufen Sie QuickSortArray (SortArray, lngMin, j, lngColumn) Wenn (i <lngMax), dann QuickSortArray aufrufen (SortArray, i, lngMax, lngColumn)

End Sub

6
Nigel Heffernan

Natural Number (Strings) Schnelle Sortierung  

Nur um das Thema anzuhäufen. Wenn Sie Zeichenfolgen mit Zahlen sortieren, erhalten Sie normalerweise Folgendes:

    Text1
    Text10
    Text100
    Text11
    Text2
    Text20

Sie möchten aber wirklich die numerischen Werte erkennen und sortiert werden 

    Text1
    Text2
    Text10
    Text11
    Text20
    Text100

So geht's ...

Hinweis: 

  • Ich habe die Quick Sort vor langer Zeit aus dem Internet geklaut, nicht sicher, wo jetzt ... 
  • Ich habe die CompareNaturalNum-Funktion übersetzt, die ursprünglich in C aus dem Internet geschrieben wurde.
  • Unterschied zu anderen Q-Sorten: Ich tausche die Werte nicht aus, wenn BottomTemp = TopTemp ist

Natürliche Zahl Schnelle Sortierung

Public Sub QuickSortNaturalNum(strArray() As String, intBottom As Integer, intTop As Integer)
Dim strPivot As String, strTemp As String
Dim intBottomTemp As Integer, intTopTemp As Integer

    intBottomTemp = intBottom
    intTopTemp = intTop

    strPivot = strArray((intBottom + intTop) \ 2)

    Do While (intBottomTemp <= intTopTemp)
        ' < comparison of the values is a descending sort
        Do While (CompareNaturalNum(strArray(intBottomTemp), strPivot) < 0 And intBottomTemp < intTop)
            intBottomTemp = intBottomTemp + 1
        Loop
        Do While (CompareNaturalNum(strPivot, strArray(intTopTemp)) < 0 And intTopTemp > intBottom) '
            intTopTemp = intTopTemp - 1
        Loop
        If intBottomTemp < intTopTemp Then
            strTemp = strArray(intBottomTemp)
            strArray(intBottomTemp) = strArray(intTopTemp)
            strArray(intTopTemp) = strTemp
        End If
        If intBottomTemp <= intTopTemp Then
            intBottomTemp = intBottomTemp + 1
            intTopTemp = intTopTemp - 1
        End If
    Loop

    'the function calls itself until everything is in good order
    If (intBottom < intTopTemp) Then QuickSortNaturalNum strArray, intBottom, intTopTemp
    If (intBottomTemp < intTop) Then QuickSortNaturalNum strArray, intBottomTemp, intTop
End Sub

Natürlicher Nummernvergleich (wird für die Schnelle Sortierung verwendet)

Function CompareNaturalNum(string1 As Variant, string2 As Variant) As Integer
'string1 is less than string2 -1
'string1 is equal to string2 0
'string1 is greater than string2 1
Dim n1 As Long, n2 As Long
Dim iPosOrig1 As Integer, iPosOrig2 As Integer
Dim iPos1 As Integer, iPos2 As Integer
Dim nOffset1 As Integer, nOffset2 As Integer

    If Not (IsNull(string1) Or IsNull(string2)) Then
        iPos1 = 1
        iPos2 = 1
        Do While iPos1 <= Len(string1)
            If iPos2 > Len(string2) Then
                CompareNaturalNum = 1
                Exit Function
            End If
            If isDigit(string1, iPos1) Then
                If Not isDigit(string2, iPos2) Then
                    CompareNaturalNum = -1
                    Exit Function
                End If
                iPosOrig1 = iPos1
                iPosOrig2 = iPos2
                Do While isDigit(string1, iPos1)
                    iPos1 = iPos1 + 1
                Loop

                Do While isDigit(string2, iPos2)
                    iPos2 = iPos2 + 1
                Loop

                nOffset1 = (iPos1 - iPosOrig1)
                nOffset2 = (iPos2 - iPosOrig2)

                n1 = Val(Mid(string1, iPosOrig1, nOffset1))
                n2 = Val(Mid(string2, iPosOrig2, nOffset2))

                If (n1 < n2) Then
                    CompareNaturalNum = -1
                    Exit Function
                ElseIf (n1 > n2) Then
                    CompareNaturalNum = 1
                    Exit Function
                End If

                ' front padded zeros (put 01 before 1)
                If (n1 = n2) Then
                    If (nOffset1 > nOffset2) Then
                        CompareNaturalNum = -1
                        Exit Function
                    ElseIf (nOffset1 < nOffset2) Then
                        CompareNaturalNum = 1
                        Exit Function
                    End If
                End If
            ElseIf isDigit(string2, iPos2) Then
                CompareNaturalNum = 1
                Exit Function
            Else
                If (Mid(string1, iPos1, 1) < Mid(string2, iPos2, 1)) Then
                    CompareNaturalNum = -1
                    Exit Function
                ElseIf (Mid(string1, iPos1, 1) > Mid(string2, iPos2, 1)) Then
                    CompareNaturalNum = 1
                    Exit Function
                End If

                iPos1 = iPos1 + 1
                iPos2 = iPos2 + 1
            End If
        Loop
        ' Everything was the same so far, check if Len(string2) > Len(String1)
        ' If so, then string1 < string2
        If Len(string2) > Len(string1) Then
            CompareNaturalNum = -1
            Exit Function
        End If
    Else
        If IsNull(string1) And Not IsNull(string2) Then
            CompareNaturalNum = -1
            Exit Function
        ElseIf IsNull(string1) And IsNull(string2) Then
            CompareNaturalNum = 0
            Exit Function
        ElseIf Not IsNull(string1) And IsNull(string2) Then
            CompareNaturalNum = 1
            Exit Function
        End If
    End If
End Function

isDigit (wird in CompareNaturalNum verwendet)

Function isDigit(ByVal str As String, pos As Integer) As Boolean
Dim iCode As Integer
    If pos <= Len(str) Then
        iCode = Asc(Mid(str, pos, 1))
        If iCode >= 48 And iCode <= 57 Then isDigit = True
    End If
End Function
6
Profex
Dim arr As Object
Dim InputArray

'Creating a array list
Set arr = CreateObject("System.Collections.ArrayList")

'String
InputArray = Array("d", "c", "b", "a", "f", "e", "g")

'number
'InputArray = Array(6, 5, 3, 4, 2, 1)

' adding the elements in the array to array_list
For Each element In InputArray
    arr.Add element
Next

'sorting happens
arr.Sort

'Converting ArrayList to an array
'so now a sorted array of elements is stored in the array sorted_array.

sorted_array = arr.toarray
4
Prasand Kumar

Sie wollten keine Excel-basierte Lösung, aber da ich heute das gleiche Problem hatte und mit anderen Office-Anwendungsfunktionen testen wollte, schrieb ich die Funktion unten.

Einschränkungen:

  • 2-dimensionale Arrays;
  • maximal 3 Spalten als Sortierschlüssel;
  • hängt von Excel ab;

Getestetes Aufrufen von Excel 2010 aus Visio 2010


Option Base 1


Private Function sort_array_2D_Excel(array_2D, array_sortkeys, Optional array_sortorders, Optional tag_header As String = "Guess", Optional tag_matchcase As String = "False")

'   Dependencies: Excel; Tools > References > Microsoft Excel [Version] Object Library

    Dim Excel_application As Excel.Application
    Dim Excel_workbook As Excel.Workbook
    Dim Excel_worksheet As Excel.Worksheet

    Set Excel_application = CreateObject("Excel.Application")

    Excel_application.Visible = True
    Excel_application.ScreenUpdating = False
    Excel_application.WindowState = xlNormal

    Set Excel_workbook = Excel_application.Workbooks.Add
    Excel_workbook.Activate

    Set Excel_worksheet = Excel_workbook.Worksheets.Add
    Excel_worksheet.Activate
    Excel_worksheet.Visible = xlSheetVisible

    Dim Excel_range As Excel.Range
    Set Excel_range = Excel_worksheet.Range("A1").Resize(UBound(array_2D, 1) - LBound(array_2D, 1) + 1, UBound(array_2D, 2) - LBound(array_2D, 2) + 1)
    Excel_range = array_2D


    For i_sortkey = LBound(array_sortkeys) To UBound(array_sortkeys)

        If IsNumeric(array_sortkeys(i_sortkey)) Then
            sortkey_range = Chr(array_sortkeys(i_sortkey) + 65 - 1) & "1"
            Set array_sortkeys(i_sortkey) = Excel_worksheet.Range(sortkey_range)

        Else
            MsgBox "Error in sortkey parameter:" & vbLf & "array_sortkeys(" & i_sortkey & ") = " & array_sortkeys(i_sortkey) & vbLf & "Terminating..."
            End

        End If

    Next i_sortkey


    For i_sortorder = LBound(array_sortorders) To UBound(array_sortorders)
        Select Case LCase(array_sortorders(i_sortorder))
            Case "asc"
                array_sortorders(i_sortorder) = XlSortOrder.xlAscending
            Case "desc"
                array_sortorders(i_sortorder) = XlSortOrder.xlDescending
            Case Else
                array_sortorders(i_sortorder) = XlSortOrder.xlAscending
        End Select
    Next i_sortorder

    Select Case LCase(tag_header)
        Case "yes"
            tag_header = Excel.xlYes
        Case "no"
            tag_header = Excel.xlNo
        Case "guess"
            tag_header = Excel.xlGuess
        Case Else
            tag_header = Excel.xlGuess
    End Select

    Select Case LCase(tag_matchcase)
        Case "true"
            tag_matchcase = True
        Case "false"
            tag_matchcase = False
        Case Else
            tag_matchcase = False
    End Select


    Select Case (UBound(array_sortkeys) - LBound(array_sortkeys) + 1)
        Case 1
            Call Excel_range.Sort(Key1:=array_sortkeys(1), Order1:=array_sortorders(1), Header:=tag_header, MatchCase:=tag_matchcase)
        Case 2
            Call Excel_range.Sort(Key1:=array_sortkeys(1), Order1:=array_sortorders(1), Key2:=array_sortkeys(2), Order2:=array_sortorders(2), Header:=tag_header, MatchCase:=tag_matchcase)
        Case 3
            Call Excel_range.Sort(Key1:=array_sortkeys(1), Order1:=array_sortorders(1), Key2:=array_sortkeys(2), Order2:=array_sortorders(2), Key3:=array_sortkeys(3), Order3:=array_sortorders(3), Header:=tag_header, MatchCase:=tag_matchcase)
        Case Else
            MsgBox "Error in sortkey parameter:" & vbLf & "Maximum number of sort columns is 3!" & vbLf & "Currently passed: " & (UBound(array_sortkeys) - LBound(array_sortkeys) + 1)
            End
    End Select


    For i_row = 1 To Excel_range.Rows.Count

        For i_column = 1 To Excel_range.Columns.Count

            array_2D(i_row, i_column) = Excel_range(i_row, i_column)

        Next i_column

    Next i_row


    Excel_workbook.Close False
    Excel_application.Quit

    Set Excel_worksheet = Nothing
    Set Excel_workbook = Nothing
    Set Excel_application = Nothing


    sort_array_2D_Excel = array_2D


End Function

Dies ist ein Beispiel zum Testen der Funktion:

Private Sub test_sort()

    array_unsorted = dim_sort_array()

    Call msgbox_array(array_unsorted)

    array_sorted = sort_array_2D_Excel(array_unsorted, Array(2, 1, 3), Array("desc", "", "asdas"), "yes", "False")

    Call msgbox_array(array_sorted)

End Sub


Private Function dim_sort_array()

    Dim array_unsorted(1 To 5, 1 To 3) As String

    i_row = 0

    i_row = i_row + 1
    array_unsorted(i_row, 1) = "Column1": array_unsorted(i_row, 2) = "Column2": array_unsorted(i_row, 3) = "Column3"

    i_row = i_row + 1
    array_unsorted(i_row, 1) = "OR": array_unsorted(i_row, 2) = "A": array_unsorted(i_row, 3) = array_unsorted(i_row, 1) & "_" & array_unsorted(i_row, 2)

    i_row = i_row + 1
    array_unsorted(i_row, 1) = "XOR": array_unsorted(i_row, 2) = "A": array_unsorted(i_row, 3) = array_unsorted(i_row, 1) & "_" & array_unsorted(i_row, 2)

    i_row = i_row + 1
    array_unsorted(i_row, 1) = "NOT": array_unsorted(i_row, 2) = "B": array_unsorted(i_row, 3) = array_unsorted(i_row, 1) & "_" & array_unsorted(i_row, 2)

    i_row = i_row + 1
    array_unsorted(i_row, 1) = "AND": array_unsorted(i_row, 2) = "A": array_unsorted(i_row, 3) = array_unsorted(i_row, 1) & "_" & array_unsorted(i_row, 2)

    dim_sort_array = array_unsorted

End Function


Sub msgbox_array(array_2D, Optional string_info As String = "2D array content:")

    msgbox_string = string_info & vbLf

    For i_row = LBound(array_2D, 1) To UBound(array_2D, 1)

        msgbox_string = msgbox_string & vbLf & i_row & vbTab

        For i_column = LBound(array_2D, 2) To UBound(array_2D, 2)

            msgbox_string = msgbox_string & array_2D(i_row, i_column) & vbTab

        Next i_column

    Next i_row

    MsgBox msgbox_string

End Sub

Wenn jemand dies mit anderen Office-Versionen testet, bitte hier posten, falls Probleme auftreten.

2
lucas0x7B

Ich frage mich, was würden Sie über diesen Arraysortiercode sagen. Die Implementierung ist schnell und erledigt die Aufgabe ... noch nicht für große Arrays getestet. Es funktioniert für eindimensionale Arrays, für mehrdimensionale zusätzliche Werte müsste die Matrix zur Neupositionierung neu aufgebaut werden (mit einer geringeren Dimension als das ursprüngliche Array).

       For AR1 = LBound(eArray, 1) To UBound(eArray, 1)
            eValue = eArray(AR1)
            For AR2 = LBound(eArray, 1) To UBound(eArray, 1)
                If eArray(AR2) < eValue Then
                    eArray(AR1) = eArray(AR2)
                    eArray(AR2) = eValue
                    eValue = eArray(AR1)
                End If
            Next AR2
        Next AR1
0
Jarek

Heapsort Implementierung. Ein O (n log (n)) (sowohl der durchschnittliche als auch der schlechteste Fall) ist vorhanden instabil Sortieralgorithmus.

Verwendung mit: Call HeapSort(A), wobei A ein eindimensionales Array von Varianten mit Option Base 1 ist.

Sub SiftUp(A() As Variant, I As Long)
    Dim K As Long, P As Long, S As Variant
    K = I
    While K > 1
        P = K \ 2
        If A(K) > A(P) Then
            S = A(P): A(P) = A(K): A(K) = S
            K = P
        Else
            Exit Sub
        End If
    Wend
End Sub

Sub SiftDown(A() As Variant, I As Long)
    Dim K As Long, L As Long, S As Variant
    K = 1
    Do
        L = K + K
        If L > I Then Exit Sub
        If L + 1 <= I Then
            If A(L + 1) > A(L) Then L = L + 1
        End If
        If A(K) < A(L) Then
            S = A(K): A(K) = A(L): A(L) = S
            K = L
        Else
            Exit Sub
        End If
    Loop
End Sub

Sub HeapSort(A() As Variant)
    Dim N As Long, I As Long, S As Variant
    N = UBound(A)
    For I = 2 To N
        Call SiftUp(A, I)
    Next I
    For I = N To 2 Step -1
        S = A(I): A(I) = A(1): A(1) = S
        Call SiftDown(A, I - 1)
    Next
End Sub
0

Dies ist, was ich zum Sortieren im Speicher verwende - es kann leicht erweitert werden, um ein Array zu sortieren.

Sub sortlist()

    Dim xarr As Variant
    Dim yarr As Variant
    Dim zarr As Variant

    xarr = Sheets("sheet").Range("sing col range")
    ReDim yarr(1 To UBound(xarr), 1 To 1)
    ReDim zarr(1 To UBound(xarr), 1 To 1)

    For n = 1 To UBound(xarr)
        zarr(n, 1) = 1
    Next n

    For n = 1 To UBound(xarr) - 1
        y = zarr(n, 1)
        For a = n + 1 To UBound(xarr)
            If xarr(n, 1) > xarr(a, 1) Then
                y = y + 1
            Else
                zarr(a, 1) = zarr(a, 1) + 1
            End If
        Next a
        yarr(y, 1) = xarr(n, 1)
    Next n

    y = zarr(UBound(xarr), 1)
    yarr(y, 1) = xarr(UBound(xarr), 1)

    yrng = "A1:A" & UBound(yarr)
    Sheets("sheet").Range(yrng) = yarr

End Sub
0
Reged

Ich denke, mein Code (getestet) ist "gebildet", vorausgesetzt je einfacher desto besser .

Option Base 1

'Function to sort an array decscending
Function SORT(Rango As Range) As Variant
    Dim check As Boolean
    check = True
    If IsNull(Rango) Then
        check = False
    End If
    If check Then
        Application.Volatile
        Dim x() As Variant, n As Double, m As Double, i As Double, j As Double, k As Double
        n = Rango.Rows.Count: m = Rango.Columns.Count: k = n * m
        ReDim x(n, m)
        For i = 1 To n Step 1
            For j = 1 To m Step 1
                x(i, j) = Application.Large(Rango, k)
                k = k - 1
            Next j
        Next i
        SORT = x
    Else
        Exit Function
    End If
End Function
0
Moreno