iLogic: How to run an Assembly-level rule from a component rule?

iLogic: How to run an Assembly-level rule from a component rule?

JamesNordgren
Advocate Advocate
7,357 Views
5 Replies
Message 1 of 6

iLogic: How to run an Assembly-level rule from a component rule?

JamesNordgren
Advocate
Advocate

OK, I thought this would be a no-brainer until I have actually tried - now Im stumped.

 

I need a way to run a rule which is saved in my top-level assembly using iLogic rule which is saved in a part file in the parent assembly.

 

I have even tried using an external rule in a txt file, but that gives the error "Component: This function can only be used in an assembly."  - which makes no sense to me.   I hope I am just missing something simple.  I cant believe with all its other strengths, that iLogic would be so limited in that regard.   Why is there not simply a snippet under the 'Run Other' that allows you to specify an assembly file and the rule name?  (like there is for running a rule in a component from the assembly)

 

Any and All suggestions welcome.

 

James

Accepted solutions (1)
7,358 Views
5 Replies
Replies (5)
Message 2 of 6

MegaJerk
Collaborator
Collaborator
Accepted solution

I believe that there isn't a snippet for this due to the design philosophies that surround the document relationships produced by Inventor. Basically, not only is it wise for the user to keep his models designed from the top down, but it is also the inherent way that Inventor associates things internally. An Assembly has occurrences, and those occurrences are the representations of Documents as viewed from within your initial Assembly. A Document that is an occurrence inside of another Document has no direct knowledge of what it's inside of! 

Now, you can of course 'create' that knowledge, but there are some gotchas involved due to the nature of the beast. 

A few things to remember. 

1) If you are editing a component that is inside of an open assembly, and you are editing the component by way of double clicking on it from said Assembly, your active document is the Assembly Document, and no whatever you're editing. 

2) You can not Save an Active Document if you are currently editing a document that is an occurrence of the Active Document. 

3) Rules that have been created on a document that has not been saved, will not be visible to any other document. 

This may seem a bit over the top, but because of the multiple ways that you can open files in Inventor, it is necessary to do a little work before we get into the running of the rules. 

The following code will allow you to run a rule in a document not associated with the open document, but you will have to, of course, do a little work to correct the paths to the file as well as the name of the rule. 

*EDIT NOTE : This code, if used by someone else, may not work if you aren't working Part --> Assembly as we are in this case! 




Dim myDoc As Document
myDoc = ThisApplication.ActiveDocument

Dim myEdit As Document
myEdit = ThisApplication.ActiveEditDocument

Dim addIns As ApplicationAddIns
addIns = ThisApplication.ApplicationAddIns

Dim addIn As ApplicationAddIn
addIn = ThisApplication. _
ApplicationAddIns.ItemById("{3bdd8d79-2179-4b11-8a5a-257b1c0263ac}") Dim iLogic As Object iLogic = addIn.Automation Dim oDoc As Document If myDoc Is myEdit Then oDoc = ThisApplication.Documents.Open("C:\MegaFolder\Jerk.iam", False) Else oDoc = myDoc If oDoc.Dirty = True Then MessageBox.Show("Please save the parent document before running!") oDoc = Nothing Return End If End If Try Call iLogic.RunRule(oDoc, "RULE_TEST_NAME") Catch MessageBox.Show("Unable to run the rule", "RunRule Error") Finally oDoc = Nothing End Try

 

Pretty round-about huh? 

External rules seem to have been created to alleviate this problem, but because they do not always apply (or are not always appropriate), typically a change in design is the way to go at that point, again, due to the relationships of Documents.

Because I do not know what it is you're making, the following may not apply to you, however, I would suggest looking at your design to see if it's possible to change how you're gathering / passing data that is meaningful to said design. 




If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub
Message 3 of 6

