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

Omarranger TreeView-noder ved at trække og slippe

Introduktion.

Jeg håber, du fandt sidste uges selvstudie om ImageCombo Control nyttig til dine Microsoft Access-projekter. Med TreeView ImageCombo Control kunne vi skabe en smuk rullemenu med flere muligheder og rumme den i et lille rum på formularen.

Ligeledes har vi i en tidligere session lært, hvordan man tilføjer nye noder på et bestemt sted i nodehierarkiet eller sletter en node og tilføjer en ny for at flytte en node på trævisningskontrollen.

Denne metode anmoder om oprettelse af en ny post i kildetabellen for den nye node. Eller slet en eksisterende post og opret en ny for at flytte en eksisterende node for at gøre den permanent. På en måde, med brugen af ​​Tilføj/Slet funktioner, kunne vi tilføje nye noder eller omarrangere de eksisterende noder på TreeView-kontrollen. Hvad angår omarrangering af noder, har vi en bedre måde at gøre det på, i stedet for at slette noder og genskabe dem. Træk noden fra dens aktuelle placering, og slip den, hvor vi ønsker, at den skal være på TreeView-kontrollen. Dette er, hvad vi skal lære i denne episode

Denne enkle tilgang behøver kun at opdatere ændringen af ​​ParentID-feltværdien for relaterede poster for at gøre ændringen permanent.

De emner, der hidtil er dækket i tidligere sessioner.

  1. Microsoft TreeView Control Tutorial
  2. Oprettelse af adgangsmenu med TreeView-kontrol
  3. Tildeling af billeder til TreeView-kontrol
  4. Tildeling af billeder til TreeView Control-2
  5. TreeView Control Check-Mark Tilføj slet noder
  6. TreeView ImageCombo Drop-down Adgangsmenu

Men vi kan stå over for nogle udfordringer, mens vi bruger denne metode, og det kommer vi til lidt senere i denne session.

Demodatatabel og formular.

Vi har brug for en tabel og en formular. Vi har allerede en passende tabel med navnet Sample oprettet i en tidligere selvstudiesession. Hvis du allerede har downloadet demodatabasen fra den anden linkside, der er givet ovenfor, kan du også bruge denne database til denne session. Vi vil bruge følgende objekter fra den database til vores Drag-Drop-eksperimenter:

  • Tabel:Eksempel
  • Formular:frmSample

TreeView-kontrolbilledet på frmSample med demodata er givet nedenfor til reference:

Du kan downloade demodatabasen (ProjectMenu.zip ) fra den anden linkside ovenfor, og udtræk ProjectMenu.accdb database.

