Suppressing Parts in Sub Folders of Folder in Top Level Assembly

Suppressing Parts in Sub Folders of Folder in Top Level Assembly

Damian_LeeF852L
Participant Participant
228 Views
13 Replies
Message 1 of 14

Suppressing Parts in Sub Folders of Folder in Top Level Assembly

Damian_LeeF852L
Participant
Participant

I am trying to suppress parts in folders contained within a parent folder. The code below works at top level, but I am stuck as to how to get it to work at the next level down.

Sub Main()
	
'Set lockout relays And test terminals
	FolderToHide="6 Test Terms + 2 Lockouts"
    HideParts(FolderToHide)
End Sub

Function HideParts(FolderToHide)
    MessageBox.Show(FolderToHide, "Title")
	Dim oDoc As Document = ThisDoc.Document
Dim oModelPane As BrowserPane = oDoc.BrowserPanes.Item("Model")
Dim oTopNode As BrowserNode = oModelPane.TopNode

For Each oBFolder As BrowserFolder In oTopNode.BrowserFolders
		If oBFolder.Name = FolderToHide Then
			oDoc.SelectSet.Clear
			oDoc.SelectSet.Select(oBFolder)
			ThisApplication.CommandManager.ControlDefinitions.Item("AssemblyCompSuppressionCtxCmd").Execute
		End If
	
Next
End Function

The screenshot may help explain what I am trying to achieve.

Any help on this would be greatly appreciated.
0 Likes
Accepted solutions (2)
229 Views
13 Replies
Replies (13)
Message 2 of 14

WCrihfield
Mentor
Mentor
Accepted solution

HI @Damian_LeeF852L.  Browser nodes are not all in one straight list.  So, if one node is a 'child' of another node, but you do not know the name of the 'parent' node, then you will need a 'recursive' routine to find the 'child'.  And be aware that the 'command' that you are executing will just 'toggle' the suppression status.  So, if they are currently suppressed, it will unsuppress them...or if they are not suppressed it will suppress them...if some are suppressed and some not suppressed it will inverse their current suppression status.  Here is an example code which includes a recursive routine that you can try out.

Sub Main
	Dim oInvApp As Inventor.Application = ThisApplication
	Dim oADoc As AssemblyDocument = TryCast(oInvApp.ActiveDocument, Inventor.AssemblyDocument)
	If oADoc Is Nothing Then Return
	Dim sFolderName As String = "6 Test Terms + 2 Lockouts"
	'get BrowserPane by its InternalName per Document Type
	Dim oModelPane As Inventor.BrowserPane = GetModelBrowserPane(oADoc)
	Dim oFolder As Inventor.BrowserFolder = RecursivelyFindBrowserFolder(oModelPane.TopNode.BrowserFolders, sFolderName)
	If oFolder IsNot Nothing Then
		oFolder.BrowserNode.EnsureVisible()
		oFolder.BrowserNode.DoSelect()
		oInvApp.CommandManager.ControlDefinitions.Item("AssemblyCompSuppressionCtxCmd").Execute()
	End If
	If oADoc.RequiresUpdate Then oADoc.Update2(True)
End Sub

Function GetModelBrowserPane(oDoc As Document) As Inventor.BrowserPane
	For Each oPane As Inventor.BrowserPane In oDoc.BrowserPanes
		'gets it by InternalName, per Document Type
		If oPane.BuiltIn And oPane.TreeBrowser And _
			(oPane.InternalName = "AmBrowserArrangement" Or _
			oPane.InternalName = "DlHierarchy" Or _
			oPane.InternalName = "PmDefault") Then Return oPane
		Next 'oPane
	Return Nothing
End Function

Function RecursivelyFindBrowserFolder(folders As Inventor.BrowserFoldersEnumerator, _
	folderName As String) As Inventor.BrowserFolder
	For Each oFolder As Inventor.BrowserFolder In folders
		If oFolder.Name = folderName Then Return oFolder
		If oFolder.BrowserNode.BrowserFolders.Count > 0 Then
			RecursivelyFindBrowserFolder(oFolder.BrowserNode.BrowserFolders, folderName)
		End If
	Next 'oFolder
	Return Nothing
End Function

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 14

Damian_LeeF852L
Participant
Participant

Hi thank you for the reply. I copied your code to a new rule to test it. It executed without any errors but it did not toggle the suppression of the items contained within folder "6 Test Terms + 2 Lockouts". Am I doing something wrong?

 

