Create New iProperty if Parameter exists

Create New iProperty if Parameter exists

emanuel.c
Collaborator Collaborator
1,153 Views
5 Replies
Message 1 of 6

Create New iProperty if Parameter exists

emanuel.c
Collaborator
Collaborator

Unfortunately, I know enough iLogic to have gotten myself stuck in the weeds... I have this piece of code (copied from a larger code). My issue is in the Private Function CutL_iProp. What I'd like it to do is, if FindParameter_FL returns something (in other words, if User Parameter "FL" exists) then proceed with creating iProperty "Cut Length"=Parameter("FL").

How do I access either ParamFL or function FindParameter_FL from within Public function CutL_iProp? Or why do I get the errors? And maybe there is a better way to create the new iProperty if Parameter("FL") exists...

Thank you for the help!

 

Sub Main()
	Dim oPart As PartDocument = ThisDoc.FactoryDocument
	Dim invdoc As Document = ThisDoc.FactoryDocument
	Dim oSubType As String = invdoc.SubType
	oUserParams = GetUserParams(invdoc) 'Function GetUserParams returns UserParameters Collection
	ParamFL = FindParameter_FL(invdoc, "FL") 'Function FindParameter_FL returns the looked for parameter: FL - "Final Length"
			
	If ParamFL Is Nothing Then
		ParamFL = oUserParams.AddByValue("FL", 0, UnitsTypeEnum.kInchLengthUnits)
	Else			
		'It already exists with its own value
	End If

	Dim CL As String = CutL_iProp(oPart)
	Logger.Info(CL)
End Sub

'Get user parameters collection ***************************************************************************************************
Public Function GetUserParams(invdoc As Inventor.Document) As UserParameters
	
	Dim cd As ComponentDefinition = Nothing
    Select Case invdoc.DocumentType
        Case Is = Inventor.DocumentTypeEnum.kAssemblyDocumentObject
            Dim docAssembly As Inventor.AssemblyDocument = invdoc
            cd = docAssembly.ComponentDefinition
        Case Is = Inventor.DocumentTypeEnum.kPartDocumentObject
            Dim docPart As Inventor.PartDocument = invdoc
            cd = docPart.ComponentDefinition
    End Select
   
	If cd IsNot Nothing Then
		Dim oParams As Parameters
		oParams = cd.Parameters		
		Dim oUserParams As UserParameters
		oUserParams = oParams.UserParameters
	    Return oUserParams
    End If
Return Nothing
End Function

'See if parameter "FL" exists *****************************************************************************************************
Function FindParameter_FL(invdoc As Inventor.Document, strParameter As String) As Inventor.Parameter
	Dim oParams As Parameters
	If invdoc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Or _
		invdoc.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
		If invdoc.ComponentDefinition.IsModelStateMember Then
			invdoc = invdoc.ComponentDefinition.FactoryDocument
		End If
		oParams = invdoc.ComponentDefinition.Parameters
	Else
		Return Nothing
	End If
    For Each oParam As Inventor.Parameter In oParams
        If oParam.Name = strParameter Then
            Return oParam
		End If
    Next
	Return Nothing
End Function

'Define / Create iProperty: "CUT LENGTH" ******************************************************************************************
Private Function CutL_iProp(part As PartDocument) As String	
	If FindParameter_FL Is Nothing Then
		'Do nothing
	Else
		Dim oCL As Double = Parameter("FL")
		Dim PropertyName As String = "CUT LENGTH"
		Dim PropertyValue As String = RoundToFraction(oCL, 1 / 16, RoundingMethod.Round) & " in"
		Dim oCProps As PropertySet = part.PropertySets.Item("Inventor User Defined Properties")
		Dim oCLProp As Inventor.Property	
		Dim oExists As Boolean = False
		For Each oCProp As Inventor.Property In oCProps
			If oCProp.Name = PropertyName Then
				oCLProp = oCProp
				oCProp.Value=PropertyValue
				oExists = True			
		End If
		Next
		If oExists = False Then
			oCLProp = oCProps.Add(PropertyValue, PropertyName)
		End If
	End If
End Function

 

 

 

0 Likes
Accepted solutions (2)
1,154 Views
5 Replies
Replies (5)
Message 2 of 6

WCrihfield
Mentor
Mentor

Hi @emanuel.c.  That's a lot of code for what seemed like a fairly simple task.  Here is an 'all-in-one' iLogic rule that I believe will get the job done for you.  I'm using the parameter's Expression, instead of its Value, so we don't have to worry about units conversions.  That will only work though, if there is no equation there, just a regular numerical value.

See if this works any better for you:

Dim oPDoc As PartDocument = ThisDoc.FactoryDocument
oParams = oPDoc.ComponentDefinition.Parameters
Dim oFLParam As Inventor.Parameter = Nothing
For Each oParam As Inventor.Parameter In oParams
	If oParam.Name = "FL" Then
		oFLParam = oParam
		Exit For
	End If
Next
If IsNothing(oFLParam) Then
	oFLParam = oParams.UserParameters.AddByValue("FL", 0, UnitsTypeEnum.kInchLengthUnits)
