Hi everyone,
I am working on code that will only run when the value of a parameter changes. The code is about changing the direction of a cross - section in an .IDW drawing.
The variable is String type, which has two values, 'Value1' and 'Value2'. I take the value of the variable and in the If loop I give a condition to make the code execute only when the value of the variable changes. But unfortunately the code executes every time, regardless of whether the variable has changed value from "Value1" to "Value2" or is still one value.
What am I doing wrong here? Have I misdefined the condition at any point?
Sub Main()
Dim invApp As Inventor.Application
Dim modelingEvents As ModelingEvents
invApp = System.Runtime.InteropServices.Marshal.GetActiveObject("Inventor.Application")
modelingEvents = invApp.ModelingEvents
AddHandler modelingEvents.OnParameterChange, AddressOf modelingEvents_ParameterChange
iProperties.Value("Custom", "Parameter_A") = Parameter("Component.iam.Parameter_A")
Parameter_A = iProperties.Value("Custom", "Parameter_A")
modelingEvents_ParameterChange(ThisDoc.Document, Parameter_A, kAfter, Value, kEventHandled)
End Sub
Sub modelingEvents_ParameterChange(documentObject As _Document, parameter As String, beforeOrAfter As EventTimingEnum, context As NameValueMap, ByRef handlingCode As HandlingCodeEnum)
Dim oDoc As DrawingDocument
oDoc = ThisDoc.Document
Dim oOpen As SectionDrawingView
Dim oClosed As SectionDrawingView
oOpen = oDoc.ActiveSheet.DrawingViews.Item(nr_A)
oClosed = oDoc.ActiveSheet.DrawingViews.Item(nr_B)
If beforeOrAfter = kAfter Then
oOpen.ReverseDirection
oClosed.ReverseDirection
End If
End Sub
I modelled the code on the solution developed in this thread: https://forums.autodesk.com/t5/inventor-programming-ilogic/ilogic-modeling-events-onparameterchange/...
Solved! Go to Solution.
Hi everyone,
I am working on code that will only run when the value of a parameter changes. The code is about changing the direction of a cross - section in an .IDW drawing.
The variable is String type, which has two values, 'Value1' and 'Value2'. I take the value of the variable and in the If loop I give a condition to make the code execute only when the value of the variable changes. But unfortunately the code executes every time, regardless of whether the variable has changed value from "Value1" to "Value2" or is still one value.
What am I doing wrong here? Have I misdefined the condition at any point?
Sub Main()
Dim invApp As Inventor.Application
Dim modelingEvents As ModelingEvents
invApp = System.Runtime.InteropServices.Marshal.GetActiveObject("Inventor.Application")
modelingEvents = invApp.ModelingEvents
AddHandler modelingEvents.OnParameterChange, AddressOf modelingEvents_ParameterChange
iProperties.Value("Custom", "Parameter_A") = Parameter("Component.iam.Parameter_A")
Parameter_A = iProperties.Value("Custom", "Parameter_A")
modelingEvents_ParameterChange(ThisDoc.Document, Parameter_A, kAfter, Value, kEventHandled)
End Sub
Sub modelingEvents_ParameterChange(documentObject As _Document, parameter As String, beforeOrAfter As EventTimingEnum, context As NameValueMap, ByRef handlingCode As HandlingCodeEnum)
Dim oDoc As DrawingDocument
oDoc = ThisDoc.Document
Dim oOpen As SectionDrawingView
Dim oClosed As SectionDrawingView
oOpen = oDoc.ActiveSheet.DrawingViews.Item(nr_A)
oClosed = oDoc.ActiveSheet.DrawingViews.Item(nr_B)
If beforeOrAfter = kAfter Then
oOpen.ReverseDirection
oClosed.ReverseDirection
End If
End Sub
I modelled the code on the solution developed in this thread: https://forums.autodesk.com/t5/inventor-programming-ilogic/ilogic-modeling-events-onparameterchange/...
Solved! Go to Solution.
Solved by Willow04. Go to Solution.
Solved by WCrihfield. Go to Solution.
Solved by WCrihfield. Go to Solution.
Solved by WCrihfield. Go to Solution.
Hi @Willow04. There are two main things wrong with your rule. First, you should not have the 'Event Handler' (the routine that reacts to the event) in the same rule with the code for changing the value of that parameter. Second, you should not be 'calling' the Event Handler routine to run from the Sub Main routine. It will just run on its own when that event happens. That one line of code within the Sub Main area which includes "AddHandler" is the line that specifies what event to handle, and which Sub routine will be used to 'handle' that event. One rule will set the iProperty value and parameter value, then another rule will create/start the event handler, and that rule that creates/starts the event handler should only be ran once per Inventor session, not multiple times, because each time it gets ran, it will create another instance of the event handler running in the background. The only way to get rid of an event handler running in the background, that was created by an iLogic rule that way is to close/restart Inventor. There are ways to design in an 'exit plan' for removing the event handler, but only if that extra code was already included when it was originally created, and when a specific other event happens, or some value changes, that will trigger the removal of the running event handler.
Wesley Crihfield
(Not an Autodesk Employee)
Hi @Willow04. There are two main things wrong with your rule. First, you should not have the 'Event Handler' (the routine that reacts to the event) in the same rule with the code for changing the value of that parameter. Second, you should not be 'calling' the Event Handler routine to run from the Sub Main routine. It will just run on its own when that event happens. That one line of code within the Sub Main area which includes "AddHandler" is the line that specifies what event to handle, and which Sub routine will be used to 'handle' that event. One rule will set the iProperty value and parameter value, then another rule will create/start the event handler, and that rule that creates/starts the event handler should only be ran once per Inventor session, not multiple times, because each time it gets ran, it will create another instance of the event handler running in the background. The only way to get rid of an event handler running in the background, that was created by an iLogic rule that way is to close/restart Inventor. There are ways to design in an 'exit plan' for removing the event handler, but only if that extra code was already included when it was originally created, and when a specific other event happens, or some value changes, that will trigger the removal of the running event handler.
Wesley Crihfield
(Not an Autodesk Employee)
Here is an example of the rule that could be used just for creating the event handler. It will first check the Document object provided by the Event itself, to see if it is a DrawingDocument or not. If it is not a drawing, then it will just exit that Sub routine, without trying to do anything else, because this event handler will be monitoring this type of event for all documents that you work with while that session of Inventor is running. Next it only reacts during the 'after' timing of the event. Then it creates a DrawingDocument type variable, since the provided variable is just for a generic Document, to provide Intellisense recognition. Then it declares the two variables for SectionDrawingView. Then it 'tries' to set their values, but I do not know what those two variables shown ("nr_A" & "nr_B") represent, so I do not know if it will succeed in finding those very specific views. I wrapped those 'risky' lines of code within condensed Try...Catch...End Try statements, to avoid potential errors from crashing the rule/routine. Then it 'tries' to reverse their direction, but that will only work if the views themselves were found, and they were the right type of views.
Sub Main()
If oModelingEvents Is Nothing Then oModelingEvents = ThisApplication.ModelingEvents
AddHandler oModelingEvents.OnParameterChange, AddressOf oModelingEvents_OnParameterChange
End Sub
'variable declared between routines so that all routines will recognize it, and can access it
Dim oModelingEvents As ModelingEvents
Sub oModelingEvents_OnParameterChange(Doc As Document, Param As String, _
BeforeOrAfter As EventTimingEnum, Context As NameValueMap, ByRef HandlingCode As HandlingCodeEnum)
If Doc.DocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then Exit Sub
If BeforeOrAfter = EventTimingEnum.kAfter Then
Dim oDDoc As DrawingDocument = Doc
Dim oOpen, oClosed As SectionDrawingView
Try : oOpen = oDDoc.ActiveSheet.DrawingViews.Item(nr_A) : Catch : End Try
Try : oClosed = oDDoc.ActiveSheet.DrawingViews.Item(nr_B) : Catch : End Try
Try : oOpen.ReverseDirection : Catch : End Try
Try : oClosed.ReverseDirection : Catch : End Try
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) 👍.
Wesley Crihfield
(Not an Autodesk Employee)
Here is an example of the rule that could be used just for creating the event handler. It will first check the Document object provided by the Event itself, to see if it is a DrawingDocument or not. If it is not a drawing, then it will just exit that Sub routine, without trying to do anything else, because this event handler will be monitoring this type of event for all documents that you work with while that session of Inventor is running. Next it only reacts during the 'after' timing of the event. Then it creates a DrawingDocument type variable, since the provided variable is just for a generic Document, to provide Intellisense recognition. Then it declares the two variables for SectionDrawingView. Then it 'tries' to set their values, but I do not know what those two variables shown ("nr_A" & "nr_B") represent, so I do not know if it will succeed in finding those very specific views. I wrapped those 'risky' lines of code within condensed Try...Catch...End Try statements, to avoid potential errors from crashing the rule/routine. Then it 'tries' to reverse their direction, but that will only work if the views themselves were found, and they were the right type of views.
Sub Main()
If oModelingEvents Is Nothing Then oModelingEvents = ThisApplication.ModelingEvents
AddHandler oModelingEvents.OnParameterChange, AddressOf oModelingEvents_OnParameterChange
End Sub
'variable declared between routines so that all routines will recognize it, and can access it
Dim oModelingEvents As ModelingEvents
Sub oModelingEvents_OnParameterChange(Doc As Document, Param As String, _
BeforeOrAfter As EventTimingEnum, Context As NameValueMap, ByRef HandlingCode As HandlingCodeEnum)
If Doc.DocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then Exit Sub
If BeforeOrAfter = EventTimingEnum.kAfter Then
Dim oDDoc As DrawingDocument = Doc
Dim oOpen, oClosed As SectionDrawingView
Try : oOpen = oDDoc.ActiveSheet.DrawingViews.Item(nr_A) : Catch : End Try
Try : oClosed = oDDoc.ActiveSheet.DrawingViews.Item(nr_B) : Catch : End Try
Try : oOpen.ReverseDirection : Catch : End Try
Try : oClosed.ReverseDirection : Catch : End Try
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) 👍.
Wesley Crihfield
(Not an Autodesk Employee)
By the way, if the rule for creating the event handler routine is an 'internal' rule, instead of an external rule, and those two variables ("nr_A" & "nr_B") represent local parameter values, then that is a bad combination. Every time the values of either of those two parameters changes, it will cause that rule to run, which will create another instance of the event handler, which may cause multiple reactions to the same event, and may reduce Inventor's performance. Including those two unquoted parameter names in the 'other' rule would be OK, but not in the one for creating he event handler. Alternatives would be to make the rule that created the event handler an external rule, and/or change how you specify which views to get.
Wesley Crihfield
(Not an Autodesk Employee)
By the way, if the rule for creating the event handler routine is an 'internal' rule, instead of an external rule, and those two variables ("nr_A" & "nr_B") represent local parameter values, then that is a bad combination. Every time the values of either of those two parameters changes, it will cause that rule to run, which will create another instance of the event handler, which may cause multiple reactions to the same event, and may reduce Inventor's performance. Including those two unquoted parameter names in the 'other' rule would be OK, but not in the one for creating he event handler. Alternatives would be to make the rule that created the event handler an external rule, and/or change how you specify which views to get.
Wesley Crihfield
(Not an Autodesk Employee)
Thank you very much! I will try it and give a respone!
Thank you very much! I will try it and give a respone!
@WCrihfield thank you for such comprehensive answers! Thank you for such comprehensive answers, I have achieved the desired result.
I have moved the main code to the main .iam assembly to the rule with name "oModelEvent.OnParameterChange" and I conditioned it to track the change of only a specific parameter "Engine_Type". In Event Triggers, I have set the rule to always run when this assembly is opened.
Sub Main
Dim oModelEvent As ModelingEvents
oModelEvent = ThisApplication.ModelingEvents
AddHandler oModelEvent.OnParameterChange, AddressOf oModelEvent_ParameterChange
End Sub
Sub oModelEvent_ParameterChange(DocumentObject As _Document, Parameter As Parameter, BeforeOrAfter As EventTimingEnum, Context As NameValueMap, ByRef HandlingCode As HandlingCodeEnum)
FullFilename = ThisDoc.Path & "Modular_Transporter\.idw"
Dim oDoc As DrawingDocument = ThisApplication.Documents.Open(FullFilename, False)
Auto = iLogicVb.Automation
If BeforeOrAfter = kAfter And Parameter.Name = "Engine_Type" Then
Auto.RunRule(oDoc, "Reverse_Direction")
End If
End Sub
When a change in the value of a parameter is registered, the "Reverse_Driection" rule that I placed in the .IDW file is triggered. The rule is as follows.
Dim oDoc As DrawingDocument
oDoc = ThisDoc.Document
Dim Postion_1 As SectionDrawingView
Dim Postion_2 As SectionDrawingView
Postion_1 = oDoc.ActiveSheet.DrawingViews.Item(3)
Postion_2 = oDoc.ActiveSheet.DrawingViews.Item(6)
Postion_1.ReverseDirection
Postion_2.ReverseDirection
The (3) and (6) numbers refer to the section positions in the model viewer in the .IDW file.
The code works as I expected, thanks again for your help!
@WCrihfield thank you for such comprehensive answers! Thank you for such comprehensive answers, I have achieved the desired result.
I have moved the main code to the main .iam assembly to the rule with name "oModelEvent.OnParameterChange" and I conditioned it to track the change of only a specific parameter "Engine_Type". In Event Triggers, I have set the rule to always run when this assembly is opened.
Sub Main
Dim oModelEvent As ModelingEvents
oModelEvent = ThisApplication.ModelingEvents
AddHandler oModelEvent.OnParameterChange, AddressOf oModelEvent_ParameterChange
End Sub
Sub oModelEvent_ParameterChange(DocumentObject As _Document, Parameter As Parameter, BeforeOrAfter As EventTimingEnum, Context As NameValueMap, ByRef HandlingCode As HandlingCodeEnum)
FullFilename = ThisDoc.Path & "Modular_Transporter\.idw"
Dim oDoc As DrawingDocument = ThisApplication.Documents.Open(FullFilename, False)
Auto = iLogicVb.Automation
If BeforeOrAfter = kAfter And Parameter.Name = "Engine_Type" Then
Auto.RunRule(oDoc, "Reverse_Direction")
End If
End Sub
When a change in the value of a parameter is registered, the "Reverse_Driection" rule that I placed in the .IDW file is triggered. The rule is as follows.
Dim oDoc As DrawingDocument
oDoc = ThisDoc.Document
Dim Postion_1 As SectionDrawingView
Dim Postion_2 As SectionDrawingView
Postion_1 = oDoc.ActiveSheet.DrawingViews.Item(3)
Postion_2 = oDoc.ActiveSheet.DrawingViews.Item(6)
Postion_1.ReverseDirection
Postion_2.ReverseDirection
The (3) and (6) numbers refer to the section positions in the model viewer in the .IDW file.
The code works as I expected, thanks again for your help!
Can't find what you're looking for? Ask the community or share your knowledge.