Applying rules to multiple parts in the same folder

Applying rules to multiple parts in the same folder

berry.lejeune
Advocate Advocate
631 Views
11 Replies
Message 1 of 12

Applying rules to multiple parts in the same folder

berry.lejeune
Advocate
Advocate

Hello all,

 

I've run into a little bit of a problem.

I'm designing grave stones, and I've already made an extesive library with all kinds of different setups of gravestones.

Now when I make a new stone, in general the base is the same, I install a headstone. In the assembly there's a global rule that links to the headstone and I can easlily change the dimensions with a form

Screenshot_955.png

Attached is my workflow: In the assembly I press the button "afmetingen rug" and this triggers a rule that will open a form and there I can change the dimensions of the headstone. 

 

The button "afmetingen rug" triggers this code

Dim ass As AssemblyDocument = ThisApplication.ActiveEditDocument
For Each comp As ComponentOccurrence In ass.ComponentDefinition.Occurrences 
	If comp.Name.Contains("Rs") Then
		 iLogicVb.RunRule(comp.Name, "Form 1")
	End If
Next

 So if there's a component in the assembly that contains "Rs" then it'll run a rule in that part "Form 1"

 

The rule in the part is below

iLogicForm.Show("Form 1")

 This rule activates a form in that part that  is shown in the first picture where I can change the length (lengte) ,width (breedte) and thickness (dikte)

 

Now comes to problematic part: there are about 200 different variaties of headstones. Does this now mean that for every single headstone I have to make the form and the rule inside the part or am I missing something?

Or can this be done otherwise?

 

All the headstones in the library contain the same 3 parameters (lengte, breedte and dikte for the BOM)

 

Thanks

0 Likes
Accepted solutions (1)
632 Views
11 Replies
Replies (11)
Message 2 of 12

WCrihfield
Mentor
Mentor

Hi @berry.lejeune.  Just to clarify...are you wanting to eliminate the internal iLogic rule and internal iLogic Form from within every headstone part, and replace them with a single external iLogic rule and single global iLogic Form...or are you just looking for a way to apply one rule to multiple files?  Technically speaking, there is no way to apply one rule run to multiple files at the same time, but there are certainly ways to iterate through multiple components in an assembly, or referenced documents, or files in a folder, open them (if needed), run a rule on them, then close them (of they had to be opened).  If files are actively being referenced by an open assembly or drawing, then they may already be open in the background, but just not visibly (with no document tab).  If they are invisibly open in the background due to opening the assembly, then you will not usually need to open them by code, or close them by code, to work on them by code.

 

You can see the number of currently open documents in the lower right corner of your Inventor screen, in the 'status bar'.  If your status bar is not showing, it can be turned on on the View tab,  Windows panel, click on the User Interface tool's drop-down, then add a checkmark to the checkbox next to Status Bar.  For instance, I can have 4 document tabs visible, but 92 documents open, because two of the document tabs are for assemblies, and one is for a drawing, while the other is a new, unsaved document.

 

There is also an Autodesk developed tool in the Autodesk App Store that you may be able to use, called "iLogic Rule Batch Tool" at the following link:

https://apps.autodesk.com/INVNTOR/en/Detail/Index?id=7381718697722491251 

 

Edit:  Just adding that there is an advantage to using 'local'/'internal' rules/Forms, even though it may not be as efficient as a single external/global one.  With internal versions, they are 'linked' to the document that they are saved within, and will often keep their focus on that one document, while external/global alternatives will attempt to work on whichever document happens to be actively showing on your screen when they launch, which may be the main assembly in this case, instead of a gravestone part being referenced in the background.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 3 of 12

berry.lejeune
Advocate
Advocate

@WCrihfield I'm not so sure what is the best way to go about this.

What I also did in the meantime is creating a global form. This form has the parameters in it that need to be changed in my headstone/coverplate. The only thing that I need to do is activate the corresponding part and activate the global form. (the parameters are all having the same names throughout the parts)

