Well something changed between Inventor 2019 and 2020 (currently using version 2020.0.1), this problem as resurfaced. Inventor is unstable after deleting assembly sketch dimensions that were created by code and deleted by hand. A detailed process list is below:
1. Code creates dimensional constraints in an assembly sketch, and modifies parameter export features.
2. Code creates custom parameters that use the dimensional parameters in their expressions (for rounding tricks).
3. User saves file and forgets all about this having happily completed their task.
4. User revisits same file many moons later, and wants to modify by hand the assembly sketch. During this time, they delete one or more of the dimensions being used in step 1 above.
5. User attempts to 'rebuild all' or runs same code command to 'update2', Inventor reads an incomplete parameter's table and crashes.
5a. User runs custom code to delete custom parameters with expressions that used orphaned dimensional parameters.
5b. User manually deletes custom parameters with expressions that used orphaned dimensional parameters.
5c. User or code run an update command (or rebuild all command), Inventor crashes.
Alternate step 5: User saves and closes file, or code saves and closes file. Then reopens it, Inventor reads the table data and populates in-memory data from the cleaned table, and does not crash upon update.
I have sent in several crash updates on this. Currently my Autodesk account can not access its 'View Support Cases' page as it once again redirects back to the home page.
Current version of Code that attempts to clean custom parameters before recreating them:
Public Sub ATRWideRound()
Try
GetInventorApplication()
If invApp IsNot Nothing Then
If invApp.ActiveDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
Dim invdoc As Inventor.Document = invApp.ActiveDocument
Dim trans As Transaction = invApp.TransactionManager.StartTransaction(invdoc, "ATRWide")
ATRWideRoundReset(invdoc, trans)
trans.End()
End If
End If
Catch ex As Exception
Dim eh As New ErrorHandler(ex)
eh.HandleIt()
End Try
End Sub
Public Function RemoveParameterAndIProperty(param As Parameter, dcs As List(Of DimensionConstraint), invDoc As Inventor.Document) As Boolean
Dim booSuccess As Boolean = False
Try
Dim booFound As Boolean = False
Dim strName As String = String.Empty
If param.HealthStatus <> HealthStatusEnum.kDeletedHealth Then
For Each dc As DimensionConstraint In dcs
If dc.Parameter.Name = param.Name Then
dc.Parameter.ExposedAsProperty = False
Dim iProp As [Property] = FindiProperty(Tools.UserDefinedPropertySetID, dc.Parameter.Name, invDoc)
If iProp IsNot Nothing Then iProp.Delete()
' ExportParameterAsFeetInches(dc.Parameter)
booFound = True
Exit For
End If
Next
strName = param.Name
param.Delete()
Else
'don't remove - its has already been deleted by Inventor during the processing of our current code thread, such as when a user parameter that kept this one around as a formula value was deleted first.
End If
'still check for iproperties that need to be removed after parameter was deleted.
If booFound = False AndAlso String.IsNullOrWhiteSpace(strName) = False Then
Dim iProp As [Property] = FindiProperty(Tools.UserDefinedPropertySetID, strName, invDoc)
If iProp IsNot Nothing Then iProp.Delete()
End If
booSuccess = True
Catch ex As Exception
'Dim strname As String = String.Empty
'Try
' If param IsNot Nothing Then
' If param.Name IsNot Nothing Then
' strname = param.Name
' End If
' End If
' 'MsgBox("Can not delete parameter and iProperty: " & strname & vbCrLf & ex.InnerException.ToString)
'Catch ex2 As Exception
' 'MsgBox("Can not delete parameter and iProperty, Inventor has a catastrophic error on this parameter. You will need to reload the file to clean.")
'End Try
End Try
Return booSuccess
End Function
Public Sub ATRWideRoundReset(ByRef docAsm As Inventor.AssemblyDocument, Optional ByRef trans As Transaction = Nothing)
'find "Clearance Profile" sketch
Dim skClearanceProfile As PlanarSketch = Nothing
For Each psk As PlanarSketch In docAsm.ComponentDefinition.Sketches
If psk.Name = "Clearance Profile" Then
skClearanceProfile = psk
Exit For
End If
Next
Dim dcATRs As New List(Of DimensionConstraint)
Dim dcWides As New List(Of DimensionConstraint)
Dim dcAllATRs As New List(Of DimensionConstraint)
Dim dcAllWides As New List(Of DimensionConstraint)
If skClearanceProfile IsNot Nothing Then
For Each dc As Inventor.DimensionConstraint In skClearanceProfile.DimensionConstraints
If dc.Parameter.Name.Contains("ATR") Then
dcAllATRs.Add(dc)
If Not dc.Parameter.Name = "ATRD" Then dcATRs.Add(dc)
ElseIf dc.Parameter.Name.Contains("WIDE") Then
dcAllWides.Add(dc)
If Not dc.Parameter.Name = "WIDED" Then dcWides.Add(dc)
End If
Next
Else
MsgBox("Can not find sketch named 'Clearance Profile'")
End If
'look for existing atr-wide rounded parameters'clear them out
Dim booReLoadFile As Boolean = False
Dim exATRs As List(Of Parameter) = GetParameterValues(docAsm, "ATR", True)
If exATRs.Count > 0 Then
Dim exATRRs As New List(Of Parameter)
For Each param As Parameter In exATRs
If param.Name.Substring(param.Name.Length - 1, 1) = "R" Then exATRRs.Add(param)
Next
For Each param As Parameter In exATRRs
exATRs.Remove(param)
Next
For Each param As Parameter In exATRRs
If RemoveParameterAndIProperty(param, dcAllATRs, docAsm) = False Then
booReLoadFile = True
End If
Next
For Each param As Parameter In exATRs
If RemoveParameterAndIProperty(param, dcAllATRs, docAsm) = False Then
booReLoadFile = True
End If
Next
End If
Dim exWides As List(Of Parameter) = GetParameterValues(docAsm, "WIDE", True)
If exWides.Count > 0 Then
Dim exWideRs As New List(Of Parameter)
For Each param As Parameter In exWides
If param.Name.Substring(param.Name.Length - 1, 1) = "R" Then exWideRs.Add(param)
Next
For Each param As Parameter In exWideRs
exWides.Remove(param)
Next
For Each param As Parameter In exWideRs
If RemoveParameterAndIProperty(param, dcAllWides, docAsm) = False Then
booReLoadFile = True
End If
Next
For Each param As Parameter In exWides
If RemoveParameterAndIProperty(param, dcAllWides, docAsm) = False Then
booReLoadFile = True
End If
Next
End If
If booReLoadFile Then
MsgBox("File has errors and needs to be reloaded.")
Dim strFileName As String = docAsm.FullFileName
docAsm.Save()
docAsm.Close()
docAsm = OpenInventorFile(New IO.FileInfo(strFileName))
End If
'once old parameters are cleared out, create new ones based soley on the existence of the parameters found from the dimensions
Dim dcATRWIDES As New List(Of DimensionConstraint)
dcATRWIDES.AddRange(dcATRs)
dcATRWIDES.AddRange(dcWides)
For Each dc As DimensionConstraint In dcATRWIDES
dc.Parameter.ExposedAsProperty = False
Dim iProp As [Property] = FindiProperty(Tools.UserDefinedPropertySetID, dc.Parameter.Name, docAsm)
If iProp IsNot Nothing Then iProp.Delete()
ExportParameterAsFeetInches(dc.Parameter)
Dim paraRound As Inventor.Parameter = Nothing
Dim paramName As String = dc.Parameter.Name
If paramName.ToUpper.Contains("ATR") Or paramName.ToUpper.Contains("WIDE") Then
'round(( ATR1 - 0.49 in ) / 1 in) * 1 in
Dim sign As String = "+"
Dim strExpression As String = "round(( " & paramName & " " & sign & " 0.49 in ) / 1 in) * 1 in"
Dim dRemainderInches As Double = (CDbl(dc.Parameter.Value) * 2.54) Mod 1
If 0.09 < dRemainderInches AndAlso dRemainderInches < 1 / 32 Then
strExpression = "round(( " & dc.Parameter.Name & " ) / 1 in) * 1 in"
End If
Dim strName As String = dc.Parameter.Name & "R"
Try
Dim uParams As UserParameters = docAsm.ComponentDefinition.Parameters.UserParameters
paraRound = uParams.AddByExpression(strName, strExpression, Inventor.UnitsTypeEnum.kInchLengthUnits)
Catch ex As Exception
Dim eh As New ErrorHandler(ex)
eh.HandleIt()
End Try
End If
ExportParameterAsFeetInches(paraRound)
Next
If dcWides.Count > 0 Then
Dim intRoundDown As Integer
dcWides.Sort(Function(x, y) CInt(x.Parameter.Name.Replace("WIDE", "")).CompareTo(CInt(y.Parameter.Name.Replace("WIDE", ""))))
For i As Integer = 0 To dcWides.Count - 1
dcWides(i).Parameter.ExposedAsProperty = False
Dim iProp As [Property] = FindiProperty(Tools.UserDefinedPropertySetID, dcWides(i).Parameter.Name, docAsm)
If iProp IsNot Nothing Then iProp.Delete()
ExportParameterAsFeetInches(dcWides(i).Parameter)
'if next value is smaller than current value then this is the last integer we want to round down
If i > 0 Then 'must always be 1 below the max count
Dim dblValue As Double = dcWides(i - 1).Parameter.Value
Dim dblValue2 As Double = dcWides(i).Parameter.Value
If Math.Round(dblValue, 8) < Math.Round(dblValue2, 8) Then
'get integer value from name
Dim strNumber As String = dcWides(i).Parameter.Name
strNumber = strNumber.ToUpper.Replace("WIDE", "")
intRoundDown = CInt(strNumber)
'Exit For
End If
End If
Next
For i As Integer = 1 To intRoundDown - 1
'get ATR rounded value by name = ATR1R
Dim uParam As UserParameter = docAsm.ComponentDefinition.Parameters.UserParameters.Item("ATR" & i & "R")
If uParam IsNot Nothing Then
uParam.Expression = "round(( " & "ATR" & i & " - 0.49 in ) / 1 in) * 1 in"
Dim dRemainderInches As Double = (CDbl(uParam.Value) * 2.54) Mod 1
If 0.09 < dRemainderInches AndAlso dRemainderInches < 1 / 32 Then
uParam.Expression = "round(( " & "ATR" & i & " ) / 1 in) * 1 in"
End If
End If
Next
End If
If docAsm.RequiresUpdate = True Then
Dim strFileName As String = docAsm.FullFileName
Dim transName As String = String.Empty
Dim booRestartTransaction As Boolean = False
If trans IsNot Nothing Then
booRestartTransaction = True
transName = trans.DisplayName
trans.End()
End If
docAsm.Save()
docAsm.Close()
docAsm = OpenInventorFile(New IO.FileInfo(strFileName))
docAsm.Update2(True)
If booRestartTransaction Then
trans = invApp.TransactionManager.StartTransaction(docAsm, "transName")
End If
End If
End Sub
Example of code used to create dimension:
'add vertical dimension constraint
Dim sdcVert As DimensionConstraint = skProfile.DimensionConstraints.AddTwoPointDistance(slMirror.StartSketchPoint, OffsetProfile(i).StartProfilePoint.SketchPoint, DimensionOrientationEnum.kHorizontalDim,
tg.CreatePoint2d(OffsetProfile(0).StartProfilePoint.SketchPoint.Geometry.X / 2, OffsetProfile(0).StartProfilePoint.SketchPoint.Geometry.Y + ((1 + i) * dDimensionOffset)), False)
With sdcVert.Parameter
.Name = OffsetProfile(i).StartProfilePoint.PointID
'.DisplayFormat = ParameterDisplayFormatEnum.kArchitecturalDisplayFormat
.Visible = True
.Precision = Inventor.LinearPrecisionEnum.kSixteenthsFractionalLinearPrecision
.ExposedAsProperty = True
' MsgBox(.InUse)
With .CustomPropertyFormat
.PropertyType = CustomPropertyTypeEnum.kTextPropertyType
.Units = Inventor.UnitsTypeEnum.kFootLengthUnits
.Precision = CustomPropertyPrecisionEnum.kSixteenthsFractionalLengthPrecision
'.ShowUnitsString = True
End With
End With
sdcProfileVert.Add(sdcVert)
'add horizontal dimension constraints
Dim intOppositeID As Integer = ((OffsetProfile.Count - 1) / 2) + i
Dim sdcHorz As DimensionConstraint = skProfile.DimensionConstraints.AddTwoPointDistance(OffsetProfile(i).StartProfilePoint.SketchPoint, OffsetProfile(intOppositeID).StartProfilePoint.SketchPoint, DimensionOrientationEnum.kVerticalDim,
tg.CreatePoint2d(lastPoint1.SketchPoint.Geometry.X + ((1 + i) * dDimensionOffset), 0), False)
With sdcHorz.Parameter
.Name = sdcVert.Parameter.Name.Replace("ATR", "WIDE")
.Visible = True
.Precision = Inventor.LinearPrecisionEnum.kSixteenthsFractionalLinearPrecision
.ExposedAsProperty = True
With .CustomPropertyFormat
.PropertyType = CustomPropertyTypeEnum.kTextPropertyType
.Units = Inventor.UnitsTypeEnum.kFootLengthUnits
.Precision = CustomPropertyPrecisionEnum.kSixteenthsFractionalLengthPrecision
'.ShowUnitsString = True
End With
End With
sdcProfileHorz.Add(sdcHorz)
I would really like to have a stable Inventor on this issue. I'm having to write a lot of workaround code (its not ideal to close and reopen the file in mid processing) just to keep the user working.
Thanks,
Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/