0 Likes
Message 4 of 14

Damian_LeeF852L
Participant
Participant

Sorry, my mistake, your code works perfectly. I did not realise that I had hidden the components. The suppression was getting toggled but they were invisible so I still could not see them.

Thank you very much for this code it saves me having multiple top level folders.

0 Likes
Message 5 of 14

Damian_LeeF852L
Participant
Participant

One last thing. Would it be possible to the coding in Main Sub into a function? I need to call it up serval times from my main code using different folder names to toggle the visibility of. 

I tried putting it into a function and calling it by using the code below but I got an error message (Error on Line 195 : 'Return' statement in a Function, Get, or Operator must return a value.). 

'Set Dual Protection
	
	If Dual_Protection="Yes" Then
		sFolderName="Dual Protection"
    	HideParts(sFolderName)
	End If
End Sub

Function HideParts(sFolderName)
	
		Dim oInvApp As Inventor.Application = ThisApplication
	Dim oADoc As AssemblyDocument = TryCast(oInvApp.ActiveDocument, Inventor.AssemblyDocument)
	If oADoc Is Nothing Then Return
	'get BrowserPane by its InternalName per Document Type
	Dim oModelPane As Inventor.BrowserPane = GetModelBrowserPane(oADoc)
	Dim oFolder As Inventor.BrowserFolder = RecursivelyFindBrowserFolder(oModelPane.TopNode.BrowserFolders, sFolderName)
	If oFolder IsNot Nothing Then
		oFolder.BrowserNode.EnsureVisible()
		oFolder.BrowserNode.DoSelect()
		oInvApp.CommandManager.ControlDefinitions.Item("AssemblyCompSuppressionCtxCmd").Execute()
	End If
	If oADoc.RequiresUpdate Then oADoc.Update2(True)
	End Function
	

  

0 Likes
Message 6 of 14

WCrihfield
Mentor
Mentor

Hi @Damian_LeeF852L.  There are a few ways this could be done.  When using a 'recursive' process, you always need a separate Sub routine just to manage the 'recursion' steps, where it is designed in a way so that we can manually run it once, then it will keep calling itself to run again as many times as may be required to reach its goal which may be at an unknown number of steps either up or down.  That is just the nature of a recursive routine, like the one named 'RecursivelyFindBrowserFolder' in my example above.  There is nothing wrong with breaking a code up a larger task into multiple separate routines to handle smaller, specific tasks.  I will post a single iLogic rule below which has 5 separate code routines in it.  You do not necessarily need to use all 5 of them if you don't want to.  The last two routines show different ways to achieve a similar goal.  One of those last two, with 'Toggle' in its name, uses the folder browser node selection, followed by a command execution (manual user interface actions simulation), similar to in the previous examples, which is often not the best way to do things by code, for various reasons.  Then there is a routine that uses true API methods to suppress those components, instead of user actions simulation tactics.  The one which uses true API methods gives us more control, but requires a bit more code to apply that added control in an error proof way.  The one named GetModelBrowserPane is obviously not always going to be necessary, and can be bypassed in most common situations.  Its advantage is being language independent, because it gets that browser pane by its internal name, which is different in different types of documents, instead of its 'English' display name.  These small, separate, specific code routines that may be commonly used many times, and potentially used by many different iLogic rules, can be stored in an external iLogic rule designed for keeping such common code routines, so simplify things.  But that is a whole other large can of worms, so to speak.

Sub Main
	Dim oInvApp As Inventor.Application = ThisApplication
	Dim oADoc As AssemblyDocument = TryCast(oInvApp.ActiveDocument, Inventor.AssemblyDocument)
	If oADoc Is Nothing Then Return
	Dim sFolderName As String = "6 Test Terms + 2 Lockouts"
	
	'just toggles suppression status, without checking or knowing current status
	ToggleSuppressionOfBrowserFolder(oADoc, sFolderName)
	
	'specify True to suppress, or False to unsuppress
	SetSuppressionOfComponentsInBrowserFolder(oADoc, sFolderName, True)
	
	If oADoc.RequiresUpdate Then oADoc.Update2(True)
End Sub

Function GetModelBrowserPane(doc As Inventor.Document) As Inventor.BrowserPane
	For Each oPane As Inventor.BrowserPane In doc.BrowserPanes
		'gets it by InternalName, per Document Type
		If oPane.BuiltIn And oPane.TreeBrowser And _
			(oPane.InternalName = "AmBrowserArrangement" Or _
			oPane.InternalName = "DlHierarchy" Or _
			oPane.InternalName = "PmDefault") Then Return oPane
		Next 'oPane
	Return Nothing