JamesNordgren
Advocate
Advocate
Hi MegaJerk (love the handle, btw)
Thank you for your help!
I realize now that I may have backed myself into a corner here, but I am way too far down this road to re-structure the whole thing now to use external rules. If I knew all that I know now when I began this project, I may have found a way to have it all run at the top assembly level, but I was a total novice.
My assembly contains a part file called Config.ipt, which is basically the parameter calculator for all the parameters used by all of the other parts in the assembly. I did things this way because Inventor does not let you link component parameters to assembly parameters in an assembly where that component is used: the old cyclic dependency. So that is why I have all the parts in the assembly linked to the parameters in the Config part.
This config part has just one rule, which calls a form, which has all the input fields for all these parameters. On that form is a button which I want to fire a BOM collector rule which is (and has to be) in the parent assembly file.

I have a workaround, which was to just have the BOM Collector rule in the assembly use a separate form, but it would be much better if I could fire that rule from the button on the main form.

Here is the top assembly and all the rules which control constraints and component selection... The rule 'Startup' is what fires from the iTrigger and runs the rule with the main form in the Config part.
[cid:image004.jpg@01CE8F78.27D23C60]

Here is the Config part, with the main parameter calculator rule. The rule Run.Collect.BOM is where I was trying to run an external txt rule, but it gives the error about having to be in an assembly... so frustrating!
[cid:image005.png@01CE8F76.7DABB140]

Here is the main form, with the button at the bottom I want to run the rule in the assembly

[cid:image008.jpg@01CE8F78.27D23C60]

I understand most of what you are saying about the document relationships, but I still cant believe with all its other functionality that there is no way to do this! Why does a subcomponent need to know anything about its containing document in order to have it run a rule in an assembly file, which will always be open and at a specified, hard-coded path when the rule is run?
I know this is a lot to understand without actually having the files, but any other suggestions??
I am sure you have better things to do, but I would be happy to send files if you wanted to look

Thanks a bunch!

James



''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Author:

MegaJerk (Mentor)

Date:

08-02-2013 11:34 AM


I believe that there isn't a snippet for this due to the design philosophies that surround the document relationships produced by Inventor. Basically, not only is it wise for the user to keep his models designed from the top down, but it is also the inherent way that Inventor associates things internally. An Assembly has occurrences, and those occurrences are the representations of Documents as viewed from within your initial Assembly. A Document that is an occurrence inside of another Document has no direct knowledge of what it's inside of!

Now, you can of course 'create' that knowledge, but there are some gotchas involved due to the nature of the beast.

A few things to remember.

1) If you are editing a component that is inside of an open assembly, and you are editing the component by way of double clicking on it from said Assembly, your active document is the Assembly Document, and no whatever you're editing.

2) You can not Save an Active Document if you are currently editing a document that is an occurrence of the Active Document.

3) Rules that have been created on a document that has not been saved, will not be visible to any other document.

This may seem a bit over the top, but because of the multiple ways that you can open files in Inventor, it is necessary to do a little work before we get into the running of the rules.

The following code will allow you to run a rule in a document not associated with the open document, but you will have to, of course, do a little work to correct the paths to the file as well as the name of the rule.

Dim myDoc As Document
myDoc = ThisApplication.ActiveDocument
Dim myEdit As Document
myEdit = ThisApplication.ActiveEditDocument
Dim addIns As ApplicationAddIns
addIns = ThisApplication.ApplicationAddIns
Dim addIn As ApplicationAddIn
addIn = ThisApplication.ApplicationAddIns.ItemById("{3bdd8d79-2179-4b11-8a5a-257b1c0263ac}")
Dim iLogic As Object
iLogic = addIn.Automation
Dim oDoc As Document
If myDoc Is myEdit Then
oDoc = ThisApplication.Documents.Open("C:\MegaFolder\Jerk.iam", False)
Else
oDoc = myDoc
If oDoc.Dirty = True Then
MessageBox.Show("Please save the parent document before running!")
oDoc = Nothing
Return
End If
End If
Try Call iLogic.RunRule(oDoc, "RULE_TEST_NAME")
Catch
MessageBox.Show("Unable to run the rule", "RunRule Error")
Finally oDoc = Nothing
End Try


Pretty round-about huh?

External rules seem to have been created to alleviate this problem, but because they do not always apply (or are not always appropriate), typically a change in design is the way to go at that point, again, due to the relationships of Documents.

Because I do not know what it is you're making, the following may not apply to you, however, I would suggest looking at your design to see if it's possible to change how you're gathering / passing data that is meaningful to said design.




[Description: cid:image8e4647.jpg@9776527f.9c6f431a]

James Nordgren
Mechanical Engineer
Research & Development

Email: jnordgren@deltastar.com

Delta Star Inc.
3550 Mayflower Drive
Lynchburg
Virginia 24501

Tel: 434 845-0921
Web: www.deltastar.com
0 Likes
Message 4 of 6

MegaJerk
Collaborator
Collaborator

Before we dig too much deeper into this, let's look at your question that you posted near the end of your post, and then we'll move on from there. 

 


Q) Why does a sub component need to know anything about its containing document in order to have it run a rule in an assembly file, which will always be open and at a specified, hard-coded path when the rule is run?

 

A) It doesn't always have to, but because it sometimes has to, it's probably best to make sure that it does. For instance - An open sub component that is in active edit because it was double clicked from an assembly, will need to check back with that parent assembly (which is the ActiveDocument) in order to see if it's dirty (needs to be saved). Otherwise you can run into problems with changes that you've done, not being visible to any programmatic references that are pointing to that parent document. 

Remember that when you are accessing documents in a programmatic way, it's looking at the objects as they were when they were saved. If you make an edit to your assembly, edit a part, and then make a reference BACK to the assembly from within the part, it will not see any of the changes that you've made because they technically were never saved and it accessed the last saved document at the location you specified in your code! 


Of course you may NEVER run into that problem! It's just one of those things where if it can be done, it probably will be done. If you set up your rules, saved everything, and were planning on never making changes to them, then everything would / will be totally peachy. I just point out stuff like this, and code around stuff like this, just in case things are done in a strange way because iLogic errors are usually rather mysterious. 


-------

 

 

Moving on. 

Though you say that you will not be able to fix things at this point in the design, I suspect that you may have not backed yourself into the deep pit that you might think you have. 

You are correct about our horrid little friend Mr.Cyclic Dependency being a big enemy in the fight to keep things sane, but the way you did things is pretty standard from what I've seen when it comes to code. 

No matter what, so long as you are able to interact with your model in a way that is efficient, then it's probably A-OK that you keep things on the same track. However, if you feel that it's getting to be a bit cumbersome, and ultimately you'd like to be able to interact with things from the top level with no digging, then the following work flow might be able to patch things up a bit (but is by no means a sexy fix). 


Main Assembly --> User Form (from Main Assembly) ---> iLogic to Push values to Dummy Part --> Dummy Part iLogic Calculations --> Linked Parameters everywhere else get updated 

This of course would mean that you would need to copy over any user needed Parameters from your Dummy Part to your Assembly (as in you would need to recreate them), and is not particularly pretty but gets it done. 


Ultimately I enjoy having all of my math being done inside of the assembly, and pushed down (via iLogic) to all of the required parts. Though it gives a high level of control, it certainly is a LOT more tedious and requires a whole lot more forethought into how you'd like to accomplish things / interact with your parts. 

It would look something like 

Main Assembly ---> User Form ---> iLogic Calculations ---> (Optional) Check Baseline Parameter Against Proposed User Changes ---> If Change Run Rule Associated With Type of Parts

Beyond all of this though is what I said a little ways above. If you can work with it, and others can work with it, and it's fast and good, then simply continue! It is certainly not my intention to knock your design / work flow, but to ultimately explain why the thing that you wanted to do doesn't have an easy button (or easy command) that exists inside of the iLogic snippets presented in Inventor. 

Give the code a shot, and tell me if it is working correctly. If not, then there is more work to be done! 

PS: It would seem that your pictures either did not attach correctly, or were linked incorrectly. 😞 

 



If my solution worked or helped you out, please don't forget to hit the kudos button 🙂
iLogicCode Injector: goo.gl/uTT1IB

GitHub
Message 5 of 6

JamesNordgren
Advocate
Advocate

MegaThanks to MegaJerk!!   I was able to paste your code sample directly and it works perfectly.  All I needed to do to get it ready for our production environment was to add a couple lines to pick up the local filepath, and change the messagebox text.

I am very happy with how this configurator works now, and I couldnt do it without your help on here.

 

I may still pursue the re-design you spoke of, where everything is being calculated at the assembly level and then pushing params down to the parts, but most likely I will spend that effort on my next project.  I will definitely need some guidance on how to do it. 🙂

 

Here is the finished code that allows me to run an Assembly-level rule from a part file which is an occurrence in that assembly.  I also included some screen shots to help explain.

'
'****************************************************************
'****************************************************************
rev = 1.01


Dim myDoc As Document
myDoc = ThisApplication.ActiveDocument
Dim myEdit As Document
myEdit = ThisApplication.ActiveEditDocument
Dim addIns As ApplicationAddIns
addIns = ThisApplication.ApplicationAddIns
Dim addIn As ApplicationAddIn
addIn = ThisApplication.ApplicationAddIns.ItemById("{3bdd8d79-2179-4b11-8a5a-257b1c0263ac}")
Dim iLogic As Object
iLogic = addIn.Automation
Dim oDoc As Document
Dim mypath As String
mypath = ThisDoc.Path
If myDoc Is myEdit Then
oDoc = ThisApplication.Documents.Open(mypath + "\" + sJobNumber + ".COVER.WLD.iam", False)
Else
oDoc = myDoc
If oDoc.Dirty = True Then
MessageBox.Show("Please save the Cover Weldment Assembly before running!")
oDoc = Nothing
Return
End If
End If
Try 
Call iLogic.RunRule(oDoc, "Collect.BOM")
Catch
MessageBox.Show("Unable to run the rule", "RunRule Error")
Finally 
oDoc = Nothing
End Try

 

cover.asm.JPG

 

 

Main Assembly shown above

 

config.file.JPG

Config file as Assembly Occurrence shown above

 

 

main.form.JPG

Main Input Form in config file shown above.

 

Sorry for the large pics, I just wanted it to be more clear what I was trying to do...

 

Thanks again!

 

James

Message 6 of 6

Andrew_Burnett
Enthusiast
Enthusiast

I have used this code and it works great from the part but it I try to push the rule in the part from the assembly I get an error.  Does anyone know if there is another way of getting this to work from in the assembly?

 

Long story short I have a form that is located in a part that I use in the assembly for modifying the assembly.  The form updates the part but I need it to run a update rule in the assembly file.

 

Here is the snippet of the code.

Any help would be appreciated.

 

SyntaxEditor Code Snippet

Dim myDoc As Document
myDoc = ThisApplication.ActiveDocument

Dim myEdit As Document
myEdit = ThisApplication.ActiveEditDocument

Dim addIns As ApplicationAddIns
addIns = ThisApplication.ApplicationAddIns

Dim addIn As ApplicationAddIn
addIn = ThisApplication. _
ApplicationAddIns.ItemById("{3bdd8d79-2179-4b11-8a5a-257b1c0263ac}")
        
Dim iLogic As Object
iLogic = addIn.Automation

Dim oDoc As Document

MessageBox.Show(myDoc.ReferencingDocuments(1).FullDocumentName)

If myDoc Is myEdit Then
        'Add the assembly file name here. You may have to find the parent 
        'file name from oDoc.ReferencingDocuments(1).FullDocumentName
    oDoc = ThisApplication.Documents.Open(myDoc.ReferencingDocuments(1).FullDocumentName, False)
    Else
    oDoc = myDoc
    If oDoc.Dirty = True Then
        MessageBox.Show("Please save the parent document before running!")
        oDoc = Nothing
        Return
    End If
End If

Try 
        'Add the rule you want to run here
        Call iLogic.RunRule(oDoc, "TH Nozz 1 Update")
        Catch 
        MessageBox.Show("Unable to run the rule", "RunRule Error") 
        Finally 
        oDoc = Nothing
End Try

 

0 Likes