[AutoIt] ListView nach mehreren Kriterien sortieren

02/25/2011 19:47 Endtothenight#1
Hi zusammen,
für mein aktuelles Projekt ist es nötig, dass ich ein ListView nach mehreren Kriterien sortiere, also mit verschiedenen Prioritäten. Das ganze sieht in etwa wie eine Bundesligatabelle aus.

Prioritäten: Punkte > Tordifferenz > geschossene Tore

Ich hab das jetzt mal mit den folgenden Codeschnippseln probiert:
PHP Code:
Global $B_DESCENDING[_GUICtrlListView_GetColumnCount($db_zs4)]
_GUICtrlListView_SimpleSort($db_zs4 ,$B_DESCENDING 10
Wie ihr jetzt wahrscheinlich merkt bedeuten die Variablen folgendes:
PHP Code:
$db_zs4 //- Datenbank/Listview mit den Werten
$B_DESCENDING //- Das habe ich selbst nicht ganz verstanden, soll aber angeblich vom höchtsen zum tiefsten Wert sortieren, machts aber genau anderesherum
10 //- Spalte mit den Punkten
//- Spalte mit der TDifferenz
//- Spalte mit den geschossenen Toren 
Ich habe nun mehrere Probleme, mit denen ich etwas überfragt bin:
1. Wie bringe ich den dazu, dass der größte Wert oben steht
2. Wie erkläre ich dem das mit den Prioritäten?


Ich hoffe ihr könnt mir da etwas weiterhelfen :)

Vielen Dank im Vorraus
02/25/2011 19:50 PenGuin :O#2
Wenn du deinen Befehl _GUICtrlListView_SimpleSort in den Editor eingibst, den Befehl markierst und F1 drückst, kommst du zur Hilfe mit einem Beispiel.
Lies bitte zuerst das, und falls noch Fragen offen sind, kannst du dich gerne wieder melden ;)

PS:
Falls du Englisch nicht gut verstehst, kannst du dir auf [Only registered and activated users can see links. Click Here To Register...] die deutsche Hilfedatei auf der linken Seite downloaden.
02/25/2011 19:55 Endtothenight#3
Das habe ich bereits getan, sonst wär ich auch garnicht auf diese Funktion gekommen, nur verstehe ich noch nicht ganz wie ich das mit dem Aufsteigend/Absteigend zu verstehen habe. Dort steht in der Hilfe, dass man da entweder True , False oder einen Array angeben kann. bei True und Fals meckert er, das ihm das nicht reicht, daher habe ich gegoogelt und das mit dem "$B_DESCENDING[_GUICtrlListView_GetColumnCount($db_zs4)]" hab ich dort gefunden. Was man jetzt genau mit dem Array erreichen kann habe ich wiederum nicht verstanden...
02/25/2011 21:23 PenGuin :O#4
Hab mal eben ne eigene Funktion für dich geschrieben, die nach Column Klick sortiert:

Code:
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>

$hGUI = GUICreate("Beispiel", 226, 155, 192, 124)
$hList = GUICtrlCreateListView("Column 1|Column 2", 8, 8, 209, 89)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 100)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 100)
GUISetState()

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

For $i = 1 To 3
	GUICtrlCreateListViewItem("Item " & $i & "|" & $i, $hList)
Next

Do
	Sleep(50)
Until GUIGetMsg() = -3

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg, $wParam
	$hLV = $hList
	If Not IsHWnd($hList) Then $hLV = GUICtrlGetHandle($hList)

	$tNMHDR = DllStructCreate($tagNMHDR, $lParam)
	$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
	$iCode = DllStructGetData($tNMHDR, "Code")

	Switch $hWndFrom
		Case $hLV
			If $iCode = $LVN_COLUMNCLICK Then
				$tInfo = DllStructCreate($tagNMLISTVIEW, $lParam)
				_SortColumn($hLV, 1, DllStructGetData($tInfo, "SubItem"))
			EndIf
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc


Func _SortColumn($hWnd, $iSort, $iColumn)
	; PenGuin :O
	;iSort:
	;0 Ascend    1 Descend
	If Not IsHwnd($hWnd) Then Return SetError(-1)
	If Not IsInt($iSort) Then Return SetError(-2)
	If Not IsInt($iColumn) Then Return SetError(-3)
	Local $iItems = _GUICtrlListView_GetItemCount($hWnd)
	Local $aItems[$iItems]
	For $i = 0 To $iItems - 1
		$aItems[$i] = _GUICtrlListView_GetItemText($hWnd, $i, $iColumn)
	Next
	_ArraySort($aItems, $iSort)
	For $i = 0 To UBound($aItems) - 1
		_GUICtrlListView_SetItemText($hWnd, $i, $aItems[$i], $iColumn)
	Next
	Return 1
EndFunc
Falls noch Fragen bestehen, einfach fragen ;)
02/26/2011 12:01 Endtothenight#5
Hi,

@Penguin: Deine Lösung sortiert leider nur eine Spalte ;) Damit kommeich nicht ganz weit^^

Naja, ich hab mich gestern nochmal ne stunde hingesetzt und das ganze mit BubbleSort gelöst. Ist zwar wahrscheinlich etwas zu kompliziert geschrieben und ich hätte es irgendwo abkürzen können, aber es läuft ohne Probleme :)

Hier der Code:


Vlt kann das ja mal jemand irgendwo gebrauchen ;)

Danke für eure/deine Hilfe!

MfG,

Morris
02/26/2011 14:44 PenGuin :O#6
Ach du wolltest bei einem Klick alle Spalten sortieren?
Ja dann geht das ganz leicht :D

Moment.

Code:
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>

$bDescend = True

$hGUI = GUICreate("Beispiel", 226, 155, 192, 124)
$hList = GUICtrlCreateListView("Column 1|Column 2", 8, 8, 209, 89)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 100)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 100)
GUISetState()

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

For $i = 1 To 3
	GUICtrlCreateListViewItem("Item " & $i & "|" & $i, $hList)
Next

Do
	Sleep(50)
Until GUIGetMsg() = -3

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg, $wParam
	$hLV = $hList
	If Not IsHWnd($hList) Then $hLV = GUICtrlGetHandle($hList)

	$tNMHDR = DllStructCreate($tagNMHDR, $lParam)
	$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
	$iCode = DllStructGetData($tNMHDR, "Code")

	Switch $hWndFrom
		Case $hLV
			If $iCode = $LVN_COLUMNCLICK Then
				$tInfo = DllStructCreate($tagNMLISTVIEW, $lParam)	
                                    _GUICtrlListView_SimpleSort($hLV, $bDescend, DllStructGetData($tInfo, "SubItem"))
			EndIf
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc
02/26/2011 16:56 Endtothenight#7
Ich bleib aber doch bei meiner Variante, da verstehe ich was passiert ;)
02/26/2011 17:44 PenGuin :O#8
Das einzige Problem war, dass du an SimpleSort zwar False oder True übergeben kannst, aber nicht als einfacher Wert, da der 2. Parameter eine Variable erwartet (ByRef) deshalb einfach True/False in Variable ablegen und damit callen.

Und WM_Notify erkennt einfach nur, ob nun auf eine Column geklickt wurde.