sql >> Databasteknik >  >> RDS >> Access

ListView Control Tutorial-02

Introduktion.

Fortsättning från förra veckans ActiveX ListView Control Tutorial-01.

I den här sessionen av handledningen kommer vi att lära oss hur man söker och hittar de specifika rad- och kolumnvärdena och visar dem på en etikettkontroll på formulär. Detta är mycket användbart när vi har en stor mängd data i ListView-kontrollen. Vi kommer också att lära oss hur vissa ListView-egendomsinställningar används.

Först och främst kommer vi att se hur lätt det är att ordna om kolumnerna, som vi gör med Access Datasheet View som vi vill att de ska vara på ListView-kontrollen. Vi har lagt till några TextBoxes, ComboBox, Command Buttons och Label för enklare val av sökparametrar och visning av sökresultat.

Jag har gjort några ändringar i förra veckans demodata. De första kolumnvärdena har jag tagit från Employees Table of Northwind.accdb exempeldatabasen. Skapat en fråga för att sammanfoga efternamns- och förnamnsvärdena med fältnamnet Student och EmployeeID som används som nyckel (X01, X02 ...).

Innan vi går till sökoperationerna kommer vi att kontrollera hur man omarrangerar kolumner med dra och släpp-metoden.

Obs! Om du inte har gått igenom den tidigare självstudiesidan och vill fortsätta med den här sessionen, gå till sidan ListView Control Tutorial-01 och ladda ner demodatabasen längst ner på sidan.

Packa upp filen och öppna databasen. Demoformuläret kommer att vara i normal vy.

  1. Öppna din databas, med den senaste sessionens demoformulär, eller formuläret som du har skapat, öppna den i normalvy.

    Nu kommer vi att försöka dra och flytta en kolumn från mitten av listan (säg kolumnen Vikt) och släppa den till Ålder kolumn och se vad som händer. Det som förväntas hända är att kolumnen Ålder ska flyttas åt höger och infoga den inkommande kolumnen på dess plats.

  2. Flytta muspekaren på kolumnrubriken med namnet Vikt klicka och håll nere vänster musknapp. När du trycker ner vänster musknapp kommer kolumnrubriken att flyttas något nedåt.

  3. Försök nu att dra kolumnen till vänster och släpp den i kolumnen Ålder .

    Ingenting kommer att hända, eftersom vi inte har aktiverat den här funktionen i egenskapsbladet och det är den enda inställningen som vi måste ändra för att den här funktionen ska fungera.

  4. Ändra formuläret i designvyn.

  5. Högerklicka på ListView-kontrollen och markera alternativet ListViewCtrl-objekt och välj Egenskaper.

  6. Det finns ett alternativ 'AllowColumnReorder ' på höger sida. Markera det och klicka sedan på Använd knappen följt av OK för att stänga egenskapsvyn.

  7. Försök nu att upprepa steg 2 och 3 ovan och se vad som händer.

    Det är den enda inställningen du behöver för att aktivera den här funktionen på ListView Control. Du kanske tänker, vad sägs om att ordna om raderna?.

    Den funktionen behöver programmera vissa händelseprocedurer som vi gjorde tidigare i TreeView Control Drag-Drop Events. Den delen kommer vi att göra efter ett tag.

  8. Du kan experimentera med vilken kolumn som helst för att flytta vart du vill, inklusive den första kolumnen också.

Obs! Innan du släpper källkolumnen se till att målkolumnen täcks av den inkommande kolumnramen innan du försöker släppa. Annars kan den inkommande kolumnen flyttas till nästa kolumnposition på höger sida.

Därefter kommer vi att lära oss hur man snabbt hittar information från ListView, förutsatt att vi har en stor mängd data i den.

Vi har lagt till en subrutin till Tutorial-01 Module för att ladda kolumnhuvudet Namn i en kombinationsruta på formuläret med den röda bakgrundsfärgen. Kolumnnamnet kommer att användas för att hitta kolumnvärdet (ålder, höjd, vikt eller klass) för en elev.

Ny VBA-kod har lagts till i Form Class-modulen.

Följande nya VBA-procedur läggs till i förra veckans handledningsformulärs klassmodul:

txtColCombo skapar listan med kolumnrubriketiketter (fältnamn) i ComboBox. En av dessa uppgifter om elevens ålder, längd, vikt eller Klass kan hittas tillsammans med elevens namn som en del av sök-och-hit-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 kommer inte att laddas med ett standardvärde för kolumnrubriknamn. Om valt visas det kolumnvärdet för eleven i den stora etiketten under elevens namn. Om det lämnas tomt, kommer sökoperationen endast att hitta elevens namn.

Sökoperationsmetoden är mycket flexibel och snabb. Vi har två sätt att hitta en post.

Hitta posten genom att ange söktexten. Söktexten kan vara från vilken som helst av kolumnerna antingen texten helt eller delvis några tecken från vänster. Eftersom vi har två kategorier av objektmedlemmar i rad i ListView-kontrollen:ListItem - den första kolumnen och andra kolumner är ListSubItems. Textsökningen på dessa objekt utförs separat.

En alternativgrupp med två kryssrutor finns bredvid textrutan för söktextinmatning på formuläret för att välja sök-och-hit-alternativ. Det första alternativet är valt som standard och sökningen utförs i den första kolumnen (ListItem ) för att leta efter den givna texten.

Välj det andra alternativet för att söka efter texten i ListSubItem kolumner.

