Rule hangs at oDef = oBOMRow.ComponentDefinitions.Item(1)

Rule hangs at oDef = oBOMRow.ComponentDefinitions.Item(1)

checkcheck_master
Advocate Advocate
558 Views
11 Replies
Message 1 of 12

Rule hangs at oDef = oBOMRow.ComponentDefinitions.Item(1)

checkcheck_master
Advocate
Advocate

Hello..

I have a rule that stumbles on:
oDef = oBOMRow.ComponentDefinitions.Item(1)
in a particular assembly.
While in another assembly there is no problem.
This in a Sub ProcessBOMRowsRecursively.

I'm using the Model Data BOMView.
On purpose to also have insight into Phantom assemblies.

It's in a certain document, it doesn't happen right away.
Before oDef is defined, how can I determine what kind of document it is and whether or not I want to go through it?
I mean in the case of a Content Center or Library part.

Any idea what that could be?

Could it be a suppressed part or assembly?

 

Btw should wat should it be?

oDef = oBOMRow.ComponentDefinitions(1)
oDef = oBOMRow.ComponentDefinitions.item(1)

 The 841 where is goes wrong, thereafter where I call the BOMView:

Sub BOM_First_Loop_Get_ListsData_TotalQTY_LengthsData(oBOMRows As BOMRowsEnumerator, Optional SubQty As Integer = 1)
  Dim oBOMRow As BOMRow															
  
  Logger.debug("Here in BOM_First_Loop_Get_ListsData_TotalQTY_LengthsData")
  
  For Each oBOMRow In oBOMRows
	  
	'----------------------------------------------------------------------------------------------------
	' Progress Bar, update the Message shown within the Progress Bar with each loop.
	oProgressBar.Message = "Start Calculation " '& i & " Of " & oSteps_Progress_Bar	 
	    
	'----------------------------------------------------------------------------------------------------
	' Let's only get the first definition
    ' It would only be more than one if rows were merged
    Dim oDef As ComponentDefinition
    'oDef = oBOMRow.ComponentDefinitions(1)
	oDef = oBOMRow.ComponentDefinitions.Item(1)
	
	Dim oDoc As Document = oBOMRow.ComponentDefinitions.Item(1).Document	
	Logger.debug("Here in BOM_First_Loop_Get_ListsData_TotalQTY_LengthsData" & vbNewLine & "oDoc: " & oDoc .FullFileName)	
			'----------------------------------------------------------------------------------------------------
			' In case of unsaved items in the Main Assembly Exit the program
			' Set boolForcedTerminated = True
			' Because there is a chance that it will be noticed again and the program can act on it by closing
			If oDoc.FullFileName = ""










						'----------------------------------------------------------------------------------------------------
							' Connect to the BOM to collect data
							Dim oBOM As BOM
						  	oBOM = oAsmDoc.ComponentDefinition.BOM
						   												
						  	' Make sure it's enabled
						  	oBOM.StructuredViewEnabled = True
						  	oBOM.StructuredViewFirstLevelOnly = False
						  	'oBOM.PartsOnlyViewEnabled = True   										
						    
							' Select BOM Type
						  	Dim oBOMView As BOMView
						   	oBOMView = oBOM.BOMViews(1) 'Model Data
						    'oBOMView = oBOM.BOMViews("Structured")
						   	'oBOMView = oBOM.BOMViews("Parts Only")
						   						
							'----------------------------------------------------------------------------------------------------
							' Renumber and sort the BOM
							' Will that affect the output?
							Try
								oBOMView.Renumber(1, 1)
						   		oBOMView.Sort2("Item")	
							Catch
								' Sort will not work for Model Data BOM
							End Try 
	
0 Likes
559 Views
11 Replies
Replies (11)
Message 2 of 12

A.Acheson
Mentor
Mentor

This VBA sample has a definition filter type of or you can use the

ComponentDefinition.Type Property

You will need to check if definition is an 

“kAssemblyComponentDefinitionObject“


Both .item(1) and (1) are acceptable. See this post

I haven’t analyzed your code so not sure where it may be going wrong for you.  

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 3 of 12

jjstr8
Collaborator
Collaborator

Without more info, the only thing that comes to mind is a suppressed part.  The easiest way to resolve it is to set the LOD to Master before accessing the BOM.  As for ComponentDefinitions(1) versus ComponentDefinitions.Item(1), they are interchangeable.  Behind the scenes, the Item property is automatically generated for a class that has an indexer.  I can't think of an instance in the Inventor API where they renamed the indexer.

0 Likes
Message 4 of 12

checkcheck_master
Advocate
Advocate
Thank you both for your reaction.
0 Likes
Message 5 of 12

checkcheck_master
Advocate
Advocate

It is indeed due to suppressed assemblies.

 

I actually expected that with going through the BOMRows this would not be an issue.
After all, the BOMrows seem to me to be guiding at all times regarding the quantities.
I would like to inform the user whether and what is suppressed and therefore not processed.
How do I do that when using ProcessBOMRowsRecursively?
Can I do this before oDoc is appointed?
Now I made a TryCatch of it just after For Each oBOMRow In oBOMRows.
That seems to work with what I've been able to test so far.
I'm thinking I could send the Catch result to the logger.debug to see if something goes wrong, how would you guys handle that?

 

