sql >> Databáze >  >> RDS >> Access

Ovládání ListView Zpracování událostí přetažením

Úvod.

Jsme obeznámeni s operacemi Drag and Drop na TreeView Control v Ms-Access, který mění uspořádání uzlů. Všechny základní záznamy pro řídicí uzly Treeview pocházejí z jediné přístupové tabulky. Vždy aktualizujeme ParentID zdrojového uzlu hodnotu pole, s hodnotou ID cílového uzlu ve stejném záznamu tabulky, aby se změnila pozice v ovládacím prvku TreeView. Záznamy se fyzicky nikam neposouvají.

Zde, s přidáním ListView Control spolu s TreeView Control, plánujeme pracovat se dvěma různými přístupovými tabulkami.

  1. lvCategory – Kód a popis kategorie.
  2. lvProducts – produkty podle kategorií.

Tímto způsobem je snazší pochopit vztah mezi oběma tabulkami. Jaké změny musíme provést a kde, když se jedna položka produktu (položka ListView) přesune z jedné kategorie do druhé v ovládacím prvku TreeView.

lvCategory Přístupová tabulka obsahuje 20 záznamů pro uzly TreeView a lvProducts Tabulka má 45 pro ovládací prvek ListView. Jeden nebo více záznamů v tabulce Produkty přímo souvisí s kategorií produktu v tabulce kategorií. Vztah mezi nimi byl aktualizován o hodnotu pole Category ID (CID) v ParentID v tabulce produktů. pole tak, aby se změna kategorie produktu okamžitě projevila na ovládacím prvku ListView.

Tabulka ukázkových dat byla převzata z ukázkové databáze Microsoft Access Northwind.accdb a rozdělena na dvě části.

Na základě hodnoty pole ParentID záznamů lvProduct bychom mohli filtrovat a vypisovat všechny související položky produktů v ovládacím prvku ListView, když je v ovládacím prvku TreeView vybrán uzel kategorie.

Témata, kterými jsme se doposud zabývali.

Níže jsou uvedena hlavní témata StreeView , Seznam obrázků , ImageCombo, a ListView Ovládací prvky, které jsme dosud probrali v MS-Access:

  1. Výukový program pro ovládání Microsoft TreeView
  2. Vytvoření přístupové nabídky pomocí TreeView Control
  3. Přiřazení obrázků k ovládacímu prvku TreeView
  4. Přiřazení obrázků k TreeView Control-2
  5. Ovládací prvek TreeView zaškrtněte políčko Přidat a odstranit uzly
  6. Rozbalovací nabídka přístupu TreeView ImageCombo
  7. Změňte uspořádání uzlů TreeView přetažením
  8. Ovládání ListView s MS-Access TreeView

Úloha přetažení ListView.

Pokud jde o operaci Drag and Drop v ListView, je to jednoduché cvičení, které porovnává stejnou metodu v samotném ovládacím prvku TreeView. Protože akce Drag Drop zahrnuje ovládací prvky TreeView i ListView, používáme stejnou proceduru události TreeView0_OLEDragDrop() s jednoduchým kódem VBA.

Položky produktu uvedené v ovládacím prvku ListView patří k aktuální položce kategorie vybrané v ovládacím prvku TreeView.

Uživatel vybere konkrétní položku produktu z ovládacího prvku ListView, pokud si myslí, že patří do jiné položky kategorie, přetáhne ji na cílovou položku kategorie na ovládacím prvku TreeViewC.

Přesunutá položka ListView Product Item bude přidána do seznamu položek, které patří do změněné kategorie. Hodnota pole ParentID záznamu produktu se aktualizuje pomocí ID záznamu cílové kategorie (hodnota CID).

Je to pouze jednosměrná akce, vždy přesuňte položku ListView z jedné kategorie a umístěte ji na jiný uzel kategorie v ovládacím prvku TreeView.

Demonstrační přístupový formulář ListView přetažením frmListViewDrag’ zkušební provoz Obrázek obrazovky je uveden níže:

Na obrázku výše Nápoje Kategorie ve stromu TreeView byla vybrána. Produkty patřící do kategorie Beverages byly uvedeny v seznamu ListView Control.

Návrhové zobrazení výše uvedeného formuláře:

Seznam názvů ovládacích prvků ve formuláři je uveden níže:

  1. Ovládací prvek TreeView:TreeView0
  2. Ovládací prvek ListView:ListView0
  3. Ovládací prvek ImageList:ImageList3
  4. Příkazové tlačítko:cmdClose

Kód VBA na frmListViewDrag Modul třídy:

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

Známé segmenty kódu VBA.

V Form_Load() Událostní procedura, inicializujeme ovládací prvky TreeVew, ListView, ImageList. Vytvoří ColumnHeading ovládacího prvku ListView, před vyplněním položek seznamu v ovládacím prvku ListView. Na konci této rutiny zavoláme podprogram LoadTreeView().

Funkce LoadTreeView() podprogram vyplní uzly kategorií produktů v ovládacím prvku TreeView se záznamy z lvCategory Stůl. Načítání uzlů do ovládacího prvku TreeView je dvoukrokový proces. Proč tomu tak je, spíše než to udělat najednou? Tento aspekt byl podrobně vysvětlen na dřívější stránce, 7. odkaz na seznamu odkazů uveďte výše, pokud si to chcete projít. Opakovat je zde všechny nemusí být vhodné.

