Any vbScript Guru's????

Author
Discussion

Plotloss

Original Poster:

67,280 posts

275 months

Wednesday 28th April 2004
quotequote all
Can tell me whats wrong with this?

Its going one interation too far and throwing an object required error.

Sub CheckUncheckChildren(Node)
If Node.Children > 0 Then
Set ParentNode = Node
intChildIndex = ParentNode.Child.Index
Do While intChildIndex <> ParentNode.Child.LastSibling.Index
ParentNode.Child.Checked = ParentNode.Checked
Treeview1.Nodes(intChildIndex).Next.Checked = ParentNode.Checked
If TreeView1.Nodes(intChildIndex).Children >0 Then
Set NewNode = Treeview1.Nodes(intChildIndex)
Call CheckUncheckChildren(NewNode)
End If
intChildIndex = TreeView1.Nodes(intChildIndex).Next.Index
Loop
End If
End Sub

I have been looking at this for so long I cant see the wood for the trees...

Jay-Aim

598 posts

246 months

Wednesday 28th April 2004
quotequote all
Do While intChildIndex <> ParentNode.Child.LastSibling.Index -1?????


PetrolTed

34,443 posts

308 months

Wednesday 28th April 2004
quotequote all
Matt, you know the real answer is to simply walk away, have a cup of tea and then go back and spot it immediately.

pdV6

16,442 posts

266 months

Wednesday 28th April 2004
quotequote all
Are you starting in the right place?

plotloss said:

intChildIndex = ParentNode.Child.Index



intChildIndex = ParentNode.FirstChild.Index ?



[edited to add:] Ignore this - I was talking

>> Edited by pdV6 on Wednesday 28th April 14:04

steve-p

1,448 posts

287 months

Wednesday 28th April 2004
quotequote all
I'm not completely sure what you are trying to do but it is generally safer to use the methods provided for iterating nodes e.g.

Set ParentNode = Node
Set TNode = ParentNode.First
Do While Not TNode Is Nothing
TNode.Checked = ParentNode.Checked
If TNode.Children > 0 Then
CheckUncheckChildren(TNode)
End If
Set TNode = TNode.Next
Loop

Or something like that anyway.



>> Edited by steve-p on Wednesday 28th April 13:47

pdV6

16,442 posts

266 months

Wednesday 28th April 2004
quotequote all
Plotloss said:
Its going one interation too far and throwing an object required error.


Pushing this code through VB6 as opposed to VBScript, the object required error could simply be that NewNode is not declared anywhere!

It looks like you're trying to make all child nodes of a given node inherit the checked() property value of the parent node. Your code seems to miss out the children of the last child.

Woudln't a simpler approach be:


my example said:

Sub CheckUncheckChildrenPD(ByRef iNode As Node)
Dim ChildNode As Node

If iNode Is Nothing Then Exit Sub
Set ChildNode = iNode.Child
While Not (ChildNode Is Nothing)
ChildNode.Checked = iNode.Checked
Call CheckUncheckChildrenPD(ChildNode)
Set ChildNode = ChildNode.Next
Wend
End Sub




>> Edited by pdV6 on Wednesday 28th April 14:05

Plotloss

Original Poster:

67,280 posts

275 months

Wednesday 28th April 2004
quotequote all
NewNode is Dim'd at the top.

You'll have to excuse my numptiness on this. I am a CASE tool developer and I only have to resort to vbscript when I need to negotiate the COM (thankfully disappearing in the next realease of the tool!)

I'll try the above.

Thanks fellas its much appreciated

jam1et

1,536 posts

257 months

Wednesday 28th April 2004
quotequote all
Let's play the genealogy game!

Sub CheckUncheckChildren(Node)
If Node.Children > 0 Then
Set ParentNode = Node
intChildIndex = ParentNode.Child.Index
Do While intChildIndex <= ParentNode.Child.LastSibling.Index
ParentNode.Child.Checked = ParentNode.Checked
'Treeview1.Nodes(intChildIndex).Next.Checked = ParentNode.Checked
If TreeView1.Nodes(intChildIndex).Children >0 Then
Set NewNode = Treeview1.Nodes(intChildIndex)
Call CheckUncheckChildren(NewNode)
End If
intChildIndex = TreeView1.Nodes(intChildIndex).Next.Index
Loop
End If
End Sub

