I'm not sure exactly what's happening.
I found a rule online that allows adding rules to files programmatically. It works when run locally, but not when run as an external rule--unless the local rules are touched by creating, and then cancelling, a new rule.
Steps to reproduce:
And:
What might be causing this?
Why does opening the local rule editor change anything?
Is the property set not being initialized properly?
Sub Main
Dim oDoc As Document = ThisDoc.Document
Dim ruleName As String = "file://Handler"
Dim eventType As String = "BeforeDocSave"
Dim oSet As PropertySet = Nothing
Dim internalName As String = "{2C540830-0723-455E-A8E2-891722EB4C3E}"
If Not oDoc.PropertySets.PropertySetExists(internalName, oSet) Then
oSet = oDoc.PropertySets.Add("_iLogicEventsRules", internalName)
Dim oAuto As IiLogicAutomation = iLogicVb.Automation
Dim oRule As iLogicRule = oAuto.AddRule(oDoc, "DeleteMe", "")
oSet.Add(oRule.Name, "BeforeDocSave700", 700)
oDoc.Update
oSet.Item("BeforeDocSave700").Delete
oAuto.DeleteRule(oDoc, "DeleteMe")
oDoc.Update
End If
'if it is an External rule, then add "file://" to start of rule name
Dim oProp As Inventor.Property = Nothing
For propId As Integer = 700 To 799
Try
oProp = oSet.ItemByPropId(propId)
If oProp.Value = ruleName Then
MsgBox("This rule has already been added to this event trigger. Exiting.", vbExclamation, "")
Exit Sub
End If
Catch
oProp = oSet.Add(ruleName, eventType & propId, propId)
Exit For
End Try
Next
oDoc.Update
End Sub
Solved! Go to Solution.
I'm not sure exactly what's happening.
I found a rule online that allows adding rules to files programmatically. It works when run locally, but not when run as an external rule--unless the local rules are touched by creating, and then cancelling, a new rule.
Steps to reproduce:
And:
What might be causing this?
Why does opening the local rule editor change anything?
Is the property set not being initialized properly?
Sub Main
Dim oDoc As Document = ThisDoc.Document
Dim ruleName As String = "file://Handler"
Dim eventType As String = "BeforeDocSave"
Dim oSet As PropertySet = Nothing
Dim internalName As String = "{2C540830-0723-455E-A8E2-891722EB4C3E}"
If Not oDoc.PropertySets.PropertySetExists(internalName, oSet) Then
oSet = oDoc.PropertySets.Add("_iLogicEventsRules", internalName)
Dim oAuto As IiLogicAutomation = iLogicVb.Automation
Dim oRule As iLogicRule = oAuto.AddRule(oDoc, "DeleteMe", "")
oSet.Add(oRule.Name, "BeforeDocSave700", 700)
oDoc.Update
oSet.Item("BeforeDocSave700").Delete
oAuto.DeleteRule(oDoc, "DeleteMe")
oDoc.Update
End If
'if it is an External rule, then add "file://" to start of rule name
Dim oProp As Inventor.Property = Nothing
For propId As Integer = 700 To 799
Try
oProp = oSet.ItemByPropId(propId)
If oProp.Value = ruleName Then
MsgBox("This rule has already been added to this event trigger. Exiting.", vbExclamation, "")
Exit Sub
End If
Catch
oProp = oSet.Add(ruleName, eventType & propId, propId)
Exit For
End Try
Next
oDoc.Update
End Sub
Solved! Go to Solution.
Solved by WCrihfield. Go to Solution.
Hi @meGVGMF. That code looks similar to what I posted in my contribution post (Link Here). I just followed your instructions and used the code you posted several times, each time using a different starter template to make the New document from, and all 3 different types of documents. Every test resulted in the trigger working the first time I clicked Save (and specified where to save it), every time. I just put a simple MsgBox in the 'Handler' rule, with a simple message, so I could tell that it ran. I'm still not sure why some folks have troubles with this process, and I don't. Maybe it is due to starting from a different set of source template files, I'm not sure. I'm guessing it has to do with the initialization process, but if so, we must still be missing something. Right now your code (and mine) are only running through the initialization process if the hidden PropertySet had to be created by this rule. Maybe in certain situations, even the pre-existing PropertySet may need to be 'initialized'. Maybe if the PropertySet already exists, but does not currently have any rules in it, it may need to be initialized again after opening the document? Just a thought, but it may be worth looking into, and wouldn't be that difficult to implement/include in the rule.
PS. Since I can not seem to replicate the problem on my end, I may have to rely on the research & reports of others, like yourself, to help work out the bugs in this process.
Wesley Crihfield
(Not an Autodesk Employee)
Hi @meGVGMF. That code looks similar to what I posted in my contribution post (Link Here). I just followed your instructions and used the code you posted several times, each time using a different starter template to make the New document from, and all 3 different types of documents. Every test resulted in the trigger working the first time I clicked Save (and specified where to save it), every time. I just put a simple MsgBox in the 'Handler' rule, with a simple message, so I could tell that it ran. I'm still not sure why some folks have troubles with this process, and I don't. Maybe it is due to starting from a different set of source template files, I'm not sure. I'm guessing it has to do with the initialization process, but if so, we must still be missing something. Right now your code (and mine) are only running through the initialization process if the hidden PropertySet had to be created by this rule. Maybe in certain situations, even the pre-existing PropertySet may need to be 'initialized'. Maybe if the PropertySet already exists, but does not currently have any rules in it, it may need to be initialized again after opening the document? Just a thought, but it may be worth looking into, and wouldn't be that difficult to implement/include in the rule.
PS. Since I can not seem to replicate the problem on my end, I may have to rely on the research & reports of others, like yourself, to help work out the bugs in this process.
Wesley Crihfield
(Not an Autodesk Employee)
Thanks for the response.
Just to be clear: My template has no local rules or any external rules configured. When I open the new file, I save it immediately to the file system. Then I run the external rule that assigns the handler. Trying to save after this doesn't activate it, until after interacting with the local rules editor.
Maybe in certain situations, even the pre-existing PropertySet may need to be 'initialized'.
Actually the interaction with the local rules editor solves the problem permanently, so the property set, once it's truly initialized (assuming it really is a problem with the initialization, although I can't see any other possibility), works exactly as expected, and our processes continue regularly and successfully adding and removing rules from the triggers.
Thanks for the response.
Just to be clear: My template has no local rules or any external rules configured. When I open the new file, I save it immediately to the file system. Then I run the external rule that assigns the handler. Trying to save after this doesn't activate it, until after interacting with the local rules editor.
Maybe in certain situations, even the pre-existing PropertySet may need to be 'initialized'.
Actually the interaction with the local rules editor solves the problem permanently, so the property set, once it's truly initialized (assuming it really is a problem with the initialization, although I can't see any other possibility), works exactly as expected, and our processes continue regularly and successfully adding and removing rules from the triggers.
Here is a file you could try testing with, generated according to our (I think pretty standard) template, at least to rule out that as the cause.
Here is a file you could try testing with, generated according to our (I think pretty standard) template, at least to rule out that as the cause.
Yep. That made the difference. The problem occurred just as you described when I used your part as a template to start the new document from. It wasn't happening that way with any of my existing template files. Maybe all of mine have been around too long, and might have had their Event Triggers set messed with at some point in their lineage.
Wesley Crihfield
(Not an Autodesk Employee)
Yep. That made the difference. The problem occurred just as you described when I used your part as a template to start the new document from. It wasn't happening that way with any of my existing template files. Maybe all of mine have been around too long, and might have had their Event Triggers set messed with at some point in their lineage.
Wesley Crihfield
(Not an Autodesk Employee)
For what it's worth, when the rule to assign the handler is called, the handler becomes visible in the event triggers dialogue, despite not reacting to the event.
For what it's worth, when the rule to assign the handler is called, the handler becomes visible in the event triggers dialogue, despite not reacting to the event.
Hi @meGVGMF. I think I finally figured it out. I put the 'initialization' process out into its own Sub routine, just to make it more modular during later testing, because I started trying it both before and after the main task of the rule. I even modified it to put a MsgBox into the temporary rule, then run that temporary rule before moving on to delete it, and the property it was put in. That did not seem to help. After I got it working, I started narrowing down things while keeping it working, and I believe that the 'initialization' step simply needs to happen 'after' adding your normal rule to the Event Triggers property set, before the triggering action will be enabled...when stuff is new like this. That is the combination/process that ended up working for me.
The 'Initialization' step may not need to be in its own Sub routine for this to work, but just done at the end of the main process, instead of before it. Another little detail I had to change, when doing the 'initialization' after the main process, was to change the Name & PropID of the temporary Property it was creating, because those were already being used by the main process, so it threw an error. I left a few lines in there that I commented out, so you should be able to just delete those if you want to.
Here is my rule code now:
Sub Main
Dim oDoc As Document = ThisDoc.Document
'if it is an External rule, then add "file://" to start of rule name
Dim ruleName As String = "file://Handler"
Dim eventType As String = "BeforeDocSave"
'Dim oNewlyCreated As Boolean = False
Dim oSet As PropertySet = Nothing
Dim oInternalName As String = "{2C540830-0723-455E-A8E2-891722EB4C3E}"
If Not oDoc.PropertySets.PropertySetExists(oInternalName, oSet) Then
oSet = oDoc.PropertySets.Add("_iLogicEventsRules", oInternalName)
oNewlyCreated = True
End If
' If oNewlyCreated Or oSet.Count = 0 Then
' InitializeEventTriggers(oDoc)
' End If
Dim oProp As Inventor.Property = Nothing
For propId As Integer = 700 To 799
Try
oProp = oSet.ItemByPropId(propId)
If oProp.Value = ruleName Then
MsgBox("This rule has already been added to this event trigger. Exiting.", vbExclamation, "")
Exit Sub
End If
Catch
oProp = oSet.Add(ruleName, eventType & propId, propId)
Exit For
End Try
Next
oDoc.Update
InitializeEventTriggers(oDoc)
oDoc.Update
End Sub
Sub InitializeEventTriggers(oDoc As Document)
Dim oSet As PropertySet = Nothing
Dim oInternalName As String = "{2C540830-0723-455E-A8E2-891722EB4C3E}"
If Not oDoc.PropertySets.PropertySetExists(oInternalName, oSet) Then
oSet = oDoc.PropertySets.Add("_iLogicEventsRules", oInternalName)
End If
Dim oAuto As IiLogicAutomation = iLogicVb.Automation
Dim oRule As iLogicRule = oAuto.AddRule(oDoc, "DeleteMe", "")
'oRule.Text = "MsgBox(" & Chr(34) & "DeleteMe Rule Just Ran." & Chr(34) & ",," & Chr(34) & Chr(34) & ")"
oTempProp = oSet.Add(oRule.Name, "BeforeDocSave799", 799)
'oAuto.RunRuleDirect(oRule)
oDoc.Update
oTempProp.Delete
oAuto.DeleteRule(oDoc, "DeleteMe")
oDoc.Update
End Sub
Woohoo! 😀
Wesley Crihfield
(Not an Autodesk Employee)
Hi @meGVGMF. I think I finally figured it out. I put the 'initialization' process out into its own Sub routine, just to make it more modular during later testing, because I started trying it both before and after the main task of the rule. I even modified it to put a MsgBox into the temporary rule, then run that temporary rule before moving on to delete it, and the property it was put in. That did not seem to help. After I got it working, I started narrowing down things while keeping it working, and I believe that the 'initialization' step simply needs to happen 'after' adding your normal rule to the Event Triggers property set, before the triggering action will be enabled...when stuff is new like this. That is the combination/process that ended up working for me.
The 'Initialization' step may not need to be in its own Sub routine for this to work, but just done at the end of the main process, instead of before it. Another little detail I had to change, when doing the 'initialization' after the main process, was to change the Name & PropID of the temporary Property it was creating, because those were already being used by the main process, so it threw an error. I left a few lines in there that I commented out, so you should be able to just delete those if you want to.
Here is my rule code now:
Sub Main
Dim oDoc As Document = ThisDoc.Document
'if it is an External rule, then add "file://" to start of rule name
Dim ruleName As String = "file://Handler"
Dim eventType As String = "BeforeDocSave"
'Dim oNewlyCreated As Boolean = False
Dim oSet As PropertySet = Nothing
Dim oInternalName As String = "{2C540830-0723-455E-A8E2-891722EB4C3E}"
If Not oDoc.PropertySets.PropertySetExists(oInternalName, oSet) Then
oSet = oDoc.PropertySets.Add("_iLogicEventsRules", oInternalName)
oNewlyCreated = True
End If
' If oNewlyCreated Or oSet.Count = 0 Then
' InitializeEventTriggers(oDoc)
' End If
Dim oProp As Inventor.Property = Nothing
For propId As Integer = 700 To 799
Try
oProp = oSet.ItemByPropId(propId)
If oProp.Value = ruleName Then
MsgBox("This rule has already been added to this event trigger. Exiting.", vbExclamation, "")
Exit Sub
End If
Catch
oProp = oSet.Add(ruleName, eventType & propId, propId)
Exit For
End Try
Next
oDoc.Update
InitializeEventTriggers(oDoc)
oDoc.Update
End Sub
Sub InitializeEventTriggers(oDoc As Document)
Dim oSet As PropertySet = Nothing
Dim oInternalName As String = "{2C540830-0723-455E-A8E2-891722EB4C3E}"
If Not oDoc.PropertySets.PropertySetExists(oInternalName, oSet) Then
oSet = oDoc.PropertySets.Add("_iLogicEventsRules", oInternalName)
End If
Dim oAuto As IiLogicAutomation = iLogicVb.Automation
Dim oRule As iLogicRule = oAuto.AddRule(oDoc, "DeleteMe", "")
'oRule.Text = "MsgBox(" & Chr(34) & "DeleteMe Rule Just Ran." & Chr(34) & ",," & Chr(34) & Chr(34) & ")"
oTempProp = oSet.Add(oRule.Name, "BeforeDocSave799", 799)
'oAuto.RunRuleDirect(oRule)
oDoc.Update
oTempProp.Delete
oAuto.DeleteRule(oDoc, "DeleteMe")
oDoc.Update
End Sub
Woohoo! 😀
Wesley Crihfield
(Not an Autodesk Employee)
After more testing and elimination cycles, I got rid of a few more unnecessary document update calls, because those can be time consuming when working with existing documents that may already have a lot of stuff in them. Deleted some of the other unnecessary stuff, too. Then developed a really nice little bit of code near the start, that checks within the 'target' document to see if the rule we are about to add to the 'triggers' is 'local/internal' to that document, and if not, it automatically adds the needed 'prefix' to the beginning of the rule's name. 😊 I had another routine I had made months ago for that purpose, but even that wasn't quite this simplistic, plus it was a separate routine that was being called, which isn't always ideal, especially if it just needs to be ran once. Also, instead of hard-coded values, we could also use various other routines for supplying the stuff that may change from one run to the next, like rule name, event type, PropID range, to make this process more dynamic. The sky is the limit.
I attached my revised & refined code to this post as a Text file this time, to keep clutter down.
Wesley Crihfield
(Not an Autodesk Employee)
After more testing and elimination cycles, I got rid of a few more unnecessary document update calls, because those can be time consuming when working with existing documents that may already have a lot of stuff in them. Deleted some of the other unnecessary stuff, too. Then developed a really nice little bit of code near the start, that checks within the 'target' document to see if the rule we are about to add to the 'triggers' is 'local/internal' to that document, and if not, it automatically adds the needed 'prefix' to the beginning of the rule's name. 😊 I had another routine I had made months ago for that purpose, but even that wasn't quite this simplistic, plus it was a separate routine that was being called, which isn't always ideal, especially if it just needs to be ran once. Also, instead of hard-coded values, we could also use various other routines for supplying the stuff that may change from one run to the next, like rule name, event type, PropID range, to make this process more dynamic. The sky is the limit.
I attached my revised & refined code to this post as a Text file this time, to keep clutter down.
Wesley Crihfield
(Not an Autodesk Employee)
No problem. Thank you too, for providing the 'clean' part I needed to experience the issue myself, and some good step by step instructions on how to reproduce it. I have been involved in several other forum discussions about this type of issue over the last few years, but haven't been able to nail this little bug down before now. I'm glad we were finally able to figure it out. Now I will have to go back and revise my contribution posts too, so that others can find this version which fixes that pesky initialization issue. 👍
Wesley Crihfield
(Not an Autodesk Employee)
No problem. Thank you too, for providing the 'clean' part I needed to experience the issue myself, and some good step by step instructions on how to reproduce it. I have been involved in several other forum discussions about this type of issue over the last few years, but haven't been able to nail this little bug down before now. I'm glad we were finally able to figure it out. Now I will have to go back and revise my contribution posts too, so that others can find this version which fixes that pesky initialization issue. 👍
Wesley Crihfield
(Not an Autodesk Employee)
You are welcome.
I actually just had another user contact me through a private message, saying that he was trying to use the 'Part Geometry Change' event (within the Event Triggers), but it is acting the same way as yours initially did (doesn't immediately trigger, until manual rule editor interaction). And after I directed him to this post, he said it now works for the 'Before Save Document' event, but not for the 'Part Geometry Change' event yet, so I may still have more research ahead for this process, but I haven't had time to look into it yet myself. The way it was described, it sounds similar to this 'Initialization' problem, but if so, I may have to edit it further. Maybe, if I leave it as a reference-able Sub routine, I will have to add a few more 'input' variables to its definition line, to customize it to the specific event that is being worked with at the time. I don't know yet without further research & testing.
Wesley Crihfield
(Not an Autodesk Employee)
You are welcome.
I actually just had another user contact me through a private message, saying that he was trying to use the 'Part Geometry Change' event (within the Event Triggers), but it is acting the same way as yours initially did (doesn't immediately trigger, until manual rule editor interaction). And after I directed him to this post, he said it now works for the 'Before Save Document' event, but not for the 'Part Geometry Change' event yet, so I may still have more research ahead for this process, but I haven't had time to look into it yet myself. The way it was described, it sounds similar to this 'Initialization' problem, but if so, I may have to edit it further. Maybe, if I leave it as a reference-able Sub routine, I will have to add a few more 'input' variables to its definition line, to customize it to the specific event that is being worked with at the time. I don't know yet without further research & testing.
Wesley Crihfield
(Not an Autodesk Employee)
Can't find what you're looking for? Ask the community or share your knowledge.