End If
oValForProp = RoundToFraction(Val(oFLParam.Expression), 1/16, RoundingMethod.Round)
'this would create a matching custom iProperty called "FL"
'If Not oFLParam.ExposedAsProperty Then
'	oFLParam.ExposedAsProperty = True
'End If
oCProps = oPDoc.PropertySets.Item("Inventor User Defined Properties")
Dim oCutLengthProp As Inventor.Property = Nothing
If oCProps.Count > 0 Then
	For Each oCProp As Inventor.Property In oCProps
		If oCProp.Name = "CUT LENGTH" Then
			oCutLengthProp = oCProp
			oCutLengthProp.Value = oValForProp
			Exit For
		End If
	Next
End If
If IsNothing(oCutLengthProp) Then
	oCutLengthProp = oCProps.Add(oValForProp, "CUT LENGTH")
End If

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 :bulb: or you can Explore My CONTRIBUTIONS

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 6

emanuel.c
Collaborator
Collaborator

Hi and thank you for the input. Yes I'm certain the code can be simplified and I wish to work towards that as I learn more. The thing is, I pieced it together from various sources with various help and it was working so I didn't wish to slice into it for fear I might mess it up.

 

For some reason I get an error when I run the code you sent. Not sure why...

 

Capture.PNG

0 Likes
Message 4 of 6

J-Camper
Advisor
Advisor
Accepted solution

I'm not on 2022 Inventor yet, so I can't test the IsModelStateMember check so I commented that line out, but the following should do what you are asking:

Sub Main
	Dim currentDef As ComponentDefinition = TryCast(ThisApplication.ActiveDocument.ComponentDefinition, AssemblyComponentDefinition)
	If IsNothing(currentDef) Then currentDef = TryCast(ThisApplication.ActiveDocument.ComponentDefinition, PartComponentDefinition)
	If IsNothing(currentDef) Then Logger.Debug("Not run in Part or Assembly Document") : Exit Sub
	
	Dim allParams As Parameters
	'If currentDef.IsModelStateMember Then allParams = currentDef.FactoryDocument.ComponentDefinition.Parameters
	If IsNothing(allParams) Then allParams = currentDef.Parameters
	
	Dim paramName As String = "FL"
	Dim iPropName As String = "CUT LENGTH"
	Dim ActualParam As Inventor.Parameter
	
	Try
		ActualParam = allParams.Item(paramName)
		'Exists do nothing
	Catch
		ActualParam = allParams.UserParameters.AddByValue(paramName, 0, UnitsTypeEnum.kInchLengthUnits)
	End Try
	
	'now we know the parameter exists
	iPropertyManager(currentDef.Document, ActualParam.Value, iPropName, True)
	
End Sub

Sub iPropertyManager(oDoc As Document, ValueObject As Object, iPropName As String, OverWrite As Boolean)
	Dim customIprops As PropertySet = oDoc.PropertySets("Inventor User Defined Properties")
	Try
		Dim newProp As Inventor.Property = customIprops(iPropName)
		If newProp.Value <> ValueObject And OverWrite = True Then newProp.Value = ValueObject
	Catch
		customIprops.Add(ValueObject, iPropName)
	End Try
End Sub

 

You don't need to loop for properties/parameters.  If you know the name you are looking for, you can do a simple Try/Catch to get properties/parameters.

 

Let me know if you have any questions, or if this is not working as intended

0 Likes
Message 5 of 6

WCrihfield
Mentor
Mentor
Accepted solution

Was that part a Content Center part, or something similar where the file might be in a ReadOnly library area?  Did the parameter contain an equation, instead of a simple numerical value?  If so, we will have to change how we are getting its value within the RoundToFraction method, and may end up having to do some unit conversion.  If the parameter did not already exist, and was created with a value of zero, then maybe when we use the RoundToFraction method on it later, it doesn't like working with a value of zero...I haven't tested that scenario yet.  Also perhaps I presumed too much and you really prefer to have each step of the code separated out into different Subs & Functions to help compartmentalize the tasks for reuse in other projects.

 

Also I try to use a Loop if it is possible to do so, before using a Try...Catch block, just because that is generally the proper route, and often requires less processing time/resources in use after the fact.  However, using a loop often requires a bit more code, and perhaps slightly more time to write than a Try...Catch block.  I've done it both ways though, so it's not a big deal unless its part of a much larger automation project that might be more time consuming or resource consuming.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 6 of 6

emanuel.c
Collaborator
Collaborator

@J-Camper Thanks Jeffrey, the code works well. The reason I used the For loops was spurred by this forum post here https://forums.autodesk.com/t5/inventor-ilogic-and-vb-net-forum/ilogic-detect-if-parameter-exist-if-... All 'fault' goes to @JamieVJohnson2 😊 but @WCrihfield seemed to agree with it. I see Try-Catch used a lot in searching for Parameters or iProperties but based on those posts I went with the separate functions which return the searched Parameter. My largest assemblies may have up to hundreds of same parts, I don't know if the For loops would indeed make a difference or not.

 

@WCrihfield Yes, it was a content center part, but writable and the parameter isn't an expression but inch-length. Possible in the fraction conversion like you say. Yes it is nice to have the parameter searching in a separate function. I think you had helped me with some blocks of code there. They work great!

 

Thank you both for the help! I declare, I spent a few hours on it so I finally posted here and learned folks helped in a heart beat.