Edited to say I cant take the credit for this one, had some help from one of my programmers. That is to say I showed it to him and he pointed it out, I was just the go between really

>> Edited by jam1et on Wednesday 28th April 14:50

Plotloss

Original Poster:

67,280 posts

275 months

Wednesday 28th April 2004
quotequote all
Hmmmn tried that, still not working...

Still checks all the boxes, but still goes an iteration too far.

pdV6

16,442 posts

266 months

Wednesday 28th April 2004
quotequote all
Plotloss said:
Hmmmn tried that, still not working...

Did you try my version? The sanity checks therein are a belt & braces approach to stopping it going too far.
Seems to work ok in VB6.

Re: the "object required" error, as you seem to have a global intance of a node declared outside the scope of your subroutine, could it be that other parts of the code access this node variable, but as a side effect of running the CheckUncheck code it has ended up getting set to Nothing? Better to restrict variables to the miniumim scope required to get the job done in order to avoid just this sort of mess.

Actually, that raises an interesting point. As your node variable is external to the subroutine and the subroutine is recursive, you aren't getting a new instance of the variable on each re-entrant call to the routine; they are all using the same instance of the node and all are changing it. This is probably why the original code seemed to un/check the nodes in an odd order and missed some out. Definately try using a node declared locally within the sub, as per my example.

Plotloss

Original Poster:

67,280 posts

275 months

Wednesday 28th April 2004
quotequote all
Tried doing them in the sub, nothing doing, just trying yours now.

It goes too far.

I have put some message boxes in.

Check the grandparent, first child is checked, that has children. 4 children, iterates 5 times.

Last time I get the object required error because there is no next on the last iteration.

If you see what I mean.

pdV6

16,442 posts

266 months

Wednesday 28th April 2004
quotequote all
Maybe VBScript works differently to VB6, but the last time .Next is called, it sould return the special object "Nothing", which is caught by the loop in order to terminate it.

We could manually force the issue thus:

example 2 said:

Sub CheckUncheckChildrenPD(ByRef iNode As Node)
Dim ChildNode As Node

If iNode Is Nothing Then Exit Sub
Set ChildNode = iNode.Child
While Not (ChildNode Is Nothing)
ChildNode.Checked = iNode.Checked
Call CheckUncheckChildrenPD(ChildNode)
If Not ChildNode = ChildNode.LastSibling Then
Set ChildNode = ChildNode.Next
Else
Set ChildNode = Nothing
End If
Wend
End Sub

pdV6

16,442 posts

266 months

Thursday 29th April 2004
quotequote all
{This post appears to have dropped into a black hole during yesterday's outages...}

Or we could take the "Nothings" out of the equation entirely:

example3 said:

Sub CheckUncheckChildrenPD(ByRef iNode As Node)
Dim ChildNode As Node
Dim done As Boolean

If iNode Is Nothing Then Exit Sub
If iNode.Children = 0 Then Exit Sub
Set ChildNode = iNode.Child
While Not done
ChildNode.Checked = iNode.Checked
Call CheckUncheckChildrenPD(ChildNode)
If ChildNode = ChildNode.LastSibling Then
done = True
Else
Set ChildNode = ChildNode.Next
End If
Wend
End Sub



>> Edited by pdV6 on Thursday 29th April 15:49

jam1et

1,536 posts

257 months

Thursday 29th April 2004
quotequote all
Had another suggestion regarding the original piece of code.

Try updating the parentnode before looping back by adding this:

'etc etc
Set ParentNode=TreeView1.Nodes(intChildIndex)
Loop

Plotloss

Original Poster:

67,280 posts

275 months

Friday 30th April 2004
quotequote all
Pete, you are a god or at the very least an envoy of his in the West Country.

Sorted!!

Thanks everyone else as well.

PH is a wonderful thing.

Find me at PF and I'll get 'em in. :beers:

pdV6

16,442 posts

266 months

Friday 30th April 2004
quotequote all
No worries. As a matter of interest, which version did the trick?

I've spent far too much time ing around with treeviews in my time - can't be healthy!

Plotloss

Original Poster:

67,280 posts

275 months

Friday 30th April 2004
quotequote all
Example3