Na konci výše uvedeného podprogramu je LoadListView() podprogram byl volán s hodnotou CID prvního záznamu kategorie 1 jako parametr.

Hodnota pole Záznamy produktu s ParentID 1 byly filtrovány a uvedeny v ovládacím prvku ListView. Tento postup byl podrobně vysvětlen v příspěvku z minulého týdne, 8. položce, ve výše uvedeném seznamu odkazů.

Podprogramy akce Drag-Drop.

Následující podprogramy spojené s akcí Drag and Drop budou provedeny automaticky v pořadí, v jakém jsou uvedeny níže:

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

První a poslední podprogram inicializují zapojené uzly a na konci resetují jejich stav.

Druhý, podprogram OLEDragOver() funguje jako procedura události MouseMove a sleduje pohyb myši během operace přetažení. Když je myš nad uzlem, zvýrazní NodeText a sleduje jeho trajektorii, dokud se neuvolní levé tlačítko myši.

Samotný kód procedury TreeView0_OLEDragDrop() je uveden níže.

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

Akce Drag Drop krok za krokem.

Procedura TreeView0_OLEDragDrop() se spustí ihned po uvolnění levého tlačítka myši k dokončení akce přetažení. Na začátku kódu byly aktivní reference a reference cílového uzlu TreeView uloženy v tv_nodSource a tv_nodTarget objekt Proměnné resp.

Dále provedeme kontrolu, zda ListItem byla vypuštěna na platný uzel TreeView nebo ne. Pokud je upuštěn na stejný zdrojový uzel kategorie nebo na prázdnou oblast v ovládacím prvku TreeView, pak tyto pohyby nejsou platné. Pokud byl shozen do prázdné oblasti ovládacího prvku TreeView, pak tv_nodTarget objektová proměnná bude obsahovat hodnotu Nic. V tom případě to zobrazí zprávu a ukončí program.

Dále se hodnoty klíče TreeView Source a Target Node ukládají do dvou řetězcových proměnných. Pokud jsou oba klíče stejné, položka ListItem se přetáhne na svůj vlastní nadřazený uzel (uzel kategorie) v ovládacím prvku TreeView. Spouštění programu se přeruší a pokračuje dále.

Pokud se oba klíče liší, je čas aktualizovat změnu v ParentID záznamu produktu pole s CID záznamu cílové kategorie Kód a obnovte položky ListView.

Hodnota klíče vybrané položky seznamu (PID hodnota pole) byl uložen do strListItemKey Řetězcová proměnná.

Skutečné CID záznamu kategorie hodnota pole byla extrahována z cílového uzlu odstraněním hodnoty znaku předpony X a uložena do proměnné vCatID . Toto je hodnota, kterou budeme aktualizovat v poli ParentID v záznamu produktu, abychom umístili položku seznamu pod novou kategorii.

Podobně byla extrahována hodnota klíčového PID produktu vybrané položky seznamu a uložena do proměnné lngPID . Toto bylo použito jako kritérium pro filtrování a výběr konkrétního záznamu produktu pro aktualizaci pole ParentID pomocí vCatID .

AKTUALIZACE Pro filtrování záznamu pomocí lngPID byl vytvořen dotaz SQL Kódujte jako kritéria pro filtrování záznamu produktu a aktualizaci vCatID Hodnota v P arentID pole.

Provést metoda Currentdb byl volán pomocí SQL a aktualizuje změnu.

Zvýraznění uzlu bylo resetováno na zdrojový uzel.

Dále byl zavolán podprogram TreeView0_NodeClick() pomocí tv_nodSource jako parametr, který odráží změnu v ovládacím prvku ListView.

Tlačítko Zavřít Kliknutím na tlačítko se formulář zavře.

Stáhněte si ukázkovou databázi.

Můžete si stáhnout ukázkovou databázi, vyzkoušet si zkušební provoz a prostudovat kód VBA.


PŘEJI VÁM ŠŤASTNÝ NOVÝ ROK.

ZPRACOVÁNÍ UDÁLOSTÍ S PŘÍSTUPEM MS

  1. S modulem třídy MS-Access
  2. Příležitosti a definování vlastních událostí
  3. Karta Textové pole seznamu Combo List
  4. Přístup k ovládacím polím a událostem formuláře
  5. Přístup k ovládacím polím formuláře a události 2
  6. Přístup k ovládacím polím formuláře a události 3
  7. Samozřejmě v modulu třídy pro podformulář
  8. Samozřejmě v modulu třídy a datech
  9. Výpadek událostí a přehledů o přístupu
  10. Nepřítomnosti a skrytí řádku zprávy
  11. Zvýraznění událostí a řádku sestav
  12. S Texboxem a příkazovým tlačítkem
  13. S příkazovým tlačítkem textového pole
  14. Withevents a všechny typy ovládání formuláře



  1. Vypočítejte percentil v MySQL na základě součtů

  2. Zkontrolujte statistické cíle v PostgreSQL

  3. Jak vytvořit uživatele pomocí pgAdmin

  4. Změňte datový typ sloupce na sériový