End Function

Function RecursivelyFindBrowserFolder(folders As Inventor.BrowserFoldersEnumerator, _
	folderName As String) As Inventor.BrowserFolder
	For Each oFolder As Inventor.BrowserFolder In folders
		If oFolder.Name = folderName Then Return oFolder
		If oFolder.BrowserNode.BrowserFolders.Count > 0 Then
			RecursivelyFindBrowserFolder(oFolder.BrowserNode.BrowserFolders, folderName)
		End If
	Next 'oFolder
	Return Nothing
End Function

Sub ToggleSuppressionOfBrowserFolder(doc As Inventor.Document, folderName As String)
	'get BrowserPane by its InternalName per Document Type
	Dim oModelPane As Inventor.BrowserPane = GetModelBrowserPane(doc)
	Dim oFolder As Inventor.BrowserFolder = RecursivelyFindBrowserFolder(oModelPane.TopNode.BrowserFolders, folderName)
	If oFolder IsNot Nothing Then
		oFolder.BrowserNode.EnsureVisible()
		oFolder.BrowserNode.DoSelect()
		ThisApplication.CommandManager.ControlDefinitions.Item("AssemblyCompSuppressionCtxCmd").Execute()
	End If
End Sub

Sub SetSuppressionOfComponentsInBrowserFolder(doc As Inventor.Document, folderName As String, suppress As Boolean)
	Dim oModelPane As Inventor.BrowserPane = GetModelBrowserPane(doc)
	Dim oFolder As Inventor.BrowserFolder = RecursivelyFindBrowserFolder(oModelPane.TopNode.BrowserFolders, folderName)
	If (oFolder Is Nothing) OrElse (oFolder.BrowserNode.BrowserNodes.Count = 0) Then Return
	For Each oChildNode As Inventor.BrowserNode In oFolder.BrowserNode.BrowserNodes
		Dim oNO As Object = Nothing
		Try : oNO = oChildNode.NativeObject : Catch : End Try
		If oNO Is Nothing Then Continue For
		Dim oOcc As Inventor.ComponentOccurrence = TryCast(oNO, Inventor.ComponentOccurrence)
		If oOcc Is Nothing Then Continue For
		If (suppress = True) And (oOcc.Suppressed = False) Then
			Try
				oOcc.Suppress(True) 'True = skip save
			Catch
			End Try
		ElseIf (suppress = False) And (oOcc.Suppressed = True) Then
			Try
				oOcc.Unsuppress()
			Catch
			End Try
		End If
	Next 'oChildNode
End Sub

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 7 of 14

Damian_LeeF852L
Participant
Participant

Hi, thank you for your very comprehensive code and explanation. The code works, however, all I would like to do is toggle the suppression status of a sub folder each time I call it. I am new to ilogic and am still on a steep learning curve. Could you please take the options out of the above code so that it only toggles the suppression state? Thank you in advance.

0 Likes
Message 8 of 14

WCrihfield
Mentor
Mentor

Sure.  In this version, I eliminated that large sub routine named 'SetSuppressionOfComponentsInBrowserFolder', and eliminated the function named 'GetModelBrowserPane'.  And I managed to merge the remaining two functions into one, where the folders collection is the last input, and is optional, which maintains its functionality without making it any more difficult to use.  I have not tested this yet, but below is the condensed and simplified code example you can try.

Also, you mentioned potentially wanting to run this on multiple folders at the same time.  If so, we may be able to make the 'Sub Main...End Sub' routine a bit more user friendly too.  For example, we could include a 'List(Of String)' where we could store multiple folder names within it, then iterate through those names in a loop, running the custom Sub routine once for each folder name.  Or, we could add some additional code that would search for all browser folder names in the whole assembly, then present that list of names to the user, so that the user can select one (or more) from that list, to run the toggle code on.  But that would add more manual user interaction, which may subtract from the automation benefit.  Just some ideas.

Sub Main
	Dim oADoc As AssemblyDocument = TryCast(ThisApplication.ActiveDocument, Inventor.AssemblyDocument)
	If oADoc Is Nothing Then Return
	Dim sFolderName As String = "6 Test Terms + 2 Lockouts"
	
	'just toggles suppression status, without checking or knowing current status
	ToggleSuppressionOfBrowserFolder(oADoc, sFolderName)
	
	If oADoc.RequiresUpdate Then oADoc.Update2(True)
