sql >> Database teknologi >  >> RDS >> Access

ListView Control Tutorial-02

Introduktion.

Fortsat fra sidste uges ActiveX ListView Control Tutorial-01.

I denne session af selvstudiet lærer vi, hvordan du søger og finder de bestemte række- og kolonneværdier og viser dem på en etiketkontrol på formularen. Dette er meget nyttigt, når vi har en stor mængde data i ListView-kontrollen. Vi vil også lære brugen af ​​nogle ListView-egenskabsindstillinger.

Først og fremmest vil vi se, hvor nemt det er at omarrangere kolonnerne, som vi gør med Access Datasheet View, som vi ønsker, at de skal være på ListView Control. Vi har tilføjet nogle TextBoxes, ComboBox, Command Buttons og Label for nemmere valg af søgeparametre og visning af søgeresultater.

Jeg har lavet nogle ændringer i sidste uges demodata. De første kolonneværdier har jeg taget fra Employees Table of Northwind.accdb eksempeldatabasen. Oprettede en forespørgsel for at forbinde efternavns- og fornavnsværdierne med feltnavnet Student og EmployeeID brugt som nøgle (X01, X02 ...).

Før vi går til søgeoperationerne, vil vi kontrollere, hvordan man omarrangerer kolonner ved hjælp af træk og slip-metoden.

Bemærk: Hvis du ikke har gennemgået den tidligere selvstudieside og gerne vil fortsætte med denne session, så gå til ListView Control Tutorial-01-siden og download demodatabasen fra bunden af ​​den side.

Pak filen ud og åbn databasen. Demoformularen vil være i normal visning.

  1. Åbn din database med den sidste sessions demoformular, eller den formular, du har oprettet, åbn den i normal visning.

    Nu vil vi prøve at trække og flytte en kolonne fra midten af ​​listen (f.eks. kolonnen Vægt) og slippe den til Alder kolonne og se, hvad der sker. Det, der forventes at ske, er, at kolonnen Alder skal skifte til højre og indsætte den indgående kolonne i stedet for.

  2. Flyt musemarkøren på kolonneoverskriften med navnet Vægt klik og hold venstre museknap nede. Når du trykker på venstre museknap, flyttes kolonneoverskriften lidt ned.

  3. Prøv nu at trække kolonnen til venstre og slip den på kolonnen Alder .

    Der vil ikke ske noget, fordi vi ikke har aktiveret denne funktion i egenskabsarket, og det er den eneste indstilling, vi skal ændre for at denne funktion kan fungere.

  4. Skift formularen i designvisning.

  5. Højreklik på ListView Control og fremhæv muligheden ListViewCtrl Object og vælg Egenskaber.

  6. Der er muligheden 'AllowColumnReorder ' på den højre side. Sæt et flueben for at vælge det, og klik derefter på Anvend knappen efterfulgt af OK knappen for at lukke ejendomsvisningen.

  7. Prøv nu at gentage ovenstående trin 2 og 3 ovenfor og se, hvad der sker.

    Det er den eneste indstilling, du behøver for at aktivere denne funktion på ListView Control. Måske tænker du måske, hvad med at omarrangere rækkerne?.

    Denne funktion skal programmere nogle hændelsesprocedurer, som vi gjorde tidligere i TreeView Control Drag-Drop Events. Den del gør vi efter noget tid.

  8. Du kan eksperimentere med en hvilken som helst kolonne for at flytte hvor som helst du vil, inklusive den første kolonne også.

Bemærk: Før du slipper kildekolonnen, skal du se, at målkolonnen er dækket af den indgående kolonneramme, før du forsøger at slippe. Ellers kan den indgående kolonne skifte til den næste kolonneposition på højre side.

Dernæst vil vi lære, hvordan man hurtigt finder nogle oplysninger fra ListView, forudsat at vi har en stor mængde data i den.

Vi har tilføjet en underrutine til Tutorial-01 Module for at indlæse kolonneoverskriftens navne i en kombinationsboks på formularen med den røde baggrundsfarve. Kolonnenavnet bruges til at finde kolonneværdien (Alder, Højde, Vægt eller Klasse) for en elev.

Ny VBA-kode tilføjet til Form Class Module.

Følgende nye VBA-procedure er tilføjet til sidste uges vejledningsformulars klassemodul:

txtColCombo opretter listen over kolonneoverskriftsetiketter (feltnavne) i ComboBox. En af disse detaljer om elevens alder, højde, vægt, eller Klasse kan findes sammen med elevens navn som en del af søg-og-find-operationen.

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

Combobox vil ikke blive indlæst med en standardværdi for kolonneoverskriftsnavn. Hvis den er valgt, vises denne kolonneværdi for eleven i den store etiket under elevens navn. Hvis det efterlades tomt, vil søgeoperationen kun finde elevens navn.

Søgeoperationsmetoden er meget fleksibel og hurtig. Vi har to metoder til at finde en post.

Find posten ved at angive søgeteksten. Søgeteksten kan være fra enhver af kolonnerne, enten teksten helt eller delvist få tegn fra venstre. Da vi har to kategorier af objektmedlemmer i træk i ListView-kontrollen:ListItem - den første kolonne og andre kolonner er ListSubItems. Tekstsøgningen på disse objekter udføres separat.

En indstillingsgruppe med to afkrydsningsfelter er tilvejebragt ved siden af ​​søgetekstindtastningstekstboksen på formularen for at vælge søge-og-find-mulighederne. Den første mulighed er valgt som standard, og søgningen udføres i den første kolonne (ListItem ) for at lede efter den givne tekst.

Vælg den anden mulighed for at søge i teksten i ListSubItem kolonner.

