Access
 sql >> Database >  >> RDS >> Access

Gestione degli eventi di trascinamento della selezione di controllo ListView

Introduzione.

Abbiamo familiarità con le operazioni di trascinamento della selezione su TreeView Control, in Ms-Access che riorganizza i nodi. Tutti i record di base per i nodi di controllo Treeview provengono da un'unica tabella di accesso. Aggiorniamo sempre il ParentID del nodo sorgente valore del campo, con il Valore ID del Nodo di Destinazione sullo stesso record Tabella, per effettuare il cambio di posizione sul Controllo TreeView. I record non vengono spostati fisicamente da nessuna parte.

Qui, con l'aggiunta di ListView Control insieme a TreeView Control, prevediamo di lavorare con due diverse tabelle di accesso.

  1. lvCategory – Codice categoria e descrizione.
  2. lvProducts – Prodotti per categoria.

In questo modo è più facile comprendere la relazione tra le due tabelle. Quali modifiche dobbiamo apportare e dove, quando un elemento del prodotto (elemento ListView) si sposta da una categoria all'altra sul controllo TreeView.

La lvCategory Access Table ha 20 record per i nodi TreeView e lvProducts La tabella ha 45 per il controllo ListView. Uno o più record nella tabella Prodotti sono direttamente correlati a una categoria di prodotti nella Tabella delle categorie. La relazione tra loro è stata aggiornata con il valore del campo ID categoria (CID) nella tabella dei prodotti ParentID campo in modo che il cambio di categoria del prodotto si rifletta immediatamente sul controllo ListView.

La tabella di dati demo è stata presa da Northwind.accdb database di esempio di Microsoft Access e divisa in due parti.

Sulla base del valore del campo ParentID, dei record lvProduct, potremmo filtrare ed elencare tutti gli elementi di prodotto correlati nel controllo ListView, quando un nodo di categoria viene selezionato nel controllo TreeView.

Argomenti che abbiamo trattato finora.

Di seguito sono riportati gli argomenti principali su TreeView , Elenco immagini , ImageCombo e Vista elenco Controlli che abbiamo trattato finora in MS-Access:

  1. Esercitazione sul controllo di Microsoft TreeView
  2. Creazione del menu di accesso con il controllo TreeView
  3. Assegnazione di immagini al controllo TreeView
  4. Assegnazione di immagini a TreeView Control-2
  5. Segnale di spunta Controllo TreeView Aggiungi Elimina nodi
  6. Menu di accesso a discesa TreeView ImageCombo
  7. Riorganizza i nodi TreeView trascinandoli e rilasciandoli
  8. Controllo ListView con TreeView di MS-Access

L'attività di trascinamento di ListView.

Per quanto riguarda l'operazione di trascinamento della selezione di ListView, è un semplice esercizio che confronta lo stesso metodo all'interno del solo controllo TreeView. Poiché l'azione Drag Drop coinvolge sia i controlli TreeView che ListView, utilizziamo la stessa procedura evento TreeView0_OLEDragDrop() con un semplice codice VBA.

Gli elementi del Prodotto elencati nel controllo ListView appartengono all'elemento della categoria corrente selezionato nel controllo TreeView.

L'utente seleziona un particolare articolo di prodotto dal controllo ListView, se pensa che appartenga a un articolo di categoria diverso, quindi trascinalo sull'articolo di categoria di destinazione sul controllo TreeViewC.

L'articolo del prodotto ListView spostato verrà aggiunto all'elenco degli articoli che appartengono alla categoria modificata. Il valore del campo ParentID del record del prodotto viene aggiornato con l'ID record della categoria di destinazione (valore CID).

È solo un'azione unidirezionale, spostare sempre l'elemento ListView da una categoria e rilasciarlo su un nodo di categoria diverso sul controllo TreeView.

La demo drag-drop di ListView Modulo di accesso frmListViewDrag' s esecuzione di prova L'immagine dello schermo è riportata di seguito:

Nell'immagine sopra, le Bevande La categoria in TreeView è stata selezionata. I prodotti appartenenti alla categoria Bevande sono stati elencati nel controllo ListView.

La visualizzazione del design del modulo di cui sopra:

L'elenco dei nomi di controllo sul modulo è riportato di seguito:

  1. Controllo TreeView:TreeView0
  2. Controllo ListView:ListView0
  3. Controllo ImageList:ImageList3
  4. Pulsante di comando:cmdClose

Il codice VBA in frmListViewDrag Modulo di classe:

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

I segmenti di codice VBA familiari.

Nel Carica_modulo() Procedura evento, inizializziamo i controlli TreeVew, ListView, ImageList. Crea le ColumnHeadings del controllo ListView, prima di popolare gli elementi List nel controllo ListView. Alla fine di questa routine, chiamiamo la subroutine LoadTreeView().

LoadTreeView() subroutine popola i nodi di categoria dei prodotti nel controllo TreeView, con i record di lvCategory Tavolo. Il caricamento di nodi sul controllo TreeView è un processo in due fasi. Perché è così, invece di farlo in una volta sola? Questo aspetto è stato spiegato in dettaglio in una Pagina precedente, il 7° link nell'elenco dei collegamenti forniti sopra se desideri esaminarlo. Ripeterli tutti qui potrebbe non essere appropriato.

