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: 

Adding rule to trigger programmatically doesn't work on untouched files

12 REPLIES 12
SOLVED
Reply
Message 1 of 13
meGVGMF
704 Views, 12 Replies

Adding rule to trigger programmatically doesn't work on untouched files

meGVGMF
Advocate
Advocate

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:

  1. Create external rule with the code below (and create another to be used as the event handler, called "Handler")
  2. Create new file
  3. Run the handler-adding rule in question
  4. Proc the event
  5. [Handler doesn't run]

And:

  1. Steps 1 through 3 above
  2. Begin to create a local rule, and when the editor opens, close it without saving
  3. Proc the event
  4. [Handler should run]

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

 

 

0 Likes

Adding rule to trigger programmatically doesn't work on untouched files

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:

  1. Create external rule with the code below (and create another to be used as the event handler, called "Handler")
  2. Create new file
  3. Run the handler-adding rule in question
  4. Proc the event
  5. [Handler doesn't run]

And:

  1. Steps 1 through 3 above
  2. Begin to create a local rule, and when the editor opens, close it without saving
  3. Proc the event
  4. [Handler should run]

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

 

 

Labels (6)
12 REPLIES 12
Message 2 of 13
WCrihfield
in reply to: meGVGMF

WCrihfield
Mentor
Mentor

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

EESignature

(Not an Autodesk Employee)

0 Likes

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

EESignature

(Not an Autodesk Employee)

Message 3 of 13
meGVGMF
in reply to: WCrihfield

meGVGMF
Advocate
Advocate

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.

0 Likes

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.

Message 4 of 13
meGVGMF
in reply to: WCrihfield

meGVGMF
Advocate
Advocate

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.

0 Likes

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.

Message 5 of 13
WCrihfield
in reply to: meGVGMF

WCrihfield
Mentor
Mentor

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

EESignature

(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

EESignature

(Not an Autodesk Employee)

Message 6 of 13
meGVGMF
in reply to: WCrihfield

meGVGMF
Advocate
Advocate
Yeah, I wonder... I wish I knew what was actually going on under the hood.

The property set is definitely being created. Is there maybe some kind of call that needs to be made to have it registered as existing, somewhere else?
0 Likes

Yeah, I wonder... I wish I knew what was actually going on under the hood.

The property set is definitely being created. Is there maybe some kind of call that needs to be made to have it registered as existing, somewhere else?
Message 7 of 13
meGVGMF
in reply to: WCrihfield

meGVGMF
Advocate
Advocate

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.

0 Likes

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.

Message 8 of 13
WCrihfield
in reply to: meGVGMF

WCrihfield
Mentor
Mentor

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

EESignature

(Not an Autodesk Employee)

0 Likes

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

EESignature

(Not an Autodesk Employee)

Message 9 of 13
WCrihfield
in reply to: meGVGMF

WCrihfield
Mentor
Mentor
Accepted solution

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

EESignature

(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

EESignature

(Not an Autodesk Employee)

Message 10 of 13
meGVGMF
in reply to: WCrihfield

meGVGMF
Advocate
Advocate
Awesome, thanks very much for working through this, I wasn't even sure where to start. My week's done as of 10 minutes ago, but I'll look into getting this up and running at the first opportunity next week.

Awesome, thanks very much for working through this, I wasn't even sure where to start. My week's done as of 10 minutes ago, but I'll look into getting this up and running at the first opportunity next week.
Message 11 of 13
WCrihfield
in reply to: meGVGMF

WCrihfield
Mentor
Mentor

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

EESignature

(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

EESignature

(Not an Autodesk Employee)

Message 12 of 13
meGVGMF
in reply to: WCrihfield

meGVGMF
Advocate
Advocate
Okay, as much as I can see how it's different, I still can't say that I understand what it's doing. That said, it works for my usecases, anyway. Thanks again!
0 Likes

Okay, as much as I can see how it's different, I still can't say that I understand what it's doing. That said, it works for my usecases, anyway. Thanks again!
Message 13 of 13
WCrihfield
in reply to: meGVGMF

WCrihfield
Mentor
Mentor

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

EESignature

(Not an Autodesk Employee)

0 Likes

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

EESignature

(Not an Autodesk Employee)

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

Post to forums  

Autodesk Design & Make Report