Automatically Toggle Thickness Export Option

Automatically Toggle Thickness Export Option

NOEL_GETTINGBYCZTUC
Advocate Advocate
1,599 Views
15 Replies
Message 1 of 16

Automatically Toggle Thickness Export Option

NOEL_GETTINGBYCZTUC
Advocate
Advocate

Hi,

 

Please forgive me, I don't have much coding experience and the search topics didn't really seem to answer my query.

What I'm wanting to do is automatically toggle the "Export" option on the "Thickness" parameter so that it is set to Export for sheet metal parts but not for standard parts.

 

This is already the case in my part templates, the issue is that when a standard part is converted to sheet metal or vice versa, the Export option setting does not update.

 

I'd like to be able to run a rule to check a part's type, and then set the option as required, something like:

If > ThisDocument.Type = sheet metal

then > Thickness.Export = True

else > Thickness.Export = False

Endif

 

I'd like to be able to run this on demand, on a whole assembly and all children without needing to add the rule into thousands of parts individually.

Even better would be if this could be run during normal processes like during a rebuild-all or a save.

 

Any help is greatly appreciated.

 

Cheers, Noel

0 Likes
Accepted solutions (1)
1,600 Views
15 Replies
Replies (15)
Message 2 of 16

petr.meduna
Advocate
Advocate
Accepted solution

Hello, try this code in assembly. You can also set this rule as external rule and attach it to BeforeSave trigger.

Sub main()
'definition of assembly
Dim assembly As AssemblyDocument = ThisDoc.Document

'variable for sheetmetal
Dim comp As SheetMetalComponentDefinition

'name of thickness parameter; you can also write it manually and comment following for loop
Dim nameOfParam As String = ""

'search in assembly for sheetmetal document a write its thickness parameter name
For Each doc As Document In assembly.AllReferencedDocuments
	If Not TypeOf doc.ComponentDefinition Is SheetMetalComponentDefinition Then Continue For
	nameOfParam = doc.ComponentDefinition.Thickness.Name
	Exit For
Next

'exit rule while no sheetmetals are available
If String.IsNullOrEmpty(nameOfParam) Then Exit Sub

'search assembly for sheetmetals
Dim para As Inventor.Parameter
For Each doc As Document In assembly.AllReferencedDocuments
	If TypeOf doc.ComponentDefinition Is SheetMetalComponentDefinition Then
		comp = doc.ComponentDefinition
		
		'if document is sheetmetal, export parameter
		comp.Thickness.ExposedAsProperty = True
	Else
		'search in parameters collection for thickness parameter, even if the actual component isn't sheetmetal
		Try
			para = doc.ComponentDefinition.Parameters.Item(nameOfParam)
			para.ExposedAsProperty = False
		Catch
		End Try
	End If
Next
End Sub

 

Message 3 of 16

WCrihfield
Mentor
Mentor

Hi @NOEL_GETTINGBYCZTUC.  I have a very similar custom Sub routine that can be used in an iLogic rule, that is just for exporting a specific parameter to a custom iProperty.  You supply the Document object, and the name of the Parameter to the routine, then it attempts to get a parameter with the specified name within the supplied document and set its ExposedAsProperty value.  My normal routine will allow you to also specify an input variable called "bExport", which is a Boolean, then that will be used to set that property of the parameter.  However, I customized the custom routine in the following example to check if it is a sheet metal part or not, and react differently in each case, as you specified in your original post.

Sub ExportParam(oDoc As Document, sParamName As String)
	If oDoc Is Nothing OrElse oDoc.IsModifiable = False Then Return
	Dim oParam As Inventor.Parameter = Nothing
	Try : oParam = oDoc.ComponentDefinition.Parameters.Item(sParamName) 'Part or Assembly
	Catch : oParam = oDoc.Parameters.Item(sParamName) 'if its a Drawing
	Catch : Return : End Try
	If oParam Is Nothing Then Return
	If oDoc.SubType = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}" Then 'sheet metal
		If oParam.ExposedAsProperty = False Then oParam.ExposedAsProperty = True
	Else 'not a sheet metal part
		If oParam.ExposedAsProperty = True Then oParam.ExposedAsProperty = False
	End If
End Sub

The normal routine with the extra input variable usually looks like this:

Sub ExportParam(oDoc As Document, sParamName As String, bExport As Boolean)
	If oDoc Is Nothing OrElse oDoc.IsModifiable = False Then Return
	Dim oParam As Inventor.Parameter = Nothing
	Try : oParam = oDoc.ComponentDefinition.Parameters.Item(sParamName) 'Part or Assembly
	Catch : oParam = oDoc.Parameters.Item(sParamName) 'if its a Drawing
	Catch : Return : End Try
	If oParam Is Nothing Then Return
	If oParam.ExposedAsProperty <> bExport Then oParam.ExposedAsProperty = bExport
