Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Run all part rule from total assembly file

13 REPLIES 13
SOLVED
Reply
Message 1 of 14
tamnn.designer
734 Views, 13 Replies

Run all part rule from total assembly file

Hi Bro.

How can i run all part rule from external in assembly file.  Many thanks. (All part i coppy parameter from template already, but still not have rule to define the number ) => Now i want to run it from assembly file.

 

Parameter("extent_dim_Y") = SheetMetal.FlatExtentsLength
iLogicVb.RunRule("extent_dim_Y")
iLogicVb.UpdateWhenDone = True
Parameter("extent_dim_X") = SheetMetal.FlatExtentsWidth
iLogicVb.RunRule("extent_dim_X")
iLogicVb.UpdateWhenDone = True
Parameter("part_area") = surfaceArea = iProperties.Area
iLogicVb.RunRule("part_area")
iLogicVb.UpdateWhenDone = True
Parameter("extent_dim_T") = Parameter("Thickness")
iLogicVb.RunRule("extent_dim_T")
iLogicVb.RunRule("Thickness")
iLogicVb.UpdateWhenDone = True
InventorVb.DocumentUpdate()
MultiValue.UpdateAfterChange = True
Parameter.UpdateAfterChange = True

 

13 REPLIES 13
Message 2 of 14

Hi @tamnn.designer 

 

If you want to run all the rules in all the parts in an assembly you can use something like this.

 

Dim oDef As AssemblyComponentDefinition = ThisDoc.Document.ComponentDefinition

For Each oOcc In oDef.Occurrences _
	.OfType(Of ComponentOccurrence) _
	.Where(Function(x) x.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject)

	'get collection of rules
	Dim oRules As Object = iLogicVb.Automation.Rules(oOcc.Definition.Document)

	'make sure there are rules in the file
	If (oRules Is Nothing) Then Continue For

	'get each rule 
	For Each oRule In oRules
		Dim sRuleName As String = oRule.Name
		'run the rule in the component
		iLogicVb.RunRule(oOcc.Name, sRuleName)
	Next
Next

 

