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

(Not an Autodesk Employee)