Listview sortieren nach zweiter Spalte

  • Hallo zusammen,

    wie die Überschrift schon sagt, würde ich gern die Einträge meiner Listview beim aufrufen dieser nach der Spalte zwei sortieren lassen, nur leider bekomme ich das nicht hin bzw. weiß ich nicht, wie ich das anstelle. Die Listview zum sortieren zu bringen ist ja kein Problem, jedoch macht sie dieses Momentan immer über die erste nicht wie ich es gerne hätte über die zweite.

    Ausschnitt:

    Spoiler anzeigen
    [autoit]

    Func SCHMUCK()
    $Z = 0
    If $M = 3 Then TITELLEISTE(TRANSLATION("Adelsschmuck"), 1, 410)
    If $M = 22 Then TITELLEISTE(TRANSLATION("Seeschlachtschmuck"), 1, 410)
    If $M = 23 Then TITELLEISTE(TRANSLATION("Redeschmuck"), 1, 410)
    If $M = 814 Then TITELLEISTE(TRANSLATION("Jobschmuck See"), 1, 410)
    If $M = 815 Then TITELLEISTE(TRANSLATION("Jobschmuck Land"), 1, 410)
    If $M = 816 Then TITELLEISTE(TRANSLATION("Kolonieschmuck See"), 1, 410)
    If $M = 817 Then TITELLEISTE(TRANSLATION("Kolonieschmuck Land"), 1, 410)
    If $M = 818 Then TITELLEISTE(TRANSLATION("Skillschmuck"), 1, 410)
    IF $M = 819 THEN TITELLEISTE(TRANSLATION("Ring"),1,410)
    IF $M = 820 THEN TITELLEISTE(TRANSLATION("Halskette"),1,410)
    IF $M = 821 THEN TITELLEISTE(TRANSLATION("Assistance"),1,410)
    $LISTVIEW = GUICtrlCreateListView(TRANSLATION("Schmuckname") & " |" & TRANSLATION("Stufe") & " ", 10, 50, 410, 580, $LVS_REPORT)
    GUICtrlSendMsg($LISTVIEW, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
    GUICtrlSendMsg($LISTVIEW, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
    _GUICTRLLISTVIEW_SETCOLUMN($LISTVIEW, 1, TRANSLATION("Stufe"), -1, 1)
    $ZAHL = 0
    For $I = 1 To $ANZSCHMUCK
    IF ($SCHMUCK[$I][3] = "Adelsschmuck" And $M = 3) OR ($SCHMUCK[$I][3] = "Seeschlachtschmuck" And $M = 22) OR ($SCHMUCK[$I][3] = "Redeschmuck" And $M = 23) OR ($SCHMUCK[$I][3] = "Jobschmuck See" And $M = 814) OR ($SCHMUCK[$I][3] = "Jobschmuck Land" And $M = 815) OR ($SCHMUCK[$I][3] = "Kolonieschmuck See" And $M = 816) OR ($SCHMUCK[$I][3] = "Kolonieschmuck Land" And $M = 817) OR ($SCHMUCK[$I][3] = "Skillschmuck" And $M = 818) OR ($SCHMUCK[$I][3]="Ring" AND $M = 819) OR ($SCHMUCK[$I][3]="Halskette" AND $M = 820) OR ($SCHMUCK[$I][3]="Assistance" AND $M= 821) OR ($SCHMUCK[$I][3] <> "Seeschlachtschmuck" And $SCHMUCK[$I][3] <> "Redeschmuck" And $SCHMUCK[$I][3] <> "Jobschmuck See" And $SCHMUCK[$I][3]<> "Jobschmuck Land" And $SCHMUCK[$I][3]<> "Kolonieschmuck See" And $SCHMUCK[$I][3]<> "Kolonieschmuck Land" And $SCHMUCK[$I][3]<> "Skillschmuck" And $SCHMUCK[$I][3]<>"Ring" AND $SCHMUCK[$I][3]<>"Halskette" AND $SCHMUCK[$I][3]<>"Assistance" And $SCHMUCK[$I][3] <> "Adelsschmuck" And $M = 3) Then ; $SCHMUCK[$I][3] die [3] gibt die Zeile an, wo er welchen Schmuck ausließt
    $Z = $Z + 1
    $CLICKSCHMUCK[$Z][0] = GUICtrlCreateListViewItem($SCHMUCK[$I][0] & "|" & $SCHMUCK[$I][1], $LISTVIEW)
    $CLICKSCHMUCK[$Z][1] = $I
    If $JUMPAKTIV = 1 And $SCHMUCK[$I][0] = $SPRUNGOBJ Then $JUMPTEMP = $CLICKSCHMUCK[$Z][0]
    EndIf
    Next
    $TEMP[33] = GUICtrlCreateLabel(" ", 10, 50, 410, 580)
    GUICtrlSetState(-1, $GUI_DISABLE)
    Global $B_DESCENDING[_GUICTRLLISTVIEW_GETCOLUMNCOUNT($LISTVIEW)]
    _GUICTRLLISTVIEW_SETCOLUMNWIDTH($LISTVIEW, 0, 330)
    $SCHMUCKWAHL = $Z
    EndFunc

    [/autoit]


    Könnte mir bitte wer sagen wie ich hier die Auswahl $LVS_SORTASCENDING dann auf die zweite Spalte bekomme?

    Mfg Ghostleader

    3 Mal editiert, zuletzt von Ghostleader (18. August 2014 um 13:10) aus folgendem Grund: Ist gelöst nun :-)

    • Offizieller Beitrag

    Bsp.:

    Spoiler anzeigen
    [autoit]


    #include <ListViewConstants.au3>
    #include <GuiConstantsEx.au3>
    #include <GuiListView.au3>

    [/autoit] [autoit][/autoit] [autoit]

    GUICreate("ListView SimpleSort", 400, 300)
    $hListView = GUICtrlCreateListView("col1|col2|col3", 2, 2, 394, 268)
    GUICtrlSendMsg($hListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
    GUICtrlSendMsg($hListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
    GUICtrlCreateListViewItem("line4|5|more_a", $hListView)
    GUICtrlCreateListViewItem("line5|4.50 |more_c", $hListView)
    GUICtrlCreateListViewItem("line5|4.0 |more_c", $hListView)
    GUICtrlCreateListViewItem("line3|23|more_e", $hListView)
    GUICtrlCreateListViewItem("line2|0.34560 |more_d", $hListView)
    GUICtrlCreateListViewItem("line1|1.0 |more_b", $hListView)
    GUICtrlCreateListViewItem("line1|0.1 |more_b", $hListView)
    GUICtrlCreateListViewItem("line1|10|more_b", $hListView)
    _GUICtrlListView_SetColumnWidth($hListView, 0, 75)
    _GUICtrlListView_SetColumnWidth($hListView, 1, 75)
    _GUICtrlListView_SetColumnWidth($hListView, 2, 75)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    Global $B_DESCENDING[_GUICtrlListView_GetColumnCount($hListView)]
    _GUICtrlListView_SimpleSort($hListView, $B_DESCENDING, 2) ; 3ter Parameter ist Spalten-Index, Nullbasiert

    [/autoit] [autoit][/autoit] [autoit]

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    [/autoit]
  • Hi BugFix,
    für was ist genau

    [autoit]

    Global $B_DESCENDING[_GUICtrlListView_GetColumnCount($hListView)]

    [/autoit]


    Ist bei mehrspaltigen ListViews der Parameter 2 und 3 eigentlich das gleiche :?:

  • Hallo zusammen,

    BugFix

    Vielen lieben Dank für dein Beispiel, hat super funktioniert mit:

    [autoit]

    _GUICtrlListView_SimpleSort($LISTVIEW, $B_DESCENDING, 1)

    [/autoit]

    Tweaky

    Zitat

    Ist bei mehrspaltigen ListViews der Parameter 2 und 3 eigentlich das gleiche


    Wenn ich das richtig verstehe, dann ist es das nicht. Das sind die Parameter die angeben, nach welcher Spalte sich das Sortieren richten soll, in meinem Fall 1 weil die zweite Spalte ja Parameter 1 hat.
    In BugFix seinem Beispiel 2, da ja seine Sortierung nach der dritten Spalte geht und du aber bei den Spalten angaben immer mit 0 beginnst.

    Sollte ich mich Irren dann bitte Korrigieren.

    Nichts desto trotz Thema gelöst vielen dank BugFix.

    Mfg Ghostleader

    • Offizieller Beitrag

    Hi BugFix,
    für was ist genau

    [autoit]

    Global $B_DESCENDING[_GUICtrlListView_GetColumnCount($hListView)]

    [/autoit]


    Ist bei mehrspaltigen ListViews der Parameter 2 und 3 eigentlich das gleiche :?:

    Global $B_DESCENDING[_GUICtrlListView_GetColumnCount($hListView)] erzeugt ein Array mit der Anzahl der Spalten. In diesem kann man noch separat für jede Spalte die Sortierrichtung angeben. (Für dieses Bsp. könnte man ebensogut eine Boolsche Variable übergeben)
    Insofern klärt sich auch deine zweite Frage: Parameter 2 und 3 unterscheiden sich deutlich. Parameter 3 gibt an welche Spalte sortiert werden soll. In meinem Bsp. habe ich für die Spalten keine extra Sortierrichtung vorgegeben, da Standard aufsteigend ist. Ein erneuter Aufruf würde, da Parameter 4 nicht extra gesetzt ist, die Sortierrichtung umkehren (Toggle: True/False)

  • Hm,
    theoretisch klar, aber kannst du mal ein Bsp zeigen wie man dann die Sortierrichtung von mehreren Spalten angibt?
    Und wenn man im Parameter 2 bereits die Richtung je Spalte angegeben hat, warum muss man dann noch im Parameter 3 eine Spalte angeben?
    Sorry aber steh gerade auf dem Schlauch :S

  • Hallo nochmal,

    das angeben der Spalte welche sortiert werden klappt zwar, aber nicht mit dem gewünschten Effect der Größe nach.

    Ausgelesen wird in einer .data In dieser gibt es eine Zeile die die Prozentzahlen an gibt, entweder 25% oder 50% oder 75% oder 100%.

    Eigentlich sollte er so auslesen: 25,25,25 --> 50,50,50 --> 75,75,75 --> 100,100,100. Das nur ein Beispiel können auch mehr Items sein.
    Momentan liest er so aus: 100,100,100,25,25,25,75,75,75,50,50,50 :S

    Kann man das noch ändern?

    Mfg Ghostleader

    • Offizieller Beitrag

    Naja, das passiert, weil AutoIt die Prozentzahlen nicht als Zahlen behandelt, sondern als Strings (diese werden von links nach rechts in ihrer Wertigkeit sortiert).
    Prog@ndy hat mal ein NaturalArraySort geschrieben. Wenn man das in die ListView-Sortierung einbaut, dann werden auch Prozentzahlen richtig sortiert:

    Spoiler anzeigen
    [autoit]


    #include <ListViewConstants.au3>
    #include <GuiConstantsEx.au3>
    #include <GuiListView.au3>

    [/autoit] [autoit][/autoit] [autoit]

    GUICreate("ListView SimpleSort Natural", 400, 300)
    $hListView = GUICtrlCreateListView("col1|col2|col3", 2, 2, 394, 268)
    GUICtrlSendMsg($hListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
    GUICtrlSendMsg($hListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
    GUICtrlCreateListViewItem("line4|5%|more_a", $hListView)
    GUICtrlCreateListViewItem("line5|75% |more_c", $hListView)
    GUICtrlCreateListViewItem("line5|49% |more_c", $hListView)
    GUICtrlCreateListViewItem("line3|23%|more_e", $hListView)
    GUICtrlCreateListViewItem("line2|55% |more_d", $hListView)
    GUICtrlCreateListViewItem("line1|60% |more_b", $hListView)
    GUICtrlCreateListViewItem("line1|98% |more_b", $hListView)
    GUICtrlCreateListViewItem("line1|3%|more_b", $hListView)
    _GUICtrlListView_SetColumnWidth($hListView, 0, 75)
    _GUICtrlListView_SetColumnWidth($hListView, 1, 75)
    _GUICtrlListView_SetColumnWidth($hListView, 2, 75)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    Global $B_DESCENDING[_GUICtrlListView_GetColumnCount($hListView)]
    _GUICtrlListView_SimpleSortNatural($hListView, $B_DESCENDING, 1) ; 3ter Parameter ist Spalten-Index, Nullbasiert

    [/autoit] [autoit][/autoit] [autoit]

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _GUICtrlListView_SimpleSortNatural($hWnd, ByRef $vSortSense, $iCol, $bToggleSense = True)
    Local $iItemCount = _GUICtrlListView_GetItemCount($hWnd)
    If $iItemCount Then
    Local $iDescending = 0
    If UBound($vSortSense) Then
    $iDescending = $vSortSense[$iCol]
    Else
    $iDescending = $vSortSense
    EndIf
    Local $vSeparatorChar = Opt('GUIDataSeparatorChar')
    Local $iColumnCount = _GUICtrlListView_GetColumnCount($hWnd)
    Local Enum $iIndexValue = $iColumnCount, $iItemParam ; Additional columns for the index value and ItemParam
    Local $aListViewItems[$iItemCount][$iColumnCount + 2]

    [/autoit] [autoit][/autoit] [autoit]

    Local $aSelectedItems = StringSplit(_GUICtrlListView_GetSelectedIndices($hWnd), $vSeparatorChar)
    Local $aCheckedItems = __GUICtrlListView_GetCheckedIndices($hWnd)
    Local $sItemText, $iFocused = -1
    For $i = 0 To $iItemCount - 1 ; Rows
    If $iFocused = -1 Then
    If _GUICtrlListView_GetItemFocused($hWnd, $i) Then $iFocused = $i
    EndIf
    _GUICtrlListView_SetItemSelected($hWnd, $i, False)
    _GUICtrlListView_SetItemChecked($hWnd, $i, False)
    For $j = 0 To $iColumnCount - 1 ; Columns
    $sItemText = StringStripWS(_GUICtrlListView_GetItemText($hWnd, $i, $j), $STR_STRIPTRAILING)
    If (StringIsFloat($sItemText) Or StringIsInt($sItemText)) Then
    $aListViewItems[$i][$j] = Number($sItemText)
    Else
    $aListViewItems[$i][$j] = $sItemText
    EndIf
    Next
    $aListViewItems[$i][$iIndexValue] = $i ; Index value
    $aListViewItems[$i][$iItemParam] = _GUICtrlListView_GetItemParam($hWnd, $i) ; ItemParam
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ; Sort the ListView array
    _ArrayNaturalSort($aListViewItems, $iDescending, 0, 0, $iCol)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To $iItemCount - 1 ; Rows
    For $j = 0 To $iColumnCount - 1 ; Columns
    _GUICtrlListView_SetItemText($hWnd, $i, $aListViewItems[$i][$j], $j)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    _GUICtrlListView_SetItemParam($hWnd, $i, $aListViewItems[$i][$iItemParam]) ; ItemParam

    [/autoit] [autoit][/autoit] [autoit]

    For $j = 1 To $aSelectedItems[0]
    If $aListViewItems[$i][$iIndexValue] = $aSelectedItems[$j] Then
    If $aListViewItems[$i][$iIndexValue] = $iFocused Then
    _GUICtrlListView_SetItemSelected($hWnd, $i, True, True)
    Else
    _GUICtrlListView_SetItemSelected($hWnd, $i, True)
    EndIf
    ExitLoop
    EndIf
    Next
    For $j = 1 To $aCheckedItems[0]
    If $aListViewItems[$i][$iIndexValue] = $aCheckedItems[$j] Then
    _GUICtrlListView_SetItemChecked($hWnd, $i, True)
    ExitLoop
    EndIf
    Next
    Next
    If $bToggleSense Then ; Automatic sort sense toggle
    If UBound($vSortSense) Then
    $vSortSense[$iCol] = Not $iDescending
    Else
    $vSortSense = Not $iDescending
    EndIf
    EndIf
    EndIf
    EndFunc ;==>_GUICtrlListView_SimpleSortNatural

    [/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ;===============================================================================
    ;
    ; Name...........: _NaturalCompare
    ; Description ...: Compare two strings using Natural (Alphabetical) sorting.
    ; Syntax.........: _NaturalCompare($s1, $s2, $iCase = 0)
    ; Parameters ....: $s1, $s2 - Strings to compare
    ; $iCase - Case sensitive or insensitive comparison
    ; |0 - Case insensitive (default)
    ; |1 - Case sensitive
    ; Return values .: Success - One of the following:
    ; |0 - Strings are equal
    ; |-1 - $s1 comes before $s2
    ; |1 - $s1 goes after $s2
    ; Failure - Returns -2 and Sets @Error:
    ; |1 - $s1 or $s2 is not a string
    ; |2 - $iCase is invalid
    ; Author ........: Erik Pilsits
    ; Modified.......:
    ; Remarks .......: Original algorithm by Dave Koelle
    ; Related .......: StringCompare
    ; Link ..........: http://www.davekoelle.com/alphanum.html
    ; Example .......: Yes
    ;
    ; ;==========================================================================================
    Func _NaturalCompare($s1, $s2, $iCase = 0)
    If (Not IsString($s1)) Or (Not IsString($s2)) Then Return SetError(1, 0, -2)
    If $iCase <> 0 And $iCase <> 1 Then Return SetError(2, 0, -2)

    [/autoit] [autoit][/autoit] [autoit]

    Local $n = 0, $iLen = 1
    Local $s1chunk, $s2chunk

    [/autoit] [autoit][/autoit] [autoit]

    While $n == 0 ; get next chunk
    ; STRING 1
    $iLen = 1
    If StringIsDigit(StringLeft($s1, 1)) Then
    ; chunk of digits
    For $i = 2 To StringLen($s1)
    If StringIsDigit(StringMid($s1, $i, 1)) Then
    $iLen += 1
    Else
    ExitLoop
    EndIf
    Next
    Else
    ; chunk of letters
    For $i = 2 To StringLen($s1)
    If Not StringIsDigit(StringMid($s1, $i, 1)) Then
    $iLen += 1
    Else
    ExitLoop
    EndIf
    Next
    EndIf
    $s1chunk = StringLeft($s1, $iLen)

    [/autoit] [autoit][/autoit] [autoit]

    ; STRING 2
    $iLen = 1
    If StringIsDigit(StringLeft($s2, 1)) Then
    ; chunk of digits
    For $i = 2 To StringLen($s2)
    If StringIsDigit(StringMid($s2, $i, 1)) Then
    $iLen += 1
    Else
    ExitLoop
    EndIf
    Next
    Else
    ; chunk of letters
    For $i = 2 To StringLen($s2)
    If Not StringIsDigit(StringMid($s2, $i, 1)) Then
    $iLen += 1
    Else
    ExitLoop
    EndIf
    Next
    EndIf
    $s2chunk = StringLeft($s2, $iLen)

    [/autoit] [autoit][/autoit] [autoit]

    ; ran out of chunks, strings are the same, return 0
    If $s1chunk == "" And $s2chunk == "" Then Return 0

    [/autoit] [autoit][/autoit] [autoit]

    ; remove chunks from strings
    $s1 = StringMid($s1, StringLen($s1chunk) + 1)
    $s2 = StringMid($s2, StringLen($s2chunk) + 1)

    [/autoit] [autoit][/autoit] [autoit]

    ; Case 1: both chunks contain letters
    If (Not StringIsDigit($s1chunk)) And (Not StringIsDigit($s2chunk)) Then
    $n = StringCompare($s1chunk, $s2chunk, $iCase)
    Else
    ; Case 2: both chunks contain numbers
    If StringIsDigit($s1chunk) And StringIsDigit($s2chunk) Then
    Local $i1chunk = Int($s1chunk)
    Local $i2chunk = Int($s2chunk)
    If $i1chunk > $i2chunk Then
    Return 1
    ElseIf $i1chunk < $i2chunk Then
    Return -1
    EndIf
    Else
    ; Case 3: one chunk has letters, the other has numbers; or one is empty
    ; if we get here, this should be the last and deciding test, so return the result
    Return StringCompare($s1chunk, $s2chunk, $iCase)
    EndIf
    EndIf
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Return $n
    EndFunc ;==>_NaturalCompare

    [/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ArrayNaturalSort
    ; Description ...: Sort a 1D or 2D array on a specific index using the quicksort/insertionsort algorithms.
    ; Syntax.........: _ArrayNaturalSort(ByRef $avArray[, $iDescending = 0[, $iStart = 0[, $iEnd = 0[, $iSubItem = 0]]]])
    ; Parameters ....: $avArray - Array to sort
    ; $iDescending - [optional] If set to 1, sort descendingly
    ; $iStart - [optional] Index of array to start sorting at
    ; $iEnd - [optional] Index of array to stop sorting at
    ; $iSubItem - [optional] Sub-index to sort on in 2D arrays
    ; Return values .: Success - 1
    ; Failure - 0, sets @error:
    ; |1 - $avArray is not an array
    ; |2 - $iStart is greater than $iEnd
    ; |3 - $iSubItem is greater than subitem count
    ; |4 - $avArray has too many dimensions
    ; Author ........: Jos van der Zande <jdeb at autoitscript dot com>
    ; Modified.......: LazyCoder - added $iSubItem option, Tylo - implemented stable QuickSort algo, Jos van der Zande - changed logic to correctly Sort arrays with mixed Values and Strings, Ultima - major optimization, code cleanup, removed $i_Dim parameter
    ; Prog@ndy - natural sort
    ; Remarks .......:
    ; Related .......:
    ; Link ..........;
    ; Example .......; Yes
    ; ===============================================================================================================================
    Func _ArrayNaturalSort(ByRef $avArray, $iDescending = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0)
    If Not IsArray($avArray) Then Return SetError(1, 0, 0)

    [/autoit] [autoit][/autoit] [autoit]

    Local $iUBound = UBound($avArray) - 1

    [/autoit] [autoit][/autoit] [autoit]

    ; Bounds checking
    If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound
    If $iStart < 0 Then $iStart = 0
    If $iStart > $iEnd Then Return SetError(2, 0, 0)

    [/autoit] [autoit][/autoit] [autoit]

    ; Sort
    Switch UBound($avArray, 0)
    Case 1
    __ArrayNaturalQuickSort1D($avArray, $iStart, $iEnd)
    If $iDescending Then _ArrayReverse($avArray, $iStart, $iEnd)
    Case 2
    Local $iSubMax = UBound($avArray, 2) - 1
    If $iSubItem > $iSubMax Then Return SetError(3, 0, 0)

    [/autoit] [autoit][/autoit] [autoit]

    If $iDescending Then
    $iDescending = -1
    Else
    $iDescending = 1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    __ArrayNaturalQuickSort2D($avArray, $iDescending, $iStart, $iEnd, $iSubItem, $iSubMax)
    Case Else
    Return SetError(4, 0, 0)
    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    Return 1
    EndFunc ;==>_ArrayNaturalSort

    [/autoit] [autoit][/autoit] [autoit]

    ; #INTERNAL_USE_ONLY#============================================================================================================
    ; Name...........: __ArrayNaturalQuickSort1D
    ; Description ...: Helper function for sorting 1D arrays
    ; Syntax.........: __ArrayNaturalQuickSort1D(ByRef $avArray, ByRef $iStart, ByRef $iEnd)
    ; Parameters ....: $avArray - Array to sort
    ; $iStart - Index of array to start sorting at
    ; $iEnd - Index of array to stop sorting at
    ; Return values .: None
    ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima
    ; Modified.......: Prog@ndy - natural sort
    ; Remarks .......: For Internal Use Only
    ; Related .......:
    ; Link ..........;
    ; Example .......;
    ; ===============================================================================================================================
    Func __ArrayNaturalQuickSort1D(ByRef $avArray, ByRef $iStart, ByRef $iEnd)
    If $iEnd <= $iStart Then Return

    [/autoit] [autoit][/autoit] [autoit]

    Local $vTmp

    [/autoit] [autoit][/autoit] [autoit]

    ; InsertionSort (faster for smaller segments)
    If ($iEnd - $iStart) < 15 Then
    Local $i, $j, $vCur
    For $i = $iStart + 1 To $iEnd
    $vTmp = $avArray[$i]

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    For $j = $i - 1 To $iStart Step -1
    If (_NaturalCompare($vTmp, $avArray[$j], 1) >= 0) Then ExitLoop
    $avArray[$j + 1] = $avArray[$j]
    Next

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $avArray[$j + 1] = $vTmp
    Next
    Return
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; QuickSort
    Local $L = $iStart, $R = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)]
    Do
    While (_NaturalCompare($avArray[$L], $vPivot, 1) < 0)
    $L += 1
    WEnd
    While (_NaturalCompare($avArray[$R], $vPivot, 1) > 0)
    $R -= 1
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    ; Swap
    If $L <= $R Then
    $vTmp = $avArray[$L]
    $avArray[$L] = $avArray[$R]
    $avArray[$R] = $vTmp
    $L += 1
    $R -= 1
    EndIf
    Until $L > $R

    [/autoit] [autoit][/autoit] [autoit]

    __ArrayNaturalQuickSort1D($avArray, $iStart, $R)
    __ArrayNaturalQuickSort1D($avArray, $L, $iEnd)
    EndFunc ;==>__ArrayNaturalQuickSort1D

    [/autoit] [autoit][/autoit] [autoit]

    ; #INTERNAL_USE_ONLY#============================================================================================================
    ; Name...........: __ArrayNaturalQuickSort2D
    ; Description ...: Helper function for sorting 2D arrays
    ; Syntax.........: __ArrayNaturalQuickSort2D(ByRef $avArray, ByRef $iStep, ByRef $iStart, ByRef $iEnd, ByRef $iSubItem, ByRef $iSubMax)
    ; Parameters ....: $avArray - Array to sort
    ; $iStep - Step size (should be 1 to sort ascending, -1 to sort descending!)
    ; $iStart - Index of array to start sorting at
    ; $iEnd - Index of array to stop sorting at
    ; $iSubItem - Sub-index to sort on in 2D arrays
    ; $iSubMax - Maximum sub-index that array has
    ; Return values .: None
    ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima
    ; Modified.......: Prog@ndy - natural sort
    ; Remarks .......: For Internal Use Only
    ; Related .......:
    ; Link ..........;
    ; Example .......;
    ; ===============================================================================================================================
    Func __ArrayNaturalQuickSort2D(ByRef $avArray, ByRef $iStep, ByRef $iStart, ByRef $iEnd, ByRef $iSubItem, ByRef $iSubMax)
    If $iEnd <= $iStart Then Return

    [/autoit] [autoit][/autoit] [autoit]

    ; QuickSort
    Local $i, $vTmp, $L = $iStart, $R = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)][$iSubItem]
    Do

    [/autoit] [autoit][/autoit] [autoit]

    While ($iStep * _NaturalCompare($avArray[$L][$iSubItem], $vPivot, 1) < 0)
    $L += 1
    WEnd
    While ($iStep * _NaturalCompare($avArray[$R][$iSubItem], $vPivot, 1) > 0)
    $R -= 1
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    ; Swap
    If $L <= $R Then
    For $i = 0 To $iSubMax
    $vTmp = $avArray[$L][$i]
    $avArray[$L][$i] = $avArray[$R][$i]
    $avArray[$R][$i] = $vTmp
    Next
    $L += 1
    $R -= 1
    EndIf
    Until $L > $R

    [/autoit] [autoit][/autoit] [autoit]

    __ArrayNaturalQuickSort2D($avArray, $iStep, $iStart, $R, $iSubItem, $iSubMax)
    __ArrayNaturalQuickSort2D($avArray, $iStep, $L, $iEnd, $iSubItem, $iSubMax)
    EndFunc ;==>__ArrayNaturalQuickSort2D

    [/autoit]
    • Offizieller Beitrag

    Hm,
    theoretisch klar, aber kannst du mal ein Bsp zeigen wie man dann die Sortierrichtung von mehreren Spalten angibt?
    Und wenn man im Parameter 2 bereits die Richtung je Spalte angegeben hat, warum muss man dann noch im Parameter 3 eine Spalte angeben?
    Sorry aber steh gerade auf dem Schlauch


    Die Sortierrichtung gibtst du vor, wenn du z.B. bei Sortierung nach erster Spalte (Index 0) aufwärts sortieren willst, bei Sortierung nach zweiter Spalte (Index 1) abwärts sortieren willst. Gibst du dann den Sortierbefehl mit Angabe der jeweiligen Spalte, wird die vordefinierte Sortierrichtung für die Spalte verwendet. Wenn du nicht togglest, ist die Sortierrichtung ja fix. Und über die vordefinierte Richtung kannst du das in jeder Spalte einzeln definieren.

    Hier wird bei Spaltenklick die vordefinierte Sortierrichtung aktiv:

    Spoiler anzeigen
    [autoit]

    #include <WindowsConstants.au3>
    #include <ListViewConstants.au3>
    #include <GuiConstantsEx.au3>
    #include <GuiListView.au3>

    [/autoit] [autoit][/autoit] [autoit]

    GUICreate("ListView SimpleSort by Column Click", 400, 300)
    $hListView = GUICtrlCreateListView("col1|col2|col3", 2, 2, 394, 268)
    GUICtrlSendMsg($hListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
    GUICtrlSendMsg($hListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
    GUICtrlCreateListViewItem("line4|5|more_a", $hListView)
    GUICtrlCreateListViewItem("line5|4.50 |more_c", $hListView)
    GUICtrlCreateListViewItem("line5|4.0 |more_c", $hListView)
    GUICtrlCreateListViewItem("line3|23|more_e", $hListView)
    GUICtrlCreateListViewItem("line2|0.34560 |more_d", $hListView)
    GUICtrlCreateListViewItem("line1|1.0 |more_b", $hListView)
    GUICtrlCreateListViewItem("line1|0.1 |more_b", $hListView)
    GUICtrlCreateListViewItem("line1|10|more_b", $hListView)
    _GUICtrlListView_SetColumnWidth($hListView, 0, 75)
    _GUICtrlListView_SetColumnWidth($hListView, 1, 75)
    _GUICtrlListView_SetColumnWidth($hListView, 2, 75)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
    Global $B_DESCENDING[3] = [True,True,False] ; ==> ab,ab,auf

    [/autoit] [autoit][/autoit] [autoit]

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)

    [/autoit] [autoit][/autoit] [autoit]

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    If ($hWndFrom = $hWndListView) And ($iCode = $LVN_COLUMNCLICK) Then
    $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
    _GUICtrlListView_SimpleSort($hWndListView, $B_DESCENDING, DllStructGetData($tInfo, "SubItem"), False) ; kein Toggle
    EndIf
    EndFunc ;==>WM_NOTIFY

    [/autoit]