Ny formular til træk-slip-prøvekørsler.

  1. Åbn ProjectMenu.accdb-databasen.

  2. Lav en kopi af tabellen Eksempel og navngiv den som Sample_bk, hold det sikkert, vi skal bruge dets originale data uden ændringer senere. Når vi eksperimenterer med træk-slip-metoden, er det nødvendigt at opdatere ParentId-feltets værdi på prøvedemotabellen. Men vi har brug for de originale data senere, uden disse ændringer.

  3. Opret en ny formular med navnet frmDragDrop .

  4. frmDragDrop Form Design vil se ud som billedet nedenfor, når du er færdig med det.

  5. Indsæt TreeView-kontrolelementet fra ActiveX-kontrolelementernes liste, og placer det på formularen, og efterlad nok plads over kontrolelementet, så vi kan oprette to kommandoknapper og en overskriftsmærke over den. Træk størrelseshåndtaget i nederste højre hjørne for at gøre det stort nok til at vise alle noderne uden at rulle.

  6. Skift navnet Egenskabsværdi for TreeView Control til TreeView0 .

  7. Indsæt en kommandoknap over og venstre kant af TreeView-kontrolelementet. Skift dens navn Ejendomsværdi til cmdExpand og Billedtekst værdi til Udvid alle .

  8. Indsæt en anden kommandoknap over og til højre kant af TreeView-kontrolelementet. Skift dens navn Egenskabsværdi til cmdCollapse og Billetten Ejendomsværdi til Skjul alle.
  9. Indsæt en etiketkontrol over kommandoknapperne, bred nok til at skrive overskriften som vist ovenfor, og skift dens skriftstørrelse 14.

  10. Ignorer ImageList Control, for øjeblikket har jeg kommenteret kodelinjerne, der ændrer Node ImageList-indeksnumrene. Senere kan du importere billedlistekontrollen med manuelt uploadede billeder fra vores tidligere selvstudiedemodatabase (fra den 4. linkside ovenfor) og bruge den til at vise nodebilleder på noder. Når nodepositioner ændres under træk-slip-handlinger, skal vi også ændre nodebilleder afhængigt af nodens position (rodniveauknude eller børneknude) på TreeView-kontrollen.

    Træk-slip formularmodulkode.

  11. Vis VBA-kodemodulet for formularen frmDragDrop, kopier og indsæt følgende VBA-kode (dette er kun den første halvdel af formularmodulkoden) i frmDragDrop-formularens klassemodul og gem formularen:

    Option Compare Database
    Option Explicit
    
    Dim tv As MSComctlLib.TreeView
    Dim db As DAO.Database
    Dim rst As DAO.Recordset
    Dim imgListObj As MSComctlLib.ImageList
    Const KeyPrfx As String = "X"
    
    Private Sub Form_Open(Cancel As Integer)
    Set tv = Me.TreeView0.Object
    
    'Set imgListObj = Me.ImageList1.Object
    'tv.ImageList = imgListObj
    
    LoadTreeView
    
    End Sub
    
    Sub LoadTreeView()
    Dim strKey As String
    Dim strPKey As String
    Dim strText As String
    Dim strsQL As String
    
    strsQL = "SELECT * FROM Sample ORDER BY ID"
    
    Set db = CurrentDb
    Set rst = db.OpenRecordset(strsQL, dbOpenDynaset)
        
    tv.Nodes.Clear
    
    'Add all Items are added as Root Nodes
    Do While Not rst.BOF And Not rst.EOF
        strKey = KeyPrfx & CStr(rst!ID)
        strText = rst!desc
        tv.Nodes.Add , , strKey, strText
        
        'With tv.Nodes.Item(strKey)
        '    .Image = 1
        '    .SelectedImage = 4
        'End With
    
        rst.MoveNext
    Loop
    
    'Prepare to update the Parent-Key of Nodes
    'wherever applicable to move and position the Child Nodes
    strPKey = ""
    rst.MoveFirst
    Do While Not rst.EOF
        strPKey = Nz(rst!parentid, "")
        
        If Len(strPKey) > 0 Then
            strPKey = KeyPrfx & strPKey
            strKey = KeyPrfx & CStr(rst!ID)
            strText = rst!desc
            
            'Move the Child Node under it's Parent-Node
            Set tv.Nodes.Item(strKey).Parent = tv.Nodes.Item(strPKey)
            
    'Update Image and SelectedImage Properties
    'with ImageList Index numbers
            'With tv.Nodes.Item(strKey)
            '    .Image = 2
            '    .SelectedImage = 3
            'End With
    
        End If
        rst.MoveNext
    Loop
    
    rst.Close
    Set rst = Nothing
    Set db = Nothing
    
    End Sub
    
    
    Private Sub TreeView0_NodeClick(ByVal Node As Object)
    Dim SelectionNode As MSComctlLib.Node
        
    'Ensure that the clicked node equals the selected node in the tree
    If Not Node Is Nothing Then
        Set SelectionNode = Node
           If SelectionNode.Expanded = True Then
                SelectionNode.Expanded = False
            Else
                SelectionNode.Expanded = True
            End If
    End If
    End Sub
    
    Private Sub cmdCollapse_Click()
    Dim tmpnod As MSComctlLib.Node
    For Each tmpnod In tv.Nodes
        If tmpnod.Expanded = True Then
            tmpnod.Expanded = False
        End If
    Next
    
    End Sub
    
    Private Sub cmdExpand_Click()
    Dim tmpnod As MSComctlLib.Node
    For Each tmpnod In tv.Nodes
        If tmpnod.Expanded = False Then
            tmpnod.Expanded = True
        End If
    Next
    
    End Sub

    Jeg ved, at du er bekendt med ovenstående kode, hvis du allerede har gennemgået de tidligere episoder, undtagen LoadTreeView() subrutine med nogle ændringer. Her er udfyldning af TreeView-noder blevet opdelt i en to-trins proces.

    Kort fortalt er dette, hvad der sker i denne underrutine.

    • Alle posterne på Eksempel Tabellen er blevet indlæst som knudepunkter på rodniveau i TreeView Control, med en ID-feltværdi som Nøgle, i det første trin.

    • Igen er disse poster blevet læst en anden gang, og kontroller for en værdi i Forældre-id felt, hvis det er tomt, vil noden blive bibeholdt som node på rodniveau.

    • Hvis ParentID-feltet har en Value, skal du identificere noden med ParentID-værdien som Node-Key og flyt den aktuelle node som dens underordnede node eller dens [Selativ] Parameter (af Tilføj () Metode) værdi bliver opdateret.

    • Selvom det ser ud til, at to-trins node-udfyldningsproceduren er en unødvendig øvelse, er der en god grund til, at vi er nødt til at følge denne metode. Vi vil vende tilbage til dette lidt senere, og du vil vide det uden meget forklaring.

    • På Formularens Design har jeg givet en ImageList Control. Du kan indsætte ImageList ActiveX Control og upload nogle billeder i det manuelt fra disken, eller kopier og indsæt denne kontrol med billeder fra tidligere download af demodatabaser. I begge tilfælde skal du sørge for, at navnet på ImageList-kontrollen er ImageList1 . Ellers skal du ændre navnet i koden.

    • Aktiver derefter de kommenterede linjer i Form_Open() Event Procedure. Aktiver følgende linjer ved at fjerne kommentarsymbolet fra begyndelsen af ​​linjen:

      'Set imgListObj = Me.ImageList1.Object
      'tv.ImageList = imgListObj
      

    • I TreeView0_ OLEDragDrop() Subrutine (i 2. del af VBA-koden) aktiverer billedindeksparametrene for noder ved også at fjerne kommentarsymbolerne fra disse linjer. Med disse ændringer vil nodebillederne blive vist på TreeView Control. Hvis du har din egen billedlistekontrol med uploadede billeder, skal du ændre indeksnumrene baseret på det billede, du gerne vil indsætte på noderne.

      TreeView0_NodeClick() Hændelsesprocedure Udvider den aktuelle node, hvis underordnede knudepunkter er i en sammenklappet tilstand, ellers vil underknudepunkter blive skjult. Normalt styres denne handling (uden kode) ved at klikke på +/- Symbol på trælinjen for noden med underordnede noder.

      Underrutinerne cmdExpand_Click() og cmdCollapse_Click() Hændelser Udvider henholdsvis alle noder og skjuler alle noder.

      Når ovenstående kode kører, ser displayet ud som formularvisningsbilledet vist nedenfor:

    • Du kan gemme frmDragDrop Form og åbn den i normal visning. Hvis alt gik godt, vil du se ovenstående skærm. Prøv Udvid alle og Skjul alle Kommandoknapper og kontroller, om de også virker. Hvis ikke, så kontroller igen, at følgende indstillinger er korrekte eller ej:

    • i) TreeView Controls navn er:TreeView0

    • ii) Vis egenskabsarket for Exampand All Kommandoknap, og vælg [Begivenhedsprocedure] i Ved klik Begivenhedsejendom.

    • iii) Sørg for, at den samme indstilling er intakt for Skjul alle Kommandoknap også.

    • iv) Klik på en node, der har underordnede noder, for at se, om de kollapser eller udvides ved gentagne klik.

    • v) Hvis ImageList Control er placeret på formularen, skal dens navn være ImageList1 .

      Lad os fortsætte med den anden del af VBA-koden, der implementerer Drag-Drop-begivenhederne.

    Anden halvdel af VBA-koden.

  12. Kopier følgende anden del af VBA-koden på frmDragDrop Form Module, der implementerer Drag-Drop handlingen, og indsæt den under den eksisterende kode:

    Private Sub TreeView0_OLEStartDrag(Data As Object, AllowedEffects As Long)
        Set Me.TreeView0.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)
        
        Dim SelectedNode As MSComctlLib.Node
        Dim nodOver As MSComctlLib.Node
        
        If tv.SelectedItem Is Nothing Then
            'Select a node if one is not selected
            Set SelectedNode = tv.HitTest(x, y)
            If Not SelectedNode Is Nothing Then
                SelectedNode.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
    
    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 sourceNode As MSComctlLib.Node
        Dim SourceParentNode As MSComctlLib.Node
        Dim targetNode As MSComctlLib.Node
        
        Dim tmpRootNode As MSComctlLib.Node
        Dim strtmpNodKey As String
        Dim ChildNode As MSComctlLib.Node
        
        Dim strSPKey As String
        Dim strTargetKey As String
        
        Dim strsQL As String
        Dim intKey As Integer
        Dim intPKey As Integer
        
        On Error Resume Next
        
        Select Case Screen.ActiveControl.Name
                
               Case TreeView0.Name
                    Set sourceNode = tv.SelectedItem
                
        End Select
        
        'Get Source Parent Node & Target Node Reference
        Set SourceParentNode = sourceNode.Parent
        Set targetNode = tv.HitTest(x, y)
                
        'If any errors then exit
        If Err <> 0 Then
            MsgBox Err & " : " & Err.Description, vbInformation + vbCritical, "OLEDragDrop()"
            Err.Clear
            Exit Sub
        Else
            On Error GoTo 0
        End If
        
    
        'Get/define Source parent Node Key to compare it with Target Node Key
        If SourceParentNode Is Nothing Then
            strSPKey = "Empty"
        Else
            strSPKey = SourceParentNode.Key
        End If
        
        'Check the Target Node/Location and define the Key
         Select Case True
            Case targetNode Is Nothing
                strTargetKey = "Empty"
            
            Case targetNode.Key = ""
                strTargetKey = "Empty"
                Set targetNode = Nothing
            Case Else
                strTargetKey = targetNode.Key
         End Select
        
        'Make sure the Target Node is not the source Node's own parent
        If strTargetKey = strSPKey Then Exit Sub
        
        'Track User's Node move action, check for error.
        On Error Resume Next
        
        If targetNode Is Nothing Then
            
            'If target Node is Nothing (the Node dropped in the empty area),
            'then the Node must be moved to the Root-level
            'save the original sourceNode.Key
            strtmpNodKey = sourceNode.Key
            
            'Modify the source Node Key, with addition of some text, say 'Empty', like 'X5Empty'
            'So that a temporary Node can be created with the original source Node key.
            'Note: Two Nodes with the same Key cannot remain in memory at the same time.
            'The Source Node with key 'X5Empty' deleted later,
            'temporary Node takes it's droped location.
            sourceNode.Key = sourceNode.Key & strTargetKey
    
            'Create the temporary Root Node, with original sourceNode Key
            Set tmpRootNode = tv.Nodes.Add(, , strtmpNodKey, sourceNode.Text)
            
            'define the Root Node image indexes
            'With tmpRootNode
            '    .Image = 1
            '    .SelectedImage = 4
            'End With
            
            'Move all child Nodes from SourceNode,if any,
            'as tmpRootNode's Children
            Do Until sourceNode.Children = 0
                Set sourceNode.Child.Parent = tmpRootNode
                
                'modify Node image indexes
                'With sourceNode
                '    .Image = 2
                '    .SelectedImage = 3
                'End With
            Loop
    
            'Delete the Source Node with modified Key from TreeView
            tv.Nodes.Remove sourceNode.Index
            
            'Move the tmpRootNode with original Key
            'to the dropped location on TreeView
            Set sourceNode = tmpRootNode
        Else
            'Move the sourceNode under targetNode as child
            Set sourceNode.Parent = targetNode
            
            'modify Node image indexes
            'With sourceNode
            '    .Image = 2
            '    .SelectedImage = 3
            'End With
        End If
        
        'Notify, if there was an Error then Exit, else Update PrentID of related Record.
        If Err <> 0 Then
            MsgBox Err & " : " & "Unable to move:" & vbCrLf & Err.Description, vbInformation + vbCritical, "DragDrop2()"
            Exit Sub
        Else
            'Build and execute the SQL statement to update the record
            If targetNode Is Nothing Then
                intKey = Val(Mid(sourceNode.Key, 2))
                strsQL = "UPDATE Sample SET ParentID = Null" & _
                         " WHERE ID = " & intKey
            Else
                intKey = Val(Mid(sourceNode.Key, 2))
                intPKey = Val(Mid(targetNode.Key, 2))
                
                strsQL = "UPDATE sample SET ParentID = " & intPKey & _
                         " WHERE ID = " & intKey
            End If
            
            'Modify the table records
            CurrentDb.Execute strsQL, dbFailOnError
            
            'If an error raised then refresh TreeView and exit
            If Err <> 0 Then
                MsgBox Err & " : " & Err.Description
                LoadTreeView 'Refresh/display TreeView without changes
            Else
                'Sort Nodes
                If sourceNode.Parent Is Nothing Then
                    sourceNode.Root.Sorted = True
                Else
                    sourceNode.Parent.Sorted = True
                End If
                
                tv.Nodes(sourceNode.Key).Selected = True
            End If
        End If
        On Error GoTo 0
    
    End Sub
    
    Private Sub TreeView0_OLECompleteDrag(Effect As Long)
    
        'Turn off the drophighlight
        Set tv.DropHighlight = Nothing
    
    End Sub
    
    Private Sub Form_Close()
    
    Set tv = Nothing
    End Sub