Screenshot_956.png

Screenshot_957.png

I think I'll use this way. What would be an extra now is that when I select the part (not activate) and then hit the button the part will activate, and when I press done on the form the assembly will be active again

0 Likes
Message 4 of 12

nstevelmans
Advocate
Advocate

Hi, you can create this external rule and start it in an assembly.

In the Part you create a rule The name off the rule “Show Form” 

 

' Start of iLogic Rule ===============================================================================

'Check whether open document is an assembly and exit rule if not
oDoc = ThisDoc.ModelDocument
If oDoc.DocumentType = kPartDocumentObject Then
MessageBox.Show("This rule can only be run in an assembly file - exiting rule", "")
Return
End If

Dim targetOcc As ComponentOccurrence = Nothing
Do While True
	' Note the below line will prompt the user to pick an assembly occurrence (this can be a single part file or a sub-assembly of the active document...
	targetOcc = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select Occurrence to Modify...(Press ESC to cancel)") 
	If Not targetOcc Is Nothing Then
		Exit Do
	Else
		Dim Res As MsgBoxResult = MsgBox("No model selected - exit?", 36, "")
		If Res = vbYes Then
			Return
		Else
			' Do nothing - keep on looping...
		End If
	End If
Loop

Try
iLogicVb.RunRule(targetOcc.Name, "Show Form")
Catch
MsgBox("Error - There needs to be an iLogic rule called 'Show Form' in the assembly occurrence you have selected. This rule needs to contain code in 'show' the iLogic form you want to display. The code to do this will need to be similar to: ""iLogicForm.Show(""Form 1"")""", 64, "")
End Try

' End of iLogic Rule ========

 

 

 

   ! For administrative reasons, please mark a "Solution as solved" when the issue is solved !

Message 5 of 12

berry.lejeune
Advocate
Advocate

Hi @nstevelmans ,

part of your code is already a big step I'm searching for. The fact that I start the code and it makes me select a part is already a big advantage! When selecting the part, can the part also be activated? And when activated, I have a global form, can this form then also be activated?

Screenshot_958.png

0 Likes
Message 6 of 12

WCrihfield
Mentor
Mentor

Hi @berry.lejeune.  In your Message 3 above, it looks like the assembly is still the true 'active' document in both cases, but in the second image, it looks like you have maybe entered into 'Edit Mode' of the assembly component, making all other component geometry greyed out.  Is that correct.  If so, then that document you are working with in that second image would be the value of the 'ThisApplication.ActiveEditDocument', while the main assembly would still be the value of the 'ThisApplication.ActiveDocument' property.  And if that form you were showing in that second image was your global form, not just an internal form of the part, then it must work with the 'active edit document', instead of the 'active document', which would be an advantage in your situation.  In order to be able to enter into Edit Mode of that one component by code, we would first need a way to identify it by code.  Maybe by its name, as shown in the model browser tree, or by 'Pick' method, or other way.  Then you can use the ComponentOccurrence.Edit method to enter Edit Mode, and ComponentOccurrence.ExitEdit method to exit Edit Mode of the component.  That should be good enough to make it be in focus for when you show the global form right after that point.  The global form could be shown from the same rule that enters the component into edit mode though, instead of injecting another internal rule into the component file.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 7 of 12

nstevelmans
Advocate
Advocate

Hi, in every part must be as rule with the name "Show Form" 

the rule can do anything then also opening as Global Form

 

iLogicForm.ShowGlobal("test", FormMode.NonModal)

 

0 Likes
Message 8 of 12

WCrihfield
Mentor
Mentor

Hi @berry.lejeune.  Based solely on your response in Message 5 above, here is an iLogic rule example that should do all of those things you were asking about there.

 

