Event Trigger bug

Event Trigger bug

nmaravalN6QFT
Participant Participant
1,293 Views
17 Replies
Message 1 of 18

Event Trigger bug

nmaravalN6QFT
Participant
Participant

Good day,

 

I can run my rule manually and save without error,

but when I event trigger before save, an error appears...

 

I guess my code is correct if I can run it manually,

but why does it not work with event trigger?

 

Did anyone have this problem and find the source?

 

Cheers!

0 Likes
Accepted solutions (1)
1,294 Views
17 Replies
Replies (17)
Message 2 of 18

WCrihfield
Mentor
Mentor

Hi @nmaravalN6QFT.  What is your code trying to do?  Beware that if your code is accessing file name or path, and the document has not been saved yet for the first time, it will fail, because the document does not have a file yet on disk, so no file name or path.  That is usually one problem when running code before save.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 18

nmaravalN6QFT
Participant
Participant

File is already created and saved

 

Here is the code:

 

'Verify if doc is a part
If ThisApplication.ActiveDocument.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
	Feedback = 0
Else
	ThisApplication.Documents.Open(ThisDoc.Document.FullFileName)
	Feedback = 1
End If

AreaSelect = iLogicVb.Automation.GetNamedEntities(ThisDoc.Document).FindEntity("AREA")

ThisApplication.CommandManager.DoSelect(AreaSelect)
AreaInch = ThisDoc.Document.SelectSet.Item(1).Evaluator.Area

'conversion cm^2 in pi^2
AreaFeet = Round((AreaInch / 929.0304), 0)

Parameter("AREA") = AreaFeet

InventorVb.DocumentUpdate()

If Feedback = 1 Then
	ThisDoc.Document.Save
	ThisDoc.Document.Close(True)
End If

 

Error refer to ligne 13 if I am in the part and 25 if I'm in an assembly

0 Likes
Message 4 of 18

WCrihfield
Mentor
Mentor

Hi @nmaravalN6QFT.  Are you aware that the term 'ThisApplication.ActiveDocument' may return/represent a different document than the term 'ThisDoc.Document'?  When used in a local/internal iLogic rule, the term 'ThisDoc.Document' will always return/represent the local document (the document that the rule is saved within).  It is a iLogic only term, and has sort of a 'pecking order' as to what it will return/represent in different scenarios.  However, the 'ThisApplication.ActiveDocument' term will always point to whichever document happens to be 'active' at the moment that term is used, which is sometimes not the document folks are expecting it to represent.  It can be pretty tricky.  Is your iLogic rule a local/internal rule (saved within a document), or an external rule?

 

I am not sure about the intent of your first If...Then block of code, so I was not sure how to modify it, without breaking something that may be intentional.  I made a few edits to your code that may help some, but I would need to know more about the scenario to provide a better working solution.

 

Dim oDoc As Document = ThisDoc.Document
'!!! 'ThisApplication.ActiveDocument' may represent a different document than 'ThisDoc.Document' !!!
'Verify if doc is a part
If ThisApplication.ActiveDocument.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
	Feedback = 0
Else
	ThisApplication.Documents.Open(oDoc.FullFileName)
	Feedback = 1
End If
Dim AreaSelect As Object = Nothing
Try
	AreaSelect = iLogicVb.Automation.GetNamedEntities(oDoc).FindEntity("AREA")
Catch
	MsgBox("Error trying to retrieve entity named 'AREA'.", vbCritical, "Entity Not Found")
	'Logger.Error("Error trying to retrieve entity named 'AREA'.")
	Return
End Try
If IsNothing(AreaSelect) Then
	MsgBox("Entity named 'AREA' not found.  Exiting rule.", vbCritical, "Entity Not Found")
	'Logger.Debug("Entity named 'AREA' not found.  Exiting rule.")
	Return
End If

oDoc.SelectSet.Clear
ThisApplication.CommandManager.DoSelect(AreaSelect)
'oDoc.SelectSet.Select(AreaSelect)
Dim AreaInch As Double = oDoc.SelectSet.Item(1).Evaluator.Area

'conversion cm^2 in pi^2
Dim AreaFeet As Double = Round((AreaInch / 929.0304), 0)
'FYI:  the following iLogic shortcut snippet does not specify which document to target
Parameter("AREA") = AreaFeet
'possible alternative below
'oDoc.ComponentDefinition.Parameters.Item("AREA").Value = AreaFeet