Til Drag-Drop-handlingen er der fire underrutiner, de udføres automatisk, når du trækker noderne, fremhæver noden, når den flyttes over andre noder, og til sidst slipper den på en anden node eller på det tomme område på rodniveau .

Kodens vigtigste underrutiner.

  • TreeView0_OLEStartDrag() - Initialiserer det valgte element og indstiller noden til ingenting
  • TreeView0_OLEDragOver() - Fungerer som Mouse Move Event, fremhæver noden, når der trækkes en node over den, på vej til målknuden.
  • TreeView0_OLEDragDrop() – Udfører kontrol og kontroller, placerer noderne i den droppede placering og opdaterer posten på basistabellen.
  • TreeView0_OLEcompleteDrag() - DropHighlight-egenskaben er indstillet til Ingenting.

Vi kan udføre træk og slip med TreeView0_OLEDragDrop() Subrutine alene. I så fald vil der ikke være nogen node-fremhævning, når kildenoden bevæger sig over andre noder, fra det ene sted til det andet, bortset fra at musemarkøren skifter til at trække en anden pil bag sig, som i eksempelbilledet nedenfor :

Så vi vil være opmærksomme på denne subrutine og kontrollere koden i detaljer fra begyndelsen. I begyndelsen af ​​subrutinen har vi erklæret de nødvendige noder og strengvariabler og andre.

