TreeView Drag And Drop

jmiaebrown

Board Regular
Joined
Jul 13, 2008
Messages
129
Hi, Does anyone have any working VBA Excel examples showing how to process drag and drop events? What I want to do is modify the items in a column based on changes in the treeview.

Thanks.
 

Excel Facts

What is the last column in Excel?
Excel columns run from A to Z, AA to AZ, AAA to XFD. The last column is XFD.
how come its so hard to find out about how to use a ListView in VBA? I have seen alot of unanswered questions on the subject of dragging and dropping and other stuff. Is there anyone who has a working implementation of the ListView willing to share and de-mystify?

Thanks.
 
Upvote 0
Are you talking about a ListView or a TreeView - they are totally different things!
 
Upvote 0
Are you talking about a ListView or a TreeView - they are totally different things!

A TreeView. ListView came in because I have been thinking about which would be more efficient for my needs. Currently, I am using a TreeView to show a list of values from a range. There is no hierarchial structure so each item would represent a parent node. I want the ability to update the order of the items on the spreadsheet by moving the nodes on the TreeView. This has proven to be difficult as I can't seem to modify the node's index directly. I am now researching Collections to see if it gives me the flexibility to place items where I want them in the stack and then just update the TreeView based on Collection's order. Sound like a good approach?

Thanks.
 
Last edited:
Upvote 0
Why not just use a listbox and some command buttons?
 
Upvote 0
Are you talking about a ListView or a TreeView - they are totally different things!
Sorry to take so long to respond. I am using a TreeView. I have taken another approach using a Collection. I use the collection to hold the data and build the TreeView. I am almost there, I just need to know if I can add items where I want to in the collection. The "Add" method is defined as:

Add(Item, [Key], [Before], [After])

Does the [Before] and [After] parameters reference the index of the list? So that I could place and item before [Before] or after [After]? Hopefully?

Thanks
 
Upvote 0
Woo Hoo!!!! I think I got it... I am not a coding master but I am going to post what I did just in case it could help some one else.

Code:
Dim TList As Collection
Private Sub UserForm_Initialize()
     With Me
        .btnClose.Caption = "Close"
        .lblSpec = vbNullString
        With .TreeView1
            .Style = tvwTreelinesPlusMinusText
            .LineStyle = tvwRootLines
            .SingleSel = True
            .HotTracking = True
        End With
     End With
     Set TList = New Collection
     Call loadList
End Sub

'Load the collection with the data
Private Sub loadList()
     Dim rngData
     Dim tc As String, md As String, mKey As String, mTxt As String
     Dim idx As Long

    'Gets the distinct values from the column
    mods = Globals.getDistinctData

    'Get the testcase ids
    Set rngData = ActiveWorkbook.Worksheets("Sheet1").Range("DataRng")
    With rngData
        For idx = 1 To .Cells.count
            If Not IsEmpty(.Cells(idx, 1)) Then
                ' get the id
                tc = .Cells(idx, 1)
                ' get the name
                md = rngData.Offset(0, -2).Cells(idx, 1)
                ' if the tc is not empty
                If (Len(tc) > 0) Then
                    ' build the key and the text
                    mKey = "tc:" & TList.count + 1
                    mTxt = (TList.count + 1) & ". " & md & " : " & tc
                    'add to the collection
                    TList.Add mTxt, mKey
                End If
            End If
        Next idx
        'Update the Tree
        If (TList.count > 0) Then
            Call updateTree(TList)
        End If
    End With
End Sub

'Select the clicked node
Private Sub Treeview1_NodeClick(ByVal Node As MSComctlLib.Node)
     Me.lblSpec.Caption = "Moving Node: " & Node.Index
     TreeView1.SelectedItem = Node
End Sub

'Highlight what is dragged over
Private Sub TreeView1_OLEDragOver(Data As MSComctlLib.DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single, State As Integer)
    Dim nodSelected As Node
    Dim nodOver As Node
    If TreeView1.SelectedItem Is Nothing Then
        Set nodSelected = TreeView1.HitTest(x * 20, y * 20)
        If Not nodSelected Is Nothing Then
            nodSelected.Selected = True
        End If
    Else
        If TreeView1.HitTest(x * 20, y * 20) Is Nothing Then
        Else
            Set nodOver = TreeView1.HitTest(x * 20, y * 20)
            Set TreeView1.DropHighlight = nodOver
        End If
    End If
    'Scrolling doesnt work yet
    If y > 0 And y < 100 Then
        m_iScrollDir = -1
    ElseIf y > (TreeView1.Height - 200) And y < TreeView1.Height Then
        m_iScrollDir = 1
    End If
End Sub

'Move the selected node after the destination node
Private Sub TreeView1_OLEDragDrop(Data As MSComctlLib.DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single)
    Dim sNode As Node
    Dim dNode As Node
    Dim dNodeKey As String
    Dim dNodeTxt As String
    Dim newNodeKey As String
    Dim newNodeTxt As String

    On Error Resume Next
    Effect = fmDropEffectMove
    
    Set sNode = TreeView1.SelectedItem
    Set dNode = TreeView1.HitTest(x * 20, y * 20)
    
    newNodeKey = sNode.Key
    newNodeTxt = sNode.Text
                 
    Set TreeView1.DropHighlight = dNode
    
    ' remove the item from the list
    TList.Remove sNode.Key
    
    ' add the new item using the [After] param to place the item where
    'we want to
    TList.Add newNodeTxt, newNodeKey, , dNode.Key
    
    ' clear the Tree
    TreeView1.Nodes.clear
    
    ' update the tree
    Call updateTree(TList)
  