oDoc.Update

If Feedback = 1 Then
	oDoc.Save
	oDoc.Close(True)
End If

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 5 of 18

nmaravalN6QFT
Participant
Participant

Thanks for your help,

 

It's an external rule

 

Basically this rule writes the area of a flat part, with opening in it, into a parameter I can export to excel later.

Openings size and quantity can change depending of the project

 

The first if bloc is if my part is saved in an assembly it needs to be open, area actualised, save and close

 

It might be an easier way, but couldn't find it

 

I tried your code, but it seems to stop at the ligne 25, same as before.

 

but I really don't understand why it is working when I launch the rule manually, but if triggered it doesn't...

0 Likes
Message 6 of 18

WCrihfield
Mentor
Mentor

OK.  I understand the situation better now.  But I still have a question (or few).  When you put this rule under the 'Before Save Document' event in the Event Triggers dialog, which tab did you do that in ('This Document', 'All Documents', 'Parts', 'Assemblies', etc.)?  If you did it in the 'This Document' tab of the part, it should then only get ran when that specific part document gets saved.  However, sometimes when you save an assembly or a drawing that is referencing a part, it will also save the part, but the part will not be the 'active' document at that time.  That is one scenario to avoid using the 'ThisApplication.ActiveDocument' term in.  If this rule is being triggered to run while an assembly is 'active', it is not that simple to get the document that a specific component within that assembly is referencing.  More lines of code would be needed to get a specific part from within an assembly.  You would have to be able to identify which component within the assembly is representing the part, then extract the document object that it is representing, or look at the assemblies referenced document to find the right one by its file name, or similar.  If there are many versions of the part document that you want this code to target, then using a hard-coded full file name will not work, so you would have to think of another way to identify it.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 7 of 18

nmaravalN6QFT
Participant
Participant

I put the event trigger in this document,

That's why I put the first If bloc, so if the rule is launched in the assembly the part will need to be opened and then the rest of the rules will be executed, and finally saved and closed.

 

But that is not my actual problem, because even if I am in the part the rule is not working when triggered,

but works well when ran manually...

The DoSelect seems to be the problem but why can't it be triggered?

0 Likes
Message 8 of 18

WCrihfield
Mentor
Mentor

Hi @nmaravalN6QFT.  I have another rule you can try out if you want.  I totally eliminated the whole selection thing, because it did not seem necessary.  We already have the object we were searching for set as the value of a variable, then all we should need to do is use that variable directly with the Evaluator.Area properties.  I also included a lot more code to help handle the scenario of when an assembly may be the active document when the rule gets ran.  That part of the code could be more efficient if I knew how to uniquely identify the target part amongst possibly a great many other components and/or sub-assembly components.  Right now it is only making sure it finds any part within the assembly, then trying to run the custom Sub routine on every part it finds in the assembly.  I left a couple of commented out lines of code in there, as clues for other possible ways of finding the specific part within an assembly that you may or may not be able to take advantage of in future development.  I set the Sub routine up with Try...Catch blocks and Logger entries, instead of MsgBox's, so hopefully it won't pop-up a ton of messages, interrupting the rule every time it encounters a problem.  I am also using the API route of accessing the parameter and setting its Value/Expression, instead of the iLogic shortcut snippet, which can be pointing to the wrong target document.  Since your code is converting units, in order to preserve that, I decided to set the parameter's Expression (a String) instead of its Value, to avoid the units being understood as 'database units', instead of the intended units.

Here is the new code:

Sub Main
	Dim oDoc As Document = ThisDoc.Document
	If oDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
		Dim oPDoc As PartDocument = oDoc
		GetAreaToParam(oPDoc, "AREA", "AREA")
	ElseIf oDoc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
		'find the part within this assembly, then run the Sub routine below on that part document object
		Dim oADoc As AssemblyDocument = oDoc
		Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
		Dim oOccs As ComponentOccurrences = oADef.Occurrences
		'Dim oOcc As ComponentOccurrence = oOccs.ItemByName("MyAreaPart")
		For Each oOcc As ComponentOccurrence In oOccs
			If oOcc.Suppressed Then Continue For
			If TypeOf oOcc.Definition Is VirtualComponentDefinition Then Continue For
			Dim oOpened As Boolean = False
			oOccDocType = oOcc.ReferencedDocumentDescriptor.ReferencedDocumentType
			If oOccDocType <> DocumentTypeEnum.kPartDocumentObject Then Continue For
			Dim oOccDoc As PartDocument = oOcc.ReferencedDocumentDescriptor.ReferencedDocument
			'find a way to make sure it is one of the correct parts to process
			'If oOccDoc.FullFileName.Contains("MyAreaPart") Then
			GetAreaToParam(oOccDoc, "AREA", "AREA")
		Next
		If oADoc.RequiresUpdate Then oADoc.Update
		If oADoc.Dirty Then oADoc.Save
	End If