End Sub

Sub ToggleSuppressionOfBrowserFolder(doc As Inventor.Document, folderName As String, _
	Optional folders As Inventor.BrowserFoldersEnumerator = Nothing)
	Dim oModelPane As Inventor.BrowserPane = doc.BrowserPanes.Item("AmBrowserArrangement")
	'If Not oModelPane.Visible Then oModelPane.Activate()
	If folders Is Nothing Then folders = oModelPane.TopNode.BrowserFolders
	For Each oFolder As Inventor.BrowserFolder In folders
		If oFolder.Name = folderName Then
			oFolder.BrowserNode.EnsureVisible()
			oFolder.BrowserNode.DoSelect()
			ThisApplication.CommandManager.ControlDefinitions.Item("AssemblyCompSuppressionCtxCmd").Execute()
			Exit Sub
		Else
			If oFolder.BrowserNode.BrowserFolders.Count > 0 Then
				ToggleSuppressionOfBrowserFolder(doc, folderName, oFolder.BrowserNode.BrowserFolders)
			End If
		End If
	Next 'oFolder
End Sub

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 9 of 14

Damian_LeeF852L
Participant
Participant

I am getting an error with the "As" in the function of the code you sent. The error message says "Statement cannot appear within a method body. End of method assumed".

0 Likes
Message 10 of 14

WCrihfield
Mentor
Mentor

Did the error message say which line of code it was on?  The keyword "As" is used in several places, so I'm not sure which instance it may be referring to.  That keyword is used to specify which Type a variable represents.  Without knowing which line the error occurred on, I just have to guess, so my first guess would to try changing the following line of code:

For Each oFolder As Inventor.BrowserFolder In folders

...like this:

For Each oFolder In folders

When iterating through each object in certain kinds of collections, some do not like it when we declare the 'Type' of the variable we are using, because it is 'implied' by the Type of the collection.  But most of the time, specifying its Type is not only allowed, but encouraged.

Edit:  I just created a small test assembly, with several instances of the same part in it, two browser folders at the top level, with each top level folder having one sub folder.  Each top level folder has one part in it, then each sub folder has 2 parts in them.  When I changed the folder name in the rule to one of the sub folder names, then ran the rule, it toggled the suppression of the two components in that sub folder, as expected.  Ran it again, and it toggled them again, as expected.  No errors.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 11 of 14

Damian_LeeF852L
Participant
Participant

I have pasted your code into a new rule and it runs perfectly. I got the error when I tried combining it with my code. I will post my current code which I am trying to incorporate your sub folder coding into. The code below is a simplified version of what I am trying to do. This code only works with top level folders. Each time I run it, it switches to the Primary model state (which has everything suppressed). It the deletes model state "Configuration" (if it exists). It then recreates it, sets it to active and unsuppresses all the items I require.

Sub Main()
	
'Get the active document
Dim oDoc As Document
Dim sourceName As String = "[Primary]"
Dim newName As String = "Configuration"
Dim doc As Document = ThisDoc.Document
Dim FolderToHide As String
Dim AVR_Parameter As String
Dim MFI_Parameter As String
Dim DualProtection_Parameter As String


oDoc = ThisDoc.Document

' Switch to the "[Primary]" Model State
oDoc.ComponentDefinition.ModelStates.Item("[Primary]").Activate()

	AVR_Parameter = AVR
		MFI_Parameter = MFI
			DualProtection_Parameter = Dual_Protection



'check if model state "Configuration" exists and delete it if it does
Try

			
	oDoc.ComponentDefinition.ModelStates.Item("Configuration").Delete
Catch
End Try

' Get source Model State
Dim sourceState As ModelState = doc.ComponentDefinition.ModelStates.Item(sourceName)

' Create new Model State
Dim newState As ModelState = doc.ComponentDefinition.ModelStates.Add(newName)

	If MFI = "Yes" Then
		FolderToHide="MFI & Synchroscope"
    	HideParts(FolderToHide)
	End If
			
'Set Dual AVR

	If AVR = "A12N-T" Then
		FolderToHide="A12N-T"
    	HideParts(FolderToHide)	
	End If

'Set Dual Protection
	
	If Dual_Protection="Yes" Then
		FolderToHide="Dual Protection"
    	HideParts(FolderToHide)
	End If

