Listbox in Access per Mausklick sortieren
01. Juni 2008 von Werner Mager · Gelesen: 3634 · heute: 1Das man Listboxen und GridViews mit einem Mausklick auf die Kopfzeilen sortieren kann, ist mittlerweile in fast allen Programmen Standard - leider nur in fast allen. Microsoft Access bildet hierbei eine Ausnahme. Das wahrscheinlich beliebteste Programm um “mal eben” schnell eine Datenbank zu erstellen, eine hübsche Oberfläche oder einen Report zu gestalten, bietet diese Funktion von Haus aus nicht. Aber mit ein paar kleinen Tricks kann man diese - eins, zwei, drei - nachrüsten.
Trick eins - Den Klick auf die Kopfzeile erkennen
Um einen Klick auf die Listbox abzufangen, muss das Ereignis “MouseDown” implementiert werden. Hier rufen wir die Funktion “Sortlistbox” auf, die im Folgenden erarbeitet wird:
Private Sub Listbox1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) SortListbox Listbox1, X, Y End Sub
Dabei werden die Koordinaten des Klicks übergeben. Ist Y <=210, so wurde auf die Kopfzeile geklickt (Die Höhe 210 gilt aber nur für die Standard-Schriftart Tahoma mit 8pt, bei anderen Schriftarten ist die Höhe entsprechend zu wählen):
Function SortListbox(lf As ListBox, X As Single, Y As Single) If Y <= 210 Then ' sortieren... End If End Function
Trick zwei - Die geklickte Spalte ermitteln
Nun müssen wir herausfinden, welche Spalte geklickt wurde. Der X-Wert des Klicks ist nun von Bedeutung. Wir verwenden die Eigenschaft “ColumnWidth” der Listbox, die alle Spaltenbreiten als Komma-getrennte Liste enthält. Diese zerlegen wir mit “split” und summieren die Breiten, bis wir den X-Wert erreicht haben:
Function getColumn(X, lf As Object) As Integer Dim columns columns = Split(lf.ColumnWidths, ";") sum = 0 While sum < X And getColumn <= UBound(columns) ' summiere Breite sum = sum + CInt(columns(getColumn )) getColumn = getColumn + 1 Wend End Function
Nun kennen wir die Spalte, die geklickt wurde. Über die Eigenschaft “Header” erhalten wir den Namen der Spalte, was uns ermöglicht, nach dieser zu sortieren. Die Funktion SortListbox sieht nun so aus:
Function SortListbox(lf As ListBox, X As Single, Y As Single) If Y <= 210 Then Column = getColumn(X, lf) header = lf.Column(Column - 1, 0) If Not IsNull(header) Then ' sortiere nach der ermittelten Spalte … End If End If End Function
Trick drei - Die Datenquelle modifizieren
Das eigentliche Sortieren geschieht nun durch Änderung der Rowsource der Listbox. Dies übernimmt die Funktion “reOrder”, die das SQL-Statement der Listbox um die nötigen OrderBy-Anweisungen ergänzt:
Function SortListbox(lf As ListBox, X As Single, Y As Single) If Y <= 210 Then Column = getColumn(X, lf) header = lf.Column(Column - 1, 0) If Not IsNull(header) Then reordered = reOrder(lf.rowsource, header$) lf.rowsource = reordered End If End If End Function Function reOrder(rowsource As String, byWhat As String) ' Leerzeichen entfernen rowsource = Trim(rowsource) ' Falls byWhat einen Alias hat, diesen ermitteln byWhat = getAlias(rowsource, byWhat)‘ Direkte Quelle? If Not (Mid(rowsource, 1, 6) = "select") Then reOrder = "SELECT * from " & rowsource & " ORDER by " & byWhat & ";" Else ' SQl-String? reOrder = removeOrderBy(rowsource) & " ORDER BY " & byWhat & ";" ‘ Beim zweiten Klick absteigend sortieren If (rowsource = reOrder) And InStr(reOrder, "DESC") = 0 Then reOrder = Mid(reOrder, 1, Len(reOrder) - 1) + " DESC;" End If End If End Function
Reorder greift dabei noch auf folgende Funktionen zurück:
Function removeOrderBy(src As String) i = InStr(src, "ORDER BY") If Not (i = 0) Then removeOrderBy = Trim(Mid(src, 1, i - 1)) Exit Function End If If Mid(src, Len(src)) = ";" Then removeOrderBy = Trim(Mid(src, 1, Len(src) - 1)) Exit Function End If removeOrderBy = Trim(src) End Function Function getAlias(sqlstr As String, obj As String) As String ' Suche in String i = InStr(sqlstr, " " + obj) If i = 0 Then i = InStr(sqlstr, "[" + obj) End If If Not (i = 0) Then ' Wenn direkt davor "as [" oder "as " steht… If Trim(Mid(sqlstr, i - 3, 3)) = "as" Then getAlias = lastWord(Mid(sqlstr, 1, i - 4)) Exit Function End If End If ' sonst existiert kein Alias getAlias = "[" & obj & "]" End Function Function lastWord(str As String) As String Dim words words = Split(str, " ") lastWord = words(UBound(words)) End Function
Mit der Funktion SortListbox lässt sich nun jede ListBox in Access mit einer Zeile Code sortierbar machen. Die hier vorgestellten Methoden fügt man am besten als Modul zu dem Access Projekt hinzu.
Download Beispielprojekt und VBA-Modul
Wie immer habe ich das ganze in einem kleinen Beispielprojekt zusammengefasst:
Und für alle, die es kurz und knapp mögen, hier das Modul mit der Funktion sortListbox:
20. Juni 2008 um 21:38
[…] End Sub Das Modul dazu habe ich in meinem Blog beschrieben: Listbox in Access per Mausklick sortieren Viel Spa
25. Januar 2012 um 14:23
Hallo zusammen,
auch wenns schon etwas älter hier ist, hat mir sehr geholfen.
Besten Dank *Daumhoch*