Running a external rule instead of a regular rule

Running a external rule instead of a regular rule

NikelARH4K2
Contributor Contributor
1,013 Views
10 Replies
Message 1 of 11

Running a external rule instead of a regular rule

NikelARH4K2
Contributor
Contributor

I am trying to modify this to have it run a external rule on each part within assembly that has a specific rule in it. Anyone mind giving me a hand

Dim oDoc As AssemblyDocument = ThisDoc.Document
 
'define the ilogicAutomation
Dim iLogicAuto As Object 
iLogicAuto = iLogicVb.Automation 
 
Dim oRuleName As String = "Master_Parts_List" 
Dim oRule As Object 
 
For Each doc As Document In oDoc.AllReferencedDocuments
On Error Resume Next
oRule = iLogicAuto.GetRule(doc, oRuleName) 
'run the rule
iLogicAuto.RunRuleDirect(oRule) 
Next
0 Likes
1,014 Views
10 Replies
Replies (10)
Message 2 of 11

Curtis_Waguespack
Consultant
Consultant

Hi @NikelARH4K2 

 

I didn't test this, but I think this should do it

 

For Each doc As Document In ThisDoc.Document.AllReferencedDocuments
	iLogicVb.Automation.RunExternalRule(doc, "Master_Parts_List" )
Next

EESignature

Message 3 of 11

NikelARH4K2
Contributor
Contributor

its kind of of working, it does run the rule on each part if it has the rule Master_Parts_List on it but it populates errors when the part doesn't have the Master_Parts_List  on it. I thought "On Error Resume Next" could stop that

it also runs the external rule on the same assembly that the code is on, it should be only doing parts within the assembly

Dim oDoc As AssemblyDocument = ThisDoc.Document

'define the ilogicAutomation
Dim iLogicAuto As Object 
iLogicAuto = iLogicVb.Automation 

Dim oRuleName As String = "Master_Parts_List" 
Dim oRule As Object 

For Each doc As Document In oDoc.AllReferencedDocuments
	On Error Resume Next
	oRule = iLogicAuto.GetRule(doc, oRuleName) 
	'run the rule
	iLogicVb.Automation.RunExternalRule(doc, "Part_Insert_Master_Parts_List_Link" )
Next

 

0 Likes
Message 4 of 11

WCrihfield
Mentor
Mentor

Hi @NikelARH4K2.  Just a quick tip...the On Error Resume Next would not work in that situation, unless it simply could not find the external rule that it is supposed to run.  If the errors are being caused by the 'other' rule (the external rule), then that would not cause 'this' rule to encounter those errors.  The 'other' rule would need a way to avoid the errors that it might cause.

 

Also, if you posted the contents of that external rule, we may be able to take a look at it and help you fix it so it does not throw errors in those situations, or attempt to act upon the main assembly when ran remotely like this.  If it is trying to act upon the main assembly, then there likely needs to be one or more changes made to how you are specifying which document for that rule to be focusing its attention on.  For instance, you may need to change 'ThisApplication.ActiveDocument' phrases to 'ThisDoc.Document'.

 

Edit:  Also, that 'GetRule' method being used within the loop will not throw an error if it does not find that rule in that document.  There simply will not be a value assigned to the 'oRule' variable that time around.  However, since you are declaring the oRule variable outside of that loop, that variable may hold on to its previous value.  And...the automation object can be declared as 'IiLogicAutomation' type object, instead of just Object.  And the rule object can be declared as 'iLogicRule' type, instead of just Object.  They will offer Intellisense tips when their type is declared properly like that.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 5 of 11

Curtis_Waguespack
Consultant
Consultant

@NikelARH4K2 

 

I just did a quick test, and I think all you need is what I posted earlier, unless I'm still not understanding your goal.

 

Here's what I have:

  • An assembly with 2 parts
  • A rule called Rule0 in the assembly ( although this could be an external rule also)
    • this rule contains the following 3 lines:
For Each doc As Document In ThisDoc.Document.AllReferencedDocuments
	iLogicVb.Automation.RunExternalRule(doc, "Rule1" )
Next
  • An external rule called Rule1
    • this rule contains one line:  
msgbox(Thisdoc.FileName)

 

When Rule0 is run it steps through each document in the assembly and runs the external Rule1 on that document, which displays a message box with the file name of that document as shown below.

 

Curtis_Waguespack_1-1721930382596.png

 

 

 

EESignature

0 Likes
Message 6 of 11

AMN3161
Advocate
Advocate

The external rule just pull data from a note pad document and replaces the rule

Dim oRuleName As String = "Master_Parts_List"
Dim oTxtFileName As String = "C:\_VAULT_WORKSPACE\JOBS\FAB\Ilogic Rules\External Rules\Referenced Rules\Master Parts List Link (REF).txt"
Dim oRuleText As String = IO.File.ReadAllText(oTxtFileName)
Dim oDoc As Document = ThisApplication.ActiveEditDocument
Dim oRuleExists As Boolean = False
Dim iLogicAuto = iLogicVb.Automation
iLogicAuto.RulesEnabled = True
iLogicAuto.RulesOnEventsEnabled = True
Dim oRule As iLogicRule


Dim TargetRuleName As String = "Master_Parts_List"

Dim auto As IiLogicAutomation  = iLogicVb.Automation
Dim doc As Inventor.Document = ThisApplication.ActiveEditDocument

' Get the rules 
Dim ruleCol As System.Collections.IEnumerable = auto.Rules(doc)
Dim bRuleExists As Boolean = False	

' make sure the rules collection exists
If Not ruleCol Is Nothing Then
    ' string to hold the rule names
    Dim name As String = ""
    ' Go through each of the rules
    For Each rule As iLogicRule In ruleCol
        ' check the name of the rule
        If TargetRuleName.ToUpper = rule.Name.ToUpper Then
            bRuleExists = True
            Exit For
        End If
    Next
End If

If bRuleExists Then
	
	MessageBox.Show("The Master Parts List Rule exists in this file, i will replace it with the most current version", "Rule Exists")

	iLogicAuto.DeleteRule(oDoc, oRuleName)
	
	oRule = iLogicAuto.AddRule(oDoc, oRuleName, "")
	
	oRule.Text = oRuleText
	
	iLogicVb.DocumentUpdate
	
	iLogicVb.RunRule("Master_Parts_List")

	oDoc.Save

Else 

oRule = iLogicAuto.AddRule(oDoc, oRuleName, "")
	
	oRule.Text = oRuleText
	iLogicVb.DocumentUpdate
	
	iLogicVb.RunRule("Master_Parts_List")

	oDoc.Save

End If






 Basically i want the assembly rule to go through my parts and any part that has the Master_Parts_List rule to then run the external rule to replace it with new code

We are changing the way our BOM automation works and i want to update all the parts at once in one per assembly

0 Likes
Message 7 of 11

Curtis_Waguespack
Consultant
Consultant

Also, just to reiterate what @WCrihfield  said,  the external rule you are calling needs to use something like 

 

oDoc = ThisDoc.Document

vs 

oDoc = ThisApplication.ActiveDocument

 

ActiveDocument will be the document the original rule is run from ( the document that Inventor has active)

 

ThisDoc is always the document the rule is triggered from, so in my case Rule1 is being run on the part documents, so it returns the name of those documents, not the assembly document

EESignature

0 Likes
Message 8 of 11

Curtis_Waguespack
Consultant
Consultant

@AMN3161 

 

Just saw your last message.

 

I would just write your master parts list rule to work as an external rule to be run on the parts, rather than "injecting" new rule code into those part.

 

However, I had this example on hand for replacing the old rule code of an existing internal rule.

 

In my setup above, I placed this code in Rule1 and tested it and it worked well.

 

'this rule creates an internal rule in ThisDoc.Document
'	*note that the rule will run automaically when created'
'	 so in this example rule, it will throw an error 
'	 when external Rule111 is not found.	

Dim oDoc As Document = ThisDoc.Document

Dim oRuleName As String = "MyNewRule"
Dim RuleText As String

RuleText = "'Some comment here" & vbCrLf & _
"'Some other comment here" & vbCrLf & _
"   iLogicVb.RunExternalRule(" & Chr(34) & "Rule111" & Chr(34) & ")" & vbCrLf & _
"MessageBox.Show(" & Chr(34) & "Hello World" & Chr(34) & ", " & Chr(34) & "iLogic" & Chr(34) & ")"

'Delete the existing rule if needed
Try
	iLogicVb.Automation.DeleteRule(oDoc, oRuleName)
Catch
End Try

'add rule
oRule = iLogicVb.Automation.AddRule(oDoc, oRuleName, RuleText)

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

 

EESignature

0 Likes
Message 9 of 11

AMN3161
Advocate
Advocate

6 hours i was on this and the issue was this in my external rule

Dim oRuleName As String = "Master_Parts_List"
Dim oTxtFileName As String = "C:\_VAULT_WORKSPACE\JOBS\FAB\Ilogic Rules\External Rules\Referenced Rules\Master Parts List Link (REF).txt"
Dim oRuleText As String = IO.File.ReadAllText(oTxtFileName)
Dim oDoc As Document = ThisDoc.Document
Dim oRuleExists As Boolean = False

vs

Dim oRuleName As String = "Master_Parts_List"
Dim oTxtFileName As String = "C:\_VAULT_WORKSPACE\JOBS\FAB\Ilogic Rules\External Rules\Referenced Rules\Master Parts List Link (REF).txt"
Dim oRuleText As String = IO.File.ReadAllText(oTxtFileName)
Dim oDoc As Document = ThisApplication.ActiveEditDocument
Dim oRuleExists As Boolean = False

 One literally line of code, because the documet wasnt active...

0 Likes
Message 10 of 11

AMN3161
Advocate
Advocate

6 hours i was on this and the issue was this in my external rule

Dim oRuleName As String = "Master_Parts_List"
Dim oTxtFileName As String = "C:\_VAULT_WORKSPACE\JOBS\FAB\Ilogic Rules\External Rules\Referenced Rules\Master Parts List Link (REF).txt"
Dim oRuleText As String = IO.File.ReadAllText(oTxtFileName)
Dim oDoc As Document = ThisDoc.Document
Dim oRuleExists As Boolean = False

vs

Dim oRuleName As String = "Master_Parts_List"
Dim oTxtFileName As String = "C:\_VAULT_WORKSPACE\JOBS\FAB\Ilogic Rules\External Rules\Referenced Rules\Master Parts List Link (REF).txt"
Dim oRuleText As String = IO.File.ReadAllText(oTxtFileName)
Dim oDoc As Document = ThisApplication.ActiveEditDocument
Dim oRuleExists As Boolean = False

 One literally line of code, because the document wasnt active...

Message 11 of 11

WCrihfield
Mentor
Mentor

After you replace the document references, as mentioned a couple times above, there is one more tip that may help some also.  Any time a rule may get ran 'remotely' (such as by RunRule type methods, or by an event happening, while a different document may be 'active' than you had in mind), not only is it a good idea to check how you are referring to the document to focus on, for setting the value of your Document variable...it is also a good idea to check other things out too, that may be accessing a document, but without a pointer to a specific document.  In this case, I am talking about switching from using the 'iLogicVb.RunRule' method, to using the 'iLogicVb.Automation.RunRule' method, because it gives you additional control allowing you to specify which document the rule you want it to run should be focused on.  Just another suggestion.  Not sure it is a problem at this point though.  It is more important when running an external rule, than an internal one.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)