End Sub

Sub GetAreaToParam(oPartDoc As PartDocument, oEntityName As String, oParamName As String)
	Dim AreaSelect As Object = Nothing
	Try
		AreaSelect = iLogicVb.Automation.GetNamedEntities(oPartDoc).FindEntity(oEntityName)
	Catch
		'MsgBox("Error trying to retrieve entity named '" & oEntityName & "'.", vbCritical, "Entity Not Found")
		Logger.Error("Error trying to retrieve entity named 'AREA'.")
		Exit Sub
	End Try
	If IsNothing(AreaSelect) Then
		'MsgBox("Entity named '" & oEntityName & "' not found.  Exiting rule.", vbCritical, "Entity Not Found")
		Logger.Debug("Entity named 'AREA' not found.  Exiting rule.")
		Exit Sub
	End If
	Try
		Dim AreaInch As Double = AreaSelect.Evaluator.Area
		'conversion cm^2 in pi^2
		Dim AreaFeet As Double = Round((AreaInch / 929.0304), 0)
		oPartDoc.ComponentDefinition.Parameters.Item(oParamName).Expression = AreaFeet.ToString
	Catch
		'MsgBox("Error getting Area of entity, or setting its value to parameter.", vbCritical, "")
		Logger.Error("Error getting Area of entity, or setting its value to parameter.")
	End Try
	If oPartDoc.RequiresUpdate Then oPartDoc.Update
	If oPartDoc.Dirty Then oPartDoc.Save
End Sub

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 9 of 18

nmaravalN6QFT
Participant
Participant

Thanks for your time,

 

Directly in the part:

if I run it manually no error message, but the area parameter is not actuallized to the new value,

 

if I run it through event trigger, error message appears:

one first saying: file copy error on save, the access path is not found

one second saying:

error appears on saving:

-impossible to name the new version of the document .newVer

-Impossible to save the date base in

 

If it is running in an assembly only the first message is showing:

file copy error on save, the access path is not found

0 Likes
Message 10 of 18

WCrihfield
Mentor
Mentor

Hi @nmaravalN6QFT.  I think I may have seen similar looking error messages before about not being able to save, but only very, very rarely.  I do not know what causes them, but I do not believe it has anything to do with the rule code.

 

What year version of Inventor are you using?  The iLogic Logger has been available since Inventor 2019.1 version.  If you are able to use it, have you looked at the contents of the iLogic Log right after running the rule, to see if it contains any new entries.  Since I commented out all of the MsgBox's, about the only feedback left are entries in the iLogic Log using those Logger lines of code.  Seeing those entries may help us figure out what is going wrong.  If you have never looked at the iLogic Log before, these screenshots may help you find it.

WCrihfield_0-1662652388267.png

WCrihfield_1-1662652410897.png

WCrihfield_2-1662652425051.png

If you have been watching the iLogic Log, and/or have un-commented the MsgBox lines to make them show, we should be getting some feedback that should give us a clue as to where it is encountering problems.  Maybe we need more feedback in more places to help fine tune where the problem is.  For instance, I am bundling a few things together within the Try side of the last Try...Catch block in the 'GetAreaToParam' Sub routine.  Maybe we need to separate those things out into multiple Try...Catch blocks.  That might tell us more specifically if it is having trouble using the "AreaSelect.Evaluator.Area" code, or the "Round((AreaInch / 929.0304), 0)" code, or the line setting the parameter's Expression.  This type of thing can be difficult to debug remotely.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 11 of 18

nmaravalN6QFT
Participant
Participant

I'm using 2022,

 

using your last code manually or with trigger it shows:

