Einführung.
Fortsetzung von ActiveX ListView Control Tutorial-01 der letzten Woche.
In dieser Sitzung des Lernprogramms lernen wir, wie Sie bestimmte Zeilen- und Spaltenwerte suchen und finden und sie in einem Label-Steuerelement auf einem Formular anzeigen. Dies ist sehr nützlich, wenn wir eine große Datenmenge im ListView-Steuerelement haben. Wir werden auch die Verwendung einiger ListView-Eigenschaftseinstellungen lernen.
Zunächst werden wir sehen, wie einfach es ist, die Spalten neu anzuordnen, wie wir es mit Access Datasheet View tun, so wie wir sie im ListView-Steuerelement haben möchten. Wir haben einige TextBoxen, ComboBoxen, Befehlsschaltflächen und Beschriftungen hinzugefügt, um die Auswahl von Suchparametern und die Anzeige von Suchergebnissen zu vereinfachen.
Ich habe einige Änderungen an den Demodaten der letzten Woche vorgenommen. Die ersten Spaltenwerte habe ich der Employees-Tabelle der Beispieldatenbank Northwind.accdb entnommen. Eine Abfrage erstellt, um die Werte Nachname und Vorname mit dem Feldnamen Student und EmployeeID als Schlüssel (X01, X02 ...) zu verbinden.
Bevor wir uns den Suchoperationen zuwenden, werden wir prüfen, wie Spalten durch die Drag-and-Drop-Methode neu angeordnet werden.
Hinweis: Wenn Sie die frühere Tutorial-Seite noch nicht durchgegangen sind und mit dieser Sitzung fortfahren möchten, gehen Sie zur ListView Control Tutorial-01-Seite und laden Sie die Demo-Datenbank unten auf dieser Seite herunter.
Entpacken Sie die Datei und öffnen Sie die Datenbank. Das Demo-Formular wird in der Normalansicht angezeigt.
-
Öffnen Sie Ihre Datenbank mit dem Demoformular der letzten Sitzung oder das von Ihnen erstellte Formular in der Normalansicht.
Jetzt werden wir versuchen, eine Spalte aus der Mitte der Liste (z. B. die Spalte „Gewicht“) per Drag-and-Drop auf das Alter zu verschieben Spalte und sehen, was passiert. Es wird erwartet, dass die Altersspalte nach rechts verschoben wird und die eingehende Spalte an ihrer Stelle eingefügt wird.
-
Bewegen Sie den Mauszeiger auf die Spaltenüberschrift mit dem Namen Gewicht, klicken und halten Sie die linke Maustaste. Wenn Sie die linke Maustaste drücken, verschiebt sich die Spaltenüberschrift etwas nach unten.
-
Versuchen Sie nun, die Spalte nach links zu ziehen und auf der Spalte Alter abzulegen .
Es wird nichts passieren, da wir diese Funktion im Eigenschaftenblatt nicht aktiviert haben und dies die einzige Einstellung ist, die wir ändern müssen, damit diese Funktion funktioniert.
-
Ändern Sie das Formular in der Entwurfsansicht.
-
Klicken Sie mit der rechten Maustaste auf das ListView-Steuerelement und markieren Sie die Option ListViewCtrl-Objekt und wählen Sie Eigenschaften.
-
Es gibt eine Option 'AllowColumnReorder ' auf der rechten Seite. Setzen Sie ein Häkchen, um es auszuwählen, und klicken Sie dann auf Anwenden gefolgt von OK Schaltfläche, um die Eigenschaftsansicht zu schließen.
-
Versuchen Sie nun, die obigen Schritte 2 und 3 zu wiederholen, und sehen Sie, was passiert.
Dies ist die einzige Einstellung, die Sie benötigen, um diese Funktion im ListView-Steuerelement zu aktivieren. Vielleicht denkst du, wie wäre es mit einer Neuanordnung der Zeilen?.
Diese Funktion erfordert die Programmierung einiger Ereignisprozeduren, wie wir es zuvor in TreeView Control Drag-Drop-Ereignissen getan haben. Diesen Teil werden wir nach einiger Zeit erledigen.
-
Sie können mit jeder Spalte experimentieren, um sie an eine beliebige Stelle zu verschieben, einschließlich der ersten Spalte.
Hinweis: Vergewissern Sie sich vor dem Ablegen der Quellspalte, dass die Zielspalte vom Rahmen der eingehenden Spalte abgedeckt ist, bevor Sie versuchen, sie abzulegen. Andernfalls kann die eingehende Spalte auf die nächste Spaltenposition auf der rechten Seite verschoben werden.
Als Nächstes lernen wir, wie wir schnell einige Informationen aus der ListView finden können, vorausgesetzt, wir haben eine große Datenmenge darin.
Wir haben dem Tutorial-01-Modul eine Subroutine hinzugefügt, um die Namen der Spaltenüberschriften in ein Kombinationsfeld auf dem Formular mit der roten Hintergrundfarbe zu laden. Der Spaltenname wird verwendet, um den Spaltenwert (Alter, Größe, Gewicht oder Klasse) eines Schülers zu finden.
Neuer VBA-Code zum Formularklassenmodul hinzugefügt.
Die folgende neue VBA-Prozedur wurde dem Klassenmodul des Tutorial-Formulars der letzten Woche hinzugefügt:
Die txtColCombo erstellt die Liste der Spaltenkopfbeschriftungen (Feldnamen) in der ComboBox. Eine dieser Angaben zu Alter, Größe, Gewicht des Schülers oder Klasse können zusammen mit dem Namen des Schülers als Teil der Suchoperation gefunden werden.
Private Sub txtColCombo() 'Column Header List Combo Dim lvwColHead As MSComctlLib.ColumnHeader Dim cboName As ComboBox Set cboName = Me.txtCol cboName.RowSourceType = "Value List" For Each lvwColHead In lvwList.ColumnHeaders If lvwColHead.Index = 1 Then 'Nothing Else cboName.AddItem lvwColHead.Text End If Next 'cboName.DefaultValue = "=txtCol.Column(0, 0)" Set lvwColHead = Nothing Set cboName = Nothing End Sub
Die Combobox wird nicht mit einem Standardwert für den Namen der Spaltenüberschrift geladen. Wenn ausgewählt, wird dieser Spaltenwert des Schülers in der großen Beschriftung unter dem Schülernamen angezeigt. Wenn es leer gelassen wird, findet der Suchvorgang nur den Namen des Schülers.
Die Suchoperationsmethode ist sehr flexibel und schnell. Wir haben zwei Methoden, um einen Datensatz zu finden.
Suchen Sie den Datensatz, indem Sie den Suchtext eingeben. Der Suchtext kann aus jeder der Spalten stammen, entweder vollständig oder teilweise, einige Zeichen von links. Da wir im ListView-Steuerelement zwei Kategorien von Objektmitgliedern hintereinander haben:ListItem - Die erste Spalte und andere Spalten sind ListSubItems. Die Textsuche für diese Objekte wird separat durchgeführt.
Neben der TextBox für die Suchtexteingabe auf dem Formular wird eine Optionsgruppe mit zwei CheckBoxen bereitgestellt, um die Suchoptionen auszuwählen. Die erste Option ist standardmäßig ausgewählt und die Suche wird in der ersten Spalte (ListItem ), um nach dem angegebenen Text zu suchen.
Wählen Sie die zweite Option, um den Text in ListSubItem zu durchsuchen Spalten.
Hinweis: Durch die Neuanordnung der Spalten werden die Objekte nicht geändert, sondern nur ihre Anzeigeposition. Ziehen eines ListSubItem Spalte und das Einbringen in die erste Spalte ändert sich nicht es in ein ListItem Objekt.
Wenn Sie einen unbekannten Wert aus einer bestimmten Spalte abrufen möchten, wählen Sie einen Spaltennamen aus der ComboBox aus, die unterhalb der ersten TextBox im Formular für den Suchtext angegeben ist. Sie kennen beispielsweise die Körpergröße eines Schülers nicht und möchten dies herausfinden, wählen Sie den Spaltennamen Körpergröße aus aus der ComboBox.
Nachdem Sie die obigen Werte eingestellt haben, klicken Sie auf Element finden Befehlsschaltfläche für den Suchvorgang. Wenn die Suche erfolgreich war, wird das Ergebnis im großen Label-Steuerelement unterhalb der Befehlsschaltfläche angezeigt.
Klicken Sie auf die Befehlsschaltfläche [Find Item].
Ruft SearchAndFind() auf Vorgehensweise.
Private Sub SearchAndFind() 'Find by Student Name Dim lstItem As MSComctlLib.ListItem Dim strFind As String Dim strColName As String Dim strColVal As String Dim j As Integer Dim intOpt As Integer Dim msgText As String Me.Refresh intOpt = Me.Opts strFind = Nz(Me![txtFind], "") strColName = Nz(Me![txtCol], "") Select Case intOpt Case 1 Set lstItem = lvwList.FindItem(strFind, , , lvwPartial) If Not lstItem Is Nothing Then j = lstItem.Index 'format the display text msgText = lvwList.ColumnHeaders.Item(1).Text msgText = msgText & " : " & lstItem.Text & vbCr & vbCrLf Else MsgBox "Text '" & strFind & "' Not Found!", vbOKOnly + vbCritical, "cmdFind_Click()" Exit Sub End If Case 2 Set lstItem = lvwList.FindItem(strFind, lvwSubItem, , lvwPartial) If Not lstItem Is Nothing Then 'format the display text j = lstItem.Index msgText = lvwList.ColumnHeaders.Item(1).Text msgText = msgText & ": " & lstItem.Text & vbCr & vbCrLf Else MsgBox strFind & " Not Found!", vbOK + vbCritical, "cmdFind_Click()" Exit Sub End If End Select If Len(strColName) = 0 Then 'If column name is not selected GoTo nextStep Else 'Get the column value strColVal = GetColVal(lstItem, strColName) msgText = msgText & String(8 - (Len(strColName)), " ") & _ strColName & ": " & Nz(strColVal, "") End If nextStep: If Len(msgText) > 0 Then 'assign to form label lvwList.ListItems.Item(j).Selected = True lblMsg.caption = msgText End If End Sub
Zu Beginn des Programms werden sowohl der Studentenname und Spaltenname ( Optional), werden aus den TextBoxen in die Variablen strFind kopiert und strColName bzw. nach Validierungsprüfungen.
Hinweis: Die Not-in-List-Eigenschaft des Spaltennamen-Kombinationsfelds ist auf Ja festgelegt. Sie können einen gültigen Wert aus der Liste auswählen oder eingeben oder das Kombinationsfeld leer lassen. Wenn Sie einen anderen Wert eingeben, der nicht in der Liste enthalten ist, wird er nicht akzeptiert.
Basierend auf der ausgewählten Suchoption (1 - ListItem oder 2 - ListSubItem) wird die Suchmethode zu den angegebenen Objekten geleitet.
Wenn Sie eine dieser Suchmethoden verwenden, wird das ListItem-Objekt gefunden oder Zeile die den Suchtext enthält. Der Indexwert des ListItems wird in der Variablen J gespeichert zur späteren Verwendung im Programm.
Hinweis: Das System erstellt die automatischen Indexnummern automatisch zu dem Zeitpunkt, zu dem ListView-Steuerelementelemente ausgefüllt werden.
Der ListItem.Text Wert wird abgerufen. Diese Informationen werden mit dem ersten ColumnHeader verknüpft. Text (wie Student:Robert King) und in die Msgtext-Zeichenfolge eingefügt, um im Label-Steuerelement auf dem Formular angezeigt zu werden.
Wenn die Spalte Header Name in der ComboBox ausgewählt ist, dann wird die GetColVal() Die Funktion wird mit dem ListItem-Objekt und dem Textwert der Spaltenüberschrift als Parameter aufgerufen. Diese Option eignet sich gut zum Abrufen unbekannter Informationen über einen Schüler, wie z. B. die Größe des Schülers, aus dem Datensatz.
Der VBA-Code der GetColVal()-Funktion.
Private Function GetColVal(lvwItem As MSComctlLib.ListItem, ByVal colName As String) As String Dim i As Integer Dim strVal As String 'first column is student name 'check for column value from 2nd column onwards For i = 2 To lvwList.ColumnHeaders.Count If lvwList.ColumnHeaders(i).Text = colName Then 'if col name matches strVal = lvwItem.ListSubItems.Item(i - 1).Text 'get column value Exit For 'No further scanning required End If Next GetColVal = strVal 'return the retrieved the value End Function
Die obige Funktion fragt nach zwei Parametern. Der erste Parameter ist das ListItem, in dem der Name des Schülers zu finden ist. Der zweite Parameter ist der Spaltenname. Alter, Größe, Gewicht, Klasse des ausgewählten Schülers Werte werden in ListItem.ListSubItems gespeichert Objekte. Die Funktion durchsucht den lvwList.ColumnHeader Werten, um den übereinstimmenden Spaltennamen zu finden, wenn diese Spaltenindexnummer gefunden wird, wird sie zum Abrufen des Spaltenwerts aus dem ListSubItems-Objekt verwendet und gibt den Wert an das aufrufende Programm zurück.
Die Befehlsschaltfläche [Find By Key] Click Event Procedure.
Wir haben eine weitere Methode hinzugefügt, um den Namen des Schülers mithilfe des eindeutigen Schlüsselwerts von ListItem zu finden wenn es beim Erstellen der ListItem-Liste verwendet wird. Auch wenn es optional ist, ist es besser, den Unique Key String Value hinzuzufügen (sollte mit einem Buchstaben beginnen), anstatt ihn zu ignorieren.
Wenn wir beispielsweise die Informationen einer Person anhand ihrer Identifikationsnummer wie Sozialversicherungsnummer, Personalausweisnummer, Reisepassnummer oder Führerscheinnummer usw. finden müssen, kann eine dieser Informationen als Schlüsselwert für das ListItem verwendet werden. Das Auffinden eines Datensatzes mit diesem eindeutigen Wert ist sehr einfach und schneller als die obige Suche nach Text.
Die cmdKey_Click()-Ereignisprozedur.
Calls FindByKey() Subroutine.
Private Sub FindByKey() Dim colHeader As MSComctlLib.ColumnHeader Dim lvItem As MSComctlLib.ListItem Dim lvKeyVal As String Dim lvColName As String Dim txt As String Dim msgText As String Dim varcolVal As Variant lvKeyVal = UCase(Nz(Me!txtKey, "")) lvColName = Nz(Me!txtCol, "") If len(lvKeyVal) > 0 then On Error Resume Next Set lvItem = lvwList.ListItems.Item(lvKeyVal) 'get the item by Key If Err > 0 Then Err.Clear MsgBox "Key Value: '" & lvKeyVal & "' Not Found!", vbOKOnly + vbCritical, "cmdKey_Click()" On Error GoTo 0 Exit Sub End If Else MsgBox "Please Provide a Valid Key-Value!",vbOKOnly + vbCritical, "cmdKey_Click()" Exit Sub End If txt = lvItem.Text 'get the student name 'format message text msgText = lvwList.ColumnHeaders.Item(1).Text & " : " msgText = msgText & txt & vbCr & vbCrLf If Len(lvColName) > 0 Then 'if column name is given varcolVal = GetColVal(lvItem, lvColName) 'get column val of student msgText = msgText & String(8 - Len(lvColName), " ") & lvColName & ": " & varcolVal ' add it to display End If lvItem.Selected = True 'highlight the item on form Me.lblMsg.caption = msgText 'assign details to form Label End Sub
Wie Sie in der obigen Subroutine sehen können, konnten wir das ListItem direkt finden wo der Name des Schülers steht, unter Verwendung des Schlüsselwerts , mit einer einzigen Anweisung:Set lvItem =lvwList.ListItems.Item(xKeyVal).
Die nächste Zeile liest den ListItem-Text (oder den Namen des Schülers) in die Variable txt . Die nächsten beiden Zeilen erstellen den Nachrichtentext mit dem Namen des Schülers in der String-Variable msgText.
Das nächste Wenn . . .Dann -Anweisung überprüft, ob im Kombinationsfeld-Steuerelement ein Spaltenname-Wert eingegeben wurde. Wenn es gefunden wird, wird GetColVal() aufgerufen Funktion mit den erforderlichen Parametern, um den Spaltenwert zu finden und in varColVal abzurufen Variable und kehrt zum aufrufenden Programm zurück. Der Spaltenname und sein abgerufener Wert werden zur msgText-String-Variablen hinzugefügt, um auf dem Label-Steuerelement auf dem Formular angezeigt zu werden.
Die nächste Anweisung hebt die Datensatzzeile des Schülers als visuelle Anzeige hervor, dass das gesuchte Element in der Zeile gefunden wird. Der msgText-Wert wird in der Caption-Eigenschaft des Labels auf dem Formular angezeigt.
Der vollständige VBA-Code im Formularmodul.
Option Compare Database Option Explicit Dim lvwList As MSComctlLib.ListView 'ListView Control Dim lvwItem As MSComctlLib.ListItem ' Dim ObjImgList As MSComctlLib.ImageList Const prfx As String = "K" Private Sub Form_Load() Call LoadListView Call txtColCombo End Sub Private Function LoadListView() 'Populate the ListView control with Student Details Dim db As DAO.Database Dim rst As DAO.Recordset Dim intCounter As Integer Dim strKey As String 'Assign ListView Control on Form to lvwList Object Set lvwList = Me.ListView1.Object With lvwList .AllowColumnReorder = True .Enabled = True .Font = "Verdana" .Font.Bold = True .Font.Size = 9 .ForeColor = vbBlack .BackColor = vbWhite End With 'Create Column Headers for ListView With lvwList .ColumnHeaders.Clear 'initialize header area 'Syntax: .ColumnHeaders.Add Index, Key, Text, Width, Alignment, Icon .ColumnHeaders.Add , , "Student", 2500 .ColumnHeaders.Add , , "Age", 1200 .ColumnHeaders.Add , , "Height", 1200 .ColumnHeaders.Add , , "weight", 1200 .ColumnHeaders.Add , , "Class", 1200 End With 'Initialize ListView Control While lvwList.ListItems.Count > 0 lvwList.ListItems.Remove (1) Wend 'Student Names and Ids are taken from Employees Table 'through the StudentQ Query. Set db = CurrentDb Set rst = db.OpenRecordset("StudentQ", dbOpenDynaset) With lvwList Do While Not rst.EOF And Not rst.BOF intCounter = rst![EmployeeID] strKey = "X" & Format(intCounter, "00") 'Key Value sample: X01 'Syntax: .ListItems.Add(Index, Key, Text, Icon, SmallIcon) Set lvwItem = .ListItems.Add(, strKey, rst![Student]) With lvwItem 'Syntax: .Add Index,Key,Text,Report Icon,TooltipText .ListSubItems.Add , strKey & CStr(intCounter), CStr(5 + intCounter) .ListSubItems.Add , strKey & CStr(intCounter + 1), CStr(135 + intCounter) .ListSubItems.Add , strKey & CStr(intCounter + 2), CStr(40 + intCounter) .ListSubItems.Add , strKey & CStr(intCounter + 3), ("Class:" & Format(intCounter, "00")) End With rst.MoveNext Loop rst.Close Set rst = Nothing Set db = Nothing Set lvwItem = Nothing End With lvwList.Refresh End Function Private Sub cmdClose_Click() DoCmd.Close acForm, Me.Name End Sub Private Sub cmdFind_Click() Call SearchAndFind End Sub Private Sub cmdKey_Click() Call FindByKey End Sub Private Function GetColVal(lvwItem As MSComctlLib.ListItem, ByVal colName As String) As String Dim i As Integer Dim strVal As String 'first column is student name 'check for column value from 2nd column onwards For i = 2 To lvwList.ColumnHeaders.Count If lvwList.ColumnHeaders(i).Text = colName Then 'if col name matches strVal = lvwItem.ListSubItems.Item(i - 1).Text 'get column value Exit For 'No further scanning required End If Next GetColVal = strVal 'return the retrieved the value End Function Private Sub txtColCombo() 'Column Header List Combo Dim lvwColHead As MSComctlLib.ColumnHeader Dim cboName As ComboBox Set cboName = Me.txtCol cboName.RowSourceType = "Value List" For Each lvwColHead In lvwList.ColumnHeaders If lvwColHead.Index = 1 Then 'Nothing Else cboName.AddItem lvwColHead.Text End If Next 'cboName.DefaultValue = "=txtCol.Column(0, 0)" Set lvwColHead = Nothing Set cboName = Nothing End Sub Public Sub SearchAndFind() 'Find by Student Name Dim lstItem As MSComctlLib.ListItem Dim strFind As String Dim strColName As String Dim strColVal As String Dim j As Integer Dim intOpt As Integer Dim msgText As String Me.Refresh intOpt = Me.Opts strFind = Nz(Me![txtFind], "") strColName = Nz(Me![txtCol], "") Select Case intOpt Case 1 Set lstItem = lvwList.FindItem(strFind, , , lvwPartial) If Not lstItem Is Nothing Then j = lstItem.Index 'format the display text msgText = lvwList.ColumnHeaders.Item(1).Text msgText = msgText & " : " & lstItem.Text & vbCr & vbCrLf Else MsgBox "Text '" & strFind & "' Not Found in the List!", vbOKOnly + vbCritical, "cmdFind_Click()" Exit Sub End If Case 2 Set lstItem = lvwList.FindItem(strFind, lvwSubItem, , lvwPartial) If Not lstItem Is Nothing Then 'format the display text j = lstItem.Index msgText = lvwList.ColumnHeaders.Item(1).Text msgText = msgText & ": " & lstItem.Text & vbCr & vbCrLf Else MsgBox strFind & " Not Found!", vbOK + vbCritical, "cmdFind_Click()" Exit Sub End If End Select If Len(strColName) = 0 Then 'If column name is not selected GoTo nextStep Else 'Get the column value strColVal = GetColVal(lstItem, strColName) msgText = msgText & String(8 - (Len(strColName)), " ") & _ strColName & ": " & Nz(strColVal, "") End If nextStep: If Len(msgText) > 0 Then 'assign to form label lblMsg.caption = msgText lvwList.ListItems.Item(j).Selected = True End If End Sub Public Sub FindByKey() Dim colHeader As MSComctlLib.ColumnHeader Dim lvItem As MSComctlLib.ListItem Dim lvKeyVal As String Dim lvColName As String Dim txt As String Dim msgText As String Dim varcolVal As Variant lvKeyVal = UCase(Nz(Me!txtKey, "")) lvColName = Nz(Me!txtCol, "") On Error Resume Next If Len(lvKeyVal) > 0 Then Set lvItem = lvwList.ListItems.Item(lvKeyVal) 'get the item by Key If Err > 0 Then Err.Clear MsgBox "Key Value: '" & lvKeyVal & "' Not Found!", vbOKOnly + vbCritical, "cmdKey_Click()" On Error GoTo 0 Exit Sub End If Else MsgBox "Please Provide a Valid Key-Value!", vbOKOnly + vbCritical, "cmdKey_Click()" Exit Sub End If txt = lvItem.Text 'get the student name 'format message text msgText = lvwList.ColumnHeaders.Item(1).Text & " : " msgText = msgText & txt & vbCr & vbCrLf If Len(lvColName) > 0 Then 'if column name is given varcolVal = GetColVal(lvItem, lvColName) 'get column val of student msgText = msgText & String(8 - Len(lvColName), " ") & lvColName & ": " & varcolVal ' add it to display End If lvItem.Selected = True 'highlight the item on form Me.lblMsg.caption = msgText 'assign details to form Label End Sub
Laden Sie die Demo-Datenbank unter folgendem Link herunter:
- Tutorial für das Microsoft TreeView-Steuerelement
- Zugriffsmenü mit TreeView-Steuerelement erstellen
- Zuweisen von Bildern zu TreeView-Knoten
- Zuweisen von Bildern zu TreeView-Knoten-2
- TreeView Control Häkchen hinzufügen löschen
- TreeView ImageCombo Drop-down-Zugriff
- TreeView-Knoten per Drag-and-Drop neu anordnen
- ListView Control mit MS-Access TreeView
- Drag-Drop-Ereignisse des ListView-Steuerelements
- TreeView-Steuerelement mit Unterformularen