It first makes sure you are working with an assembly, then allows you to manually 'Pick' an assembly component.  You will notice that there are two possible filters for that action.  One will allow you to pick all top level components, and sub assemblies, but may not allow you to pick individual part type components that are down within sub assemblies.  The other filter will only allow you to pick part type components, and at any level of the assembly.  I left that second one commented out for now, but you can choose which will work better for you, then either change which line is commented out, or delete one of those lines, then make sure the other line is uncommented.  Next it will 'activate' the component (enter into Edit Mode for that component).  Next it will show the global iLogic form, in Modal mode.  I left some comments in the code about what that means, but will mention it here too, because it is important.  When a Form is shown in Modal mode, that means it commands focus while it is showing, and you can not interact with other things in Inventor while it is showing.  However it also means that the iLogic rule that launched that form modally, will remain 'paused' while it is showing, then resume when it is closed, which is needed here, if this rule is the one showing the form.  If this rule shows the form NonModal, then the rule's code will immediately continue running, before you even have a chance to interact stuff in the Form.  Then, depending on how the Form was closed, it will react accordingly.  For instance, if you Canceled, Closed, or clicked the 'X' on the Form, it will exit edit mode of this component, then exit the rule.  But if you clicked Done, OK, or clicked a 'run rule' type button which closed the form, then things in the code will proceed to update the document that the component is referencing, then 'deactivate' (exit out of edit mode) the component, then update the assembly.  Then it will repeat those steps at the point where it asks you to pick a component.

Sub Main
	Dim oADoc As AssemblyDocument = TryCast(ThisDoc.Document, Inventor.AssemblyDocument)
	If oADoc Is Nothing Then Return
	Dim oCM As Inventor.CommandManager = ThisApplication.CommandManager
	Dim oPickedOcc As ComponentOccurrence
	Dim sPrompt As String = "Pick Component (Press ESC key to exit selection mode)"
	'this next line is just a place marker for the 'GoTo' line at the end, for repeating
	'to exit this loop, simply do not select anything (use escape keyboard key)
	GoAgain :
	oPickedOcc = Nothing
	oPickedOcc = oCM.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, sPrompt)
	'use the one below to pick only part type components at any level of the assembly
	'oPickedOcc = oCM.Pick(SelectionFilterEnum.kAssemblyLeafOccurrenceFilter, sPrompt)
	If oPickedOcc Is Nothing Then Return 'exit the rule
	'activate this component for in-place editing within the assembly
	oPickedOcc.Edit
	'Modal means you can not interact with other things while the form is showing
	'Modal also means this code will be paused while it is showing, then resume when it is closed
	'if shown non-modal, this code will continue before your interactions within the form
	Dim oRFV As FormReturnValue = iLogicForm.ShowGlobal("Afmetingen rug", FormMode.Modal)
	'if the form was shown Modal, then the form is closed again at this point
	Select Case oRFV.Result
		Case FormResult.Cancel, FormResult.Close, FormResult.None
			oPickedOcc.ExitEdit(ExitTypeEnum.kExitToPrevious)
			Return 'exit the rule
		Case FormResult.Done, FormResult.OK, FormResult.RuleButtonApplyAndClose, FormResult.RuleButtonClose
			Dim oOccDoc As Inventor.Document = ThisApplication.ActiveEditDocument
			If oOccDoc.RequiresUpdate Then oOccDoc.Update2(True)
			'If oOccDoc.Dirty Then oOccDoc.Save
	End Select
	oPickedOcc.ExitEdit(ExitTypeEnum.kExitToPrevious)
	If oADoc.RequiresUpdate Then oADoc.Update2(True)
	GoTo GoAgain
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)

Message 9 of 12

berry.lejeune
Advocate
Advocate

Hi @WCrihfield 

This code works like I had it in my mind. I only had to change the name of the form. But when I run the code, I pick the part and then the form opens. But I can't change anything in the form, all is greyed out

Screenshot_965.png

If I double click a part in my assembly to make it active and I start my form -> then I can change my dimensions in the form. Is there maybe something I overlooked?

 

 