Bemærk: Omarrangering af kolonnerne vil ikke ændre objekterne, men kun deres visningsposition. Træk et ListSubItem kolonne og bringe den i den første kolonne ændres ikke det til et ListItem objekt.

Hvis du ønsker at hente en ukendt værdi fra en bestemt kolonne, skal du vælge et kolonnenavn fra ComboBox givet under den første tekstboks på formularen til søgeteksten. For eksempel kender du ikke en elevs højdemåling og gerne vil finde ud af det, vælg kolonnenavnet Højde fra ComboBox.

Efter indstilling af ovenstående værdi(er), klik på Find element Kommandoknap for at gå til søgeoperationen. Hvis søgningen lykkedes, vil resultatet blive vist i den store etiketkontrol under kommandoknappen.

Klik på kommandoknappen [Find element].

Kalder SearchAndFind() 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

I begyndelsen af ​​programmet er både Students navn og Kolonnenavn ( 0valgfrit), kopieres fra tekstboksene til variablerne strFind og strColName efter valideringstjek.

Bemærk: Kolonnenavnet Combo Box's Not-in-List-egenskab er indstillet til Ja. Du kan vælge en gyldig værdi fra listen eller indtaste den eller lade kombinationsboksen stå tom. Hvis du indtaster en anden værdi, som ikke er på listen, vil den ikke blive accepteret.

Baseret på den valgte søgemulighed (1 - ListItem eller 2 - ListSubItem) dirigeres scanningsmetoden til det eller de specificerede objekt(er).

Ved at bruge en af ​​disse søgemetoder finder du ListItem Object eller række der indeholder søgeteksten. Indeksværdien for listeelementet gemmes i variabel J til senere brug i programmet.

Bemærk: Systemet opretter automatisk indeksnumrene på det tidspunkt, hvor ListView-kontrolelementer udfyldes.

ListItem.Text værdi hentes. Denne information er forenet med den første ColumnHeader. Tekst (som Elev:Robert King) og tilføjet i Msgtext-strengen for at blive vist i Label-kontrolelementet på formularen.

Hvis kolonnen Header Name er valgt i ComboBox, derefter GetColVal() Funktionen kaldes med ListItem Object og Column Header Text værdien som parametre. Denne mulighed er god til at hente ukendte oplysninger om en elev, f.eks. elevens højde, fra posten.

GetColVal()-funktionen VBA-kode.

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

Ovenstående funktion beder om to parametre. Den første parameter er ListItem, hvor elevens navn findes. Den anden parameter er kolonnenavnet. Den valgte elevs Alder, Højde, Vægt, Klasse værdier gemmes i ListItem.ListSubItems Objekter. Funktionen ser gennem lvwList.ColumnHeader værdier for at finde det matchende kolonnenavn, når det er fundet, at kolonneindeksnummeret bruges til at hente kolonneværdien fra ListSubItems-objektet og returnerer værdien til det kaldende program.

Kommandoknappen [Find efter tast] Klik på Hændelsesprocedure.

Vi har tilføjet en anden metode til at finde elevens navn ved hjælp af den unikke nøgleværdi for ListItem hvis det bruges under oprettelse af ListItem List. Selvom det er valgfrit, er det bedre at tilføje unik nøglestrengværdi (skal starte med et alfabet) i stedet for at ignorere det.

For eksempel, hvis vi skal finde en persons oplysninger ud fra deres identifikationsnummer som CPR-nummer, nationalt identitetskortnummer, pasnummer eller kørekortnummer og så videre, kan en af ​​disse oplysninger bruges som nøgleværdien til ListItem. Det er meget nemt og hurtigere at finde en post med denne unikke værdi i stedet for ovenstående søg-på-tekst-metode.

CmdKey_Click()-hændelsesproceduren.

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

Som du kan se i ovenstående underrutine, kunne vi direkte finde ListItem hvor elevens navn er, med brug af nøgleværdien, med en enkelt sætning:Sæt lvItem =lvwList.ListItems.Item(xKeyVal).

Den næste linje læser ListItem-teksten (eller navnet på eleven) i variablen txt . De næste to linjer opretter meddelelsesteksten med elevens navn i msgText-strengvariablen.

Den næste Hvis . . .Så sætning kontrollerer, om en kolonnenavnsværdi er indtastet i kombinationsboksens kontrolelement. Hvis den findes, kalder du GetColVal() Funktion med de nødvendige parametre for at finde kolonneværdien og hente den i varColVal Variabel og vender tilbage til det kaldende program. Kolonnenavnet og dets hentede værdi føjes til msgText-strengvariablen for at blive vist på Label-kontrolelementet på formularen.

Den næste sætning fremhæver elevens postrække som en visuel indikation af, at det søgte element er fundet i rækken. msgText-værdien vises i etikettens billedtekstegenskab på formularen.

Den fulde VBA-kode på formularmodulet.

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 demodatabasen fra følgende link:



  1. Microsoft TreeView Control Tutorial
  2. Oprettelse af adgangsmenu med TreeView-kontrol
  3. Tildeling af billeder til TreeView-noder
  4. Tildeling af billeder til TreeView Nodes-2
  5. TreeView Control Checkmark Tilføj Slet
  6. TreeView ImageCombo Drop-down Adgang
  7. Omarranger TreeView-noder ved at trække og slippe
  8. ListView-kontrol med MS-Access TreeView
  9. ListView Control Træk-slip hændelser
  10. TreeView-kontrol med underformularer

  1. Tilslutning af IBM DB2 med IRI-software

  2. Fjern dublerede rækker i en tabel

  3. Sådan droppes en tabel i SQL

  4. Algoritme til at undgå SQL-injektion på MSSQL Server fra C#-kode?