ThisDoc.Document.Update()
End Sub

Function HideParts(FolderToHide)
Dim oDoc As Document = ThisDoc.Document
Dim oModelPane As BrowserPane = oDoc.BrowserPanes.Item("Model")
Dim oTopNode As BrowserNode = oModelPane.TopNode

For Each oBFolder As BrowserFolder In oTopNode.BrowserFolders
	'For Each oBFolder As BrowserFolder In oBFolder.BrowserFolders

		If oBFolder.Name = FolderToHide Then
			oDoc.SelectSet.Clear
			oDoc.SelectSet.Select(oBFolder)
			ThisApplication.CommandManager.ControlDefinitions.Item("AssemblyCompSuppressionCtxCmd").Execute
			
		End If
	
Next
End Function

 

0 Likes
Message 12 of 14

Damian_LeeF852L
Participant
Participant

Sorry, I posted my reply in the above by mistake.

0 Likes
Message 13 of 14

WCrihfield
Mentor
Mentor
Accepted solution

Here is a modified version of the last code you posted, where I integrated my custom Sub routine into it, to replace its 'HideParts' method.  I also slightly tweaked some of the code in the main routine.  Here is the result.

Sub Main
	'Get the ModelState 'Factory' version of the current document
	Dim oDoc As Inventor.AssemblyDocument = ThisDoc.FactoryDocument
	If oDoc Is Nothing Then Return
	If oDoc.RequiresUpdate Then oDoc.Update2(True)
	Dim oModelStates As Inventor.ModelStates = oDoc.ComponentDefinition.ModelStates
	oModelStates.MemberEditScope = MemberEditScopeEnum.kEditActiveMember
	Dim sourceName As String = "[Primary]"
	Dim newName As String = "Configuration"
	Dim FolderToHide As String
	Dim AVR_Parameter As String
	Dim MFI_Parameter As String
	Dim DualProtection_Parameter As String
	' Get source Model State '"[Primary]"
	Dim sourceState As ModelState = oModelStates.Item(sourceName)
	' Switch to the "[Primary]" Model State
	sourceState.Activate()
	AVR_Parameter = AVR
	MFI_Parameter = MFI
	DualProtection_Parameter = Dual_Protection
	'check if model state "Configuration" exists and delete it if it does
	Try
		oModelStates.Item(newName).Delete()
	Catch
	End Try
	' Create new Model State
	Dim newState As ModelState = oModelStates.Add(newName)
	'activate the new ModelState, so it will record following suppression changes
	newState.Activate()
	If MFI = "Yes" Then
		FolderToHide = "MFI & Synchroscope"
		ToggleSuppressionOfBrowserFolder(oDoc, FolderToHide)
	End If
	'Set Dual AVR
	If AVR = "A12N-T" Then
		FolderToHide = "A12N-T"
		ToggleSuppressionOfBrowserFolder(oDoc, FolderToHide)
	End If
	'Set Dual Protection
	If Dual_Protection = "Yes" Then
		FolderToHide = "Dual Protection"
		ToggleSuppressionOfBrowserFolder(oDoc, FolderToHide)
	End If
	oDoc.Update2(True)
End Sub

Sub ToggleSuppressionOfBrowserFolder(doc As Inventor.Document, folderName As String, _
	Optional folders As Inventor.BrowserFoldersEnumerator = Nothing)
	Dim oModelPane As Inventor.BrowserPane = doc.BrowserPanes.Item("AmBrowserArrangement")
	'If Not oModelPane.Visible Then oModelPane.Activate()
	If folders Is Nothing Then folders = oModelPane.TopNode.BrowserFolders
	For Each oFolder As Inventor.BrowserFolder In folders
		If oFolder.Name = folderName Then
			oFolder.BrowserNode.EnsureVisible()
			oFolder.BrowserNode.DoSelect()
			ThisApplication.CommandManager.ControlDefinitions.Item("AssemblyCompSuppressionCtxCmd").Execute()
			Exit Sub
		Else
			If oFolder.BrowserNode.BrowserFolders.Count > 0 Then
				ToggleSuppressionOfBrowserFolder(doc, folderName, oFolder.BrowserNode.BrowserFolders)
			End If
		End If
	Next 'oFolder
End Sub

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 14 of 14

Damian_LeeF852L
Participant
Participant

That works brilliantly, thank you so much.

0 Likes