Run rule after component visibility change

Run rule after component visibility change

mat_hijs
Collaborator Collaborator
778 Views
8 Replies
Message 1 of 9

Run rule after component visibility change

mat_hijs
Collaborator
Collaborator

I'm working on a configurator and to make sure the BOM reflects the configured product correctly at all times I've written a rule that checks the visibility of every component and if it's invisible sets the BOM structure override to reference and if it's visible sets the BOM structure override to default. This works, but it doesn't run automatically after a components visibility is changed. I could add a line to every other rule that runs this rule, but I'm wondering if it's somehow possible to make it automatically run after a components visibility is changed.

 

Here's my rule:

Dim oAsmDoc As AssemblyDocument = ThisDoc.Document
Dim oAsmCompDef As AssemblyComponentDefinition = oAsmDoc.ComponentDefinition
Dim oOcc As ComponentOccurrence

'Checks visibility of each component and changes the BOM Structure overrides accordingly	
For Each oOcc In oAsmCompDef.Occurrences
    
        If oOcc.Visible = True Then
		oOcc.BOMStructure = BOMStructureEnum.kDefaultBOMStructure
		Else
		oOcc.BOMStructure = BOMStructureEnum.kReferenceBOMStructure
	End If
	
Next

0 Likes
Accepted solutions (3)
779 Views
8 Replies
Replies (8)
Message 2 of 9

WCrihfield
Mentor
Mentor
Accepted solution

The Event Triggers dialog has an event trigger for "Component Suppression Change", but not for component visibility change.  You will likely have to create your own custom event handler code to suit your needs.  I believe the one best suited for your need would be the OnOccurrenceChange event under the AssemblyEvents object.  I don't know if you are familiar with creating a custom event handler, so here is a link to one of my contribution posts that may help you create it and get things set-up correctly.

 

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

bradeneuropeArthur
Mentor
Mentor
Accepted solution
Sub main
Dim AssemblyEvents As Inventor.AssemblyEvents
AssemblyEvents = ThisApplication.AssemblyEvents

  AddHandler  AssemblyEvents.OnOccurrenceChange  ,AddressOf AssemblyEvents_onOccurrenceChange 
End Sub
 
	 
  'Sub AssemblyEvents_onOccurrenceChange ( DocumentObject As Inventor.AssemblyDocument, Occurrence As ComponentOccurrence, BeforeOrAfter As EventTimingEnum, Context As NameValueMap, HandlingCode As HandlingCodeEnum )
	
'End Sub

Sub AssemblyEvents_onOccurrenceChange
	MsgBox("d")
End Sub

Regards,

Arthur Knoors

Autodesk Affiliations & Links:
blue LinkedIn LogoSquare Youtube Logo Isolated on White Background


Autodesk Software:Inventor Professional 2025 | Vault Professional 2024 | Autocad Mechanical 2024
Programming Skills:Vba | Vb.net (Add ins Vault / Inventor, Applications) | I-logic
Programming Examples:
Drawing List!|
Toggle Drawing Sheet!|
Workplane Resize!|
Drawing View Locker!|
Multi Sheet to Mono Sheet!|
Drawing Weld Symbols!|
Drawing View Label Align!|
Open From Balloon!|
Model State Lock!
Posts and Ideas:
My Ideas|
Dimension Component!|
Partlist Export!|
Derive I-properties!|
Vault Prompts Via API!|
Vault Handbook/Manual!|
Drawing Toggle Sheets!|
Vault Defer Update!

! For administrative reasons, please mark a "Solution as solved" when the issue is solved !


 


EESignature

0 Likes
Message 4 of 9

mat_hijs
Collaborator
Collaborator

What I've got right now is this:

 

Sub Main
	
	Dim oAsmEvents As AssemblyEvents = ThisApplication.AssemblyEvents
	AddHandler oAsmEvents.onOccurrenceChange, AddressOf AssemblyEvents_onOccurrenceChange
	
End Sub