Alla fine della suddetta subroutine, LoadListView() la subroutine è stata chiamata con il valore CID del primo record di categoria 1 come parametro.

I record del prodotto con il valore del campo ParentID 1 sono stati filtrati ed elencati nel controllo ListView. Questa procedura è stata spiegata in dettaglio nel post della scorsa settimana, l'ottavo elemento, tra l'elenco dei collegamenti sopra riportato.

Le subroutine di trascinamento della selezione.

Le seguenti subroutine associate all'azione Trascina e rilascia verranno eseguite automaticamente nell'ordine in cui sono presentate di seguito:

  1. TreeView0_OLEStartDrag()
  2. TreeView0_OLEDragOver()
  3. TreeView0_OLEDragDrop()
  4. TreeView0_OLECompleteDrag()

La prima e l'ultima Subroutine inizializzano rispettivamente i Nodi coinvolti e ne ripristinano lo stato alla fine.

La seconda, la subroutine OLEDragOver(), funziona come la procedura dell'evento MouseMove e tiene traccia del movimento del mouse durante l'operazione di trascinamento. Evidenzia il NodeText quando il mouse si trova su un Node e ne traccia la traiettoria fino al rilascio del pulsante sinistro del mouse.

Il solo codice della procedura TreeView0_OLEDragDrop() è elencato di seguito.

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'azione di trascinamento della selezione passo dopo passo.

La procedura TreeView0_OLEDragDrop() viene eseguita immediatamente dopo il rilascio del pulsante sinistro del mouse per completare l'azione di rilascio. All'inizio del codice, i riferimenti attivi e Target TreeView Node sono stati salvati in tv_nodSource e tv_nodTarget rispettivamente le variabili oggetto.

Successivamente, eseguiamo un controllo, se ListItem è stato rilasciato su un nodo TreeView valido o meno. Se viene rilasciato sullo stesso nodo di categoria di origine o su un'area vuota del controllo TreeView, questi spostamenti non sono validi. Se è stato rilasciato in un'area vuota del controllo TreeView, allora tv_nodTarget la variabile oggetto conterrà il valore Nothing. In tal caso, è visualizza un messaggio ed esce dal programma.

Successivamente, i valori chiave di TreeView Source e Target Node vengono salvati in due variabili stringa. Se entrambe le chiavi sono uguali, ListItem è stato trascinato e rilasciato sul proprio nodo padre (nodo di categoria) sul controllo TreeView. L'esecuzione del programma viene interrotta per continuare.

Se entrambe le chiavi sono diverse, è il momento di aggiornare la modifica sul ParentID del record del prodotto campo, con il CID del record della categoria target Codice e aggiorna gli elementi ListView.

Il valore della chiave ListItem selezionato (PID valore del campo) è stato salvato in strListItemKey Variabile stringa.

Il CID effettivo del record di categoria il valore del campo è stato estratto dal nodo di destinazione, eliminando il valore del carattere del prefisso X e salvato nella variabile vCatID . Questo è il valore che aggiorneremo nel campo ParentID del Product Record, in modo da inserire ListItem nella nuova categoria.

Allo stesso modo, il valore PID chiave del prodotto dell'elemento in elenco selezionato estratto e salvato nella variabile lngPID . Questo è stato utilizzato come criterio per filtrare e selezionare quel particolare record di prodotto per aggiornare il campo ParentID con vCatID .

Un AGGIORNAMENTO La query SQL è stata creata per filtrare il record, utilizzando il lngPID Codice come criteri, per filtrare il record del prodotto e per aggiornare il vCatID Valore nella P arentID campo.

Il Esegui metodo del Currentdb è stato chiamato con l'SQL e aggiorna la modifica.

L'evidenziazione del nodo è stata reimpostata sul nodo di origine.

Successivamente, la subroutine TreeView0_NodeClick() è stata chiamata con tv_nodSource come parametro per riflettere la modifica sul controllo ListView.

La Chiudi Il clic del pulsante chiuderà il modulo.

Scarica il database demo.

Puoi scaricare il database demo, eseguire prove e studiare il codice VBA.


TI AUGURIAMO UN FELICE ANNO NUOVO.

GESTIONE EVENTI MS-ACCESS

  1. Modulo Classe Withevents MS-Access
  2. Coneventi e definizione dei tuoi eventi
  3. Scheda Casella di testo dell'elenco combinato di eventi
  4. Accedi agli array e agli eventi di controllo dei moduli
  5. Accedi agli array di controllo dei moduli e all'evento-2
  6. Access Form Control Array ed Event-3
  7. Modulo Witheventi in classe per sottomodulo
  8. Con eventi nel modulo e dati della classe
  9. Coneventi e Access Report Event Sink
  10. Nascondi con eventi e riga di rapporto
  11. Evidenziazione con eventi e riga di report
  12. Withevents Texbox e Command Button
  13. Pulsante di comando con la casella di testo degli eventi
  14. Coneventi e tutti i tipi di controllo modulo