I stedet for at gentage linje-for-linje analyser her, har jeg kommenteret hver linje/afsnit af koder passende, så du forstår, hvad den gør, når du gennemgår koden. Du kan gå dem igennem.

Rækkefølgen af ​​Drap Drop-begivenheder

Lad os forstå rækkefølgen af ​​begivenheder, brugeren vælger en node, trækker hen over andre noder på vej til dens endelige destination og Drops det på Target Node. Eller slip det på det tomme område på TreeView Control for at gøre det til en knude på rodniveau.

Når du trækker en node hen over en anden node-tekst, bliver node-teksten fremhævet og siger, at din nuværende position er på denne node på vej, uanset hvor du skal hen herfra. Når den flyttes ud af node-teksten, forsvinder fremhævelsen. Dette sker hele vejen igennem til Target Node. TreeView0_OLEDragOver() Subroutine tager sig af denne fremhævende handling.

Når du taber en node et sted, vises TreeView0_OLEDragDrop() Subrutine tager overpris. Her skal vi analysere brugerens hensigter og træffe passende foranstaltninger. Følgende information skal gemmes og analyseres for at flytte noden til den korrekte placering.

Vigtige oplysninger at holde styr på.

  1. Kilden nodereference, nodenøgle og forældre-id værdier, node børn, hvis nogen.

  2. Målknude eller placeringsreference, nodenøgle.

  3. Hvis målet ikke er en knude, men det tomme område i TreeView-kontrollen, skal kildenoden flyttes til positionen på rodniveau.

  4. Kildeknuden, når den droppes på en anden knude, bliver målknuden den nye overordnede for kildenoden.

  5. Hvis Source Node har sine egne børn, skal de også flyttes med deres forældre.

  6. ** Når noden trækkes og slippes på sin egen forældrenode, skal du ignorere denne handling.

    ** Tjek for eksempel billedet ovenfor. Hvis vi trækker tekstboksen Node og slip den til dens overordnede node Kontroller, eller trækker kontrollerne Node og slip den på dens overordnede node Form så vil disse træk blive ignoreret.

  7. ** Hvis rodniveau Node trækkes og slippes ind i det tomme område, hvorefter der ikke foretages nogen handling, fordi det allerede er en node på rodniveau.

