trigger a rule after "Place component"

trigger a rule after "Place component"

Cosmin_V
Advocate Advocate
1,535 Views
8 Replies
Message 1 of 9

trigger a rule after "Place component"

Cosmin_V
Advocate
Advocate

Hello everyone,


I have an asssembly where is a rule, which I want to run when a component is added to adjust the assembly according to that component.

But I can't find a solution for this rule to be trigger after I place the component, 

Does anyone have any idea?

 

Many thanks!!!

0 Likes
Accepted solutions (1)
1,536 Views
8 Replies
Replies (8)
Message 2 of 9

WCrihfield
Mentor
Mentor

The only somewhat related built-in event triggers within the Event Triggers dialog are the ones named "Component Suppression Change" & "iPart or iAssembly Change Component", but neither of those would likely work for that situation.  You would need to create your own custom event handler code to handle when a component gets added to an assembly.  There are a few options available, depending on your exact needs listed under the AssemblyEvents object.  The one called "OnNewOccurrence" sounds like the best match to me.  I have a contribution post you may be interested in that may help you develop your own custom event handler code, and help you understand the terms involved, and helpful insights.

Here is a fairly simple bit of starter code, if you choose to go the iLogic rule route, instead of an Inventor Add-in.

Sub Main
	If ThisApplication.ActiveDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
		MsgBox("An Assembly Document must be active for this rule to work. Exiting.",vbOKOnly+vbCritical, "WRONG DOCUMENT TYPE")
		Exit Sub
	End If
	oADoc = ThisApplication.ActiveDocument
	Dim oAsmEvents As AssemblyEvents = ThisApplication.AssemblyEvents
	AddHandler oAsmEvents.OnNewOccurrence, AddressOf oAsmEvents_OnNewOccurrence

	Dim oAppEvents As ApplicationEvents = ThisApplication.ApplicationEvents
	AddHandler oAppEvents.OnCloseDocument, AddressOf ApplicationEvents_OnCloseDocument
End Sub

'if this is used as a 'local' rule, and you only want it to effect the 'local' assembly
'set the value of this variable with 'ThisDoc.Document' or 'ThisAssembly.Document'
'then remove the line within Sub Main that sets its value
Public oADoc As AssemblyDocument

Public Sub oAsmEvents_OnNewOccurrence(oAsmDoc As AssemblyDocument, oOcc As ComponentOccurrence, oTiming As Inventor.EventTimingEnum, oContext As Inventor.NameValueMap, ByRef HandlingCode As Inventor.HandlingCodeEnum)
	'<<<< RUN YOUR RULE FROM WITHIN THIS SUB >>>>
	'iLogicVb.RunRule("RuleName")
	'iLogicVb.RunExternalRule()
	'iLogicVb.Automation.RunRule()
	'iLogicVb.Automation.RunExternalRule()
	'If oAsmDoc Is oADoc Then
		
	'End If
End Sub

Public Sub ApplicationEvents_OnCloseDocument(oDoc As Inventor._Document, oFullName As String, oTiming As Inventor.EventTimingEnum, oContext As Inventor.NameValueMap, ByRef HandlingCode As Inventor.HandlingCodeEnum)
	If oDoc Is oADoc Then
		Dim oAsmEvents As AssemblyEvents = ThisApplication.AssemblyEvents
		Dim oAppEvents As ApplicationEvents = ThisApplication.ApplicationEvents
		RemoveHandler oAsmEvents.OnNewOccurrence, AddressOf oAsmEvents_OnNewOccurrence
		MsgBox("Removed 'OnNewEditObject' Event handler.",,"")
		RemoveHandler oAppEvents.OnCloseDocument, AddressOf ApplicationEvents_OnCloseDocument
		MsgBox("Removed 'OnCloseDocument' Event handler.",,"")
	End If
End Sub

 

If this solved your problem, or answered your question, please click ACCEPT SOLUTION.
Or, if this helped you, please click (LIKE or KUDOS) 👍.

If you want and have time, I would appreciate your Vote(s) for My IDEAS 💡or you can Explore My CONTRIBUTIONS

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 9

Cosmin_V
Advocate
Advocate

thanks @WCrihfield 

 

It works fine, but I don't understand what I have to change if i want to us it as a local rule.

 

Many thanks!!!

0 Likes
Message 4 of 9

WCrihfield
Mentor
Mentor
Accepted solution

Basically it has to do with how you specify the target document that you want the code to effect.  In a local rule, you have more control for making sure your target document is the 'local' document.  Here is a link to one of my contribution posts which I recommend you read that goes into the subject in much more detail.  The types of event triggers being created by the code I posted above will effect all documents that you may deal with while it is running/active.  The event handler will remain active in the background until you either close Inventor, or , as was my intention, until you close that original assembly document that it was created for.  If you are working with multiple other documents while your main/original assembly is open, those events the code is 'listening for' may happen within those other documents, which would trigger the code to run, unless the code is correctly checking to make sure that the document that the event happened in was your local original assembly.

I updated my code snippet for use as a 'local' rule.  The main Sub doesn't need to know anything about the 'active' or 'local' document at the time, because it is only creating the event handlers.  Those other two Sub's both check to make sure they are only acting upon the 'local' assembly document, using the ThisDoc.Document term.

Sub Main
	Dim oAsmEvents As AssemblyEvents = ThisApplication.AssemblyEvents
	AddHandler oAsmEvents.OnNewOccurrence, AddressOf oAsmEvents_OnNewOccurrence

	Dim oAppEvents As ApplicationEvents = ThisApplication.ApplicationEvents
	AddHandler oAppEvents.OnCloseDocument, AddressOf ApplicationEvents_OnCloseDocument