End Sub

'update the tree based the collection order
'since the Collection key and the TreeView key is the same
Private Sub updateTree(mCollection As Collection)
    Dim idx As Long
    With Me.TreeView1.Nodes
        .clear
        For idx = 1 To mCollection.count
            .Add Key:="tc:" & idx, Text:=mCollection.item(idx)
        Next idx
    End With
    Stop
End Sub

Private Sub btnClose_Click()
    Unload Me
End Sub

Still a little buggy... but I working at it.
 
Last edited:
Upvote 0
Woo Hoo!!!! I think I got it... I am not a coding master but I am going to post what I did just in case it could help some one else.

Code:
Dim TList As Collection
Private Sub UserForm_Initialize()
     With Me
        .btnClose.Caption = "Close"
        .lblSpec = vbNullString
        With .TreeView1
            .Style = tvwTreelinesPlusMinusText
            .LineStyle = tvwRootLines
            .SingleSel = True
            .HotTracking = True
        End With
     End With
     Set TList = New Collection
     Call loadList
End Sub

'Load the collection with the data
Private Sub loadList()
     Dim rngData
     Dim tc As String, md As String, mKey As String, mTxt As String
     Dim idx As Long

    'Gets the distinct values from the column
    mods = Globals.getDistinctData

    'Get the testcase ids
    Set rngData = ActiveWorkbook.Worksheets("Sheet1").Range("DataRng")
    With rngData
        For idx = 1 To .Cells.count
            If Not IsEmpty(.Cells(idx, 1)) Then
                ' get the id
                tc = .Cells(idx, 1)
                ' get the name
                md = rngData.Offset(0, -2).Cells(idx, 1)
                ' if the tc is not empty
                If (Len(tc) > 0) Then
                    ' build the key and the text
                    mKey = "tc:" & TList.count + 1
                    mTxt = (TList.count + 1) & ". " & md & " : " & tc
                    'add to the collection
                    TList.Add mTxt, mKey
                End If
            End If
        Next idx
        'Update the Tree
        If (TList.count > 0) Then
            Call updateTree(TList)
        End If
    End With
End Sub

'Select the clicked node
Private Sub Treeview1_NodeClick(ByVal Node As MSComctlLib.Node)
     Me.lblSpec.Caption = "Moving Node: " & Node.Index
     TreeView1.SelectedItem = Node
End Sub

'Highlight what is dragged over
Private Sub TreeView1_OLEDragOver(Data As MSComctlLib.DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single, State As Integer)
    Dim nodSelected As Node
    Dim nodOver As Node
    If TreeView1.SelectedItem Is Nothing Then
        Set nodSelected = TreeView1.HitTest(x * 20, y * 20)
        If Not nodSelected Is Nothing Then
            nodSelected.Selected = True
        End If
    Else
        If TreeView1.HitTest(x * 20, y * 20) Is Nothing Then
        Else
            Set nodOver = TreeView1.HitTest(x * 20, y * 20)
            Set TreeView1.DropHighlight = nodOver
        End If
    End If
    'Scrolling doesnt work yet
    If y > 0 And y < 100 Then
        m_iScrollDir = -1
    ElseIf y > (TreeView1.Height - 200) And y < TreeView1.Height Then
        m_iScrollDir = 1
    End If
End Sub

'Move the selected node after the destination node
Private Sub TreeView1_OLEDragDrop(Data As MSComctlLib.DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single)
    Dim sNode As Node
    Dim dNode As Node
    Dim dNodeKey As String
    Dim dNodeTxt As String
    Dim newNodeKey As String
    Dim newNodeTxt As String

    On Error Resume Next
    Effect = fmDropEffectMove
   
    Set sNode = TreeView1.SelectedItem
    Set dNode = TreeView1.HitTest(x * 20, y * 20)
   
    newNodeKey = sNode.Key
    newNodeTxt = sNode.Text
                
    Set TreeView1.DropHighlight = dNode
   
    ' remove the item from the list
    TList.Remove sNode.Key
   
    ' add the new item using the [After] param to place the item where
    'we want to
    TList.Add newNodeTxt, newNodeKey, , dNode.Key
   
    ' clear the Tree
    TreeView1.Nodes.clear
   
    ' update the tree
    Call updateTree(TList)
 
End Sub

'update the tree based the collection order
'since the Collection key and the TreeView key is the same
Private Sub updateTree(mCollection As Collection)
    Dim idx As Long
    With Me.TreeView1.Nodes
        .clear
        For idx = 1 To mCollection.count
            .Add Key:="tc:" & idx, Text:=mCollection.item(idx)
        Next idx
    End With
    Stop
End Sub

Private Sub btnClose_Click()
    Unload Me
End Sub

Still a little buggy... but I working at it.
Can you provide an excel file with a working treeview?
 
Upvote 0

Forum statistics

Threads
1,215,378
Messages
6,124,603
Members
449,174
Latest member
ExcelfromGermany

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top