INFO| 16: >>---------------------------
ERROR|Error getting Area of entity, or setting its value to parameter.

 

and with the first code, nothing appears in the logger

but an error window saying error to line 25

 

And this written in the more info tab:

System.Runtime.InteropServices.COMException (0x80004005): non-specified error (Exception of HRESULT : 0x80004005 (E_FAIL))
to System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
to Inventor.CommandManager.DoSelect(Object Entity)
to ThisRule.Main() In external rule: AREA:line 25
to Autodesk.iLogic.Exec.AppDomExec.ExecRuleInAssembly(Assembly assem)
to iLogic.RuleEvalContainer.ExecRuleEval(String execRule)

0 Likes
Message 12 of 18

WCrihfield
Mentor
Mentor
Accepted solution

OK.  So in my last code it is having a problem at one of those 3 lines of code within the Try side of the last Try...Catch block of code within the GetAreaToParam Sub routine.  That narrows it down.  We know then that it is getting the named entity OK, because it passed the tests before that point.  The error message for your first code is clearly encountering the error at the DoSelect line, which I believe is an unnecessary line of code, as I have shown in the last code I posted.  Once you have found the named entity, and have it stored to a variable, we should not have to select it to be able to get its area.  However, it may be beneficial to declare the variable that is to hold that Face as a Face, instead of Object, if we know it is going to be a Face object.  That way we get the benefit of the 'Intellisense' suggestions (pop-up info when you hover the object in the rule editor screen).

I have updated my code to check object type, and also to check for the parameter's existence.  If the parameter is not found, it will try to create it as a UserParameter, then set its Expression and set its units as feet.

Sub Main
	Dim oDoc As Document = ThisDoc.Document
	If oDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
		Dim oPDoc As PartDocument = oDoc
		GetAreaToParam(oPDoc, "AREA", "AREA")
	ElseIf oDoc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
		'find the part within this assembly, then run the Sub routine below on that part document object
		Dim oADoc As AssemblyDocument = oDoc
		Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
		Dim oOccs As ComponentOccurrences = oADef.Occurrences
		'Dim oOcc As ComponentOccurrence = oOccs.ItemByName("MyAreaPart")
		For Each oOcc As ComponentOccurrence In oOccs
			If oOcc.Suppressed Then Continue For
			If TypeOf oOcc.Definition Is VirtualComponentDefinition Then Continue For
			Dim oOpened As Boolean = False
			oOccDocType = oOcc.ReferencedDocumentDescriptor.ReferencedDocumentType
			If oOccDocType <> DocumentTypeEnum.kPartDocumentObject Then Continue For
			Dim oOccDoc As PartDocument = oOcc.ReferencedDocumentDescriptor.ReferencedDocument
			'find a way to make sure it is one of the correct parts to process
			'If oOccDoc.FullFileName.Contains("MyAreaPart") Then
			GetAreaToParam(oOccDoc, "AREA", "AREA")
		Next
		If oADoc.RequiresUpdate Then oADoc.Update
		If oADoc.Dirty Then oADoc.Save
	End If
End Sub

Sub GetAreaToParam(oPartDoc As PartDocument, oEntityName As String, oParamName As String)
	Dim AreaSelect As Object = Nothing
	Try
		AreaSelect = iLogicVb.Automation.GetNamedEntities(oPartDoc).FindEntity(oEntityName)
	Catch
		Logger.Error("Error trying to find entity named '" & oEntityName & "'.")
		Exit Sub
	End Try
	If IsNothing(AreaSelect) Then
		Logger.Debug("Entity named '" & oEntityName & "' not found.")
		Exit Sub
	End If
	Dim oFace As Face = Nothing
	If TypeOf AreaSelect Is Face Then
		oFace = AreaSelect
	Else
		Logger.Debug("The entity named '" & oEntityName & "' was not a Face object." _
		& vbCrLf & "It was a " & TypeName(AreaSelect) & " object.")
		Exit Sub
	End If
	Dim AreaInch As Double
	Try
		AreaInch = oFace.Evaluator.Area
	Catch
		Logger.Error("Error evaluating the Area of the named Face.")
		Exit Sub
	End Try
	'conversion cm^2 in pi^2
	Dim AreaFeet As Double = Round((AreaInch / 929.0304), 0)
	Dim oParams As Parameters = oPartDoc.ComponentDefinition.Parameters
	Dim oAreaParam As Inventor.Parameter = Nothing
	Try 'try to find the specifically named parameter, and set its Expression
		oAreaParam = oParams.Item(oParamName)
		oAreaParam.Expression = AreaFeet.ToString
	Catch 'that parameter was not found, so try to create it
		oAreaParam = oParams.UserParameters.AddByExpression(oParamName, AreaFeet.ToString, UnitsTypeEnum.kFootLengthUnits)
	Catch
		Logger.Error("Unable to find or create parameter named:  " & oParamName)
	End Try
	If oPartDoc.RequiresUpdate Then oPartDoc.Update
	If oPartDoc.Dirty Then oPartDoc.Save
