Access
 sql >> Base de données >  >> RDS >> Access

Tutoriel de contrôle ListView-02

Présentation.

Suite du didacticiel de contrôle ActiveX ListView-01 de la semaine dernière.

Dans cette session du didacticiel, nous apprendrons à rechercher et à trouver les valeurs de ligne et de colonne particulières et à les afficher sur un contrôle d'étiquette sur le formulaire. Ceci est très utile lorsque nous avons un grand volume de données dans le contrôle ListView. Nous apprendrons également l'utilisation de certains paramètres de propriété ListView.

Tout d'abord, nous verrons à quel point il est facile de réorganiser les colonnes, comme nous le faisons avec Access Datasheet View, comme nous le souhaitons sur le contrôle ListView. Nous avons ajouté des zones de texte, des zones de liste déroulante, des boutons de commande et des étiquettes pour faciliter la sélection des paramètres de recherche et l'affichage des résultats de la recherche.

J'ai apporté quelques modifications aux données de démonstration de la semaine dernière. Les valeurs de la première colonne que j'ai extraites de la table Employees de l'exemple de base de données Northwind.accdb. Création d'une requête pour joindre les valeurs LastName et FirstName avec le nom de champ Student et EmployeeID utilisé comme clé (X01, X02 ...).

Avant de passer aux opérations de recherche, nous allons vérifier comment réorganiser les colonnes par la méthode du glisser-déposer.

Remarque : Si vous n'avez pas parcouru la page de didacticiel précédente et que vous souhaitez poursuivre cette session, accédez à la page ListView Control Tutorial-01 et téléchargez la base de données de démonstration à partir du bas de cette page.

Décompressez le fichier et ouvrez la base de données. Le formulaire de démonstration sera en vue normale.

  1. Ouvrez votre base de données, avec le formulaire de démonstration de la dernière session, ou le formulaire que vous avez créé, ouvrez-le en vue normale.

    Maintenant, nous allons essayer de faire glisser et de déplacer une colonne du milieu de la liste (disons la colonne Poids) et de la déposer dans Âge colonne et voir ce qui se passe. On s'attend à ce que la colonne Age se déplace vers la droite et insère la colonne entrante à sa place.

  2. Déplacez le pointeur de la souris sur l'en-tête de colonne avec le nom Poids, cliquez et maintenez le bouton gauche de la souris. Lorsque vous appuyez sur le bouton gauche de la souris, l'en-tête de colonne se déplace légèrement vers le bas.

  3. Maintenant, essayez de faire glisser la colonne vers la gauche et déposez-la sur la colonne Âge .

    Rien ne se passera, car nous n'avons pas activé cette fonctionnalité dans la feuille de propriétés et c'est le seul paramètre que nous devons modifier pour que cette fonctionnalité fonctionne.

  4. Modifiez le formulaire en mode Création.

  5. Cliquez avec le bouton droit sur le contrôle ListView et mettez en surbrillance l'option ListViewCtrl Object et sélectionnez Propriétés.

  6. Il y a une option 'Autoriser la réorganisation des colonnes ' sur le côté droit. Mettez une coche pour le sélectionner, puis cliquez sur Appliquer bouton suivi de OK bouton pour fermer la vue de la propriété.

  7. Maintenant, essayez de répéter les étapes 2 et 3 ci-dessus et voyez ce qui se passe.

    C'est le seul paramètre dont vous avez besoin pour activer cette fonctionnalité sur le contrôle ListView. Peut-être pensez-vous, qu'en est-il de réorganiser les lignes ?.

    Cette fonction nécessite la programmation de certaines procédures d'événement comme nous l'avons fait précédemment dans TreeView Control Drag-Drop Events. Nous ferons cette partie après un certain temps.

  8. Vous pouvez expérimenter n'importe quelle colonne pour la déplacer où vous le souhaitez, y compris la première colonne également.

Remarque : Avant de supprimer la colonne source, vérifiez que la colonne cible est couverte par le cadre de colonne entrant avant de tenter de supprimer. Sinon, la colonne entrante peut passer à la position de colonne suivante sur le côté droit.

Ensuite, nous apprendrons comment trouver rapidement des informations à partir de ListView, en supposant que nous y avons un grand volume de données.

Nous avons ajouté une sous-routine au module Tutorial-01 pour charger les noms d'en-tête de colonne dans une zone de liste déroulante sur le formulaire avec la couleur d'arrière-plan rouge. Le nom de la colonne sera utilisé pour trouver la valeur de la colonne (âge, taille, poids ou classe) d'un élève.

Nouveau code VBA ajouté au module de classe de formulaire.

La nouvelle procédure VBA suivante est ajoutée au module de classe du formulaire de didacticiel de la semaine dernière :

Le txtColCombo crée la liste des étiquettes d'en-tête de colonne (noms de champ) dans le ComboBox. L'un de ces détails sur l'âge, la taille, le poids, de l'élève ou Classe peut être trouvé avec le nom de l'étudiant dans le cadre de l'opération de recherche et de recherche.

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

La Combobox ne sera pas chargée avec une valeur par défaut de nom d'en-tête de colonne. Si cette option est sélectionnée, la valeur de la colonne de l'étudiant s'affiche dans la grande étiquette sous le nom de l'étudiant. S'il est laissé vide, l'opération de recherche ne trouvera que le nom de l'élève.

La méthode d'opération de recherche est très flexible et rapide. Nous avons deux méthodes pour trouver un enregistrement.

Trouvez l'enregistrement en fournissant le texte de recherche. Le texte de recherche peut provenir de n'importe quelle colonne, soit le texte en entier ou en partie quelques caractères à partir de la gauche. Étant donné que nous avons deux catégories de membres d'objet à la suite dans le contrôle ListView :ListItem - la première colonne et les autres colonnes sont ListSubItems. L'opération de recherche de texte sur ces objets est effectuée séparément.

Un groupe d'options avec deux cases à cocher est fourni à côté de la zone de texte de saisie de texte de recherche sur le formulaire pour sélectionner les options de recherche et de recherche. La première option est sélectionnée par défaut et la recherche est effectuée sur la première Colonne (ListItem ) pour rechercher le texte donné.

Sélectionnez la deuxième option pour rechercher le texte dans ListSubItem colonnes.

Remarque : La réorganisation des colonnes ne modifiera pas les objets, mais uniquement leur position d'affichage. Faire glisser un ListSubItem colonne et l'amener dans la première colonne ne changera pas dans un ListItem objet.

Si vous souhaitez récupérer une valeur inconnue d'une colonne particulière, sélectionnez un nom de colonne dans le ComboBox indiqué sous le premier TextBox du formulaire pour le texte de recherche. Par exemple, vous ne connaissez pas la taille d'un élève et souhaitez la connaître, sélectionnez le nom de la colonne Taille de la ComboBox.

Après avoir défini la ou les valeurs ci-dessus, cliquez sur Rechercher un élément Bouton de commande pour effectuer l'opération de recherche. Si la recherche a réussi, le résultat sera affiché dans le grand contrôle Label sous le bouton de commande.

Clic sur le bouton de commande [Rechercher un élément].

Appelle le SearchAndFind() Procédure.

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

Au début du programme, le nom de l'étudiant et Nom de la colonne ( 0facultatif), sont copiés des TextBoxes dans les Variables strFind et strColName respectivement après les contrôles de validation.

Remarque : La propriété Pas dans la liste de la zone de liste déroulante du nom de colonne est définie sur Oui. Vous pouvez sélectionner une valeur valide dans la liste ou la saisir ou laisser la zone de liste déroulante vide. Si vous saisissez une valeur différente qui ne figure pas dans la liste, elle ne sera pas acceptée.

En fonction de l'option de recherche sélectionnée (1 - ListItem ou 2 - ListSubItem), la méthode d'analyse est dirigée vers le ou les objets spécifiés.

L'utilisation de l'une ou l'autre de ces méthodes de recherche trouvera l'objet ListItem ou rangée qui contient le texte de recherche. La valeur d'index du ListItem est enregistrée dans la variable J pour une utilisation ultérieure dans le programme.

Remarque : Le système crée automatiquement les numéros automatiques d'index au moment où les éléments de contrôle ListView sont renseignés.

Le ListItem.Text valeur est récupérée. Ces informations sont jointes au premier ColumnHeader. Texte (comme Étudiant :Robert King) et ajouté dans la chaîne Msgtext à afficher dans le contrôle Label du formulaire.

Si la colonne Header Name est sélectionnée dans le ComboBox, alors le GetColVal() La fonction est appelée avec l'objet ListItem et la valeur du texte d'en-tête de colonne comme paramètres. Cette option est utile pour récupérer des informations inconnues sur un étudiant, comme la taille de l'étudiant, à partir de l'enregistrement.

Le code VBA de la fonction GetColVal().

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

La fonction ci-dessus demande deux paramètres. Le premier paramètre est le ListItem, où se trouve le nom de l'étudiant. Le deuxième paramètre est le nom de la colonne. Âge, taille, poids, classe de l'élève sélectionné les valeurs sont stockées dans le ListItem.ListSubItems Objets. La fonction regarde à travers lvwList.ColumnHeader valeurs pour trouver le nom de colonne correspondant, lorsqu'il est trouvé, ce numéro d'index de colonne est utilisé pour récupérer la valeur de colonne à partir de l'objet ListSubItems et renvoie la valeur au programme appelant.

Le bouton de commande [Rechercher par touche] Cliquez sur la procédure d'événement.

Nous avons ajouté une autre méthode pour trouver le nom de l'étudiant en utilisant la valeur-clé unique de ListItem s'il est utilisé lors de la création de la liste ListItem. Même s'il est facultatif, il est préférable d'ajouter une valeur de chaîne de clé unique (doit commencer par un caractère alphabétique) plutôt que de l'ignorer.

Par exemple, si nous devons trouver les informations de quelqu'un par son numéro d'identification comme le numéro de sécurité sociale, le numéro de carte d'identité nationale, le numéro de passeport ou le numéro de permis de conduire, etc., l'une de ces informations peut être utilisée comme valeur clé pour le ListItem. Trouver un enregistrement avec cette valeur unique est très facile et plus rapide que la méthode de recherche par texte ci-dessus.

La procédure événementielle cmdKey_Click().

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

Comme vous pouvez le voir dans la sous-routine ci-dessus, nous pourrions directement trouver le ListItem où se trouve le nom de l'étudiant, avec l'utilisation de la valeur-clé, avec une seule instruction :Set lvItem =lvwList.ListItems.Item(xKeyVal).

La ligne suivante lit le texte ListItem (ou le nom de l'étudiant) dans la variable txt . Les deux lignes suivantes créent le texte du message avec le nom de l'étudiant dans la variable de chaîne msgText.

Le prochain Si . . .Puis L'instruction vérifie si une valeur de nom de colonne est entrée dans le contrôle de la zone de liste déroulante. S'il est trouvé, alors appelle le GetColVal() Fonction avec les paramètres requis pour trouver la valeur de la colonne et la récupérer dans varColVal Variable et retourne au programme appelant. Le nom de la colonne et sa valeur récupérée sont ajoutés à la variable de chaîne msgText à afficher sur le contrôle Label du formulaire.

L'instruction suivante met en surbrillance la ligne d'enregistrement de l'étudiant comme une indication visuelle que l'élément recherché se trouve dans la ligne. La valeur msgText est affichée dans la propriété Caption de l'étiquette sur le formulaire.

Le code VBA complet sur le module de formulaire.

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

Téléchargez la base de données de démonstration à partir du lien suivant :



  1. Tutoriel sur le contrôle Microsoft TreeView
  2. Création d'un menu d'accès avec le contrôle TreeView
  3. Affectation d'images aux nœuds TreeView
  4. Attribution d'images aux nœuds TreeView-2
  5. TreeView Control Checkmark Ajouter Supprimer
  6. Accès à la liste déroulante TreeView ImageCombo
  7. Réorganiser les nœuds TreeView par glisser-déposer
  8. Contrôle ListView avec MS-Access TreeView
  9. Événements de glisser-déposer de contrôle ListView
  10. Contrôle TreeView avec sous-formulaires