Rubrik: Controls · ListView | VB-Versionen: VB6 | 10.02.03 |
MultiSort im ListView-Control Dieses Beispiel zeigt, wie sich verschiedene Sortierfunktionen für ein ListView Control realisieren lassen. | ||
Autor: Roland Wutzke | Bewertung: | Views: 19.685 |
www.vb-power.net | System: Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt auf CD |
Sie sind dabei, einen eigenen Dateidialog oder Kunden- und Artikelverwaltung zu proggen und nutzen dazu das Listview Control. Jetzt sollen die Spalten nach verschiedenen Kriterien sortiert werden. Ein Nachteil des Listview Controls ist, dass es nur alphanumerisch sortieren kann. Doch was ist, wenn Sie es nach Datum, Zeit oder Zahl sortieren wollen?
Das nachfolgende Modul basiert auf den Tipp:
Numerische Sortierung im ListView-Control
Folgende Sortierroutinen wurden ergänzt und stehen zur Verfügung:
- SortText: Standard(Text)
- SortNumeric: Numerisch(Zahl)
- SortDate: Datum(dd.mm.yyyy)
- SortHHMM: Zeit(hh:mm)
- SortHHMMSS: Zeit(hh:mm:ss)
- SortFileDateTime: VB FileDateTime(dd.mm.yyyy hh:mm:ss)
Anmerkung: Die Sortierung "SortHHMM" und "SortHHMMSS" sind nur dann nötig, wenn die zu sortierende Zeit nicht dem Standard Format "hh:mm" oder "hh:mm:ss" entspricht.
Nachfolgenden Code bitte in ein MODUL einfügen:
Option Explicit ' **************************************************** ' * * ' * Modul MultiSort-ListView * ' * * ' * Sortiert ein Listview nach Standard Text, * ' * Numerisch, Datum(DD.MM.YYYY), Zeit(HH:MM), * ' * Zeit(HH:MM:SS) und nach der VB Function * ' * FileDateTime(DD.MM.YYYY HH:MM:SS). * ' * * ' * Basis dieses Moduls ist der Tipp in VB@rchiv * ' * "Numerische Sortierung im ListView-Control" * ' * von Michael Hartmann. * ' * Erweiterung der Sort-Funktionen * ' * von Roland Wutzke, Februar 2003. * ' * * ' **************************************************** Private Declare Function LockWindowUpdate Lib "user32.dll" ( _ ByVal hWnd As Long) As Long Public Enum lvwSortType SortText = 0 SortNumeric = 1 SortDate = 2 SortHHMM = 3 SortHHMMSS = 4 SortFileDateTime = 5 End Enum
Public Sub MultiSortListView(ByVal Index As Integer, _ ByVal CurrentListView As ListView, _ Optional vSortType As lvwSortType = SortText) Dim I As Integer Dim strFormat As String Dim strData() As String Dim lRet As Long On Error GoTo ErrorHandler ' Benutzerdefinierter Formatstring für die ' Format-Funktion ermitteln. Select Case vSortType ' Wenn vSortType = SortText, Standard Sortierung ' nach String erzwingen und die Sub verlassen. Case SortText With CurrentListView .SortKey = Index .Sorted = True .SortOrder = 1 - .SortOrder Exit Sub End With ' Formatstring für numerische Sortierung setzen Case SortNumeric strFormat = String(30, "0") & "." & String(30, "0") ' Formatstring für Sortierung nach Datum setzen Case SortDate strFormat = String(2, "0") & "." & String(2, "0") & "." & String(4, "0") ' Formatstring für Sortierung nach Zeit HHMM setzen Case SortHHMM strFormat = "hh:mm" ' Formatstring für Sortierung nach Zeit HHMMSS setzen Case SortHHMMSS strFormat = "hh:mm:ss" ' Formatstring für Sortierung nach FileDateTime setzen Case SortFileDateTime strFormat = String(2, "0") & "." & String(2, "0") & "." & String(4, "0") strFormat = strFormat & " " & "hh:mm:ss" ' Falscher, bzw. ungültiger SortType, dann Sub verlassen Case Else Exit Sub End Select ' Automatische Aktualisierung des Fensters sperren lRet = LockWindowUpdate(CurrentListView.Parent.hWnd) If lRet = 0& Then Call MsgBox("Can't lock window " & _ CurrentListView.Parent.hWnd, _ vbOKOnly + vbCritical) Exit Sub End If With CurrentListView With .ListItems If (Index > 0) Then ' Sortierung nach Subitems For I = 1 To .Count With .Item(I).ListSubItems(Index) ' Sichern des aktuellen Wertes der ' Text-Eigenschaft in der Tag-Eigenschaft, ' ohne einen evtl. Inhalt der Tag-Eigenschaft ' zu überschreiben .Tag = .Text & vbNullChar & .Tag Select Case vSortType Case SortNumeric ' Falls die Text-Eigenschaft der SubItems ' eine Zahl ist, so formatiere mit dem oben ' definierten Formatstring. If IsNumeric(.Text) Then .Text = Format$(CDbl(.Text), strFormat) End If Case SortDate ' Falls die Text-Eigenschaft der SubItems ' ein Datum ist, so formatiere mit dem oben ' definierten Formatstring. If IsDate(.Text) Then .Text = Format$(CDate(.Text), strFormat) End If Case SortHHMM ' Falls die Text-Eigenschaft der SubItems ' Zeit HH:MM ist, so formatiere mit dem oben ' definierten Formatstring. .Text = Format$(.Text, strFormat) Case SortHHMMSS ' Falls die Text-Eigenschaft der SubItems ' Zeit HH:MM:SS ist, so formatiere mit dem oben ' definierten Formatstring. .Text = Format$(.Text, strFormat) Case SortFileDateTime ' Falls die Text-Eigenschaft der SubItems ' VB FileDateTime ist, so formatiere mit dem oben ' definierten Formatstring. .Text = Format$(.Text, strFormat) End Select End With Next I Else ' Sortierung nach Mainitem For I = 1 To .Count With .Item(I) ' Sichern des aktuellen Wertes der ' Text-Eigenschaft in der Tag-Eigenschaft, ' ohne einen evtl. Inhalt der Tag-Eigenschaft ' zu überschreiben .Tag = .Text & vbNullChar & .Tag Select Case vSortType Case SortNumeric ' Falls die Text-Eigenschaft der SubItems ' eine Zahl ist, so formatiere mit dem oben ' definierten Formatstring. If IsNumeric(.Text) Then .Text = Format$(CDbl(.Text), strFormat) End If Case SortDate ' Falls die Text-Eigenschaft der SubItems ' ein Datum ist, so formatiere mit dem oben ' definierten Formatstring. If IsDate(.Text) Then .Text = Format$(CDate(.Text), strFormat) End If Case SortHHMM ' Falls die Text-Eigenschaft der SubItems ' Zeit HH:MM ist, so formatiere mit dem oben ' definierten Formatstring. .Text = Format$(.Text, strFormat) Case SortHHMMSS ' Falls die Text-Eigenschaft der SubItems ' Zeit HH:MM:SS ist, so formatiere mit dem oben ' definierten Formatstring. .Text = Format$(.Text, strFormat) Case SortFileDateTime ' Falls die Text-Eigenschaft der SubItems ' VB FileDateTime ist, so formatiere mit dem oben ' definierten Formatstring. .Text = Format$(.Text, strFormat) End Select End With Next I End If End With ' Sortiere die umformatierten Spalten neu .SortKey = Index .Sorted = True .SortOrder = 1 - .SortOrder With .ListItems If (Index > 0) Then ' Sortierung nach SubItem For I = 1 To .Count With .Item(I).ListSubItems(Index) ' Extrahiere den ursprünglichen Inhalt des ' Subitems aus der Tag Eingeschaft und ' stelle ihn wieder in die Text-Eigenschaft ' ein. strData = Split(.Tag, vbNullChar) .Text = strData(0) .Tag = strData(1) End With Next I Else ' Sortierung nach MainItem For I = 1 To .Count With .Item(I) ' Extrahiere den ursprünglichen Inhalt des ' Subitems aus der Tag Eingeschaft und ' stelle ihn wieder in die Text-Eigenschaft ' ein. strData = Split(.Tag, vbNullChar) .Text = strData(0) .Tag = strData(1) End With Next I End If End With End With ' Aufheben der Aktualisierungssperre für das Fenster lRet = LockWindowUpdate(0&) Exit Sub ErrorHandler: lRet = LockWindowUpdate(0&) Call MsgBox("Runtime error " & Err.Number & ": " & _ vbCrLf & Err.Description, vbOKOnly + vbCritical) End Sub
Beispiel:
Sie haben ein Listview mit den Spalten "Datei", "Datum" und "Größe", die durch Dir() gefüllt werden. Durch Klicken auf den Spaltenheader soll Auf- und Ab Sortiert werden. Die Funktion kann im ColumnHeader_Click Ereignis aufgerufen werden:
Private Sub ListView1_ColumnClick( _ ByVal ColumnHeader As MSComctlLib.ColumnHeader) Dim nIndex As Long nIndex = ColumnHeader.Index - 1 With ListView1 Select Case ColumnHeader ' Sortieren nach Text Case "Datei" MultiSortListView nIndex, ListView1 ' Sortieren nach FileDateTime Case "Datum" MultiSortListView nIndex, ListView1, SortFileDateTime ' Sortieren nach Zahl Case "Größe" MultiSortListView nIndex, ListView1, SortNumeric End Select End With End Sub