End Sub

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 13 of 18

nmaravalN6QFT
Participant
Participant

This time it works manually, but with the trigger I've got an Autodesk Inventor Professional error message:

error appears on saving:

-Acces denied

-impossible to save data base in

0 Likes
Message 14 of 18

nmaravalN6QFT
Participant
Participant

Despite the error message that he can't save, the rules seems to run until the save step,

But he create a new parameter each time the rule is triggered, AREA_1, AREA_1_2, ...

0 Likes
Message 15 of 18

WCrihfield
Mentor
Mentor

Again, I don't know what could be causing problems when saving the file(s), but I don't think that problem is related to the iLogic rule.  It sounds like the file(s) may be corrupted to some degree.  I have encountered similar situations before on very rare occasions.  When you save an Inventor file, a lot of stuff happens behind the scenes.  Here are a couple of links you can check out about that.  It's pretty interesting, and may help you understand what is going on there:

https://help.autodesk.com/view/INVNTOR/2022/ENU/?caas=caas/sfdcarticles/sfdcarticles/Saving-and-Open... 

'and this one:

https://help.autodesk.com/view/INVNTOR/2022/ENU/?guid=GUID-D81A080D-615D-4F6E-8AB0-65A0AF9CC778 

'or If that link doesn't work, just go into the online help page, then:

WCrihfield_0-1662723793289.png

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 16 of 18

WCrihfield
Mentor
Mentor

Also, in an attempt to fix the odd situation where it is creating a new parameter each time, I decided to replace the whole block of code that deals with the parameter, from using one big Try...Catch block, to using a normal loop of the parameters, to see if the named parameter exists first.  Then if it does exist, use a Try...Catch block specifically for setting its Expression, so we can isolate the action, to see if it is having a problem there for some reason.  Then if the parameter was not found, use a Try...Catch block specifically for creating the named parameter, to isolate that possible action, and handle any potential error there.

To use this, replace this block of code:

	Try 'try to find the specifically named parameter, and set its Expression
		oAreaParam = oParams.Item(oParamName)
		oAreaParam.Expression = AreaFeet.ToString
	Catch 'that parameter was not found, so try to create it
		oAreaParam = oParams.UserParameters.AddByExpression(oParamName, AreaFeet.ToString, UnitsTypeEnum.kFootLengthUnits)
	Catch
		Logger.Error("Unable to find or create parameter named:  " & oParamName)
	End Try

...with this block of code:

	For Each oParam As Inventor.Parameter In oParams
		If oParam.Name = oParamName Then
			oAreaParam = oParam
			Exit For
		End If
	Next
	If oAreaParam IsNot Nothing Then
		'it was found, so try to set its Expession
		Try
			oAreaParam.Expression = AreaFeet.ToString
		Catch
			Logger.Error("Error while trying to set new value to existing parameter.")
		End Try
	Else 'named parameter was Nothing (not found), so create it
		Try
			oAreaParam = oParams.UserParameters.AddByExpression(oParamName, AreaFeet.ToString, UnitsTypeEnum.kFootLengthUnits)
		Catch
			Logger.Error("Error while trying to create new user parameter.")
		End Try
	End If

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 17 of 18

nmaravalN6QFT
Participant
Participant

Your code seems to work with the trigger before save if I remove the save line in your code at the end of your Sub.

 

Thanks a lot for your help!

Message 18 of 18

WCrihfield
Mentor
Mentor

Wow.  That sure seems like an obvious one.  How did we both miss that little detail this whole time.  In a rule that is to be run just before saving, don't try to save it at the end of the code. 😆

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes