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