JayN Geschrieben 14. Februar 2007 Teilen Geschrieben 14. Februar 2007 Hallo zusammen, ich habe folgendes Problem. Ich benutze in meiner kleinen Datenbankanwendung unter Access 2000 die Listview 6. Abhängig von einem Status werden die einzelnen Zeilen mit Forecolor verschieden eingefärbt: Sub Faerbung() Dim i, j As Integer Dim status As Integer Dim si As ListSubItem For i = 1 To lstMitgliederX.ListItems.Count status = lstMitgliederX.ListItems(i).ListSubItems(9) If status > 63 Then For j = 1 To 8 Set si = lstMitgliederX.ListItems(i).ListSubItems(j) si.ForeColor = RGB(255, 0, 0) Set si = Nothing Next j End If If status > 3 And status < 64 Then For j = 1 To 8 Set si = lstMitgliederX.ListItems(i).ListSubItems(j) si.ForeColor = RGB(0, 0, 255) Set si = Nothing Next j End If If status < 3 Then For j = 1 To 8 Set si = lstMitgliederX.ListItems(i).ListSubItems(j) si.ForeColor = RGB(0, 0, 0) Set si = Nothing Next j End If Next i End Sub Für die Sortierung nach Spalten benutze ich das Modul dieses Modul: ' ------------ STANDARDMODUL ListViewSort.bas ------------ ' -------------------------------------------------------- ' Copyright (c) 2002 by Mathias Schiffer, AixSoft Software Will jetzt erstmal nicht den ganzen Code posten, evtl. ist das ja bekannt. Mein Problem ist folgendes: Wenn nun die Zeilen verschieden gefärbt sind ist erstmal alles OK, solange ich nicht sortiere. Klicke ich nun jedoch einen Spaltenkopf an, wird die Sortierung wertmäßig richtig durchgeführt, jedoch wird die Forecolor-Formatierung nicht mitsortiert. Soll heißen, im Ursprung ist die Zeile 10 rot gefärbt. Sortiere ich jetzt nach einer Spalte, bleibt diese Zeile rot gefärbt, obwohl der Datensatz nun woanders steht und ein ganz anderer Datensatz an dieser Stelle auftaucht. Kann man das irgendwie fixen? Für eure Hilfe wäre ich sehr dankbar. Gruß JayN Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 14. Februar 2007 Teilen Geschrieben 14. Februar 2007 Ruf doch einfach nach dem Sortieren nochmal Faerbung auf. Du solltest aber noch eine Behandlung für den Fall status = 3 einbauen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
JayN Geschrieben 14. Februar 2007 Autor Teilen Geschrieben 14. Februar 2007 Ruf doch einfach nach dem Sortieren nochmal Faerbung auf. Du solltest aber noch eine Behandlung für den Fall status = 3 einbauen. Auf die Idee bin ich auch schon gekommen, funktioniert aber nicht. Es scheint so, als ob er nach einem festen Index vorgeht, der bei der Sortierung nicht berücksichtigt wird. Einen status = 3 kann es nicht geben. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 14. Februar 2007 Teilen Geschrieben 14. Februar 2007 Auf die Idee bin ich auch schon gekommen, funktioniert aber nicht.Was heißt "funktioniert aber nicht"? Es scheint so, als ob er nach einem festen Index vorgeht, der bei der Sortierung nicht berücksichtigt wird.Wer ist "er"? Wie die Liste sortiert ist, sollte egal sein, weil die Farbe aus dem Wert des Subitem 9 bestimmt wird. Einen status = 3 kann es nicht geben.Kennst du den Spruch mit den sich übergebenden Pferden? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
JayN Geschrieben 14. Februar 2007 Autor Teilen Geschrieben 14. Februar 2007 Was heißt "funktioniert aber nicht"? Es ändert sich nichts an der Färbung. Wer ist "er"? Wie die Liste sortiert ist, sollte egal sein, weil die Farbe aus dem Wert des Subitem 9 bestimmt wird. Interessante Frage. Wer ist "er"... der Anwendungstroll... Na ja, es war die Listview gemeint, denke ich... Wenn ich zur Laufzeit, nach der Sortierung, die Items abfrage, so steht an der 10ten Stelle immer noch das Items, was da vor der Sortierung stand. Die sind im Objekt so indiziert. Wie die Sortierung dabei genau funktioniert, weiß ich nicht. Kennst du den Spruch mit den sich übergebenden Pferden? Klar. Aber ich bin Programmierer und kein Pfuscher. Es gibt insgesamt 3 Stati-Gruppen. Gruppe 1: 1 oder 2 Gruppe 2: 4, 8, 16 oder 32 Gruppe 3: 64 Aus diesen Werten wird der Gesamtstatus ermittelt. Und da kann es keine 3 geben... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 14. Februar 2007 Teilen Geschrieben 14. Februar 2007 Wenn ich zur Laufzeit, nach der Sortierung, die Items abfrage, so steht an der 10ten Stelle immer noch das Items, was da vor der Sortierung stand. Die sind im Objekt so indiziert. Wie die Sortierung dabei genau funktioniert, weiß ich nicht. Kann es sein, dass du Subitem 9 einfach nicht mitsortierst? Mir fällt auch auf, dass du Subitem 9 nicht färbst. Es gibt insgesamt 3 Stati-Gruppen. Gruppe 1: 1 oder 2 Gruppe 2: 4, 8, 16 oder 32 Gruppe 3: 64Das sieht eher nach Flags aus. Sicher, dass die nicht kombinierbar sind? Ansonsten wäre es unsinnig, nicht aufeinanderfolgende Werte zu benutzen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
JayN Geschrieben 14. Februar 2007 Autor Teilen Geschrieben 14. Februar 2007 Kann es sein, dass du Subitem 9 einfach nicht mitsortierst? Mir fällt auch auf, dass du Subitem 9 nicht färbst. Subitem 9 ist mit einer Breite 0 eingebunden, ist also quasi versteckt und dient nur zur Hilfe. Ob das Dingen nun sortiert wird, muss ich überprüfen. Aber wie gesagt. Wenn ich nach der Sortierung die Faerbung anstarte und zur Laufzeit die Items durchgehe, so steht an der zehnten Stelle des gleiche Item, wie vor der Sortierung. Das sieht eher nach Flags aus. Sicher, dass die nicht kombinierbar sind? Ansonsten wäre es unsinnig, nicht aufeinanderfolgende Werte zu benutzen. Unsinnig? Nee, gar nicht unsinnig. Stell Dir mal vor, es wären aufeinanderfolgende Werte. Gruppe 1: 1 oder 2 Gruppe 2: 3,4,5 oder 6 Gruppe 3: 7 Wenn nun ein Status von 5 rauskommt, wie schlüssele ich den wieder auf? Ist es 1 und 4 oder 2 und 5? :confused: Lass uns nicht über den Inhalt, sondern über das eigentliche Problem nachdenken... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 14. Februar 2007 Teilen Geschrieben 14. Februar 2007 Wenn ich nach der Sortierung die Faerbung anstarte und zur Laufzeit die Items durchgehe, so steht an der zehnten Stelle des gleiche Item, wie vor der Sortierung.Deswegen vermute ich, das es nicht mitsortiert wird. Unsinnig? Nee, gar nicht unsinnig. Stell Dir mal vor, es wären aufeinanderfolgende Werte. Gruppe 1: 1 oder 2 Gruppe 2: 3,4,5 oder 6 Gruppe 3: 7 Wenn nun ein Status von 5 rauskommt, wie schlüssele ich den wieder auf? Ist es 1 und 4 oder 2 und 5? :confused:Also sind die Werte kombinierbar, aber aus jeder Gruppe kann nur ein Wert auftauchen? Dann brauchst du nicht alle Wert als Flags zu implementieren, es reicht, wenn du jede Gruppe gegen die anderen Gruppen abgrenzt. Gruppe 1: 0 oder 1 Gruppe 2: 0, 2, 4 oder 6 Gruppe 3: 8 Aber das ist nur eine Platzoptimierung. Lass uns nicht über den Inhalt, sondern über das eigentliche Problem nachdenken... Entschuldige, dass ich versuche, logische Fehler in deinem Programm aufzudecken. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
JayN Geschrieben 14. Februar 2007 Autor Teilen Geschrieben 14. Februar 2007 Deswegen vermute ich, das es nicht mitsortiert wird. Wenn ich die anderen Subitems des Items durchgehe, so sind da auch immer noch die gleichen Werte drin. Nochmal zur Verdeutlichung, aber etwas abgekürzt: USER ORT STATUS(versteckt) JNeudorf Bielefeld 65 Klotzkopp Essen 9 Wenn ich jetzt nach User DESC sortiere, so bleibt die erste Zeile rot. Wenn in Faerbung() des erste Item (nach der Sortierung) abgefragt wird, so ist lstMitgliederX.ListItems(1).SubItems(1) = "JNeudorf". Bei der Sortierung wähle ich keine Spalten explizit aus, ich gehe also davon aus, dass die ganze Listview sortiert wird. Also sind die Werte kombinierbar, aber aus jeder Gruppe kann nur ein Wert auftauchen? Dann brauchst du nicht alle Wert als Flags zu implementieren, es reicht, wenn du jede Gruppe gegen die anderen Gruppen abgrenzt. Gruppe 1: 0 oder 1 Gruppe 2: 0, 2, 4 oder 6 Gruppe 3: 8 Aber das ist nur eine Platzoptimierung. Sieht schon besser aus, aber noch nicht richtig... die Null in der zweiten Gruppe darf nicht auftauchen. Entschuldige, dass ich versuche, logische Fehler in deinem Programm aufzudecken. Kein Problem... und außerdem ist es kein Fehler... sondern wie Du schon sagtest, höchstens eine Optimierung. Ich habe im Entwurf halt die Stati mit 2er-Potenzen belegt, um ganz sicher zu gehen, dass es keine Überschneidungen geben kann. Damals war es noch nicht klar, wie genau sich die Stati in Gruppen aufteilen würden. Und nachdem ich dann die Verarbeitung erstellt habe, hatte ich nicht den Drang die Stati sofort zu optimieren. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 14. Februar 2007 Teilen Geschrieben 14. Februar 2007 Wenn ich jetzt nach User DESC sortiere, so bleibt die erste Zeile rot. Wenn in Faerbung() des erste Item (nach der Sortierung) abgefragt wird, so ist lstMitgliederX.ListItems(1).SubItems(1) = "JNeudorf".Das heißt, an den Werten, die dir die ListItems-Collection liefert, ändert sich gar nichts? Bei der Sortierung wähle ich keine Spalten explizit aus, ich gehe also davon aus, dass die ganze Listview sortiert wird.Ich habe mir die Sortierfunktion mal in der MSDN Library angesehen. Da werden die direkten WinAPI-Nachrichten benutzt, damit werden ohnehin nur komplette Items vertauscht. Daran kann es also nicht liegen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
JayN Geschrieben 14. Februar 2007 Autor Teilen Geschrieben 14. Februar 2007 Das heißt, an den Werten, die dir die ListItems-Collection liefert, ändert sich gar nichts? Ich habe mir die Sortierfunktion mal in der MSDN Library angesehen. Da werden die direkten WinAPI-Nachrichten benutzt, damit werden ohnehin nur komplette Items vertauscht. Daran kann es also nicht liegen. Das versuche ich Dir die ganze Zeit mitzuteilen... An den Werten ändert sich bei der o.g. Zugriffsart gar nichts. Ich weiß jetzt nicht, ob ich da irgendwie die Sortierung mitberücksichtigen kann. Wenn es weiterhilft, kann ich das Sortierungsmodul hier posten. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
JayN Geschrieben 14. Februar 2007 Autor Teilen Geschrieben 14. Februar 2007 Ich habe mir die Sortierfunktion mal in der MSDN Library angesehen. Da werden die direkten WinAPI-Nachrichten benutzt, damit werden ohnehin nur komplette Items vertauscht. Daran kann es also nicht liegen. Legt die Sortierung evtl. irgendwo eine temporäre Collection oder ähnliches an? Denn irgendwie muss die Reihenfolge ja festgehalten werden. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 14. Februar 2007 Teilen Geschrieben 14. Februar 2007 Wenn es weiterhilft, kann ich das Sortierungsmodul hier posten.Nicht nötig, das gibt's ja im Web. Legt die Sortierung evtl. irgendwo eine temporäre Collection oder ähnliches an? Denn irgendwie muss die Reihenfolge ja festgehalten werden.Die Sortierfunktion arbeitet direkt mit Windows-Messages auf dem Steuerelement, und benutzt für die Sortierung ItemData-Werte, die offenbar von VB dort angelegt werden. Normalerweise sind die alle Null, und es ist daher nicht möglich, aus diesem Wert auf den Index des Eintrags zu schließen, aber so geht die Funktion vor. Es könnte sein, dass VBA die Collection nicht aktualisiert. Ob und wie man so eine Aktualisierung triggern könnte, weiß ich leider nicht. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
JayN Geschrieben 14. Februar 2007 Autor Teilen Geschrieben 14. Februar 2007 Eine Möglichkeit, die ich sehe, ist eine andere Sortierung der Listview und zwar im SQL-Statement, das vor dem Befüllen generiert wird. Das hätte jedoch bei jedem Klick eine neue Befüllung der ListView zur Folge und wäre nicht performant. Kommt also eher nicht in Frage. Irgendwelche anderen Lösungsansätze? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 14. Februar 2007 Teilen Geschrieben 14. Februar 2007 Du könntest auch selbst sortieren, über die Collection. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
JayN Geschrieben 14. Februar 2007 Autor Teilen Geschrieben 14. Februar 2007 Du könntest auch selbst sortieren, über die Collection. Mhhh... aber das hätte doch genau den gleichen Effekt, oder? Ich müsste doch die Werte an die Listview wieder zurückgeben, oder? Oder sehe ich das falsch? Wie würde man das am sinnigsten machen? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
xk4fu Geschrieben 22. Februar 2007 Teilen Geschrieben 22. Februar 2007 ich hab ein listview unter vb 6, für das ich eine sortier funktion usw geschrieben hab; wenn ich mal zeit hab, schick ich dir das per pm; mein listview ist zwar nicht direkt eingefärbt, aber ich zeige bilder an, und färbe die schrift einer zeile ein; wenns geht, musst du das halt noch ein bisl umschreiben Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
xk4fu Geschrieben 22. Februar 2007 Teilen Geschrieben 22. Februar 2007 ich sortiere meine listview folgendermasen: Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader) ListView1.SortKey = ColumnHeader.Index - 1 If ListView1.SortOrder = lvwAscending Then ListView1.SortOrder = lvwDescending Else ListView1.SortOrder = lvwAscending End If ListView1.Sorted = True End Sub damit klappt das auch bei mir ganz gut ansonsten verwende mal dieses modul: Modul: Option Explicit Private Const LVM_FIRST As Long = &H1000& Private Const LVM_SORTITEMS As Long = LVM_FIRST + 48& Private Const LVM_FINDITEM As Long = LVM_FIRST + 13& Private Const LVM_GETITEMTEXT As Long = LVM_FIRST + 45& Private Const LVFI_PARAM As Long = &H1& Private Const LVIF_TEXT As Long = &H1& Public Enum ListSortOrderConstants lvwAscending = 0& lvwDescending = 1& End Enum Private Type LVWSORT hWndListView As Long SortKey As Long SortOrder As ListSortOrderConstants End Type Private Type POINTAPI x As Long y As Long End Type Private Type LV_FINDINFO flags As Long psz As String lParam As Long pt As POINTAPI vkDirection As Long End Type Private Type LV_ITEM mask As Long iItem As Long iSubItem As Long state As Long stateMask As Long pszText As Long cchTextMax As Long iImage As Long lParam As Long iIndent As Long End Type Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, _ ByVal Message As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, _ ByRef Source As Any, _ ByVal Length As Long) Public Sub SortListView(ByVal hWndListView As Long, _ ByVal SortKey As Long, _ Optional ByVal SortOrder As ListSortOrderConstants = lvwAscending) Dim udtLVWSORT As LVWSORT With udtLVWSORT .hWndListView = hWndListView .SortKey = SortKey .SortOrder = SortOrder End With SendMessageLong hWndListView, _ LVM_SORTITEMS, _ VarPtr(udtLVWSORT), _ AddressOf CompareFunc End Sub Private Function CompareFunc(ByVal lParam1 As Long, _ ByVal lParam2 As Long, _ ByVal lParamSort As Long) As Long Dim ListViewSort As LVWSORT Dim sEntry1 As String Dim sEntry2 As String Dim vCompare1 As Variant Dim vCompare2 As Variant CopyMemory ListViewSort, _ ByVal lParamSort, _ Len(ListViewSort) sEntry1 = LvwGetText(ListViewSort, lParam1) sEntry2 = LvwGetText(ListViewSort, lParam2) If sEntry1 = sEntry2 Then Exit Function End If CompareFunc = CompareStrings(sEntry1, sEntry2, ListViewSort.SortOrder) End Function Private Function LvwGetText(ByRef ListViewSort As LVWSORT, _ ByVal lParam As Long) As String Dim udtFindInfo As LV_FINDINFO Dim udtLVItem As LV_ITEM Dim lngIndex As Long Dim baBuffer(512) As Byte Dim lngLength As Long With udtFindInfo .flags = LVFI_PARAM .lParam = lParam End With lngIndex = SendMessageLong(ListViewSort.hWndListView, _ LVM_FINDITEM, -1, _ VarPtr(udtFindInfo)) With udtLVItem .mask = LVIF_TEXT .iSubItem = ListViewSort.SortKey .pszText = VarPtr(baBuffer(0)) .cchTextMax = UBound(baBuffer) + 1 End With lngLength = SendMessageLong(ListViewSort.hWndListView, _ LVM_GETITEMTEXT, lngIndex, _ VarPtr(udtLVItem)) If lngLength > 0 Then LvwGetText = Left$(StrConv(baBuffer, vbUnicode), lngLength) End If End Function Private Function CompareStrings(ByRef sEntry1 As String, _ ByRef sEntry2 As String, _ ByVal SortOrder As ListSortOrderConstants) As Long If SortOrder = lvwAscending Then If sEntry1 < sEntry2 Then CompareStrings = -1 Else CompareStrings = 1 End If Else If sEntry1 > sEntry2 Then CompareStrings = -1 Else CompareStrings = 1 End If End If End Function Form: 'Sortierung bei Klick auf Kopfzeile Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader) If ColumnHeader.Text = MsColHeader And MbAsc = True Then SortListView ListView1.hWnd, ColumnHeader.Index - 1, lvwDescending MbAsc = False Else SortListView ListView1.hWnd, ColumnHeader.Index - 1, lvwAscending MbAsc = True End If MsColHeader = ColumnHeader.Text End Sub Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
xk4fu Geschrieben 22. Februar 2007 Teilen Geschrieben 22. Februar 2007 hier noch ein beispiel: Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
JayN Geschrieben 26. Februar 2007 Autor Teilen Geschrieben 26. Februar 2007 Ich danke Dir für diesen Ansatz. Schaue ich mir demnächst genauer an. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.