As for logging.
I am now writing text to my heart's content in a StreamWriter file.
Works until something goes wrong and the rule can no longer access the file.
How can I best prevent that?
Still want to use the logger options within iLogic?
In my humble opinion, that slows things down, or am I doing it wrong?
Is there a technique within VBNET that logs real time?

0 Likes
Message 6 of 12

jjstr8
Collaborator
Collaborator

You could loop through ComponentDefinition(1).Occurrences to look for the Suppressed property first.  Log any suppressed occurrences.  If you found any suppressed occurrences then avoid accessing the structured or parts-only BOMs.  As for logging, it sounds like a StreamWriter file gives you the most flexibility. 

 

"Works until something goes wrong and the rule can no longer access the file."  Do you mean an unhandled exception?  If so, doesn't your try-catch avoid that?

0 Likes
Message 7 of 12

checkcheck_master
Advocate
Advocate

Thanks for your response jjstr8.
I get an error, see screenshot.
When I remove (1), in:

For Each oOcc In oDef.Occurrences(1)

the rule continues.
Am I doing something wrong?

 

'----------------------------------------------------------------------------------------------------
' Let's only get the first definition
' It would only be more than one if rows were merged
Dim oDef As ComponentDefinition
'oDef = oBOMRow.ComponentDefinitions(1)
oDef = oBOMRow.ComponentDefinitions.Item(1)
Dim oOcc As ComponentOccurrence
For Each oOcc In oDef.Occurrences(1)
	 If oOcc.Suppressed = True Then Logger.Info("=============++++++++++++Occurence:" & Space(3) & oOcc.Name & " - Suppressed: " & oOcc.Suppressed)
Next

 

 

0 Likes
Message 8 of 12

jjstr8
Collaborator
Collaborator

.Occurrences is the collection, .Occurrences(1) is the first member of the collection.  The 'For Each' only works collections.  There's one condition that may not be accounted for, which is a part or assembly in a sub-assembly that is suppressed.  This forces active assembly to be in a non-master LOD where none of the first-level occurrences are suppressed.  It looks like it would be easier first check .ComponentDefinition.RepresentationManager.ActiveLevelOfDetailRepresenation.LevelOfDetail.  If it's not equal to kMasterLevelOfDetail, then you can't use the Structured or PartsOnly BOM.  If that's the case, you would have to enumerate the SubOccurrences to find the suppressed component.  This would have to be recursive to be able to drill down a unknown number of sub-assembly levels.  Can you share more details about what you're trying to accomplish?

0 Likes
Message 9 of 12

checkcheck_master
Advocate
Advocate

Thanks again for your response and explanation jjstr8.
Regarding 'Can you share more details about what you're trying to accomplish?'.
It's a rule working from the highest assembly to determine needed sub assemblies, their parts and finally the parts that remain.
In all that I would like to detect which sub assemblies and/or parts are suppressed.
This really only to alert the user that components are suppressed and that he can or cannot take action on them.
Going through the Main Assembly is based on the BOM rows.
That's it.
Not unimportant to mention, going through the BOM rows to arrive at the totals is on Krieg's advice.
That all seems to work fine by the way, in that sense I seem to have it all done.
The only thing I would like is to detect the suppressed.

0 Likes
Message 10 of 12

jjstr8
Collaborator
Collaborator

That makes better sense.  I think the Occurrences/SubOccurrences route is your only choice.  As an example, a part that's in a sub-assembly of your parent assembly can be suppressed from your parent assembly.  On its own, your sub-assembly is unaware of this, since it's an occurrence-based suppression.  In the parent assembly you'll see a LOD called '~1' for that sub-assembly.  You won't find it in the list of LODs for the sub-assembly because it's only known to the parent assembly for that occurrence of the sub-assembly.  With that in mind, the BOM is part of the component definition and only reflects the assembly by itself, not that a part is suppressed in one occurrence, but maybe not in another.  With the Occurrences/SubOccurrences method, you'll have come up with a way to get totals for each unique part and sub-assembly.

0 Likes
Message 11 of 12

checkcheck_master
Advocate
Advocate
Thanks again for your explanation.
However, I don't fully understand this one yet.

Does it make a difference to emphasize that the rule is always meant to be run from the Main Assemly?
I do this in order to be able to determine absolute numbers and not to be interested in any parent relationships.
Even when the Main Assembly is not open, but the rule is started from an assembly within that project, my intention is to open the main assembly in the background and let it be the basis for this rule.
I tested that and it seems to work fine.
Furthermore, top-down the main assembly is checked and subgroups are created:
- Assemblies with a custom property 'Combined Production Output'
- Weld assemblies
- The remaining/other parts
After that loop, the groups are cycled through in this order, always by going through the BOM rows.
Finally, we want to have an overview of the weldments divided into our breakdown structure and other parts that we need to make.
Weldments and parts within a 'Combined Production Output' assembly must be in one folder.
Furthermore, each weldment gets its own folder.
Finally, Remaining parts also in a folder.

In my simplicity I think, every assembly and their parts are passed, after all, all rows are run through.
Can I not suffice with the suppressed state of each row separately?
0 Likes
Message 12 of 12

jjstr8
Collaborator
Collaborator

I'm not understanding how you want to deal with suppressed components.  It sounds like you want a parts-only BOM of the main assembly minus anything that's suppressed.  The BOM data doesn't accurately account for suppressed components.

0 Likes