End Sub

...then an example of an iLogic rule using that first custom routine, that could be ran from any type of document would be like the following:

Sub Main
	Dim oDoc As Document = ThisDoc.Document
	ExportParam(oDoc, "Thickness")
	Dim oAllRefDocs As DocumentsEnumerator = oDoc.AllReferencedDocuments
	If oAllRefDocs.Count = 0 Then Return
	For Each oRefDoc As Document In oAllRefDocs
		ExportParam(oRefDoc, "Thickness")
	Next
	If oDoc.RequiresUpdate Then oDoc.Update2(True)
	If oDoc.Dirty Then oDoc.Save2(True)
End Sub

Sub ExportParam(oDoc As Document, sParamName As String)
	If oDoc Is Nothing OrElse oDoc.IsModifiable = False Then Return
	Dim oParam As Inventor.Parameter = Nothing
	Try : oParam = oDoc.ComponentDefinition.Parameters.Item(sParamName) 'Part or Assembly
	Catch : oParam = oDoc.Parameters.Item(sParamName) 'if its a Drawing
	Catch : Return : End Try 'could not be found, so exit routine
	If oParam Is Nothing Then Return 'could not be found, so exit routine
	If oDoc.SubType = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}" Then 'sheet metal
		If oParam.ExposedAsProperty = False Then oParam.ExposedAsProperty = True
	Else 'not a sheet metal part
		If oParam.ExposedAsProperty = True Then oParam.ExposedAsProperty = False
	End If
End Sub

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 4 of 16

NOEL_GETTINGBYCZTUC
Advocate
Advocate

Thanks @petr.meduna, that seems to work perfectly when run from my top level assembly.
I'll do some more testing before adding a trigger  and sharing with my team.

 

Thanks again. 

0 Likes
Message 5 of 16

NOEL_GETTINGBYCZTUC
Advocate
Advocate

Thanks @WCrihfield, but your rule doesn't seem to work when run from the top level assembly. I get an error message on line 17, see attached.

0 Likes
Message 6 of 16

WCrihfield
Mentor
Mentor

Sorry about the error, I should have tested the customized code before posting it.  Line 17 in that last code was designed to handle the situation where the Document being passed to the routine was a DrawingDocument.  That one line could have been completely deleted, if you never intend to use it on a drawing.  I sometimes use the parameters in drawings for various reasons, and sometimes one or more of them are just copied from 'the model'.  The DrawingDocument object does not have a ComponentDefinition, and so its Parameters collection is located directly at DrawingDocument.Parameters, instead of under a ComponentDefinition.

 

However, when I condensed that code into fewer lines (with the ":" characters) and further customized the routines within the forum code window before posting, I apparently deleted the Exception portions, forgetting about an important detail of the Try...Catch statement with multiple Catch sections (which I don't use very often), which messed up their functionality a bit.  When using more than one Catch section in a Try...Catch statement, the other Catch sections are for reacting differently to different reasons (different types of an Exception) that the Try portion may have failed.  So, when using multiple Catch sections, each of them must be designated for dealing with different specified type of Exception, so that the Catch section will only be ran when that specific type of Exception caused the failure.  This is generally not a problem when only using one Catch section.  So, I fixed that routine back to the way it is supposed to be, and left the drawing handling Catch in there...then tested it this time.  It is working as designed again now.  I had not used that specific routine in a long time, because most of my 'working' codes that deal with exposing parameters have similar, but simpler functionality integrated into larger, more complex routines, and generally do not handle the possibility of dealing with a drawing.  Apparently the snippet itself needed updating too.  Sometimes I save out a custom snippet of code too soon, then further develop it later, and no not remember to update the saved snippet.

I know you already have a solution, but I decided to post the corrected version of the routine I posted above which uses the extra input variable.  In this case, I moved the conditional statements of the 'custom' routine into the 'Main' routine, to leave the ExportParam Sub more dynamic.  However, it still does not address the possibility of multiple ModelStates being involved, which would add another level of complexity.

Sub Main
	Dim oDoc As Document = ThisDoc.Document
	If oDoc.SubType = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}" Then 'sheet metal
		ExportParam(oDoc, "Thickness", True)
	Else
		ExportParam(oDoc, "Thickness", False)
	End If
	Dim oAllRefDocs As DocumentsEnumerator = oDoc.AllReferencedDocuments
	If oAllRefDocs.Count = 0 Then Return
	For Each oRefDoc As Document In oAllRefDocs
		If oDoc.SubType = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}" Then 'sheet metal
			ExportParam(oRefDoc, "Thickness", True)
		Else
			ExportParam(oDoc, "Thickness", False)
		End If
	Next
	If oDoc.RequiresUpdate Then oDoc.Update2(True)
	If oDoc.Dirty Then oDoc.Save2(True)
