3

I'm making a code for a 3D Program CATIA and the code runs through all tree with recursive loop. I would like to exit the recursive loop, after it find a specific product. But my code keeps running , even though he found it. I wrote roughly meins. What did I make a mistake in there?

Private Sub TestMain
   .....
   call TestMainChildren
   .....
End Sub

Private Sub TestMainChildren
  For Each item In product
      .....
      If itemName = "SearchName" then
         MsgBox("Found!")
         Exit Sub
      End if
      ......
      Call TestMainChildren
   Next
End Sub

enter image description here

HackSlash
  • 4,944
  • 2
  • 18
  • 44
sem
  • 49
  • 4
  • 1
    VBA<>VB.NET Please remove the erroneous tag. – Scott Craner Dec 18 '20 at 19:12
  • 1
    Make `TestMainChildren` a Function that returns a string, then just `return theValueFound`. Initialize `dim theValueFound = String.Empty`. Now `TestMain` will receive a return value that you can evaluate. – Jimi Dec 18 '20 at 19:13
  • @Jimi Thank you for your comment. Please, give me more specific explanation? I'm beginner of VB.. – sem Dec 18 '20 at 19:31
  • @Scott I know that, but I have to make it in both CATVBA and VB.Net in Visual Basic. And the both code are not same but similar. – sem Dec 18 '20 at 19:31
  • [Function Statement (Visual Basic)](https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/function-statement). Note that `TestMainChildren` is not actually recursive as it is. *Recursive* doesn't just mean that a method calls itself. You should pass the `"SearchName"` argument to the method and the parent object to iterate recursively. – Jimi Dec 18 '20 at 19:42
  • @Andrew, he reads first product and if the first product has children, then he goes to the children product of the first product. And also if he has also children, then he goes to and so on. deep and deep. If he has no children, then he goes to the another product which is on the same level. Check the picture, please. – sem Dec 18 '20 at 20:26
  • @Andrew, that is the second sub "TestMainChildren" and it calls itself. "If" he has no children, then he call itself again and go to next product on the same level. – sem Dec 18 '20 at 20:39
  • @Andrew, Thank you for your advices. I found some code which is similar with mein. There is this line: If TestMainChildren.Porudct.Count <> 0 then exit Sub. But I don't understand, what different between without it and with it is. I have tested both and in my datagridview shows same resault. – sem Dec 20 '20 at 11:35

2 Answers2

1

To make this recursive you need to pass a starting object to the function, in this case products. Then while you are looking at child objects, only pass product collections recursively.

Private Sub TestMain    
    Dim searchName As String
    searchName = "SearchName"

    ' Start with the selected object
    Dim doc As Document
    Set doc = CATIA.ActiveDocument
    Dim prod As Product
    Set prod = doc.Product

    Dim foundItem As Object
    foundItem = TestMainChildren(doc.Selection.Item(1).Value, searchName)

    MsgBox "Found: " & foundItem.Name
End Sub

Private Function TestMainChildren(ByRef catiaObject As Object, ByVal searchName As String) As Object
    Dim item As Object
    For Each item In catiaObject.Items
        If item.Name = searchName Then
            Set TestMainChildren = item
            Exit For
        End if

        Dim catiaType As String
        catiaType = TypeName(item)
        If catiaType = "Product" Then
            Set TestMainChildren = TestMainChildren(item, searchName)
        End If
    Next item
End Sub

WARNING: This is completely untested vaporware. You will have to modify it to fit your environment, and requirements. Then do proper testing and debugging.

HackSlash
  • 4,944
  • 2
  • 18
  • 44
0

place

exit for

after fulfilled condition inside loop

edited//

Private Sub TestMain
 .....
 call TestMainChildren
 .....
End Sub

Private Sub TestMainChildren
   For Each item In product
    .....
     If itemName = "SearchName" then
      MsgBox("Found!")
      Exit for
  End if
  ......
  'Call TestMainChildren - delete this
   Next
End Sub
Tomasz
  • 426
  • 2
  • 10
  • 1
    This wouldn't help at all. The posted code is already exiting the sub when the condition is met. – Craig Dec 18 '20 at 19:33
  • Thank you for your answer. If I follow your answer, it just goes through... Could you give me more specific explanation..? – sem Dec 18 '20 at 19:37
  • 1
    i think you have made an infinite loop by calling TestMainChildren before next. just delete lane with Call TestMainChildren and replace exit sub by exit for. should work. – Tomasz Dec 18 '20 at 19:48
  • @Tomasz, Thank you for your comment. I need the call TestMainChildren, because in CATIA, each prodcut could have several products or parts, or more deeply. That reaseon why I made recursive sub and he reads each product and children products to recognize. – sem Dec 18 '20 at 20:01