Obs! Om du arrangerar om kolumnerna ändras inte objekten, utan bara deras visningsposition. Dra en ListSubItem kolumnen och föra den i den första kolumnen kommer inte att ändras det till en ListItem objekt.

Om du vill hämta ett okänt värde från en viss kolumn, välj ett kolumnnamn från ComboBox som ges under den första textrutan i formuläret för söktexten. Om du till exempel inte känner till höjdmåttet för en elev och skulle vilja ta reda på det, välj kolumnnamnet Höjd från ComboBox.

Efter att ha ställt in ovanstående värden klickar du på Sök objekt Kommandoknapp för att gå till sökoperationen. Om sökningen lyckades, kommer resultatet att visas i den stora etikettkontrollen under kommandoknappen.

Klicka på kommandoknappen [Sök objekt].

Anropar SearchAndFind() Procedur.

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 början av programmet, både Studentens namn och Kolumnnamn ( 0valfritt), kopieras från textrutorna till variablerna strFind och strColName efter valideringskontroller.

Obs! Kolumnnamnet Combo Box's Not-in-list-egenskap är inställt på Ja. Du kan välja ett giltigt värde från listan eller skriva in det eller lämna kombinationsrutan tom. Om du skriver in ett annat värde som inte finns i listan kommer det inte att accepteras.

Baserat på det valda sökalternativet (1 - ListItem eller 2 - ListSubItem) riktas skanningsmetoden till det eller de angivna objekten.

Genom att använda någon av dessa sökmetoder hittar du ListItem Object eller rad som innehåller söktexten. Indexvärdet för listobjektet sparas i variabel J för senare användning i programmet.

Obs! Systemet skapar automatiska indexnummer när ListView-kontrollobjekten fylls i.

ListItem.Text värde hämtas. Denna information sammanfogas med den första ColumnHeader. Text (som Student:Robert King) och läggs till i Msgtext-strängen för att visas i etikettkontrollen på formuläret.

Om kolumnen Header Name är vald i ComboBox, visas GetColVal() Funktionen anropas med objektet ListItem och kolumnrubrikens textvärde som parametrar. Det här alternativet är bra för att hämta okänd information om en student, som elevens höjd, från posten.

VBA-koden för GetColVal()-funktionen.

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

Ovanstående funktion frågar efter två parametrar. Den första parametern är ListItem, där elevens namn finns. Den andra parametern är kolumnnamnet. Den valda elevens Ålder, Längd, Vikt, Klass värden lagras i ListItem.ListSubItems Föremål. Funktionen letar igenom lvwList.ColumnHeader värden för att hitta det matchande kolumnnamnet, när det hittas att kolumnindexnumret används för att hämta kolumnvärde från ListSubItems-objektet och returnerar värdet till det anropande programmet.

Kommandoknappen [Sök efter nyckel] Klicka på Händelseprocedur.

Vi har lagt till en annan metod för att hitta studentens namn med det unika nyckelvärdet för ListItem om det används när du skapar ListItem List. Även om det är valfritt är det bättre att lägga till unikt nyckelsträngsvärde (bör börja med ett alfabet) istället för att ignorera det.

Till exempel, om vi måste hitta någons information med hjälp av deras identifikationsnummer som personnummer, nationellt identitetskortnummer, passnummer eller körkortsnummer och så vidare, kan en av dessa uppgifter användas som nyckelvärde för ListItem. Att hitta en post med detta unika värde är mycket enkelt och snabbare än ovanstående sök-med-text-metoden.

CmdKey_Click()-händelseproceduren.

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 subrutinen ovan kunde vi direkt hitta ListItem där studentens namn är, med hjälp av nyckel-värde, med en enda sats:Sätt lvItem =lvwList.ListItems.Item(xKeyVal).

Nästa rad läser ListItem-texten (eller namnet på studenten) i variabeln txt . De nästa två raderna skapar meddelandetexten med Elevens namn i strängvariabeln msgText.

Nästa Om . . .Då satsen kontrollerar om ett kolumnnamnsvärde anges i kombinationsrutan. Om den hittas, anropar du GetColVal() Funktion med nödvändiga parametrar för att hitta kolumnvärdet och hämta det i varColVal Variabel och återgår till det anropande programmet. Kolumnnamnet och dess värde som hämtas läggs till i strängvariabeln msgText för att visas på etikettkontrollen i formuläret.

Nästa påstående framhäver studentens postrad som en visuell indikation på att det sökta objektet finns i raden. msgText-värdet visas i etikettens Caption-egenskap på formuläret.

Den fullständiga VBA-koden på formulärmodulen.

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

Ladda ner demodatabasen från följande länk:



  1. Microsoft TreeView Control Tutorial
  2. Skapa åtkomstmeny med TreeView-kontroll
  3. Tilldela bilder till TreeView-noder
  4. Tilldela bilder till TreeView Nodes-2
  5. TreeView-kontrollmarkering Lägg till Ta bort
  6. TreeView ImageCombo rullgardinsmenyn
  7. Arrangera om TreeView-noder genom att dra och släppa
  8. ListView-kontroll med MS-Access TreeView
  9. ListView Control Drag Drop Events
  10. TreeView-kontroll med underformulär

  1. SQL Server Resumable Index:Är det bra för dig?

  2. Trigger kontra kontrollbegränsning

  3. PLSQL JDBC:Hur får man sista rad-ID?

  4. Hur kan jag se om mitt Oracle-system är inställt för att stödja Unicode eller multibyte-tecken?