Gentlemen -
I am addressing you to ask your help concerning the following problem. I am given a CATProduct, consisting of other CATProducts, CATParts or Components. Some of the them may appear many times and on different levels. There are some components which have a user defined Boolean property, called Prop and set to True.
My ambitious plan is analyze the Product tree, see how many components with the property Prop, set to True I have, and after, pass the results into an Excel file. I managed to do something which works, but just for the first level.
I am stuck when I try to go deeper and to analyze other sublevels using recursivity. Please help me and make the following code work for all levels.
I inspired myself in my work from the following topics and I want to thank Dream_Weaver and Brian Roach for their work:
1)http://www.coe.org/Collaboration/DiscussionForum/ActiveDiscussions/tabid/210/view/topic/forumid/10/postid/109025/Default.aspx
2)http://www.coe.org/Collaboration/DiscussionForum/ActiveDiscussions/tabid/210/view/topic/forumid/10/postid/111200/Default.aspx
Here is my code:
'Assumption: the active CATIA document is a CATProduct, having a multilevel structure: product of 'products, parts or components. Some of the components have a user defined Boolean property, called 'Prop, set to true.
'Language CATScript
Option Explicit
'Declaring global variables
'oCurrentTreeNode represents the CATProduct, CATPart or Component which is currently analyzed
Dim oCurrentTreeNode As Product
'If oCurrentNode is a CATProduct or a Component, then n is the number of its sub-components
Dim n As Integer
'As we walk through the Product tree, Index will count the number of CATProducts, CATParts or 'Components which have not yet been analyzed. Of course, they must have the Prop property set to True. 'In the end, Index is the number which will tell me how many components with the Prop property set to 'True are in the Product being analyzed. I DECLARED Index AS GLOBAL BECAUSE I DO NOT KNOW 'OTHER METHOD IN CATSCRIPT TO PRESERVE ITS VALUE BETWEEN TWO SUCCESIVE CALLS TO 'THE METHOD GetNextNode. IN OTHER PROGRAMMING LANGUAGES, TO OBTAIN A VARIABLE 'WITH SUCH PROPERTY, YOU DECLARED IT STATIC.
Dim Index As Integer
Index = 0
'I am using a dictionary object in order to keep track of my components
Dim QtyDict As Variant
Set QtyDict = CreateObject("Scripting.Dictionary"
'Based on Index, Counter will help me to fill in the Excel cells with the information about the analyzed 'components.
Dim Counter As Integer
'Declare a dynamic array whose elements will memorize the components of interest
Dim ProductList() As Product
Sub CATMain()
'Setting up Excel
Dim Excel As Object
Dim workbooks As workbooks
Dim workbook As workbook
Dim Sheets As Object
Dim Sheet As Object
Dim worksheet As Excel.worksheet
Err.Clear
On Error Resume Next
Set Excel = GetObject(, "EXCEL.Application"
If Err.Number <> 0 Then
Err.Clear
Set Excel = CreateObject("EXCEL.Application"
End If
Excel.Visible = True
Set workbooks = Excel.Application.workbooks
Set myworkbook = workbooks.Add
Dim EXCELWSH As Worksheet
Set EXCELWSH = EXCEL.ActiveSheet
EXCEL.ActiveSheet.Name = "Analyze"
EXCELWSH.cells(1,1).Value= "Index"
EXCELWSH.cells(1,2).Value= "Components with True Prop"
EXCELWSH.cells(1,10).Value= "Quantity"
'Call the GetNextNode method
GetNextNode CATIA.ActiveDocument.Product
'When job is done in Catia, pass the results to Excel
For Counter = 1 To Index
EXCELWSH.cells(Counter+1,1).Value = Counter 'Index
EXCELWSH.cells(Counter+1,2).Value = ProductList(Counter).PartNumber 'Part Number
EXCELWSH.cells(Counter+1,10).Value = QtyDict.Item(ProductList(Counter).PartNumber) 'Quantity
Next
End Sub
'RECURSIVE DEFINITION of GetNextNode method
Sub GetNextNode(oCurrentProduct As Product)
MsgBox "Enter GetNextNode and the number of sub-components is: " & oCurrentProduct.Products.Count
'Loop through every tree node for the current product. Use Preserve keyword in order to memorize the previous results.
ReDim Preserve ProductList(oCurrentProduct.Products.Count) 'Total number of products for this sub-component
For n = 1 To oCurrentProduct.Products.Count
Set oCurrentTreeNode = oCurrentProduct.ReferenceProduct.Products.Item(n)
‘Verify if the Prop is set to True
If (oCurrentTreeNode.ReferenceProduct.UserRefProperties.Item("Prop" .Value <> False) Then
Select Case QtyDict.Exists(oCurrentTreeNode.PartNumber)
Case True ‘The component has already been analyzed but it is 'present in another sub-component. In this case, just increase its quantity with one.
MsgBox oCurrentTreeNode.PartNumber & " Seen already!"
QtyDict.Item(oCurrentTreeNode.PartNumber) = QtyDict.Item(oCurrentTreeNode.PartNumber) + 1
Case False 'The component has not been analyzed yet.
Index = Index + 1
MsgBox oCurrentTreeNode.PartNumber & " Has not been seen yet!"
QtyDict.Add oCurrentTreeNode.PartNumber, 1
MsgBox "Index = " & Index
Set ProductList(Index) = oCurrentTreeNode
End Select
End If
‘If sub-nodes exist below the current tree node, call GetNextNode recursively. If I comment the following 'four lines, the macro works, but, as expected, just for the first Product level.
If oCurrentTreeNode.Products.Count > 0 Then
MsgBox "It works recursively!"
GetNextNode oCurrentTreeNode
End If
Next
MsgBox "Get out from GetNextNode!"
End Sub
|