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

ListView Control Drag Drop Gestion des événements

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.

  1. lvCategory – Code et description de la catégorie.
  2. 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 :

  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 au contrôle TreeView
  4. Affectation d'images à TreeView Control-2
  5. TreeView Control-Mark Add Delete Nodes
  6. Menu déroulant d'accès TreeView ImageCombo
  7. Réorganiser les nœuds TreeView par glisser-déposer
  8. 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 :

  1. Contrôle TreeView :TreeView0
  2. Contrôle ListView :ListView0
  3. Contrôle ImageList :ImageList3
  4. 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 :

  1. TreeView0_OLEStartDrag()
  2. TreeView0_OLEDragOver()
  3. TreeView0_OLEDragDrop()
  4. 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

  1. Module de cours MS-Access sur les événements
  2. Avec les événements et définition de vos propres événements
  3. Onglet de la zone de texte de la liste combinée des événements
  4. Access Form Control Arrays And Event
  5. Access Form Control Arrays And Event-2
  6. Access Form Control Arrays And Event-3
  7. Module Événements dans la classe pour le sous-formulaire
  8. Module et données des événements dans la classe
  9. Événements sans événements et récepteur d'événements de rapport d'accès
  10. Avec événements et masquage des lignes de rapport
  11. Avec événements et mise en surbrillance de la ligne de rapport
  12. Avec événements Texbox et bouton de commande
  13. Bouton de commande de la zone de texte des événements
  14. Avec événements et tous les types de contrôle de formulaire