For alle gyldige træk af Node skal vi opdatere Forældre-ID'et feltværdi for den relaterede post på Sample tabel.

Knudefald i det tomme område på rodniveau.

I tilfælde af varenummer 3 ovenfor, skal vi oprette en knude på rodniveau med det samme ID-nummer som kildenoden, hvilket ikke er tilladt. Dubleret nøgleværdi er ikke tilladt i TreeView-hierarkiet. Dette er det eneste område af kodekset, hvor du vil finde lidt forvirring om den procedure, der følges der.

Fremgangsmåden er som angivet nedenfor:

  1. Rediger den eksisterende TreeView Node Key med tilføjelse af noget ekstra tekst, (sig Key X5 ændre til X5Empty ), for at undgå nøglekonflikter, mens du opretter en midlertidig node med den originale nøgle.

  2. Opret en midlertidig Node med den originale nøgle:X5.

  3. Flyt alle underordnede noder fra kildenoden, hvis nogen, som underordnede noder til den midlertidige node.

  4. Slet TreeView-kildenoden med den ændrede nøgle:X5Empty fra TreeView Control, men den relaterede post på prøvetabellen berøres ikke.

  5. Flyt den midlertidige Node med den originale nøgle X5 med sine børn til rodniveaupositionen i TreeView Control.

  6. Opdater ParentID-feltet for den relaterede post med en nul-længde streng (“”) for at markere den som en node på rodniveau.

