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.
-
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.
-
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.
-
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.
-
Modifiez le formulaire en mode Création.
-
Cliquez avec le bouton droit sur le contrôle ListView et mettez en surbrillance l'option ListViewCtrl Object et sélectionnez Propriétés.
-
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é.
-
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.
-
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 :
- Tutoriel sur le contrôle Microsoft TreeView
- Création d'un menu d'accès avec le contrôle TreeView
- Affectation d'images aux nœuds TreeView
- Attribution d'images aux nœuds TreeView-2
- TreeView Control Checkmark Ajouter Supprimer
- Accès à la liste déroulante TreeView ImageCombo
- Réorganiser les nœuds TreeView par glisser-déposer
- Contrôle ListView avec MS-Access TreeView
- Événements de glisser-déposer de contrôle ListView
- Contrôle TreeView avec sous-formulaires