End Sub

Sub ExportParam(oDoc As Document, sParamName As String, bExport As Boolean)
	If oDoc Is Nothing OrElse oDoc.IsModifiable = False Then Return
	Dim oParam As Inventor.Parameter = Nothing
	Try : oParam = oDoc.ComponentDefinition.Parameters.Item(sParamName) 'Part or Assembly
	Catch ae As ArgumentException
		Return 'it was a model document, but the parameter was not found, so exit routine
	Catch mme As MissingMemberException
		'it was a DrawingDocument, which does not have a ComponentDefintion
		Try 'try to find the parameter in the drawing
			oParam = oDoc.Parameters.Item(sParamName)
		Catch 'do not specify an Exception type here
			Return 'the parameter was not found in the drawing either, so exit routine
		End Try
	End Try
	If oParam Is Nothing Then Return 'could not be found, so exit routine
	If oParam.ExposedAsProperty <> bExport Then oParam.ExposedAsProperty = bExport
End Sub

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 7 of 16

NOEL_GETTINGBYCZTUC
Advocate
Advocate

Hi again @WCrihfield & @petr.meduna

Any idea how to modify the script to also set the custom Thickness Property to remove trailing zeros?

0 Likes
Message 8 of 16

petr.meduna
Advocate
Advocate

@NOEL_GETTINGBYCZTUC Even if you rewrite it via script, the value always updates while saving at least. The decimals are connected with document settings, so If you wish to "remove zeroes", change precision to zero in document settings.

0 Likes
Message 9 of 16

WCrihfield
Mentor
Mentor

Hi @NOEL_GETTINGBYCZTUC.  If you just want to control the decimal places shown for the custom iProperty that was created as the result of exposing the parameter, then we can do that with a bit more code.  However, if you want to control the number of decimal places in the Parameter itself, then that is another issue altogether, and awkward to control.  To control the custom Property's formatting, once you have exposed that parameter, you will be able make changes to the CustomPropertyFormat object you get from that parameter's Parameter.CustomPropertyFormat property.  You can only change the trailing zero's when you leave the 'Property Type' as Text, instead of Number.  When you choose Number type, the Units String, Leading Zeros, Trailing Zeros, and Format options are no longer available to be changed.  This coincides with the settings you see within the following dialog, which pops-up after you right-click on an exposed parameter, and choose the "Custom Property Format..." option:

WCrihfield_0-1698840542620.png

 

Dim oCPF As CustomPropertyFormat = oParam.CustomPropertyFormat
oCPF.PropertyType = CustomPropertyTypeEnum.kTextPropertyType
oCPF.ShowTrailingZeros = False

 

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 10 of 16

NOEL_GETTINGBYCZTUC
Advocate
Advocate
That's exactly what I've been doing manually, altering the customer property format to uncheck the trailing zeros option. I've been leaving the property as text format so that it includes units.

I'm using Petr's script so I assume that I need to insert these 3 additional lines of code after line 28?
0 Likes
Message 11 of 16

WCrihfield
Mentor
Mentor

Yes, but remember to change the variable from "oParam to "para".  You could also add an additional line of code, if you want to make sure that the units string is included, but I think it is by default anyways, unless converting it from a Number type to Text type later on.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 12 of 16

NOEL_GETTINGBYCZTUC
Advocate
Advocate

What I'm not getting is where to add the extra 3 lines of code to the script below.

I tried adding it after line 28 but got an error.

 

Sub main()
'definition of assembly
Dim assembly As AssemblyDocument = ThisDoc.Document

'variable for sheetmetal
Dim comp As SheetMetalComponentDefinition

'name of thickness parameter; you can also write it manually and comment following for loop
Dim nameOfParam As String = ""

'search in assembly for sheetmetal document a write its thickness parameter name
For Each doc As Document In assembly.AllReferencedDocuments
	If Not TypeOf doc.ComponentDefinition Is SheetMetalComponentDefinition Then Continue For
	nameOfParam = doc.ComponentDefinition.Thickness.Name
	Exit For
Next

'exit rule while no sheetmetals are available
If String.IsNullOrEmpty(nameOfParam) Then Exit Sub

'search assembly for sheetmetals
Dim para As Inventor.Parameter
For Each doc As Document In assembly.AllReferencedDocuments
	If TypeOf doc.ComponentDefinition Is SheetMetalComponentDefinition Then
		comp = doc.ComponentDefinition
		
		'if document is sheetmetal, export parameter
		comp.Thickness.ExposedAsProperty = True
	Else
		'search in parameters collection for thickness parameter, even if the actual component isn't sheetmetal
		Try
			para = doc.ComponentDefinition.Parameters.Item(nameOfParam)
			para.ExposedAsProperty = False
		Catch
		End Try
	End If