Selveksperimenter med Drag Drop.

Du kan selv prøve nogle træk og slip-eksperimenter og se, hvordan det fungerer. Vælg en node, klik og hold venstre museknap nede, træk noden, og slip den på en anden node, eller slip den i et tomt område af TreeView Control. Når du trækker noden hen over anden node-tekst, fremhæves den, og når du er ude af noden, forsvinder markeringen. Den trukne node vises på den nye placering, hvor du har droppet den. Du kan gentage dette træk-slip-eksperiment ved at vælge en enkelt node eller node med børn.

Baseret på denne bevægelse af noder den relaterede posts Forældre-ID feltværdien vil blive opdateret med Nøglen værdi (ID) af den målknuderelaterede post.

Hvorfor to-trins nodeudfyldningsprocedure?

Nu går vi tilbage til LoadTreeView() Underrutine, for at tage et andet kig på den to-trins proces, vi har vedtaget til at udfylde alle noder til TreeView Control.

  • Alle poster i Eksempel Tabeller tilføjes til at begynde med som knudepunkter på rodniveau, ved at bruge ID-feltværdien som nodenøgle.

  • I det andet gennemløb af posterne, hvis ParentID-feltværdien er tom, forbliver den node som rodniveauknude uden ændring.

  • Alle andre noder-relaterede poster med forældre-id-værdi flyttes korrekt under dens overordnede node.