Public Sub AssemblyEvents_onOccurrenceChange()
	
	MsgBox("Test1",,"Test1")
	'I'm guessing this is where I should either fire my original rule or paste the contents of that rule??
	
	Dim oAsmEvents As AssemblyEvents = ThisApplication.AssemblyEvents
	RemoveHandler oAsmEvents.onOccurrenceChange, AddressOf AssemblyEvents_onOccurrenceChange
	MsgBox("Removed 'onOccurrenceChange' Event handler.", , "Remove event handler")
	
End Sub 

If I copy and paste this code in a rule and don't run it manually, nothing happens when an occurrence is changed.

If I run the rule manually, and I change an occurrence, the message boxes show twice.

If I run the rule manually again, and I change an occurrence, I get a bunch of message boxes.

It seems to me that I need to run the rule to create the event handler, but as the event handler makes the rule run again, it creates the event handler again, meaning there would be 2 of them, and only one of them gets deleted at the end of the rule.

How can I fix this so everything runs only once? I don't want to have to manually run the rule before the event handler will work.

0 Likes
Message 5 of 9

bradeneuropeArthur
Mentor
Mentor

Than you need to create an add in for it and not using I-logic.

I could help you with it if you want!

Regards,

Regards,

Arthur Knoors

Autodesk Affiliations & Links:
blue LinkedIn LogoSquare Youtube Logo Isolated on White Background


Autodesk Software:Inventor Professional 2025 | Vault Professional 2024 | Autocad Mechanical 2024
Programming Skills:Vba | Vb.net (Add ins Vault / Inventor, Applications) | I-logic
Programming Examples:
Drawing List!|
Toggle Drawing Sheet!|
Workplane Resize!|
Drawing View Locker!|
Multi Sheet to Mono Sheet!|
Drawing Weld Symbols!|
Drawing View Label Align!|
Open From Balloon!|
Model State Lock!
Posts and Ideas:
My Ideas|
Dimension Component!|
Partlist Export!|
Derive I-properties!|
Vault Prompts Via API!|
Vault Handbook/Manual!|
Drawing Toggle Sheets!|
Vault Defer Update!

! For administrative reasons, please mark a "Solution as solved" when the issue is solved !


 


EESignature

0 Likes
Message 6 of 9

mat_hijs
Collaborator
Collaborator

For flexibility reasons (I want my colleagues to be able to override rules if needed for example) I'll just make this rule run after every other rule. I'm not far enough in this programming thing to create add-ins, let alone explain to others how to use and edit them. I'll mark this post as solved though, because technically the solutions given work.

Thanks!

Message 7 of 9

WCrihfield
Mentor
Mentor
Accepted solution

It is still possible to use a rule to do this, and not have to re-run the rule each time you want to use it, you just need to set a few things up differently.  First of all, you're not checking what reason the event was fired.  There are several things that can trigger this event to be fired, but you have to check the Context NameValueMap for certain entries (name/value pairs of data) for one with the name "Visible", then if you want, you can get its value.  But the presence of that name/value pair means the event was fired because of a component visibility state change.  Now it won't show that message (or run your other rule) as many times.  Next, your code is set-up to create the event handler each time you run the rule, without checking if it is already active.  Given, this generally isn't possible, but we can use a SharedVariable (temporarily stored in Inventor's session memory) (or another similar tool) to record when we create and/or remove the event handler, that way we're not creating multiple.  Next your code is attempting to remove the event handler each time it is triggered, so it can't just continue to work in the background multiple times before being removed.  We can also use the SharedVariable trick to help with this situation, but it's usually best to have some other event set-up so that when that other event happens, it will remove the event handler.  In several of my assembly related event handlers, I set them up so that when that assembly document closes, it will trigger the part of the rule (separate Sub) to run, which removes all involved event handlers.  There are other ways to do this other than listening for document close events, but this is just a fairly simple one that I've used multiple times before.

Try this:

Sub Main
	Dim oAsmEvents As AssemblyEvents = ThisApplication.AssemblyEvents
	'only create the event handler, if it isn't already active, so there will only be one at a time
	If Not SharedVariable.Exists("OnOccurrenceChangeActive") Then
		AddHandler oAsmEvents.OnOccurrenceChange, AddressOf oAsmEvents_OnOccurrenceChange
		'create the SharedVariable to indicate that our custom event handler is now active
		SharedVariable("OnOccurrenceChangeActive") = True
	End If
	Dim oAppEvents As ApplicationEvents = ThisApplication.ApplicationEvents
	If Not SharedVariable.Exists("OnCloseDocumentActive") Then
		AddHandler oAppEvents.OnCloseDocument, AddressOf oAppEvents_OnCloseDocument
		SharedVariable("OnCloseDocumentActive") = True
	End If