Next
End Sub
0 Likes
Message 13 of 16

WCrihfield
Mentor
Mentor

Sorry for the confusion, I didn't look close enough at that other source code to realize that the Parameter object was not captured as the value of a variable in that example code.  This time, I copied the whole code you just posted to an iLogic rule, then edited it a bit, to add the needed code to it.  I had to move a couple things around also, mostly to help enable the 'Intellisense' system.  The Intellisense system is what offers hints and suggestions while you are hovering over variables, or just typed in a dot after a variable, when editing iLogic code.  The SheetMetalComponentDefinition.Thickness property returns the Parameter object that you need to target, so I captured that to a variable before using that variable to expose it, then access its custom property format stuff.  Declaring variables outside of loops is OK most of the time, and may even help improve performance sometimes, but when editing code in the iLogic rule editor user interface, that variable often looses its Type recognition within the loop after setting the first value to it, so I moved their declaration lines within the loop, to help out with the recognition in this case, since you are not too familiar with how it all works yet.

Sub main()
	'definition of assembly
	Dim assembly As AssemblyDocument = ThisDoc.Document
	
	'name of thickness parameter; you can also write it manually and comment following for loop
	Dim nameOfParam As String = ""
	
	'search in assembly for sheetmetal document a write its thickness parameter name
	For Each doc As Document In assembly.AllReferencedDocuments
		If Not TypeOf doc.ComponentDefinition Is SheetMetalComponentDefinition Then Continue For
		nameOfParam = doc.ComponentDefinition.Thickness.Name
		Exit For
	Next
	
	'exit rule while no sheetmetals are available
	If String.IsNullOrEmpty(nameOfParam) Then Exit Sub
	
	'search assembly for sheetmetals
	For Each doc As Document In assembly.AllReferencedDocuments
		If TypeOf doc.ComponentDefinition Is SheetMetalComponentDefinition Then
			'variable for sheetmetal
			Dim comp As SheetMetalComponentDefinition = doc.ComponentDefinition
			Dim oThicknessParam As Inventor.Parameter = comp.Thickness
			'if document is sheetmetal, export parameter
			oThicknessParam.ExposedAsProperty = True
			Dim oCPF As CustomPropertyFormat = oThicknessParam.CustomPropertyFormat
			oCPF.PropertyType = CustomPropertyTypeEnum.kTextPropertyType
			oCPF.ShowUnitsString = True
			oCPF.ShowTrailingZeros = False
		Else
			'search in parameters collection for thickness parameter, even if the actual component isn't sheetmetal
			Try
				Dim para As Inventor.Parameter = doc.ComponentDefinition.Parameters.Item(nameOfParam)
				para.ExposedAsProperty = False
			Catch
			End Try
		End If
	Next
End Sub

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 14 of 16

NOEL_GETTINGBYCZTUC
Advocate
Advocate
I get an error on line 27 with the above script.

Unspecified error (Exception from HRESULT: 0x80004005 (E_FAIL))
0 Likes
Message 15 of 16

WCrihfield
Mentor
Mentor

Line 27 in the code above is just:

 

oCPF.PropertyType = CustomPropertyTypeEnum.kTextPropertyType

 

...which is just setting the value of the CostomPropertyFormat.PropertyType property, so I am not sure why that line of code would cause an error.  What version of Inventor are you using?  In the latest version of Inventor, we can export Text and Boolean types of UserParameters, but in earlier versions we could not.  That may be why it is encountering an error there.  If you were not using the latest version of Inventor, and the code encountered a Text or Boolean type parameter, it would not be able to expose that parameter as a custom property, then it would not be able to do anything with its CustomPropertyFormat.  But that portion of the code should only be working with the 'Thickness' parameter of the SheetMetalComponentDefinition, which should not be either of those two unit types.  Is your code an exact copy of the last code I posted, so that line 27 is the same one shown in that example, or is Line 27 different in your copy?  If there are any sheet metal parts in your assembly that are from the Content Center, or some other type of library where it may be ReadOnly, then that may be what's causing the problem.  You can add a line into the code just inside the loop of referenced documents like the following to avoid that problem.

If doc.IsModifiable = False Then Continue For

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 16 of 16

NOEL_GETTINGBYCZTUC
Advocate
Advocate

I'm using 2022, company mandated. I have been able to expose the Thickness parameter using Petr's script though.

 

[Edit: I think my problem was read only files as mentioned above. I'll do some testing to confirm.]

0 Likes