Spørgsmålet dukker naturligvis op, hvorfor vi skal gøre det på denne måde?

Vi vil lave et simpelt eksperiment for at gøre svaret klart uden at forklare det med for mange ord. Du har måske allerede lavet nogle prøvekørsler med træk og slip prøvekørsler selv og omarrangerede noder, og i processen opdaterede du disse posters ParentID-værdier med ændringen. Så vi er nødt til at nulstille postværdierne til deres oprindelige tilstand i Samplen Tabel, før vi starter en ny demo.

Vi har allerede oprettet en kopi af vores Tabel Eksempel tidligere med navnet Sample_bk som backup. Slet eksemplet Tabel og lav en kopi fra Sample_bk med det originale navn:Eksempel .

Åbn tabellen, og se posterne og deres forældre-id-feltværdier. Eksempelbilledet af tabellen er givet nedenfor:

ID-feltværdierne er autonumre, og de er alle i sekventiel rækkefølge, og alle id-værdier er unikke. Den følgende enkle regel styrer tilføjelsen af ​​en underordnet node til TreeView-kontrollen.

Den simple børneknuderegel: Forældre-id feltværdi (forældrenøgle ) i en post forventer, at der allerede eksisterer en overordnet node i TreeView Control, med samme værdi som Node-Key (ID'et).

Tjek den tredje post fra toppen i ovenstående tabelbillede. Værdien af ​​ParentID-feltet er 2, og ID'et for den aktuelle post er 3. I dette tilfælde vil posten med ID 2 blive tilføjet til TreeView Control, før vi forsøger at tilføje den tredje post til Noden. Begge plader er ikke nødvendigvis ved siden af ​​hinanden. Tjek posten med ID-nummer 21, dens ParentID-feltværdi er 12, mindre end den aktuelle records ID-værdi 21.

I begge tilfælde, når programmet støder på ParentID-værdien i en post, antager det, at posten med ID-værdien lig med ParentID'et allerede var tilføjet som en node i TreeView-kontrollen i den tidligere cyklus med udfyldning af noderne.

Begrundelse af totrinsproceduren.

Lad os prøve nogle Drag-Drop prøvekørsler. Men før det har vi en formular med navnet frmSample, som vi har brugt i den første vejledningssession, og i den forbindelse har vi indlæst alle TreeView-noder på én gang. Ja, vi har fulgt den samme metode indtil videre, og vi har brug for nogle ændringer fra nu af. Men før det, lad os åbne den gamle formular og se, hvordan noderne vises på formularen.

  1. Åbn formularen frmSample for at se, hvordan TreeView-displayet ser ud med prøvetabelposterne indlæst ved hjælp af den gamle regel.

  2. Hvis du er færdig med at se TreeView-knuderne, så luk formularen.

  3. Åbn nu frmDragDrop Form. Vi forbereder at trække og slippe en node.

  4. Vælg noden med node-tekst tabellen, Klik og hold venstre museknap nede, træk og slip den på noden med node-tekst-formularen.

  5. Tabellen Node med dens umiddelbare Child-Node felter og dets børneknuder flyttes som underordnede noder under formularen Node.

  6. Luk formularen frmDragDrop og åbne den igen. Noderne vises korrekt, hvor du har droppet dem, ligesom billedet nedenfor.

  7. Luk nu formularen frmDragDrop.

  8. Åbn formularen frmSample for at se, hvordan denne ændring vises på denne formular. Du vil blive mødt med en fejlmeddelelse, Element ikke fundet med Fejlnummer:35601.

  9. Vælg kommandoknappen Debug for at gå til den fremhævede kodelinje, hvor fejlen opstod.

  10. Peg med musen på nodKey Param af Add()-metoden viser X3, punkt musen på Parent Key parameter, og den viser X7.

    Når vi ser på disse to parameterværdier, kan vi antage, at vi er på posten med ID-værdien 3 og forsøger at udpege denne Node som en underordnet Node, til en anden Node, der endnu ikke er udfyldt i TreeView Control, med ID-værdi 7.

  11. Tryk på F5 Tast for at åbne den samme dialogboks igen, og klik på Afslut Kommandoknap for at stoppe programmet og få formularen frem i databasevinduet. Luk frmSample Form.

  12. Åbn Eksempel Tabel for at se arrangementet af forældre-id-numrene efter vores træk og slip-handling. Posterne vil se ud som billedet nedenfor, og jeg har fremhævet den post, der udløste fejlen med ParentID-værdien 7 og viser dens overordnede rekordposition.

Efter den tidligere node, der udfyldte normal procedure, er vi på den tredje rekordposition. Siden registrerer forældre-ID-værdi 7, Nikke med ID-værdi 7 skal være til stede i TreeView Control. Noden med ID-værdi 7 er endnu ikke udfyldt i TreeView Control, men vi forsøger at referere til den ikke-eksisterende node, og dette udløser en fejl.

Selvom du sorterer posterne i ParentID-feltrækkefølgen, vil posternes nye arrangement se ud som billedet nedenfor:

Nu er en anden rekords forældreknude ikke i den forventede position.

Derfor, under disse omstændigheder, fungerer vores to-trins TreeView Nodes-indlæsningstilgang til både normale og efter træk-slip-handlinger.

I det første trin skal du udfylde alle poster som noder på rodniveau i TreeView-kontrolelementet ved at bruge ID-feltværdien som Node-Key.

Nu er alle noder i alle poster tilgængelige i TreeView Control. Det vil være nemt at flytte dem rundt, hvorhen vi vil. Det siger ikke, at nogen af ​​de nødvendige noder ikke eksisterer i TreeView.

I den anden gennemgang af det samme sæt poster er posterne med tomme ParentID-feltværdier uberørte og får lov til at forblive som knudepunkter på rodniveau. I andre tilfælde flytter noden som underordnet node under dens overordnede node ved at opdatere [Relativ] Parameter for noden med følgende sætning:

Set tv.Nodes.Item(strKey).Parent = tv.Nodes.Item(strPKey)

This is what we do through the second pass on the same set of records. You may do it by resetting the Record Pointer to the first record, by executing rst.MoveFirst before the Do . . . Loop, EOF conditions and rst.MoveNext to access each record as we normally do.

Second Step in Reverse Order.

Or you may do it in reverse order. After populating all records as Root-level Nodes the Record Pointer will be beyond the last record and on the EOF position. You may reset the record pointer to the last record, by executing rst.MoveLast before the Do . . . Loop BOF check, and execute rst.MovePrevious to access each record and move the Nodes correctly under its p arent Node. But, the Nodes may load slightly differently in the placement order of Nodes.

You may try this out yourself with the above-suggested change of Code and see the result.

Download Demo Database


  1. MS-Access Class Module og VBA
  2. MS-Access VBA Class Object Arrays
  3. MS-Access Basisklasse og afledte objekter
  4. VBA Base Class and Derived Object-2
  5. Basisklasse og afledte objektvarianter
  6. MS-Access Recordset og Class Module
  7. Adgang til klassemodul- og indpakningsklasser
  8. Wrapper Class Funktionalitet Transformation


  1. psql:FATAL:rolle postgres eksisterer ikke

  2. Returner basisdatatypen fra en SQL_variantværdi i SQL Server

  3. Fjern dublet fra en tabel

  4. Rails Console finder brugere efter række id'er