End Sub

Public Sub oAsmEvents_OnNewOccurrence(oAsmDoc As AssemblyDocument, oOcc As ComponentOccurrence, oTiming As Inventor.EventTimingEnum, oContext As Inventor.NameValueMap, ByRef HandlingCode As Inventor.HandlingCodeEnum)
	'to make sure the assembly document that the event happened in is the 'local' assembly
	'otherwise don't do anything (don't work for other assembly documents that may also be open)
	'ThisDoc.Document will always refer to the 'local' document, when used in a 'local' rule
	If oAsmDoc Is ThisDoc.Document Then
		'<<<< RUN YOUR RULE FROM WITHIN THIS SUB >>>>
		'iLogicVb.RunRule("RuleName")
		'iLogicVb.RunExternalRule()
		'iLogicVb.Automation.RunRule()
		'iLogicVb.Automation.RunExternalRule()
		'MsgBox("Ran your Rule successfully.",,"")
	End If
End Sub

Public Sub ApplicationEvents_OnCloseDocument(oDoc As Inventor._Document, oFullName As String, oTiming As Inventor.EventTimingEnum, oContext As Inventor.NameValueMap, ByRef HandlingCode As Inventor.HandlingCodeEnum)
	If oDoc Is ThisDoc.Document Then
		Dim oAsmEvents As AssemblyEvents = ThisApplication.AssemblyEvents
		Dim oAppEvents As ApplicationEvents = ThisApplication.ApplicationEvents
		RemoveHandler oAsmEvents.OnNewOccurrence, AddressOf oAsmEvents_OnNewOccurrence
		MsgBox("Removed 'OnNewEditObject' Event handler.",,"")
		RemoveHandler oAppEvents.OnCloseDocument, AddressOf ApplicationEvents_OnCloseDocument
		MsgBox("Removed 'OnCloseDocument' Event handler.",,"")
	End If
End Sub

 

If this solved your problem, or answered your question, please click ACCEPT SOLUTION.
Or, if this helped you, please click (LIKE or KUDOS) 👍.

If you want and have time, I would appreciate your Vote(s) for My IDEAS 💡or you can Explore My CONTRIBUTIONS

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 5 of 9

munderwood4GRE6
Enthusiast
Enthusiast

I've tried running this code as an internal rule but for some reason the message box shows twice when I place a component in. Am I missing something?

0 Likes
Message 6 of 9

s_bulsMCS3T
Observer
Observer

When adding a single component to an assembly, the associated event is triggered multiple times.

Is there a recommended way to ensure the event executes only once per insertion?

0 Likes
Message 7 of 9

jnowel
Collaborator
Collaborator

from my understanding the AssemblyEvent triggers Before and After component placement.

you can just add something like this

	If oAsmDoc Is ThisDoc.Document Then
		If oOcc Is Nothing Then 'this triggers BEFORE placement
			Logger.Info("Preparing to add component")
		Else  'this triggers AFTER placement
			Logger.Info("Added " & oOcc.Name)
		End If
	End If

 

0 Likes
Message 8 of 9

WCrihfield
Mentor
Mentor

Hi guys.  There is a variable built right into most of Inventor's API Event handler methods named "BeforeOrAfter", which represents a variation of the EventTimingEnum.  The code inside that method can check the value of that variable to see which 'timing' state (Before, After, or Abort) it is currently in.  When its value is kBefore (or 4097), that means the event is reacting just 'before' the actual action has taken place.  When it is 'kAfter' (or 4098), that means the action has just happened.  When it is 'kAbort' (or 4099), that means the action was aborted before it could actually happen.  Not all types of Events can be aborted, but that can sometimes be done through another of those variables built into the event handler method named "HandlingCode", which represents a variation of the HandlingCodeEnum.  That is a variable that we can change the value of, usually near the end of our code within that method, to dictate how this event reaction should be 'handled'.  Its 'kEventNotHandled' (or 514) value is the 'default', and means Inventor should continue to 'handle' this event as it usually would.  Its 'kEventHandled' (or 513) value means 'we are handling it' in a custom way, instead of the way Inventor would have normally handled it.  Its 'kEventCanceled' (or 515) value means we are 'cancelling' this action before it takes place.  We can only 'cancel' (abort) an action during its 'kBefore' timing, because that is the only 'timing state' where the action has not already taken place.  Below is a Link to the 2026 Inventor API online help documentation for the OnNewOccurrence Event, and the OnCloseDocument (application level) Event, and the OnClose (document level) Event.  If you like the design idea to eliminate the OnNewOccurrence event handler when a specific assembly closes, then I would actually recommend using the document level OnClose Event instead of the application level OnCloseDocument Event, because it is simpler and safer to use, limiting its attention to just that one document, not all documents, and limiting its lifespan to the lifespan of that one document.  Document level events can be accessed through the Document object itself, which makes it easy to follow that logic (Document.DocumentEvents).  Also, when using a document level event, there is no question about which document the event is focused on, so no need to check or compare documents.  I use that event in several places myself, because of how simple, safe, and effective it is.

AssemblyEvents.OnNewOccurrence 

ApplicationEvents.OnCloseDocument 

DocumentEvents.OnClose 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 9 of 9

jnowel
Collaborator
Collaborator

@WCrihfield,
Thanks. How you explain things really makes me understand more as i'm still a new with the eventhandlers
In the above example regarding OnNewOccurrence, instead of how I inferred the EventTiming, I could have just used directly the oTiming value.

My brain jumped straight to -> there is no oOcc yet at "Before" and will just be created at "After".