[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
Solved

# loop not finishing - logic problem !

Posted on 2007-09-28
Medium Priority
218 Views
Last Modified: 2010-04-15
Hello Experts,

I am searching a treeview for first, a Job number, then under that node, a Unit number.  The code I have works just fine with one exception: If there are two Job nodes with the same number, the code will stop searching after not finding the unit# under the first Job node.

example layout of my treeview

Designs
January
Q036118
Unit-001
Unit-002
October
Q036118
Unit-019
Unit-054

As I said, my code works, but it stops searching after the first time it finds the job number (Q036118) For example Searching for Q036118/Unit-019 would not be found,  but Q036118/Unit-002 would be found since it exists under he first node found named Q036118.

I belive I am just having problems with looping structures

Dave

delegate bool IsTargetNode(TreeNode node);

bool IsJobNode(TreeNode node)
{
return node.Text == this.txtJobNum.Text;
}

bool IsUnitNode(TreeNode node)
{
return node.Text == this.cmbUnit.Text; // assuming this pattern holds.
}

private void FindByText()  // searches whole treeview
{
this.m_vaultFolderTree.TopNode.ExpandAll();  // xpand treeview
TreeNodeCollection nodes = m_vaultFolderTree.Nodes;  //intialize the collection

//   TreeNode jobNode = null;  //  added from EE
TreeNode unitNode = null; //  added from EE

foreach (TreeNode n in nodes)
{
TreeNode jobNode = FindRecursive(n, IsJobNode);
if (jobNode != null)  // if job number is found
{
MessageBox.Show("j# found");

// search for unit node under this job node
unitNode = FindRecursive(jobNode, IsUnitNode); // search that node for unit

// if we dont find the unitnode, keep looking JDL
if (unitNode == null)  // added by me
{
MessageBox.Show("Cant find the unit under this job Number");
}

}
else
{
MessageBox.Show("Job not found!");
return;
}

if (unitNode != null)
{
MessageBox.Show("Unit found!");

DialogResult dlgRes = 0;
dlgRes = MessageBox.Show((txtJobNum.Text) + "/" + (cmbUnit.Text) + " Check Out Version to Design? ", "Check-Out Files?",                   MessageBoxButtons.YesNo, MessageBoxIcon.Question);

if (dlgRes == DialogResult.Yes)
{
CheckOut_Idw();  // search vault treeview to determine if job is in vault already
}

if (dlgRes == DialogResult.No)
{
return;  // get out
}
}
else
{
MessageBox.Show("Unit not found!");

}
}
}
}

private TreeNode FindRecursive(TreeNode treeNode, IsTargetNode isTargetNode)
{
foreach (TreeNode tn in treeNode.Nodes)
{
if (isTargetNode(tn))   // if node text matches search string
{
this.m_vaultFolderTree.SelectedNode = tn;  // select the node
return tn;
}
TreeNode foundSubNode = FindRecursive(tn, isTargetNode);
if (foundSubNode != null)
{
return foundSubNode;
}
}
return null;
}
0
Question by:DaveMon
• 3
• 3
6 Comments

LVL 7

Expert Comment

ID: 19980215
I hope some one can help you as is.
However, I would suggest that you refactor the code a bit to make it a little more readable.
Could you break up the long FindByText routine into smaller ones?
I was expecting that a routine called Find... would return what it found. I also expected something called FindByText would take in text that it is supposed to Find.
Please don't think I am trying to be critical of your code since Lord only knows everyone finds everyone else's code ugly. My point is that it is a lot to swallow and we are not at all familiar with your domain. So very clear names, a few comments, and small chunks of logic will make it easier to help.
-Cheers,
Joe
0

LVL 7

Expert Comment

ID: 19980505
My mistake, I see where a recursive routine will need outside parameters. Give me a minute and I think I'll have your fix.
0

LVL 7

Expert Comment

ID: 19980592
DaveMon,
Are units only in the treeview once?
If so add the Unit string to the key and the text.
If you do this, then you can just call m_vaultFolderTree.Nodes.Find("Unit-019, true);

I was looking at why our recursive tree view code is much simpler. In our designs a Unit is nothing without a job. Thus the Key on a Unit would be the Job key plus the Unit key. So when you are searching the TreeView you don't have to find the Job first and then the Unit. Instead you are just looking for s single key which would be something like "Q036118Unit-019"
0

LVL 2

Author Comment

ID: 19981437
Hi joe, thanks for the reply !!
Actually the Unit numbers exist under every job number,  in the same range from Unit-001 - Unit-060.   So there are thousands of "Unit-001" nodes,  but there is only one Job#/Unit#  combination  (i.e.  Q036118/Unit-027)

Furthermore,  the same JOB# can exist in more than one month folder. Here is an illustration of the layout

2007
January
Q036118
Unit-001
Unit-002
Q039231
Unit-033
October
Q036118
Unit-019
Unit-054
December
Q041567
Unit-002

So as you can see,  the combination of JOB#/Unit#   is unique,  but there are multiple Job#s and my existing code stops after the first instance, where is should keep searching for the right Job#/Unit#,  not just job#.

I know almost nothing about delegates, and some of the other "fancy" techinques in this code........  which is why I cannot debug it very well.

Dave
0

LVL 2

Author Comment

ID: 19981988
Hello all,
I have found a solution to this problem
0

LVL 2

Accepted Solution

DaveMon earned 0 total points
ID: 19990588
As usual with borrowed code,  I did not understand all the techniques used,  so the best soluton was to code the whole thing from scratch.  Which was good practice for me anyway.  This code ensures that the unique pair of Job# and Unit # are found and selected.

public void findinvault()
{
this.m_vaultFolderTree.TopNode.ExpandAll();  // xpand treeview

TreeNode temp = new TreeNode();

//Loop through the Parent Nodes
for (int k = 0; k < m_vaultFolderTree.Nodes.Count; k++)
{
//Store the Parent Node in temp
temp = m_vaultFolderTree.Nodes[k];

//Now Loop through each of the child nodes in this parent node i.e.temp
for (int i = 0; i < temp.Nodes.Count; i++)
visitChildNodes(temp.Nodes[i]); //send every child to the function for further traversal
}

}

private void visitChildNodes(TreeNode node)
{
if (node.Text == txtJobNum.Text) // if the node matches the job number
{
Console.WriteLine((node.Text) + " is the correct parent node");
}
//Loop Through this node and its childs recursively
for (int j = 0; j < node.Nodes.Count; j++)
visitChildNodes(node.Nodes[j]);

if (node.Text == cmbUnit.Text) // if the node matches the job number
{
if (node.Parent.Text == txtJobNum.Text)
{

Console.WriteLine((node.Text) + " is the unit we are looking for under " + (node.Parent.Text));
m_vaultFolderTree.SelectedNode = node;

DialogResult dlgRes = 0;
dlgRes = MessageBox.Show((txtJobNum.Text) + "/" + (cmbUnit.Text) + " Check Version out from Vault? ", "Check-Out Files to Design?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

if (dlgRes == DialogResult.Yes)
{
CheckOut_Idw();  // search vault treeview to determine if job is in vault already
}

if (dlgRes == DialogResult.No)
{
return;  // get out
}
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Screencast - Getting to Know the Pipeline
###### Suggested Courses
Course of the Month20 days, 4 hours left to enroll

#### 873 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.