Inleiding.
Vervolg van de ActiveX ListView Control Tutorial-01 van vorige week.
In deze sessie van de zelfstudie leren we hoe u de specifieke rij- en kolomwaarden kunt zoeken en vinden en deze kunt weergeven op een labelbesturingselement op formulier. Dit is erg handig wanneer we een grote hoeveelheid gegevens in het ListView-besturingselement hebben. We zullen ook het gebruik van sommige ListView-eigenschapsinstellingen leren.
Allereerst zullen we zien hoe gemakkelijk het is om de kolommen te herschikken, zoals we doen met Access Datasheet View zoals we willen dat ze in het ListView-besturingselement staan. We hebben een aantal TextBoxen, ComboBox, Command Buttons en Label toegevoegd voor een eenvoudigere selectie van zoekparameters en weergave van zoekresultaten.
Ik heb enkele wijzigingen aangebracht in de demogegevens van vorige week. De eerste kolomwaarden heb ik overgenomen uit de Employees Table of Northwind.accdb-voorbeelddatabase. Een query gemaakt om de waarden voor Achternaam en Voornaam samen te voegen met de veldnaam Student en Werknemer-ID gebruikt als Sleutel (X01, X02 ...).
Voordat we naar de zoekbewerkingen gaan, zullen we controleren hoe de kolommen opnieuw kunnen worden gerangschikt door middel van slepen en neerzetten.
Opmerking: Als u de eerdere Tutorial-pagina niet hebt doorlopen en u wilt doorgaan met deze sessie, ga dan naar de ListView Control Tutorial-01-pagina en download de demo-database onderaan die pagina.
Pak het bestand uit en open de database. Het demoformulier bevindt zich in de normale weergave.
-
Open uw database, met het demoformulier van de laatste sessie, of het formulier dat u hebt gemaakt, open het in de normale weergave.
Nu gaan we proberen een kolom uit het midden van de lijst te slepen en te verplaatsen (zeg de kolom Gewicht) en deze neer te zetten op de Leeftijd kolom en kijk wat er gebeurt. Wat er naar verwachting zal gebeuren, is dat de kolom Leeftijd naar rechts moet verschuiven en de inkomende kolom op zijn plaats moet invoegen.
-
Beweeg de muisaanwijzer over de kolomkop met de naam Gewicht, klik en houd de linkermuisknop ingedrukt. Als u de linkermuisknop indrukt, wordt de kolomkop iets naar beneden verplaatst.
-
Probeer nu de kolom naar links te slepen en neer te zetten op de kolom Leeftijd .
Er gebeurt niets, omdat we deze functie niet hebben ingeschakeld in het eigenschappenblad en dat is de enige instelling die we moeten wijzigen om deze functie te laten werken.
-
Wijzig het formulier in de ontwerpweergave.
-
Klik met de rechtermuisknop op het ListView-besturingselement en markeer de optie ListViewCtrl Object en selecteer Eigenschappen.

