Iterate through treeview nodes

J

Jonathan Brown

I'm trying to use the Microsoft Treeview Control Version 6.0 that comes as
part of the MSCommctlLib library. I've been able to create my heirarchical
structure following a how-to found here:
http://puremis.net/excel/code/080.shtml

I've set all my nodes to show checkboxes. I'm trying to uncheck all child
nodes if a parent node is unchecked. I know I have to iterate through the
tree some how and up until this point I've been able to get it to work down
to two levels, but I need it to go through all levels of any child nodes.
What's annoying is that this treeview control doesn't have a nodes collection
where I could just use a "for each node in selectednode.nodes" statement. If
that were the case then this would be easy.

Here's the code I have so far but it's not working:

Private Sub tvFilter_NodeCheck(ByVal node As MSComctlLib.node)

Dim treeNode As node

iterate:
Set treeNode = node.Child
For i = 1 To node.Children
treeNode.Checked = node.Checked
If treeNode.Children > 0 Then
Set node = treeNode
GoTo iterate:
End If
Set treeNode = treeNode.Next
Next i

end sub

I'm also being forced to use unstructured code by using the goto statement.
I tried creating a separate subprocedure that would call itself but I
couldn't get that working either. It looked something like:

Sub CheckAllChildNodes(ByVal treeNode As node, ByVal nodeChecked As Boolean)
Dim node As node

Set node = treeNode.Child

For i = 1 To treeNode.Children
node.Checked = nodeChecked

If node.Children > 0 Then
' If the current node has child nodes, call the
CheckAllChildsNodes method recursively.
Set treeNode = node.Child
CheckAllChildNodes treeNode, nodeChecked
End If

Next i

End Sub

Any ideas here would be greatly appreciated.

Thanks in advance.

Jonathan
 
C

Chip Pearson

Try

Private Sub CommandButton3_Click()
Dim OneNode As Node
For Each OneNode In Me.TreeView1.Nodes
If Not OneNode.Parent Is Nothing Then
If OneNode.Parent.Checked = False Then
OneNode.Checked = False
End If
End If
Next OneNode
End Sub


Cordially,
Chip Pearson
Microsoft Most Valuable Professional
Excel Product Group, 1998 - 2009
Pearson Software Consulting, LLC
www.cpearson.com
(email on web site)
 
R

RB Smissaert

Here general purpose code to get nodes of a treeview:

Sub GetChildNodes(oStartNode As Node, _
collNodes As Collection, _
Optional lNodeImage As Long = -1, _
Optional bIncludeStartNode As Boolean = True, _
Optional oLastNode As Object, _
Optional bIncludeLastNode As Boolean, _
Optional bFinished As Boolean, _
Optional lRecursionCount As Long)

Dim i As Long
Dim oNode As Node
Dim oChildNode As Node

If collNodes Is Nothing Then
Set collNodes = New Collection
End If

lRecursionCount = lRecursionCount + 1

If bFinished Then
Exit Sub
End If

Set oNode = oStartNode

'adding nodes to the collection
'------------------------------
If lRecursionCount = 1 Then
If bIncludeStartNode Then
If NodeToCollection(oNode, _
collNodes, _
lNodeImage, _
bIncludeStartNode, _
oLastNode, _
bIncludeLastNode) Then
bFinished = True
Exit Sub
End If
End If
Else
If NodeToCollection(oNode, _
collNodes, _
lNodeImage, _
bIncludeStartNode, _
oLastNode, _
bIncludeLastNode) Then
bFinished = True
Exit Sub
End If
End If

'recursing the treeview
'----------------------
If oNode.Children Then
Set oChildNode = oNode.Child
For i = 1 To oNode.Children
GetChildNodes oChildNode, _
collNodes, _
lNodeImage, _
bIncludeStartNode, _
oLastNode, _
bIncludeLastNode, _
bFinished, _
lRecursionCount
Set oChildNode = oChildNode.Next
Next i
End If

End Sub

Function NodeToCollection(oNode As Node, _
coll As Collection, _
Optional lNodeImage As Long = -1, _
Optional bIncludeStartNode As Boolean = True, _
Optional oLastNode As Node, _
Optional bIncludeLastNode As Boolean) As Boolean

'will return True if oLastNode was specified and has been dealt with
'-------------------------------------------------------------------
If lNodeImage > -1 Then
If oNode.Image = lNodeImage Then
If oLastNode Is Nothing Then
coll.Add oNode
Else
If oNode.Key = oLastNode.Key Then
If bIncludeLastNode Then
coll.Add oNode
End If
NodeToCollection = True
Else
coll.Add oNode
End If
End If
End If
Else
If oLastNode Is Nothing Then
coll.Add oNode
Else
If oNode.Key = oLastNode.Key Then
If bIncludeLastNode Then
coll.Add oNode
End If
NodeToCollection = True
Else
coll.Add oNode
End If
End If
End If

End Function

It has some extra functionality that you may not need and you could throw
that out, but as the arguments are optional there will be no harm to leave
it in.
So to use this code do something like this:

Dim coll As Collection

GetChildNodes Treeview1.Nodes(1), coll

All your nodes are then in the collection called coll and you can loop
through that to do whatever needs doing.


RBS


End Function
 
R

RB Smissaert

Correction, this:
Optional oLastNode As Object, _

should be:
Optional oLastNode As Node, _


RBS
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top