( thank you to @JhoelForshav  for the more efficient method of iterating the component occurrences 👍

 

I hope this helps.
Best of luck to you in all of your Inventor pursuits,
Curtis
http://inventortrenches.blogspot.com

Message 3 of 14

Hi @tamnn.designer , @Curtis_Waguespack 

I'd say in this specific case maybe its better to loop through documents rather than occurrences, since the rules are on document level and an assembly can contain more than one occurrence of the same part (going through all occurrences could then run the same rule multiple times which would be unessecary)

 

With that said I'd rewrite @Curtis_Waguespacks code to something like this:

Dim oDoc As AssemblyDocument = ThisDoc.Document
'Get all part documents referenced by assembly
For Each refDoc As Document In oDoc.AllReferencedDocuments.OfType(Of Document).Where(Function(d) d.DocumentType = DocumentTypeEnum.kPartDocumentObject)
	'Make sure there are component representations in the assembly (exclude derived parts)
	If oDoc.ComponentDefinition.Occurrences.AllReferencedOccurrences(refDoc).Count > 0
		'get collection of rules
		Dim oRules As Object = iLogicVb.Automation.Rules(refDoc)
		'make sure there are rules in the file
		If (oRules Is Nothing) Then Continue For
		'Run each rule 
		For Each oRule As iLogicRule In oRules
			iLogicVb.Automation.RunRuleDirect(oRule)
		Next
	End If
Next

 

Also @Curtis_Waguespack , Don't forget to use AllReferencedOccurrences with the AssemblyComponentDefinition as argument if you want all parts on all levels in the assembly. See example below:

Dim oDef As AssemblyComponentDefinition = ThisDoc.Document.ComponentDefinition
'All part occurrences
MsgBox(oDef.Occurrences.AllReferencedOccurrences(oDef).OfType(Of ComponentOccurrence).Where(Function(x) x.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject).Count)
'Only top level part occurrences
MsgBox(oDef.Occurrences.OfType(Of ComponentOccurrence).Where(Function(x) x.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject).Count)

 

Message 4 of 14


@JhoelForshav wrote:

 

I'd say in this specific case maybe its better to loop through documents rather than occurrences


Ahh, this is very good point, and much better approach.

 


@JhoelForshav wrote:

 

Also @Curtis_Waguespack , Don't forget to use AllReferencedOccurrences with the AssemblyComponentDefinition as argument if you want all parts on all levels in the assembly.


I had a look at that earlier, but misinterpreted why you were doing it that way. Seems very obvious now that you have pointed it out. 🙂  Thanks again!

 

 

Message 5 of 14



I had a look at that earlier, but misinterpreted why you were doing it that way. Seems very obvious now that you have pointed it out. 🙂  Thanks again!

 

 


@Curtis_Waguespack 
It's one of those things I just stumbled across one day that's been a real game changer for me ever since 😄

Message 6 of 14

Hi Bro, thank you very much for your reply.  Can you check it and comment. Many thanks and appreciate.

 

Dim oDoc As AssemblyDocument = ThisDoc.Document
'Get all part documents referenced by assembly
For Each refDoc As Document In oDoc.AllReferencedDocuments.OfType(Of Document).Where(Function(d) d.DocumentType = DocumentTypeEnum.kPartDocumentObject)
	'Make sure there are component representations in the assembly (exclude derived parts)
	If oDoc.ComponentDefinition.Occurrences.AllReferencedOccurrences(refDoc).Count > 0
		'get collection of rules
		Dim oRules As Object = iLogicVb.Automation.Rules(refDoc)
		'make sure there are rules in the file
		If (oRules Is Nothing) Then Continue For
		'Run each rule 
		For Each oRule As iLogicRule In oRules
			iLogicVb.Automation.RunRuleDirect(oRule)
			Parameter("extent_dim_Y") = SheetMetal.FlatExtentsLength
			iLogicVb.RunRule("extent_dim_Y")
			iLogicVb.UpdateWhenDone = True
			Parameter("extent_dim_X") = SheetMetal.FlatExtentsWidth
			iLogicVb.RunRule("extent_dim_X")
			iLogicVb.UpdateWhenDone = True
			Parameter("part_area") = surfaceArea = iProperties.Area
			iLogicVb.RunRule("part_area")
			iLogicVb.UpdateWhenDone = True
			Parameter("extent_dim_T") = Parameter("Thickness")
			iLogicVb.RunRule("extent_dim_T")
			iLogicVb.RunRule("Thickness")
			iLogicVb.UpdateWhenDone = True
			InventorVb.DocumentUpdate()
			MultiValue.UpdateAfterChange = True
			Parameter.UpdateAfterChange = True
		Next
	End If
Next

 

Message 7 of 14
WCrihfield
in reply to: tamnn.designer

Hi @tamnn.designer.  Just so you are aware, the following lines of code for updating things are all preparatory, meaning they only need to be included in the rule once, and can be included at or near the top of the rule, rather than after you do something.

iLogicVb.UpdateWhenDone = True

When you use the above line of code at or near the top of a rule, the rule will automatically cause the document to update whenever the code finishes, so it does not need to be placed after you do something.  It does not cause an instant update when it is encountered.  A line like this:  "iLogicVb.DocumentUpdate" will cause an instant update when it is encountered.

MultiValue.UpdateAfterChange = True

The line above will cause the document to update whenever you use the 'MultiValue' iLogic snippet to change a parameter after that point in the code, not at that line.

Parameter.UpdateAfterChange = True

The above line of code will cause the document to update when you use the Parameter() iLogic snippet to change a parameter after that point in the code, not at that line.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 8 of 14
WCrihfield
in reply to: tamnn.designer

Just some additional pointers...

You may have noticed that each of the following iLogic snippets do not have any reference to a specific document:

Parameter("extent_dim_Y")
SheetMetal.FlatExtentsLength
iProperties.Area

Those simple iLogic snippets, as they are there, do not know what specific document to look at for that information, so they are just designed to work on whichever document happens to be 'active' at the moment they are encountered.  In the case of your last code, they will be looking at the main assembly, instead of the referenced document currently being looked in that loop, within the assembly.  Sometimes you can use a slightly different version of that snippet that allows you to specify a document for it to target, like with the following:

Parameter(refDoc.DisplayName, "extent_dim_Y")

...but not always.  In those cases, you have to do things a little differently.  Usually that means having to use some longer Inventor's API code, similar to the following:

refDoc.ComponentDefinition.Parameters.Item("extent_dim_Y").Value

or

refDoc.PropertySets.Item(1).Item(1).Value

...but in the case of parameters, when going the API route, the units will be 'database units' rather than document units, for whatever type (distance, angle, mass, time) of units they are.  Database units are centimeters for distance.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 9 of 14
WCrihfield
in reply to: tamnn.designer

Hi @tamnn.designer.  I slightly edited that last code you posted, and added more comments in there for each line of code present.  Each comment is for the following line of code, in an attempt to explain what it will be trying to do.  I assume that those lines of code for accessing Parameters are meant to be interacting with the referenced part only, so I altered them in the simplest way I know how without making the overall code too much longer or any more complex.  As for all the individual rules you are running in there with "iLogicVb.RunRule()", when you use that simple line, it will be looking for the specified internal iLogic rule in one specific place.  If the overall rule (that this line of code is within) is an internal rule (saved within a document), then this line of code will look for that rule within the same document that the main rule is saved within.  If the main rule is an external rule, it will be looking for that rule in whichever document is 'active' at the time, which would be the main assembly in this case.  If those rules are all within the referenced part, then those lines of code are not needed, because the "oAuto.RunRuleDirect(oRule)" line will run them.  Since I was not sure which way you had it set-up, I left those lines of code in there, for now.

 

Dim oDoc As AssemblyDocument = ThisDoc.Document
'Get all part documents referenced by assembly
Dim oAllRefParts As IEnumerable(Of Inventor.Document) = oDoc.AllReferencedDocuments.OfType(Of Document).Where(Function(d) d.DocumentType = DocumentTypeEnum.kPartDocumentObject)
'if none were found exit rule
If oAllRefParts Is Nothing OrElse oAllRefParts.Count = 0 Then Exit Sub
'start looping through the referenced parts
For Each refDoc As Document In oAllRefParts
	'if there are no components referencing this part, skip to next referenced part
	If oDoc.ComponentDefinition.Occurrences.AllReferencedOccurrences(refDoc).Count = 0 Then Continue For
	'this is a way to specify which document for the iLogic snippets to target
	Dim SOP As IStandardObjectProvider = StandardObjectFactory.Create(refDoc)
	'get collection of rules
	Dim oAuto As IiLogicAutomation = iLogicVb.Automation
	Dim oRules As IEnumerable = oAuto.Rules(refDoc)
	'if no rules were found skip to next referenced part
	If oRules Is Nothing Then Continue For
	'Run each rule within that referenced part
	For Each oRule As iLogicRule In oRules
		oAuto.RunRuleDirect(oRule)
		'cause all further parameter changes to cause a document update
		Parameter.UpdateAfterChange = True
		'set parameter value within the referenced part
		SOP.Parameter("extent_dim_Y") = SOP.SheetMetal.FlatExtentsLength
		'this will try to run an internal iLogic rule within the main assembly, not within the referenced part
		iLogicVb.RunRule("extent_dim_Y")
		'set parameter value within the referenced part
		SOP.Parameter("extent_dim_X") = SOP.SheetMetal.FlatExtentsWidth
		'this will try to run an internal iLogic rule within the main assembly, not within the referenced part
		iLogicVb.RunRule("extent_dim_X")
		'set parameter value within the referenced part
		SOP.Parameter("part_area") = SOP.iProperties.Area
		'this will try to run an internal iLogic rule within the main assembly, not within the referenced part
		iLogicVb.RunRule("part_area")
		'set parameter value within the referenced part
		SOP.Parameter("extent_dim_T") = SOP.Parameter("Thickness")
		'this will try to run an internal iLogic rule within the main assembly, not within the referenced part
		iLogicVb.RunRule("extent_dim_T")
		'this will try to run an internal iLogic rule within the main assembly, not within the referenced part
		iLogicVb.RunRule("Thickness")
		'force an immediate document update on the main assembly, not the referenced part
		InventorVb.DocumentUpdate()
		'update this specific referenced part
		refDoc.Update2(True)
	Next 'oRule
Next 'refDoc

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 10 of 14
tamnn.designer
in reply to: WCrihfield

Hi Bro,

 

I did from external rule as you mentioned above, but nothing happen, i would like to explain you more detail. I hope you can understand more clearly. Very sorry abt my poor english and poor knowleages abt ilogic.

 

1. I have previous project which don't have any parameter and rule inside. (But i used other rule to coppy all parameter for all part already).

2. But i dont have any rule in all part above. (If is there any code coppy the rules from template part/ or from external rule to the part rule => That's would be OK.

3. I would want to use external rule as showed above to run all parameter inside each part. But they are still not work yet.

 

I am looking forward to your feedback and support. Many many thanks.

@WCrihfield

Message 11 of 14
WCrihfield
in reply to: tamnn.designer

Hi @tamnn.designer.  I see that you have asked this last part in two different places (here and at this link).  But it looks like you need two different tasks done by code, and I believe they may require two slightly different iLogic rules to do them.  And I have more questions for you, so that we can better understand how you need the two different rules be done.  The task of copying internal iLogic rules from one Inventor document to another is the simple part.  One of the things we need to know is, how do you want to specify which document to copy the origial rules from?  The simplest way would be to have that document visibly open on your screen (active) when you start this rule, then it will simply try to get the rules from the 'active' document.  Another option would be to allow you to use a file browser dialog to select a file that you want to copy the original iLogic rules from.  Which of those two options sounds like it would suit your needs better.  Both are fairly easy to do by code.  The next question is, how do you want to specify what documents you want to copy those rules into?  It sounds like you want would want the rule to target the main assembly, then loop through all of the documents it references.  But in order to get a reference to the main assembly, the main assembly would either need to be the 'active' document when you start the rule, or the rule could present you with a file browser dialog, and allow you to select the main assembly file for it to process.  Since two rules are likely needed here for these two tasks, I suspect they will both need to be done differently. 

 

When copying the one rule from the main assembly to all of its sub assemblies, you could simply start the rule for that task while the main assembly is the active document, and the rule would handle the rest.

 

But the second task, where you need to copy multiple rules from a part, to all other parts within the assembly could be done either way.  The rule could be started while the main assembly is active, then let you choose the source part file to copy the rules from using a file dialog.  Or the rule could be started while the source part is currently the 'active' document, then let you choose the main assembly file using a file dialog.  Is that source part one of the parts that is already within the main assembly?  If so, the rule would need to avoid overwriting the rules in that source part when it loops through all of the parts in the assembly.

 

Edit:  Have you added any of your iLogic rules under any of the events within the Event Triggers dialog in any of those files involved?  If not, then we do not have to mess with that whole thing, and can just focus on the rules.  If you have that one rule in your assembly set under one of the events in the Event Triggers dialog, then the rule for copying that rule down to all the other sub assemblies, would also need to copy the Event Triggers settings down to all of those sub assemblies.  If that is the case, and we do include that functionality into the rule, do you want the rule to just overwrite any Event Triggers settings that may already be present in all of those sub assemblies, or do you want to leave any current setting in place and only add to them, if needed?

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 12 of 14
tamnn.designer
in reply to: WCrihfield

Hi Sir, I would like to quick reply you as bellow. 

Other topic i ask is other way i think, i don't really know if easy or not. So there are 2 way i think it can do.

1. Coppy all rules from template to all part or sub-assemblies, that  i created before without any rules.

2. Run the rule from main-assembly file. 

I just need number, dont care abt Option 1 or Option 2.  BUT Option 2 would be greate for me,\

 

My purpose is only get some flatness information from other project i create before which don't have rule inside. That's would be great if i can get some flatness number from main assembly file that i use to make Partlist later for production. 

 

I need one external rule that can run from main assembly to get Flatness X, Y and Thickness.,.. That's it.

 

I am very sorry for some stupid question and poor knowleages/ english

Message 13 of 14
WCrihfield
in reply to: tamnn.designer

Attached are the 2 text files for the 2 iLogic rules mentioned in my previous post.  I am not sure if you still want or need them, but they are available if you are interested.  Both are designed to be started while the assembly is active.  The second one allows you to select the source part to copy rules from.  If we knew what all of those individual rules contained, we may be able to reduce them all to one main external rule, but I am not sure.  Once you get more familiar with iLogic, it is often a better option to keep as many of your rules as possible in the form of external rules, versus internal rules.  One external code is simply much easier to manage, and edit than many copies of an internal rule that are spread out through many documents.  Good luck with your project.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 14 of 14
tamnn.designer
in reply to: WCrihfield

Hi Sir,

It's exactly what we want, but it work with one code only (Coppy part rule s to all assembly parts) , the other one not work, can you help me to fix it.

 

Thank a lot.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report