-
Er is een optie 'AllowColumnReorder ' aan de rechterkant. Zet een vinkje om het te selecteren en klik vervolgens op Toepassen knop gevolgd door de OK om de eigenschappenweergave te sluiten.
-
Probeer nu de bovenstaande stappen 2 en 3 hierboven te herhalen en kijk wat er gebeurt.
Dat is de enige instelling die u nodig hebt om deze functie in het ListView-besturingselement in te schakelen. Misschien denk je misschien, hoe zit het met het herschikken van de rijen?
Die functie moet een aantal gebeurtenisprocedures programmeren, zoals we eerder deden in TreeView Control Drag-Drop-gebeurtenissen. Dat deel zullen we na een tijdje doen.
-
Je kunt met elke kolom experimenteren om overal te komen waar je maar wilt, ook met de eerste kolom.
Opmerking: Voordat u de bronkolom laat vallen, moet u ervoor zorgen dat de doelkolom wordt bedekt door het inkomende kolomframe voordat u probeert te verwijderen. Anders kan de inkomende kolom verschuiven naar de volgende kolompositie aan de rechterkant.
Vervolgens zullen we leren hoe we snel wat informatie uit de ListView kunnen vinden, ervan uitgaande dat we een grote hoeveelheid gegevens bevatten.
We hebben een subroutine toegevoegd aan de module Tutorial-01 om de kolomkopnamen in een keuzelijst met invoervak op het formulier te laden met de rode achtergrondkleur. De kolomnaam wordt gebruikt om de kolomwaarde (leeftijd, lengte, gewicht of klas) van een leerling te vinden.
Nieuwe VBA-code toegevoegd aan de Form Class-module.
De volgende nieuwe VBA-procedure is toegevoegd aan de lesmodule van het Tutorial Form van vorige week:
De txtColCombo maakt de lijst met kolomkoplabels (veldnamen) in de ComboBox. Een van deze details van Leeftijd, lengte, gewicht . van de leerling of Klasse kan samen met de naam van de student worden gevonden als onderdeel van de zoek-en-vind-operatie.
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
De combobox wordt niet geladen met een standaardwaarde van de kolomkopnaam. Indien geselecteerd, wordt die kolomwaarde van de student weergegeven in het grote label onder de naam van de student. Als het leeg wordt gelaten, zal de zoekactie alleen de naam van de leerling vinden.
De zoekbewerkingsmethode is zeer flexibel en snel. We hebben twee methoden om een record te vinden.
Zoek het record door de zoektekst op te geven. De zoektekst kan uit elk van de kolommen komen, ofwel de tekst in volledige of gedeeltelijke tekens vanaf de linkerkant. Aangezien we twee categorieën objectleden op een rij hebben in het ListView-besturingselement:ListItem - de eerste kolom en andere kolommen zijn ListSubItems. De tekstzoekbewerking op deze objecten wordt afzonderlijk uitgevoerd.
Er is een optiegroep met twee CheckBoxen naast de zoektekstinvoer TextBox op het formulier om de zoek-en-vind-opties te selecteren. De eerste optie is standaard geselecteerd en de zoekopdracht wordt uitgevoerd op de eerste kolom (ListItem ) om de gegeven tekst te zoeken.
Selecteer de tweede optie om de tekst te zoeken in het ListSubItem kolommen.
Opmerking: Door de kolommen opnieuw te rangschikken, worden de objecten niet gewijzigd, maar alleen hun weergavepositie. Een ListSubItem slepen kolom en zet het in de eerste kolom zal niet veranderen het in een ListItem voorwerp.
Als u een onbekende waarde uit een bepaalde kolom wilt ophalen, selecteert u een kolomnaam uit de ComboBox onder het eerste tekstvak op het formulier voor de zoektekst. Weet je bijvoorbeeld de lengtemaat van een leerling niet en wil je dat graag weten, selecteer dan de kolomnaam Hoogte van de ComboBox.
Nadat u de bovenstaande waarde(n) heeft ingesteld, klikt u op Item zoeken Command-knop om naar de zoekactie te gaan. Als het zoeken is gelukt, wordt het resultaat weergegeven in het grote Label-besturingselement onder de Command-knop.
De [Find Item] Command Button Click.
Roept de SearchAndFind() . aan Procedure.
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 Aan het begin van het programma worden zowel de Naam leerling en Kolomnaam ( 0optioneel), worden gekopieerd van de tekstvakken naar de variabelen strFind en strColName respectievelijk na validatiecontroles.
Opmerking: De kolomnaam Niet-in-lijst-eigenschap van Combo Box is ingesteld op Ja. U kunt een geldige waarde uit de lijst selecteren of deze intypen of de keuzelijst met invoervak leeg laten. Als u een andere waarde typt die niet in de lijst staat, wordt deze niet geaccepteerd.
Op basis van de geselecteerde zoekoptie (1 - ListItem of 2 - ListSubItem) wordt de scanmethode doorgestuurd naar de gespecificeerde Object(en).
Als u een van deze zoekmethoden gebruikt, wordt het ListItem Object . gevonden of rij die de zoektekst bevat. De indexwaarde van het ListItem wordt opgeslagen in Variabele J voor later gebruik in het programma.
Opmerking: Het systeem maakt de automatische indexnummers automatisch aan op het moment dat ListView-besturingsitems worden ingevuld.
De ListItem.Text waarde wordt opgehaald. Deze informatie wordt samengevoegd met de eerste ColumnHeader. Tekst (zoals Student:Robert King) en toegevoegd aan de Msgtext-tekenreeks om weer te geven in het Label-besturingselement op het formulier.
Als de kolom Header Name is geselecteerd in de ComboBox, dan is de GetColVal() Functie wordt aangeroepen met het ListItem Object en de Column Header Text-waarde als parameters. Deze optie is goed voor het ophalen van onbekende informatie over een student, zoals de lengte van de student, uit het record.
De GetColVal()-functie VBA-code.
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 De bovenstaande functie vraagt om twee parameters. De eerste parameter is het ListItem, waar de naam van de student wordt gevonden. De tweede parameter is de kolomnaam. Leeftijd, lengte, gewicht, klas . van de geselecteerde leerling waarden worden opgeslagen in de ListItem.ListSubItems Voorwerpen. De functie kijkt door de lvwList.ColumnHeader waarden om de overeenkomende kolomnaam te vinden, wanneer dat kolomindexnummer wordt gevonden, wordt gebruikt voor het ophalen van de kolomwaarde uit het ListSubItems-object en retourneert de waarde naar het aanroepende programma.
De [Zoeken op toets] opdrachtknop Klik op gebeurtenisprocedure.
We hebben een andere methode toegevoegd om de naam van de student te vinden met behulp van de unieke sleutelwaarde van ListItem indien gebruikt tijdens het maken van de ListItem List. Ook al is het optioneel, het is beter om Unique Key String Value toe te voegen (moet beginnen met een alfabetteken) in plaats van deze te negeren.
Als we bijvoorbeeld iemands informatie moeten vinden aan de hand van hun identificatienummer, zoals burgerservicenummer, nationaal identiteitskaartnummer, paspoortnummer of rijbewijsnummer, enzovoort, kan een van deze informatie worden gebruikt als de sleutelwaarde voor het ListItem. Het vinden van een record met deze Unieke Waarde is heel gemakkelijk en sneller dan de bovenstaande methode voor zoeken op tekst.
De cmdKey_Click()-gebeurtenisprocedure.
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 Zoals je in de bovenstaande subroutine kunt zien, kunnen we het ListItem . direct vinden waar de naam van de student is, met behulp van de Key-value, met een enkele instructie:Set lvItem =lvwList.ListItems.Item(xKeyVal).
De volgende regel leest de ListItem-tekst (of naam van de student) in de variabele txt . De volgende twee regels maken de berichttekst met de naam van de student in de msgText-tekenreeksvariabele.
De volgende Als . . .Dan statement controleert of een kolomnaamwaarde is ingevoerd in de keuzelijst met invoervak. Als het wordt gevonden, roept het de GetColVal() . aan Functie met de vereiste parameters om de kolomwaarde te vinden en op te halen in varColVal Variabel en keert terug naar het oproepende programma. De kolomnaam en de opgehaalde waarde worden toegevoegd aan de msgText-tekenreeksvariabele om weer te geven op het Label-besturingselement op het formulier.
De volgende verklaring markeert de record Rij van de student als een visuele indicatie dat het gezochte item in de rij is gevonden. De waarde msgText wordt weergegeven in de eigenschap bijschrift van het label op het formulier.
De volledige VBA-code op de formuliermodule.
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
Download de demodatabase via de volgende link:
- Microsoft TreeView Control-zelfstudie
- Toegangsmenu maken met TreeView Control
- Afbeeldingen toewijzen aan TreeView-knooppunten
- Afbeeldingen toewijzen aan TreeView Nodes-2
- TreeView Control Vinkje Toevoegen Verwijderen
- Toegang via vervolgkeuzelijst TreeView ImageCombo
- Herschik TreeView-knooppunten door middel van slepen en neerzetten
- ListView-besturing met MS-Access TreeView
- ListView Control Drag Drop-gebeurtenissen
- TreeView-besturing met subformulieren