Datenzeilen im ListView-Steuerelement neu anordnen.
In der früheren Episode dieses Tutorials haben wir gelernt, wie man die Spalten neu anordnet, indem man diese Funktion aktiviert:AllowColumnReorder Option auf dem Eigenschaftsblatt. Das Verschieben einer Zeile erfolgt jedoch durch Ziehen und Platzieren in einer anderen Zeile. Zum Neuanordnen der ListView-Steuerelementzeilen erfordert die ListItem-Drag-and-Drop-Aktion die Aktivierung dieser Funktion auf dem Eigenschaftenblatt. Aber das allein wird nicht funktionieren, benötigt VBA-Code, um das Element in der erforderlichen Reihenfolge neu anzuordnen.
Lassen Sie uns für diese Übung ein Beispiel-Zugriffsformular mit Steuerelementen und VBA-Code in unserer Datenbank erstellen. Das Beispielbild des Formulars mit ListBox- und ListView-Steuerelementen ist unten angegeben.
Wir haben eine Liste von Tabellen und Abfragen (keine Aktionsabfragen) im Listenfeld erstellt. Wenn Sie eines der Listenelemente auswählen, werden die Datensätze sofort im ListView-Steuerelement angezeigt, so wie wir sie in der DataSheet-Ansicht sehen.
Die Designaufgabe.
-
Erstellen Sie eine neue Tabelle mit einem einzelnen Textfeld mit dem Feldnamen DataList .
-
Speichern Sie die Tabelle unter dem Namen lvTables (lv steht für ListView).
-
Öffnen Sie die Tabelle in der Datenblattansicht.
-
Fügen Sie einige Tabellennamen hinzu und wählen Sie Abfragenamen aus Ihrer Datenbank in die Tabelle aus. Ich habe Tabellen aus der Northwind-Beispieldatenbank für meine Liste importiert.
Hinweis: Der Anhang Das Feld ist im ListView-Steuerelement nicht gültig. Erstellen Sie Auswahlabfragen für Tabellen mit Anhangsfeld und wählen Sie alle Felder außer dem Anhangsfeld aus.
-
Erstellen und öffnen Sie ein neues Formular in der Entwurfsansicht.
-
Fügen Sie ein ListBox-Steuerelement in das Formular ein, zeigen Sie das Eigenschaftenblatt an und ändern Sie seinen Namen Eigenschaftswert in List0 .
-
Ändern Sie das untergeordnete Label Bildunterschrift Wert in Tabellen .
-
Zeigen Sie das Eigenschaftenblatt des ListBox-Steuerelements an und legen Sie die Zeilenquelle fest Eigenschaftswert zu den lvTables Name.
-
Überprüfen Sie, ob der Zeilenquelltyp auf Tabelle/Abfrage eingestellt ist und der Eigenschaftswert der gebundenen Spalte 1 ist. Wenn anders, dann ändern.
-
Fügen Sie ein ListView-Steuerelement aus der Liste der ActiveX-Steuerelemente ein und ändern Sie seinen Namenseigenschaftswert in ListView1 .
-
Passen Sie die Größe beider Steuerelemente an, wie auf dem oben angegebenen Demo-Formularbild gezeigt.
-
Fügen Sie über den Steuerelementen eine Beschriftung ein und ändern Sie die Eigenschaftswerte Name und Beschriftung in Überschrift. Der Beschriftungswert wird vom VBA-Code geändert, wenn eine Tabelle oder Abfrage aus der ListBox ausgewählt wird.
-
Erstellen Sie unterhalb der Steuerelemente eine Befehlsschaltfläche und ändern Sie deren Name-Eigenschaftswert in cmdClose und den Caption-Eigenschaftswert auf Close .
-
Klicken Sie mit der rechten Maustaste auf das ListView-Steuerelement, markieren Sie das ListViewCtrl-Objekt Option und wählen Sie Eigenschaften .
-
Ändern Sie die Eigenschaftseinstellungen so, dass sie mit den Einstellungen in Allgemein übereinstimmen Registerkartenbild unten angegeben.
-
Abbildung des Eigenschaftsblatts des ListView-Steuerelements – Allgemeine Registerkartenansicht ist unten angegeben:
Einige dieser Optionen haben wir bereits in früheren Sitzungen festgelegt. Hier benötigen wir für unsere Drag-Drop-Aktion folgende Optionen:
-
OLEDragAutomatisch - 1
-
OLEDropManual - 1
-
FullRowSelect - True
-
HotTracking – Richtig
-
Stellen Sie sicher, dass die obigen Einstellungen mit Ihrem Eigenschaftsblatt übereinstimmen, und speichern Sie dann das Formular.
Zeigt das VBA-Modul des Formulars an.
Der Formularmodul-VBA-Code.
Kopieren Sie den folgenden VBA-Code und fügen Sie ihn in das Modul ein, wobei Sie die vorhandenen Codezeilen überschreiben, falls vorhanden:
Option Compare Database Option Explicit Dim lvwList As MSComctlLib.ListView Dim strTable As String Dim db As DAO.Database Dim rst As DAO.Recordset Private Sub Form_Load() Set lvwList = Me.ListView1.Object End Sub Private Sub Form_Unload(Cancel As Integer) On Error GoTo Form_Unload_Err Dim lvItem As ListItem Dim tmp As Long Dim criteria As String Dim strfield As String Dim flag As Boolean Dim fld As String If strTable = "" Then Set lvwList = Nothing Exit Sub End If Set db = CurrentDb Set rst = db.OpenRecordset(strTable, dbOpenDynaset) flag = False For Each lvItem In lvwList.ListItems tmp = lvItem.Index strfield = lvwList.ColumnHeaders(1).Text criteria = strfield & " = " & Chr(34) & lvItem.Text & Chr(34) rst.FindFirst criteria If Not rst.NoMatch Then If (rst.Fields(strfield).Value = lvItem.Text) _ And (rst.Fields(1).Value = tmp) Then 'GoTo nextitem Else rst.Edit rst.Fields(1).Value = tmp rst.Update End If Else MsgBox "Item: " & tmp & " Not Found!" End If Next rst.Close Set lvwList = Nothing Set lvItem = Nothing Set rst = Nothing Set db = Nothing Form_Unload_Exit: Exit Sub Form_Unload_Err: MsgBox Err & " : " & Err.Description, , "Form_Unload()" Resume Form_Unload_Exit End Sub Private Sub ListView1_ColumnClick(ByVal ColumnHeader As Object) ' When a ColumnHeader object is clicked, the ListView control ' sorts the data of that column. On the first Click on the Column 'will sort in Ascending Order, second Click will sort in Descending With Me.ListView1 ' Set the SortKey to the Index of the ColumnHeader - 1 .SortKey = ColumnHeader.Index - 1 ' Set Sorted to True to sort the list. If .SortOrder = lvwAscending Then .SortOrder = lvwDescending Else .SortOrder = lvwAscending End If .Sorted = True End With End Sub Private Sub List0_Click() strTable = List0.Value Call LoadListView(strTable) End Sub Private Sub LoadListView(ByVal s_Datasource As String) On Error GoTo LoadListView_Err Dim j As Integer Dim tmpLItem As MSComctlLib.ListItem Dim strHeading As String strHeading = UCase(s_Datasource) With Me.Heading .caption = strHeading .FontName = "Courier New" .FontSize = 20 .FontItalic = True .FontBold = True End With 'Initialize ListView Control lvwList.ColumnHeaders.Clear lvwList.ListItems.Clear Set db = CurrentDb Set rst = db.OpenRecordset(s_Datasource, dbOpenSnapshot) 'Initialize ListView & Column Headers Property Values With lvwList .Font.Size = 10 .Font.Name = "Verdana" .Font.Bold = False .GridLines = True End With With lvwList 'Syntax: .ColumnHeaders.Add Index, Key, Text, Width in Pixels, Alignment, Icon For j = 0 To rst.Fields.Count - 1 .ColumnHeaders.Add , , rst.Fields(j).Name, IIf(j = 0, 3000, 1400), 0 Next End With Dim I As Long rst.MoveFirst Do While Not rst.BOF And Not rst.EOF 'Syntax: lvwList.ListItems.Add Index, Key, Text, Icon, SmallIcon Set tmpLItem = lvwList.ListItems.Add(, , rst.Fields(0).Value) 'Name column 'Syntax: tmpLItem.ListSubItems.Add Index, Key, Text, ReportIcon, ToolTipText With tmpLItem For j = 1 To rst.Fields.Count - 1 .ListSubItems.Add , , Nz(rst.Fields(j).Value, "") Next End With rst.MoveNext Loop rst.Close With lvwList If .ListItems.Count > 0 Then .ListItems(1).Selected = True End If End With Set db = Nothing Set rst = Nothing LoadListView_Exit: Exit Sub LoadListView_Err: MsgBox Err & " : " & Err.Description, , "LoadListView()" Resume LoadListView_Exit End Sub Private Sub ListView1_OLEDragOver(data As Object, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single, State As Integer) 'Highlight the item when draged over it Set ListView1.DropHighlight = ListView1.HitTest(x, y) End Sub Private Sub ListView1_OLEDragDrop(data As Object, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single) 'Item being dropped Dim lvwDrag As ListItem 'Item being dropped on Dim lvwDrop As ListItem 'Item being readded to the list Dim lvwTarget As ListItem 'Subitem reference in dropped item Dim lvwSub As ListSubItem 'Drop position Dim intTgtIndex As Integer Dim j As Integer Set lvwDrop = lvwList.HitTest(x, y) Set lvwDrag = lvwList.SelectedItem 'save a copy of draged item 'Ignore overlapping drag or drop Item actions If (lvwDrop Is Nothing) Or (lvwDrag Is Nothing) Or (lvwDrop = lvwDrag) Then Set lvwList.DropHighlight = Nothing Set lvwDrop = Nothing Set lvwDrag = Nothing Exit Sub End If 'Save the droped position Index Number intTgtIndex = lvwDrop.Index 'Remove Dragged Item from its old position lvwList.ListItems.Remove lvwDrag.Index 'For j = intTgtIndex To ListItems.Count 'Creates a new Item in the Target Item position 'with the Dropped Item Index Number and Dragged Item.Text. 'Saves the new Item reference in lvwTarget Item. '* The original Droped-on Target) Item will be moved down '* by incrementing its original Index Number Set lvwTarget = lvwList.ListItems.Add(intTgtIndex, , lvwDrag.Text) 'Copy the original Draged Item's subitems to the new item If lvwDrag.ListSubItems.Count > 0 Then For Each lvwSub In lvwDrag.ListSubItems lvwTarget.ListSubItems.Add , lvwSub.Key, lvwSub.Text Next End If 'Highlight the draged item in its new position lvwTarget.Selected = True 'Destroy all objects Set lvwTarget = Nothing Set lvwDrag = Nothing Set lvwDrop = Nothing Set lvwList.DropHighlight = Nothing End Sub Private Sub cmdClose_Click() DoCmd.Close acForm, Me.Name End Sub
Sie sind mit dem obigen VBA-Code vertraut, mit Ausnahme der neu hinzugefügten Unterroutinen:ListView1_OLEDragOver(), ListView1_OLEDragDrop(), Form_Unload(), und die ListView1_ColumnClik() Verfahren. Die ersten beiden Verfahren helfen uns, ein Element (Zeile) zu ziehen und über ein anderes Element abzulegen, um es an einer neuen Position einzufügen. Die Prozeduren Form_Unload() und ListView1_ColumnClick() sortieren die Items.
Die folgenden Bilder zeigen die Drag-and-Drop-Aktion in Sequenzen ihrer Ausführung
Das erste Bild unten zeigt die Drag-and-Drop-Aktionssequenz. Das ListItem mit der EmployeeID 7 wird vom Benutzer nach oben gezogen und über dem ListItem mit der ID 3 abgelegt.
Das zweite Bild zeigt die Bewegung von ListItem in umgekehrter Reihenfolge.
Wenn sich der Mauszeiger über eine Zeile mit dem gezogenen Element bewegt, wird zwischen der Quell- und der Zielzeile auf dem Weg nach oben nacheinander hervorgehoben.
Die Drag-and-Drop-Aktion in Bildern.
Die Zeile mit der Mitarbeiter-ID 7 wird auf dem Element mit der Mitarbeiter-ID 3 oben abgelegt.Die segmentweise Analyse des VBA-Codes.
Bei einer Elementauswahl aus der ListBox wird die Ereignisprozedur List0_Click() ausgeführt und die Datensätze in das ListView-Steuerelement geladen.
Private Sub List0_Click() Dim strTable As String strTable = List0.Value Call LoadListView(strTable) End Sub
Der ausgewählte Tabellen-/Abfragename wird in der strTable gespeichert String-Variable. Die LoadListView() Unterroutine wird mit der Variablen strTable als Parameter ausgeführt. Wir sind diesen Kodex in früheren Sitzungen mehr als einmal durchgegangen, und Sie können diese Seiten über die Links am Ende dieser Seite besuchen, um weitere Informationen zu erhalten. Möglicherweise finden Sie einige geringfügige Änderungen, die ich an diesem Kodex vorgenommen habe.
Wir haben das ImageList Control in dieser Episode nicht verwendet, das Icon, SmallIcon Parameterwerte in der Methode ListItems.Add() und ReportIcon, TooltipText Parameterwerte in der Methode ListSubItems.Add() werden ebenfalls nicht verwendet.
Sehen wir uns an, was in ListView1_OLEDragOver() passiert und ListView1_OLEDragDrop() VBA-Codesegmente.
Die ListView1_OLEDragOver() Prozedur.
Private Sub ListView1_OLEDragOver(Data As Object, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single, State As Integer) 'Highlight the item when draged over it Set ListView1.DropHighlight = ListView1.HitTest(x, y) End Sub
Dieses Verfahren wird automatisch ausgeführt, wenn Sie versuchen, auf eine Zeile zu klicken und sie gedrückt zu halten, zu ziehen und sich auf dem Weg zur Zielzeile über andere Zeilen zu bewegen. Die Ziehaktion bewegt sich über eine andere Zeile und wird hervorgehoben.
Der ListView1.HitTest(x, y) liest die x-, y-Koordinaten, die die Zeilenposition auf dem ListView-Steuerelement bestimmen, und hebt diese Zeile hervor. Dieser Vorgang wird fortgesetzt, wenn Sie sich über anderen Zeilen befinden, bis Sie es auf der Zielzeile ablegen, indem Sie die Maustaste loslassen. Die Drop-Aktion löst ListView1_OLEDragDrop() aus Prozedur und führt die Wechselprozeduren der Quellzeile aus.
Das ListView1_OLEDragDrop-Verfahren.
Private Sub ListView1_OLEDragDrop(Data As Object, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single) 'Item being dragged Dim lvwDrag As ListItem 'Item being dropped on Dim lvwDrop As ListItem 'Item being added to the list Dim lvwTarget As ListItem 'Subitem reference used in For . . .Next loop
Dim lvwSub As ListSubItem 'Drop position index Dim intTgtIndex As Integer Set lvwDrop = lvwList.HitTest(x, y) 'save the source item Set lvwDrag = lvwList.SelectedItem 'save a copy of draged item 'Ignore overlapping drag or drop Item actions If (lvwDrop Is Nothing) Or (lvwDrag Is Nothing) Or (lvwDrop = lvwDrag) Then Set lvwList.DropHighlight = Nothing Set lvwDrop = Nothing Set lvwDrag = Nothing Exit Sub End If 'Save the droped position Index Number intTgtIndex = lvwDrop.Index 'Remove Dragged Item from its old position lvwList.ListItems.Remove lvwDrag.Index 'Creates a new Item in the Target Item position 'with the Dropped Item Index Number and Dragged Item.Text. 'Saves the new Item reference in lvwTarget Item. '* The original Droped-on Target) Item will be moved down '* by incrementing its original Index Number Set lvwTarget = lvwList.ListItems.Add(intTgtIndex, , lvwDrag.Text) 'Copy the original Draged Item's subitems to the new item If lvwDrag.ListSubItems.Count > 0 Then For Each lvwSub In lvwDrag.ListSubItems lvwTarget.ListSubItems.Add , lvwSub.Key, lvwSub.Text Next End If 'Highlight the draged item in its new position lvwTarget.Selected = True 'Destroy all objects Set lvwTarget = Nothing Set lvwDrag = Nothing Set lvwDrop = Nothing Set lvwList.DropHighlight = Nothing End Sub
Lassen Sie uns dieses Verfahren Schritt für Schritt durchgehen und verstehen, was dort passiert. Das folgende Codesegment deklariert notwendige Objektvariablen, um die Drag-and-Drop-Aktion zu handhaben:
'Item being dragged Dim lvwDrag As ListItem 'Item being dropped on Dim lvwDrop As ListItem 'Reference of the Item being added to the list Dim lvwTarget As ListItem 'Subitem reference used in For . . .Next loop Dim lvwSub As ListSubItem 'Drop position index Dim intTgtIndex As Integer Set lvwDrop = lvwList.HitTest(x, y) Set lvwDrag = lvwList.SelectedItem 'save a copy of draged item
Die ersten drei temporären ListItem-Objekte werden mit unterschiedlichen Namen deklariert.
Der lvwDrag Das ListItem-Objekt enthält die Kopie der Zeile, die wir auswählen, um sie an eine neue Position zu ziehen.
Der lvwDrop Das ListItem-Objekt speichert die Referenz der Zeile, auf der wir das gezogene Listenelement ablegen.
Während der Umstellung der ListItems-Aktion löschen wir das Quellelement von seinem ursprünglichen Speicherort und erstellen es dann am Zielspeicherort mit der Quell-ListItem-Indexnummer. Die Referenzen dieses neuen ListItems werden im lvwTarget gespeichert ListItem-Objektvariable.
Das lvwSub Variable, die als sequenzierende Objektvariable in For deklariert ist. . .Weiter Schleife. Diese Schleife erfordert, dass die ListSubItems (ab der 2. Spalte) nacheinander vom lvwDrag-Objekt durchlaufen werden. Obwohl wir das ursprüngliche ListItem gelöscht haben, haben wir eine Kopie davon im lvwDrag ListItem-Objekt gespeichert.
Die lvwDrop ListItem-Indexnummer wird im intTgtIndex gespeichert Variable.
Der lvwList.HitTest(x, y) Die Funktion liest die x-, y-Koordinaten des ListView-Steuerelements und identifiziert das Ziel-ListItem, wo wir das Quell-ListItem abgelegt haben, und erstellt eine Kopie davon im lvwDrop-Objekt.
Wir werden zuerst ein ListItem auswählen, bevor wir es an die neue Position ziehen.
Das lvwList.SelectedItem Property wird auf True gesetzt. Mit Hilfe dieses Eigenschaftsstatus kopieren wir das ausgewählte ListItem in das lvwDrag ListItem-Objekt. Das nächste Codesegment validiert sowohl Quell- als auch Ziel-ListItem-Objekte.
Validierungsprüfungen für die Drag-Drop-Aktion.
'Ignore overlapping drag or drop Item actions, 'OR drag and drop happens on the same ListItem. If (lvwDrop Is Nothing) Or (lvwDrag Is Nothing) Or (lvwDrop = lvwDrag) Then Set lvwList.DropHighlight = Nothing Set lvwDrop = Nothing Set lvwDrag = Nothing Exit Sub End If
Das obige Codesegment validiert die Drag-and-Drop-Aktion. Wenn diese Aktionen nicht mit einem gültigen Element gestartet oder beendet wurden, sind die lvwDrop- oder lvwDrag-Objekte oder beide leer. Oder eine andere ungültige Bewegung kann passieren, wenn der Benutzer eine Zeile nach oben oder unten bewegt, aber seine Meinung ändert und sie wieder in dieselbe Zeile fallen lässt. Die Erkennung solcher falscher Bewegungen beendet das Programm.
Wenn sich der obige Test als gültig erweist, fährt das Programm mit der Ausführung der nächsten Prozedur fort, um die Zeilen neu anzuordnen.
'Save the dropped position ListItem Index Number intTgtIndex = lvwDrop.Index 'Remove Dragged Item from its old position lvwList.ListItems.Remove lvwDrag.Index 'Creates a new Item in the Target Item position 'with the Dropped Item Index Number and Dragged Item.Text. 'Saves the new Item reference in lvwTarget Item. '* The original Droped-on Target) Item will be moved down '* by incrementing its original Index Number Set lvwTarget = lvwList.ListItems.Add(intTgtIndex, , lvwDrag.Text) 'Copy the original Draged Item's subitems to the new item If lvwDrag.ListSubItems.Count > 0 Then For Each lvwSub In lvwDrag.ListSubItems lvwTarget.ListSubItems.Add , lvwSub.Key, lvwSub.Text Next End If 'Highlight the draged item in its new position lvwTarget.Selected = True
Die Aktionen der obigen neun Zeilen ausführbaren Codes (andere Zeilen sind Kommentare) sind etwas unkompliziert.
Der intTgtIndex =lvwDrop.Index -Anweisung speichert die Indexnummer des Ziel-ListItems in intTgtIndex Variable.
Da wir das Source Row listItem bereits im temporären Objekt lvwDrag gespeichert haben, besteht der nächste Schritt darin, das Source ListItem aus dem ListView Control zu entfernen. Die ListItems.Remove()-Prozedur aufgerufen, mit der Anweisung lvwList.ListItems.Remove lvwDrag.Index .
Kurz gesagt, die Drag-Drop-Aktion besteht darin, ein ListItem von seiner ursprünglichen Position zu löschen und es an der Zielposition mit der Indexnummer der Zielzeile erneut zu erstellen.
Die Anweisung Set lvwTarget =lvwList.ListItems.Add(intTgtIndex, , lvwDrag.Text) erstellt das neue ListItem mit seiner Zielpositionsindexnummer intTgtIndex und dem Text Wert von Source ListItem, der zuvor im lvwDrag-Objekt gespeichert wurde.
Bei der erstmaligen Erstellung des ListItems haben wir nur diese beiden Werte, den Index und den Text verwendet Parameterwerte. Die anderen Parameteroptionen Key, Icon, haben wir nicht verwendet und SmallIcon andernfalls müssen wir diese Parameterwerte auch aus dem lvwDrag-Objekt einschließen.
Gemäß unseren oben gezeigten Drag-Drop-Beispielbildern haben wir das 7. ListItem verschoben und auf dem 3. ListItem abgelegt. Danach haben wir das 7. Item (oder Source ListItem) aus dem ListView Control gelöscht. Erstellt ein neues ListItem mit der Zielindexnummer 3.
Jetzt gibt es zwei Elemente mit der gleichen Indexnummer 3, das vorhandene mit der Indexnummer 3 und das neu erstellte mit der Indexnummer 3. Alle anderen Informationen werden aus dem lvwDrag-Objekt (oder dem 7. ListItem, das in lvwDrag gespeichert ist) übernommen Einspruch früher).
Das System inkrementiert automatisch das vorhandene ListItem 3 weiter zu den nächsten Sequenznummern 3,4,5 . . . bis 4,5,6 . . . und verschiebt sie nach vorne, um Platz für das eingehende Element zu schaffen, das dazwischen eingefügt werden kann.
Die Auswirkungen des Löschens einer Zeile und des Erstellens an anderer Stelle.
Nehmen Sie an, dass wir diese Bewegung in umgekehrter Reihenfolge machen, wie Listeneintrag Nr. 3 von oben ziehen und auf Eintrag Nr. 7 fallen lassen, was passiert dann?
Natürlich werden wir den 3. Artikel löschen und versuchen, am neuen Ort einen neuen Artikel mit der Indexnummer 7 zu erstellen. Wenn Artikel Nummer 3 gelöscht wird, verschiebt sich Artikel Nummer 4 aufwärts oder 4,5,6,7,8,9 wird zu 3,4,5,6,7,8 (um alle Artikel der Reihe nach zu machen) oder früher Element mit der Indexnummer 7 wird zu 6.
Wenn wir den neuen Artikel mit der Indexnummer 7 erstellen, wird die vorhandene 7,8 wieder zu 8,9. Wenn wir die Bewegung von Zeilen beim Löschen und Erstellen von Zeilen beobachten, verschiebt das erste Beispiel die Zielzeile nach unten, um Platz für das eingehende Element zu machen. Im zweiten erklärten Beispiel (Verschieben von 3 nach 7) wird die Zielzeile nach oben verschoben.
Hinweis: Ansehen der Mitarbeiter-ID-Wert für seine Platzierung als Anhaltspunkt dafür, dass ListItem nach unten oder oben verschoben wird, wenn wir ListItem neu anordnen.
Ich habe ListItem überall in Drag-Drop-Operationen erwähnt. Das ListItem bezieht sich nur auf die erste Spalte der ListView-Zeile. Andere Spaltenwerte sind ListSubItems oder die untergeordneten Elemente des ListItem. Das bedeutet, dass Sie nur die erste Spalte ziehen und ablegen können. Andere Spalten oder ListSubItems werden mit VBA-Code unter das ListItem verschoben.
Dies gilt, wenn Sie die FullRowSelection nicht aktiviert haben auf dem Eigenschaftsblatt des ListView-Steuerelements auf Allgemein Tab.
Wenn diese Option aktiviert ist, können Sie jede Spalte auswählen, aber das System bezieht sich auf den ListItem-Index für die Neuordnung der Zeilen. Vergleichen Sie die beiden obigen Bilder mit einem anderen Satz von zwei Beispielbildern, dem dritten und vierten Bild von oben auf dieser Seite.
Die Drag-and-Drop-Aktion funktioniert nicht, wenn die folgenden beiden Eigenschaftswerte nicht auf dem Eigenschaftenblatt des ListView-Steuerelements unter Allgemein festgelegt sind Tab.:
- ccOLEDragAutomatic =1
- ccOLEDropManual =1
Die nächsten fünf Anweisungen verschieben die ListSubItems, falls vorhanden, zu dem am neuen Ort neu erstellten ListItem.
Als nächstes wird das neu erstellte ListItem hervorgehoben.
Als nächstes werden alle erstellten temporären Objekte aus dem Speicher gelöscht.
Hinweis: Ein weiterer wichtiger Punkt, der hier zu beachten ist, ist, dass diese Anordnung temporär ist und verloren geht, wenn Sie das Formular schließen oder eine andere Tabelle/Abfrage auf das ListView-Steuerelement laden.
Wenn wir möchten, dass die geänderte Reihenfolge von ListItems dauerhaft bleibt oder bis die Reihenfolge das nächste Mal geändert wird, müssen wir in der Lage sein, die aktuelle indizierte Bestellnummer in der Tabelle selbst zu aktualisieren. Wir haben ein neues Integer-Feld mit der Feldnamen-ID in der Employees-Tabelle hinzugefügt.
Der Beispielbildschirm mit den in alphabetischer Reihenfolge neu angeordneten Mitarbeiterdaten ist unten angegeben:
Da das Feld Mitarbeiter-ID ein AutoWert-Feld ist und mit anderen zugehörigen Tabellen verknüpft ist, haben wir ein neues Zahlenfeld mit dem Feldnamen ID hinzugefügt. Dieser Feldwert wird anfangs manuell mit denselben Sequenznummern aus der Mitarbeiter-ID festgelegt. Dieser Feldwert wird anfänglich in dieser Reihenfolge sein. Aber die ListView-Zeilendaten können ihre Reihenfolge ändern, wenn Sie die Daten auf dem ListView-Steuerelement aufgrund von Drag-and-Drop-Aktionen neu anordnen.
Sehen Sie sich die MitarbeiterQ an Fragen Sie die unten angegebene SQL ab:
SELECT [FirstName] & " " & [LastName] AS EmployeeName, Employees.ID, Employees.EmployeeID, Employees.TitleOfCourtesy, Employees.Title, Employees.Address, Employees.City, Employees.Region, Employees.PostalCode, Employees.Country, Employees.HomePhone, Employees.Extension, Employees.Notes FROM Employees ORDER BY Employees.ID;
Die obige Abfrage wird als Datenquelle für das ListView-Steuerelement verwendet und sie werden nach dem ID-Feld sortiert. Das ID-Feld wird mit der geänderten Reihenfolge der Indexnummern im ListView-Steuerelement aktualisiert. Der Aktualisierungsprozess wird von Form_Unload() ausgeführt Ereignisprozedur beim Schließen des Formulars. Diese Methode stellt sicher, dass beim nächsten Öffnen des ListView-Steuerelements die Daten in der Reihenfolge vorliegen, in der Sie sie beim letzten Mal neu angeordnet haben.
Das Form_Unload() VBA-Code für Ereignisprozedur.
Private Sub Form_Unload(Cancel As Integer) Dim lvItem As ListItem Dim tmp As Long Dim criteria As String Dim strfield As String Dim fld As String If strTable = "" Then Set lvwList = Nothing Exit Sub End If Set db = CurrentDb Set rst = db.OpenRecordset(strTable, dbOpenDynaset) For Each lvItem In lvwList.ListItems tmp = lvItem.Index strfield = lvwList.ColumnHeaders(1).Text 'EmployeeName criteria = strfield & " = " & Chr(34) & lvItem.Text & Chr(34) rst.FindFirst criteria If Not rst.NoMatch Then If (rst.Fields(strfield).Value = lvItem.Text) And (rst.Fields(1).Value = tmp) Then 'GoTo nextitem Else rst.Edit rst.Fields(1).Value = tmp 'replace ID number rst.Update End If Else MsgBox "Item: " & tmp & " Not Found!" End If Next rst.Close Set lvwList = Nothing Set lvItem = Nothing Set rst = Nothing Set db = Nothing End Sub
Überprüfen Sie den EmployeeName Feldwert im obigen Bild. Sie sind in alphabetischer Reihenfolge angeordnet. Der neue ID-Feldwert in der Employees-Tabelle wird mit ihrer aktuellen ListView Control ListItem-Indexnummernfolge aktualisiert.
Wenn Sie die folgenden Punkte beachten, können Sie leicht verstehen, was wir mit dem obigen Code machen:
-
Der Text des ListItems (erste Spalte). Parameterwert ist der Name des Mitarbeiters und in alphabetischer Reihenfolge angeordnet.
-
Die ListItems im ListView-Steuerelement haben Indexnummern von 1 bis 9 in der Reihenfolge, in der sie auf dem Bildschirm angezeigt werden, d. h. die Indexnummer des ersten Elements ist 1 und die Indexnummer des letzten 9. Die ursprünglichen Daten im ID-Feld der Employees-Tabelle sind es nicht in dieser Reihenfolge.
-
Wir nehmen den Text Wert (Employee Name) des ersten ListItems und suchen Sie nach dem Namen in der Tabelle.
-
Wenn der Datensatz gefunden wird, wird die Indexnummer des aktuellen ListItem im ID-Feld der Tabelle aktualisiert (ersetzt).
-
Dieser Vorgang wurde für alle verbleibenden Datensätze in der Tabelle wiederholt.
Lassen Sie uns den VBA-Code durchgehen. Am Anfang prüfen wir, ob die Source data Table/Query in das ListView Control geladen wurde oder nicht?
Wenn die strTable Die Variable wird nicht mit dem Abfragenamen initialisiert, dann ist das ListView-Steuerelement leer. Wenn dies der Fall ist, hat der Benutzer das Formular geöffnet und geschlossen, ohne den Abfragenamen auszuwählen, um die Daten in das ListView-Steuerelement zu laden. Das Form_Unload Die Ereignisprozedur wird an dieser Stelle abgebrochen und das Formular geschlossen.
Wenn das ListView-Steuerelement Daten enthält, wird der nächste Schritt ausgeführt und die Quelldatenabfrage EmployeesQ zum Aktualisieren geöffnet.
Der nächste Schritt besteht darin, jedes ListItem durchzugehen und die Indexnummer im ID-Feld des Employees-Datensatzes zu aktualisieren.
Zuerst wird die aktuelle Zeilenindexnummer im tmp gespeichert Variable.
Der erste lvwList.ColumnHeader-Name EmployeeName und den Namen des Mitarbeiters wird aus ListItem.Text entnommen in einen Ausdruck in den Kriterien String-Variable, wie EmployeeName ="Andrew Fuller".
Die rst.FindFirst-Kriterien Der Befehl durchsucht die Quelldatentabelle, um den Datensatz mit dem angegebenen Namen zu finden. Wenn der Datensatz gefunden wird, wird die aktuelle ListItem-Indexnummer im ID-Feld aktualisiert.
Dieser Vorgang wird für alle Zeilen des ListView-Steuerelements wiederholt, und wenn er fertig ist, wird das Formular geschlossen.
Wenn Sie das nächste Mal die Datensätze aus dieser Abfrage in das ListView-Steuerelement laden, werden sie in derselben Reihenfolge angezeigt, in der Sie das Formular das letzte Mal geschlossen haben.
Hinweis:Die Abfrage wurde hier notwendig, um die Daten auf dem ID-Feld zu sortieren und sie in der geänderten Reihenfolge auf dem ListView-Steuerelement anzuzeigen.
All diese Arbeit diente dazu, die Daten in der zuletzt sortierten Reihenfolge zu speichern, damit beim nächsten Öffnen des Formulars die Daten im ListView-Steuerelement in dieser Reihenfolge angezeigt werden.
Windows Explorer-ähnliche Sortiermethode.
Im Windows Explorer können Sie die angezeigte Liste in aufsteigender oder absteigender Reihenfolge sortieren, indem Sie auf eine beliebige Spaltenüberschrift klicken. Die Spaltenüberschrift funktioniert wie eine Umschaltfläche. Wiederholtes Klicken auf die Spaltenüberschrift sortiert die Spaltendaten in aufsteigender/absteigender Reihenfolge nach dem folgenden ListView1_ColumnClick() Ereignisverfahren:
Private Sub ListView1_ColumnClick(ByVal ColumnHeader As Object) ' When a ColumnHeader object is clicked, the ListView control is ' sorted by the subitems of that column. With Me.ListView1 ' Set the SortKey to the Index of the ColumnHeader - 1 .SortKey = ColumnHeader.Index - 1 If .SortOrder = lvwAscending Then .SortOrder = lvwDescending Else .SortOrder = lvwAscending End If ' Set Sorted to True to sort the list. .Sorted = True End With End Sub
Hinweis: Die Sortierung aller Daten erfolgt nur im Textvergleichsmodus. Die ListItems und ListSubItems Hinzufügen() der dritte Parameter der Methode, die angezeigten Informationen auf dem ListView-Steuerelement sind Text Typ. Datums- und numerische Werte werden alle nur als Text behandelt.
Windows Explorer speichert die zuletzt sortierte Reihenfolge der Elemente im Ordner. Wenn wir diesen Ordner erneut öffnen, wird die Liste in der früheren sortierten Reihenfolge angezeigt.
Mit dem Form_Unload() Ereignisverfahren Diese Funktion des Windows Explorers wird in der Mitarbeitertabelle möglich. Wenn Sie das Formular nach dem Sortieren nach einer beliebigen Spalte schließen, wird diese indizierte Bestellsequenz in der Mitarbeitertabelle im ID-Feld gespeichert. Die EmployeesQ-Abfrage sortiert die Daten beim Öffnen immer nach dem ID-Feld.
Die Demo-Datenbank ist zum Download beigefügt. Es gibt zwei Demoformulare in der Datenbank. Das erste Formular zeigt das Öffnen von Tabellen und Abfragen im ListView-Steuerelement, um die Daten in der Datenblattansicht anzuzeigen. Das zweite Formular verwendet nur das EmployeesQ Abfrage allein zum Ziehen, Ablegen, Sortieren und Speichern der letzten Sortierreihenfolge von Daten für die zukünftige Verwendung.
- ActiveX ListView Control Tutorial-01.
- ListView Control Tutorial-02.
- Zuweisen von Bildern zu ListView-Elementen.
- Drag-Drop-Sortierungsereignisse des ListView-Steuerelements
- ListView Control mit MS-Access TreeView
- TreeView/ListView steuert Drag-Drop-Ereignisse