Introduction.
Nous connaissons les opérations de glisser-déposer sur TreeView Control, dans Ms-Access qui réorganise les nœuds. Tous les enregistrements de base pour les nœuds de contrôle Treeview proviennent d'une seule table d'accès. Nous mettons toujours à jour le ParentID du nœud source valeur du champ, avec la valeur d'ID du nœud cible sur le même enregistrement de table, pour effectuer le changement de position sur le contrôle TreeView. Les enregistrements ne sont physiquement déplacés nulle part.
Ici, avec l'ajout de ListView Control avec TreeView Control, nous prévoyons de travailler avec deux tables d'accès différentes.
- lvCategory – Code et description de la catégorie.
- lvProducts – Produits par catégorie.
De cette façon, il est plus facile de comprendre la relation entre les deux tables. Quels changements devons-nous apporter et où, lorsqu'un élément de produit (élément ListView) passe d'une catégorie à l'autre sur le contrôle TreeView.
La lvCatégorie La table d'accès a 20 enregistrements pour les nœuds TreeView et les lvProducts Le tableau a 45 pour le contrôle ListView. Un ou plusieurs enregistrements de la table Produits sont directement liés à une catégorie de produits dans la table des catégories. La relation entre eux a été mise à jour avec la valeur du champ d'ID de catégorie (CID) sur l'ID parent de la table des produits. afin que le changement de catégorie du produit se répercute immédiatement sur le ListView Control.
La table de données de démonstration a été extraite de Microsoft Access Sample Database Northwind.accdb et divisée en deux parties.
Sur la base de la valeur du champ ParentID, des enregistrements lvProduct, nous pourrions filtrer et répertorier tous les éléments de produit associés dans le contrôle ListView, lorsqu'un nœud de catégorie est sélectionné sur le contrôle TreeView.
Sujets que nous avons couverts jusqu'à présent.
Voici les principaux sujets sur TreeView , ListeImage , Combo Image, et ListView Contrôles, nous avons couvert jusqu'à présent dans MS-Access :
- Tutoriel sur le contrôle Microsoft TreeView
- Création d'un menu d'accès avec le contrôle TreeView
- Affectation d'images au contrôle TreeView
- Affectation d'images à TreeView Control-2
- TreeView Control-Mark Add Delete Nodes
- Menu déroulant d'accès TreeView ImageCombo
- Réorganiser les nœuds TreeView par glisser-déposer
- Contrôle ListView avec MS-Access TreeView
La tâche ListView Drag-Drop.
En ce qui concerne l'opération de glisser-déposer de ListView, il s'agit d'un simple exercice comparant la même méthode dans le contrôle TreeView seul. Étant donné que l'action Drag Drop implique à la fois les contrôles TreeView et ListView, nous utilisons la même procédure d'événement TreeView0_OLEDragDrop() avec un code VBA simple.
Les éléments de produit répertoriés dans le contrôle ListView appartiennent à l'élément de catégorie actuel sélectionné dans le contrôle TreeView.
L'utilisateur sélectionne un élément de produit particulier à partir du contrôle ListView, s'il pense qu'il appartient à un élément de catégorie différent, puis faites-le glisser et déposez-le sur l'élément de catégorie cible sur le TreeViewCcontrol.
L'élément de produit ListView déplacé sera ajouté à la liste des éléments appartenant à la catégorie modifiée. La valeur du champ ParentID de l'enregistrement de produit est mise à jour avec l'ID d'enregistrement de catégorie cible (valeur CID).
Il s'agit uniquement d'une action à sens unique, déplacez toujours l'élément ListView d'une catégorie et déposez-le sur un nœud de catégorie différent sur le contrôle TreeView.
La démo ListView par glisser-déposer Access Form frmListViewDrag’ L'image de l'écran d'essai est donnée ci-dessous :
Dans l'image ci-dessus, les Boissons La catégorie sur le TreeView a été sélectionnée. Les produits appartenant à la catégorie Boissons ont été listés dans le ListView Control.
La vue de conception du formulaire ci-dessus :
La liste des noms de contrôle sur le formulaire est donnée ci-dessous :
- Contrôle TreeView :TreeView0
- Contrôle ListView :ListView0
- Contrôle ImageList :ImageList3
- Bouton de commande :cmdClose
Le code VBA sur frmListViewDrag Module de cours :
Option Compare Database Option Explicit Dim tv As MSComctlLib.TreeView Dim lvList As MSComctlLib.ListView Dim imgList As MSComctlLib.ImageList Const Prfx As String = "X" Private Sub Form_Load() Dim db As DAO.Database Dim tbldef As TableDef Set tv = Me.TreeView0.Object tv.Nodes.Clear Set imgList = Me.ImageList3.Object With tv .Font.Size = 9 .Font.Name = "Verdana" .ImageList = imgList 'assign preloaded imagelist control End With Set lvList = Me.ListView0.Object lvList.ColumnHeaders.Clear lvList.ListItems.Clear lvList.Icons = imgList Set db = CurrentDb Set tbldef = db.TableDefs("lvProducts") 'Initialize ListView & Column Headers Property Values With lvList .ColumnHeaderIcons = imgList .Font.Size = 9 .Font.Name = "Verdana" .Font.Bold = False 'ColumnHeaders.Add() Syntax: 'lvList.ColumnHeaders.Add Index, Key, Text, Width, Alignment, Icon 'Alignment: 0 - Left, 1 - Right, 2 - Center .ColumnHeaders.Add 1, , tbldef.Fields(1).Name, 2600, 0, 5 .ColumnHeaders.Add 2, , tbldef.Fields(3).Name, 2600, 0, 5 .ColumnHeaders.Add 3, , tbldef.Fields(4).Name, 1440, 1, 5 End With Set db = Nothing Set tbldef = Nothing LoadTreeView 'Create TreeView Nodes End Sub Private Sub LoadTreeView() Dim Nod As MSComctlLib.Node Dim firstCatID As Long Dim strCategory As String Dim strCatKey As String Dim strBelongsTo As String Dim strSQL As String Dim db As DAO.Database Dim rst As DAO.Recordset 'Initialize treeview nodes tv.Nodes.Clear 'Initialize Listview nodes While lvList.ListItems.Count > 0 lvList.ListItems.Remove (1) Wend strSQL = "SELECT lvCategory.CID, lvCategory.Category, " strSQL = strSQL & "lvcategory.BelongsTo FROM lvCategory ORDER BY lvCategory.CID;" Set db = CurrentDb Set rst = db.OpenRecordset(strSQL, dbOpenSnapshot) If Not rst.BOF And Not rst.EOF Then rst.MoveFirst firstCatID = rst!CID Else Exit Sub End If ' Populate all Records as Rootlevel Nodes Do While Not rst.BOF And Not rst.EOF strCatKey = Prfx & CStr(rst!CID) strCategory = rst!Category Set Nod = tv.Nodes.Add(, , strCatKey, strCategory, 1, 2) Nod.Tag = rst!CID rst.MoveNext Loop 'In the second pass of the the same set of records 'Move Child Nodes under their Parent Nodes rst.MoveFirst Do While Not rst.BOF And Not rst.EOF strBelongsTo = Nz(rst!BelongsTo, "") If Len(strBelongsTo) > 0 Then strCatKey = Prfx & CStr(rst!CID) strBelongsTo = Prfx & strBelongsTo strCategory = rst!Category Set tv.Nodes.Item(strCatKey).Parent = tv.Nodes.Item(strBelongsTo) End If rst.MoveNext Loop rst.Close ' Populate ListView Control with Product details ' of the first Category Item LoadListView firstCatID End Sub Private Sub LoadListView(ByVal CatID) Dim strProduct As String Dim strPKey As String Dim intcount As Integer Dim tmpLItem As MSComctlLib.ListItem Dim db As DAO.Database Dim rst As DAO.Recordset Dim strSQL As String ' Initialize ListView Control While lvList.ListItems.Count > 0 lvList.ListItems.Remove (1) Wend strSQL = "SELECT lvProducts.* FROM lvProducts " strSQL = strSQL & "WHERE (lvProducts.ParentID = " & CatID & ") " strSQL = strSQL & "ORDER BY lvProducts.[Product Name];" 'Open filtered Products List for selected category Set db = CurrentDb Set rst = db.OpenRecordset(strSQL, dbOpenSnapshot) Do While Not rst.BOF And Not rst.EOF intcount = intcount + 1 strProduct = rst![Product Name] strPKey = Prfx & CStr(rst!PID) 'List Item Add() Syntax: 'lvList.ListItems.Add Index,Key,Text,Icon,SmallIcon Set tmpLItem = lvList.ListItems.Add(, strPKey, strProduct, , 3) 'first column lvList.ForeColor = vbBlue 'List second column sub-item Syntax: 'tmpLItem.ListSubItems.Add Column - Index, Key, Text, ReportIcon, ToolTipText tmpLItem.ListSubItems.Add 1, strPKey & CStr(intcount), Nz(rst![Quantity Per Unit], ""), 6 'List third column sub-item tmpLItem.ListSubItems.Add 2, strPKey & CStr(intcount + 1), Format(rst![list Price], "0.00"), 6, "In Local Currency." rst.MoveNext Loop Set db = Nothing Set rst = Nothing If intcount > 0 Then lvList.ListItems(1).Selected = True End Sub Private Sub TreeView0_NodeClick(ByVal Node As Object) Dim Cat_ID As String Cat_ID = Node.Tag LoadListView Cat_ID End Sub Private Sub TreeView0_OLEStartDrag(Data As Object, AllowedEffects As Long) Set tv.SelectedItem = Nothing End Sub Private Sub TreeView0_OLEDragOver(Data As Object, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single, State As Integer) On Error GoTo TreeView0_OLEDragOver_Err Dim nodSelected As MSComctlLib.Node Dim nodOver As MSComctlLib.Node If tv.SelectedItem Is Nothing Then 'Select a node if one is not selected Set nodSelected = tv.HitTest(X, Y) If Not nodSelected Is Nothing Then nodSelected.Selected = True End If Else If tv.HitTest(X, Y) Is Nothing Then 'do nothing Else 'Highlight the node the mouse is over Set nodOver = tv.HitTest(X, Y) Set tv.DropHighlight = nodOver End If End If TreeView0_OLEDragOver_Exit: Exit Sub TreeView0_OLEDragOver_Err: MsgBox Err & " : " & Err.Description, vbInformation, "TreeView0_OLEDragOver()" Resume TreeView0_OLEDragOver_Exit End Sub Private Sub TreeView0_OLEDragDrop(Data As Object, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single) Dim tv_nodSource As Node Dim tv_nodTarget As Node Dim strtv_ParentKey As String Dim strtv_TargetKey As String Dim strListItemKey As String Dim strSQL As String Dim vCatID As Long Dim lngPID As Long On Error GoTo TreeView0_OLEDragDrop_Err 'Get the source/destination Nodes Set tv_nodSource = tv.SelectedItem Set tv_nodTarget = tv.HitTest(X, Y) If Not tv_nodTarget Is Nothing Then strtv_ParentKey = tv_nodSource.Key strtv_TargetKey = tv_nodTarget.Key If strtv_ParentKey = strtv_TargetKey Then Exit Sub 'Extract ListItem Key strListItemKey = lvList.SelectedItem.Key 'extract Category Record CID Value 'and ListItem Product ID Key vCatID = Val(Mid(tv_nodTarget.Key, 2)) lngPID = Val(Mid(strListItemKey, 2)) 'UPDATE lvProducts Table strSQL = "UPDATE lvProducts SET ParentID = " & vCatID & _ " WHERE PID = " & lngPID CurrentDb.Execute strSQL, dbFailOnError Set tv.DropHighlight = Nothing tv_nodSource.Selected = True 'Rebuild ListView Nodes TreeView0_NodeClick tv_nodSource Else ' Invalid Target location MsgBox "The destination is invalid!", vbInformation End If TreeView0_OLEDragDrop_Exit: Exit Sub TreeView0_OLEDragDrop_Err: MsgBox Err & " : " & Err.Description, vbInformation, "TreeView0_OLEDragDrop()" Resume TreeView0_OLEDragDrop_Exit End Sub Private Sub TreeView0_OLECompleteDrag(Effect As Long) Set tv.DropHighlight = Nothing End Sub Private Sub cmdClose_Click() DoCmd.Close End Sub
Les segments de code VBA familiers.
Dans le Form_Load() Procédure événementielle, nous initialisons les contrôles TreeVew, ListView, ImageList. Il crée les ColumnHeadings du contrôle ListView, avant de remplir les éléments de liste dans le contrôle Listview. A la fin de cette routine, nous appelons la sous-routine LoadTreeView().
Le LoadTreeView() la sous-routine remplit les nœuds de catégorie des produits sur le contrôle TreeView, avec les enregistrements de lvCategory Table. Le chargement des nœuds sur le contrôle TreeView est un processus en deux étapes. Pourquoi en est-il ainsi, plutôt que de le faire en une seule fois ? Cet aspect a été expliqué en détail sur une page précédente, le 7ème lien sur la liste des liens ci-dessus si vous souhaitez le parcourir. Les répéter tous ici n'est peut-être pas approprié.
À la fin de la sous-routine ci-dessus, le LoadListView() la sous-routine a été appelée avec la valeur CID du premier enregistrement de catégorie 1 comme paramètre.
Les enregistrements de produit avec la valeur du champ ParentID 1 ont été filtrés et répertoriés sur le contrôle ListView. Cette procédure a été expliquée en détail dans le post de la semaine dernière, le 8ème élément, parmi la liste des liens ci-dessus.
Les sous-programmes d'action glisser-déposer.
Les Sous-routines suivantes associées à l'action Glisser-Déposer seront exécutées automatiquement dans l'ordre dans lequel elles sont présentées ci-dessous :
- TreeView0_OLEStartDrag()
- TreeView0_OLEDragOver()
- TreeView0_OLEDragDrop()
- TreeView0_OLECompleteDrag()
Les premier et dernier sous-programmes initialisent les nœuds impliqués et réinitialisent leur statut à la fin respectivement.
La seconde, la sous-routine OLEDragOver() fonctionne comme la procédure d'événement MouseMove et suit le mouvement de la souris pendant l'opération de glisser-déposer. Il met en surbrillance le NodeText lorsque la souris est sur un nœud et suit sa trajectoire jusqu'à ce que le bouton gauche de la souris soit relâché.
Seul le code de procédure TreeView0_OLEDragDrop() est répertorié ci-dessous.
Private Sub TreeView0_OLEDragDrop(Data As Object, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single) Dim tv_nodSource As Node Dim tv_nodTarget As Node Dim strtv_ParentKey As String Dim strtv_TargetKey As String Dim strListItemKey As String Dim strSQL As String Dim vCatID As Long Dim lngPID As Long On Error GoTo TreeView0_OLEDragDrop_Err 'Get the source/destination Nodes Set tv_nodSource = tv.SelectedItem Set tv_nodTarget = tv.HitTest(X, Y) If Not tv_nodTarget Is Nothing Then strtv_ParentKey = tv_nodSource.Key strtv_TargetKey = tv_nodTarget.Key If strtv_ParentKey = strtv_TargetKey Then Exit Sub 'Extract ListItem Key strListItemKey = lvList.SelectedItem.Key 'extract Category Record CID Value 'and ListItem Product ID Key vCatID = Val(Mid(tv_nodTarget.Key, 2)) lngPID = Val(Mid(strListItemKey, 2)) 'UPDATE lvProducts Table strSQL = "UPDATE lvProducts SET ParentID = " & vCatID & _ " WHERE PID = " & lngPID CurrentDb.Execute strSQL, dbFailOnError Set tv.DropHighlight = Nothing tv_nodSource.Selected = True 'Rebuild ListView Nodes TreeView0_NodeClick tv_nodSource Else ' Invalid Target location MsgBox "The destination is invalid!", vbInformation End If TreeView0_OLEDragDrop_Exit: Exit Sub TreeView0_OLEDragDrop_Err: MsgBox Err & " : " & Err.Description, vbInformation, "TreeView0_OLEDragDrop()" Resume TreeView0_OLEDragDrop_Exit End Sub
L'action glisser-déposer étape par étape.
La procédure TreeView0_OLEDragDrop() s'exécute immédiatement après que le bouton gauche de la souris a été relâché pour terminer l'action de dépôt. Au début du code, les références du nœud TreeView actif et cible ont été enregistrées dans tv_nodSource et tv_nodTarget variables d'objet respectivement.
Ensuite, nous effectuons une vérification, si le ListItem a été déposé sur un nœud TreeView valide ou non. S'il est déposé sur le même nœud de catégorie source ou sur une zone vide du contrôle TreeView, ces déplacements ne sont pas valides. S'il a été déposé dans une zone vide du contrôle TreeView, alors le tv_nodTarget la variable objet contiendra la valeur Nothing. Dans ce cas, il affiche un message et quitte le programme.
Ensuite, les valeurs clés du nœud source et cible de TreeView sont enregistrées dans deux variables de chaîne. Si les deux clés sont identiques, le ListItem a été glissé et déposé sur son propre nœud parent (nœud de catégorie) sur le contrôle TreeView. L'exécution du programme est interrompue.
Si les deux clés sont différentes, il est temps de mettre à jour le changement sur l'ID parent de l'enregistrement de produit. champ, avec le CID de l'enregistrement de catégorie cible Codez et actualisez les éléments ListView.
La valeur clé du ListItem sélectionné (PID valeur du champ) a été enregistré dans strListItemKey Variable de chaîne.
Le CID réel de l'enregistrement de catégorie la valeur du champ a été extraite du nœud cible, en supprimant la valeur du caractère de préfixe X et enregistrée dans la variable vCatID . Il s'agit de la valeur que nous mettrons à jour dans le champ ParentID de l'enregistrement de produit, afin de placer le ListItem sous la nouvelle catégorie.
De même, la valeur PID clé du produit de l'élément de liste sélectionné extraite et enregistrée dans la variable lngPID . Cela a été utilisé comme critère pour filtrer et sélectionner cet enregistrement de produit particulier pour mettre à jour le champ ParentID avec vCatID .
Une MISE À JOUR La requête SQL a été créée pour filtrer l'enregistrement, en utilisant le lngPID Codez en tant que critères, pour filtrer l'enregistrement de produit et mettre à jour le vCatID Valeur dans le P un ID parent champ.
Le bouton Exécuter méthode de la Currentdb a été appelé avec le SQL et met à jour le changement.
La surbrillance du nœud a été réinitialisée sur le nœud source.
Ensuite, la sous-routine TreeView0_NodeClick() a été appelée avec le tv_nodSource en tant que paramètre pour refléter la modification sur le contrôle ListView.
La fermeture Cliquez sur le bouton pour fermer le formulaire.
Télécharger la base de données de démonstration.
Vous pouvez télécharger la base de données de démonstration, effectuer des essais et étudier le code VBA.
VOUS SOUHAITE UNE TRÈS BONNE ANNÉE.
GESTION DES ÉVÉNEMENTS MS-ACCESS
- Module de cours MS-Access sur les événements
- Avec les événements et définition de vos propres événements
- Onglet de la zone de texte de la liste combinée des événements
- Access Form Control Arrays And Event
- Access Form Control Arrays And Event-2
- Access Form Control Arrays And Event-3
- Module Événements dans la classe pour le sous-formulaire
- Module et données des événements dans la classe
- Événements sans événements et récepteur d'événements de rapport d'accès
- Avec événements et masquage des lignes de rapport
- Avec événements et mise en surbrillance de la ligne de rapport
- Avec événements Texbox et bouton de commande
- Bouton de commande de la zone de texte des événements
- Avec événements et tous les types de contrôle de formulaire