End Sub

Public Sub oAsmEvents_OnOccurrenceChange(oADoc As AssemblyDocument, oOcc As ComponentOccurrence, oTiming As EventTimingEnum, oContext As NameValueMap, ByRef HandlingCode As HandlingCodeEnum)
	Dim oVisStateAfter As Boolean
	Try
		oVisStateAfter = oContext.Value("Visible")
	Catch
		'it wasn't fired due to changing the Visible state of an occurrence
		'so do nothing, and exit the sub
		Exit Sub
	End Try
	MsgBox("Changed Visibility of Occurrence named '" & oOcc.Name & "' to " & oVisStateAfter & ".", , "OnOccurrenceChange")
	'Yes, you can either paste your code here, or run the other rule from here.

	'Only remove the event handler here, if you only want to use it once per run of the rule
	'otherwise use a different event or check system to determine when to remove the event handler
	'I usually use the event of me closing the assembly document.
End Sub

Public Sub oAppEvents_OnCloseDocument(oDoc As Inventor._Document, oFullName As String, oTiming As EventTimingEnum, oContext As NameValueMap, ByRef HandlingCode As HandlingCodeEnum)
	'only remove the handlers when the 'local' assembly document closes
	If oDoc Is ThisDoc.Document Then
		If SharedVariable.Exists("OnOccurrenceChangeActive") Then
			Dim oAsmEvents As AssemblyEvents = ThisApplication.AssemblyEvents
			RemoveHandler oAsmEvents.OnOccurrenceChange, AddressOf oAsmEvents_OnOccurrenceChange
			SharedVariable.Remove("OnOccurrenceChangeActive")
			MsgBox("Removed 'OnOccurrenceChange' Event handler.", , "Remove event handler")
		End If

		If SharedVariable.Exists("OnCloseDocumentActive") Then
			Dim oAppEvents As ApplicationEvents = ThisApplication.ApplicationEvents
			RemoveHandler oAppEvents.OnCloseDocument, AddressOf oAppEvents_OnCloseDocument
			SharedVariable.Remove("OnCloseDocumentActive")
			MsgBox("Removed 'OnCloseDocument' Event handler.", , "Remove event handler")
		End If
	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)

Message 8 of 9

mat_hijs
Collaborator
Collaborator

I really appreciate you taking the time to try and make everything as clear and simple as possible, but this is still a bit above my level. I will be coming back to this post when I'm a bit further in my journey to see if I can make sense of it then. For now I'll be using the not so efficient way of running my rule after every other rule, which should have the same effect because it won't be allowed to manually change visibility of components anyway.

Thanks again, and sorry for wasting your time 😉.

Message 9 of 9

bradeneuropeArthur
Mentor
Mentor

Everyone is free to ask, regardless the level the person is on!!

 

@mat_hijs 

If you need support further in either add-ins; VBA of I-logic I am willing to train/guide you....

Regards,

Arthur Knoors

Autodesk Affiliations & Links:
blue LinkedIn LogoSquare Youtube Logo Isolated on White Background


Autodesk Software:Inventor Professional 2025 | Vault Professional 2024 | Autocad Mechanical 2024
Programming Skills:Vba | Vb.net (Add ins Vault / Inventor, Applications) | I-logic
Programming Examples:
Drawing List!|
Toggle Drawing Sheet!|
Workplane Resize!|
Drawing View Locker!|
Multi Sheet to Mono Sheet!|
Drawing Weld Symbols!|
Drawing View Label Align!|
Open From Balloon!|
Model State Lock!
Posts and Ideas:
My Ideas|
Dimension Component!|
Partlist Export!|
Derive I-properties!|
Vault Prompts Via API!|
Vault Handbook/Manual!|
Drawing Toggle Sheets!|
Vault Defer Update!

! For administrative reasons, please mark a "Solution as solved" when the issue is solved !


 


EESignature

0 Likes