0 Likes
Message 10 of 12

nstevelmans
Advocate
Advocate
Accepted solution

hi, try this

 

1. Create an external rule with the name Show Form
iLogicForm.ShowGlobal("Afmetingen rug", FormMode.NonModal)’name off the Global Form
 
2. Create a Global Form with the name “Afmetingen rug”
 
Run the ilogic rule in an Assembly.
 
Animatie.gif
 
 
Sub main


'Check whether open document is an assembly and exit rule if not
oDoc = ThisDoc.ModelDocument
If oDoc.DocumentType = kPartDocumentObject Then
MessageBox.Show("This rule can only be run in an assembly file - exiting rule", "")
Return
End If

Dim targetOcc As ComponentOccurrence = Nothing
Do While True
	' Note the below line will prompt the user to pick an assembly occurrence (this can be a single part file or a sub-assembly of the active document...
	targetOcc = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select Occurrence to Modify...(Press ESC to cancel)") 
	If Not targetOcc Is Nothing Then
		Exit Do
	Else
		Dim Res As MsgBoxResult = MsgBox("No model selected - exit?", 36, "")
		If Res = vbYes Then
			Return
		Else
			' Do nothing - keep on looping...
		End If
	End If
Loop

Try
	Dim oPartDoc As PartDocument = targetOcc.Definition.Document
	
	InjectRule(oPartDoc)
	
iLogicVb.RunRule(targetOcc.Name, "Show Form")

Catch
'MsgBox("Error - There needs to be an iLogic rule called 'Show Form' in the assembly occurrence you have selected. This rule needs to contain code in 'show' the iLogic form you want to display. The code to do this will need to be similar to: ""iLogicForm.Show(""Form 1"")""", 64, "")
End Try

End Sub




Sub InjectRule(ByVal oDoc As Document)
	Dim oRuleName As String = "Afmetingen rug"
	Dim RuleText As String
	
RuleText = "iLogicVb.RunExternalRule(" & Chr(34) & "Show Form" & Chr(34) & ")"
	' Get the iLogic automation object
	Dim iLogic As Object = iLogicVb.Automation
	'Delete the existing rule if needed
	Try
		iLogic.DeleteRule(oDoc, oRuleName)
	Catch
	End Try
	'add rule
	oRule = iLogic.AddRule(oDoc, oRuleName, RuleText)

	'rule options
	iLogicVb.Automation.GetRule(ThisDoc.Document, oRuleName).IsActive = True
	iLogicVb.Automation.GetRule(ThisDoc.Document, oRuleName).AutomaticOnParamChange = True
	'iLogicVb.Automation.GetRule(ThisDoc.Document, oRuleName).SilentOperation = True

End Sub

 
 

 

 

 

Message 11 of 12

berry.lejeune
Advocate
Advocate

Thank you @nstevelmans and @WCrihfield for your help!!!!

0 Likes
Message 12 of 12

WCrihfield
Mentor
Mentor

I do not know why the picked component would not 'activate' (enter into edit mode) the way you needed it to.  Maybe manually double-clicking on the component makes something extra happen that the ComponentOccurrence.Edit method by itself does not do, I am not sure.  I have seen other similar stuff like that though.  Such as the Component.IsActive iLogic snippet used to not only suppress or un-suppress a component, but it would also change the BOMStructure setting of it.  Then I think they changed that once or twice.  So, it would do something differently than the manual action of just suppressing a component, when many folks did not realize it.

Were you using the regular 'kAssemblyOccurrenceFilter' filter, then choosing a top level component, or were you using the alternate 'kAssemblyLeafOccurrenceFilter' filter, then choosing a sub component?  Maybe if you chose a lower level component (leaf), it would need its parent(s) activated (edited) first, then the one you picked secondarily.  Not sure.

Glad to see that you now have a satisfactory solution though.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes