Hi@WCrihfield and @gcoombridge, thanks for the responses. I definitely agree it is probably undocumented for a reason. However, using iLogic to add these rules to triggers is a really useful functionality.
One issue that may be unique to my problem is that I am trying to add an external rule to a trigger as opposed to a local rule.
After a lot of trial and error I came up with a solution that is working for me so far. If I assign a local iLogic rule to a trigger with my code, it will make the external rule trigger work as well. Since most of my documents won't have an existing local rule, I just added some code to temporarily create a local rule and trigger. Then the code deletes it the temporary rule. So I never see the temporary rule or trigger and my external rule triggers as expected. My guess is adding the local rule sets whatever unknown attribute that is needed, but that is a very blind guess.
I am adding my code below in case it proves helpful for anyone else in the future. I have only done minimal testing on it so far and I am sure it is not as robust as it could be.
Dim oDoc As Document = ThisApplication.ActiveDocument
' 'file://' is the prefix added to the name of the iLogic rule for external rules
Dim sRuleName As String = "file://Set Weight"
Dim oAuto As IiLogicAutomation = iLogicVb.Automation
Dim oRule As iLogicRule
'Apparently there is no way to check if an external rule name is valid
'the only option is to try and run it to see if it works.
'The .GetRule method does not throw an exception even if the
'external rule name is not valid.
'So it is not a good test to see if the external rule exists.
'Ref: https://forums.autodesk.com/t5/inventor-customization/check-if-external-ilogic-rule-is-loaded/td-p/5223581
'See message 4 of 5.
Dim oEventsPropSet As Inventor.PropertySet
Dim sSetName As String = "iLogicEventsRules"
Dim sInternalName As String = "{2C540830-0723-455E-A8E2-891722EB4C3E}"
'Check to see if the document has an existing custom property set indicating
'event triggers have been used before or are active.
'Using the internal name to avoid checking for _ before iLogicEventsRules
Try
oEventsPropSet = oDoc.PropertySets.Item(sInternalName)
Catch
oEventsPropSet = oDoc.PropertySets.Add(sSetName, sInternalName)
End Try
Dim oProperty As Inventor.Property
Dim intPropId As Integer
'Add the desired rule to the Before Document Save event.
'Start at the low end of the property ID set and move up to find the next
'available property ID.
For intPropId = 700 To 799
Try
oProperty = oEventsPropSet.ItemByPropId(intPropId)
If oProperty.Value = sRuleName Then
MsgBox("This rule has already been added to that event trigger. Exiting.",vbOKOnly," ")
Exit Sub
End If
Catch
oProperty = oEventsPropSet.Add(sRuleName, "BeforeDocSave" & intPropId, intPropId)
Exit For
End Try
Next
'In some cases, if the document has never had a trigger set manually or a local trigger
'added with code, the external rule trigger will show up in the list, but it will not run.
'Adding a local trigger appears to fix this problem.
'The code below makes a blank temporary iLogic rule local to the document and sets a trigger for it.
'The trigger is then deleted along with the temporary rule.
Dim sTempRuleName As String = "TempRule"
Dim bRuleExists As Boolean = False
Dim sBlank As String
'Check to see if the document already has a local rule with the same name as the sTempRuleName
'If the rule exists, we will just use it, but will be sure not to delete the rule when done.
Try
oRule = oAuto.GetRule(oDoc, sTempRuleName)
'This next line was required because the GetRule function would never throw an exception even
'if the temp rule did not exist.
sBlank = oRule.Name
bRuleExists = True
Catch
oRule = oAuto.AddRule(oDoc, sTempRuleName, "")
End Try
'Adding the temporary rule trigger after the desired external rule trigger
'so that when the temporary trigger is deleted, the external rule trigger will have the
'lowest property ID. This is mostly just to keep things clean.
'For example, this avoids the situation where the "Set Weight" trigger
'is PropID 701 and no trigger with PropID 700 exists. It does not appear that the triggers
'are sorted by property ID. Rules fire in the order shown in the event triggers menu, so
'the system must use a different attribute to track which order to fire the rules in
Dim intTempPropId As Integer
For intTempPropId = 700 To 799
Try
oProperty = oEventsPropSet.ItemByPropId(intTempPropId)
If oProperty.Value = sTempRuleName Then
'If a trigger for the temporary rule happens to already exist, just exit the for loop.
'That existing trigger should make the external rule trigger work and we do not want to
'delete the existing trigger that was there for an unrelated reason.
Exit Sub
End If
Catch
oProperty = oEventsPropSet.Add(sTempRuleName, "BeforeDocSave" & intTempPropId, intTempPropId)
'Delete the temporary local rule trigger that was just created.
oEventsPropSet.ItemByPropId(intTempPropId).Delete
'If the temporary local rule did not exist before we started,
'delete the rule To clean up the Document.
If bRuleExists = False
oAuto.DeleteRule(oDoc, sTempRuleName)
End If
Exit For
End Try
Next
Another interesting thing I noticed is the property ID number does not affect the firing order of the rules. So I guess if you wanted multiple rules to fire in a specific order all rules for that trigger would need to be deleted and then added back in the order you wanted them to run. That is, if you wanted to create a specific firing order using iLogic instead of manually dragging them to rearrange. Or if you wanted to add a rule to a trigger that fires before already assigned rules.