Hi @chris. I may have something that will work for you, but it has not been tested that much yet. It also uses the ModelStateTable, because when you need to make things either different or the same between multiple ModelStates, that is pretty much the only way to go. Otherwise you are left working with one ModelState at a time, and while doing that, you do not have access to values of the same parameter/property in other ModelStates at that time. This code example can be ran on any type of document. If ran on a drawing, it will try to get the first 'model' document being referenced by the first view in that drawing. If none found, it exits the rule. It utilizes a 'List(Of String)' type variable, which allows you to input multiple parameter names. This is where you would need to specify the names of all the parameters that you want to be the same across all ModelStates, based on the 'primary' ModelState. Then it runs a custom Sub routine, then updates the main document.
The custom Sub routine first checks that all input data has been provided properly, and that the specified document is either a part or assembly, then makes sure it is working with the 'factory' version, if one is available. There will not be a 'factory' if there are not 2 or more ModelStates present in it, which it also checks right after that. If fewer, it exits the routine. The 'primary' ModelState is always the first one in the ModelStates collection, so it uses that fact to get its name, for reference later (for localization related issues). Then it gets the table. Then it gets a reference to the row for the 'primary' ModelState, for reference later. Since I have not done enough studies to know if the 'primary' ModelState will always be the first row within the ModelStateTable.TableRows collection, I do not assume that, and get it by its name, to be safe. Then it starts iterating the provided parameter names. Then it tries to find the column for that specific parameter. If column is found, it then gets the cell within that row for the primary ModelState for the parameter, using the parameter's column as cross reference for cell location. Then starts iterating rows. If the row is the one for primary ModelState, then skip to next row. Get cell in that row at the parameter column intersection, then set its value using the value from the primary ModelState row's cell...essentially copying the value from the primary ModelState to that non-primary ModelState. Then it does another update. I believe a document update may be needed both before and after making parameter type changes to documents which have multiple ModelStates, based on online help documentation describing a situation like that.
Below is the code example.
Sub Main
Dim oDoc As Document = ThisDoc.FactoryDocument 'Nothing if DrawingDocument
If oDoc Is Nothing Then oDoc = ThisDoc.ModelDocument 'if was DrawingDocument get model
If oDoc Is Nothing Then Return 'if drawing had no 'model' referenced in it yet
'define which parameters you want to be the same accross all ModelStates
Dim oParamNames As New List(Of String)
oParamNames.Add("Length")
EnsureParamsSameInAllModelStates(oDoc, oParamNames)
oDoc.Update2(True)
End Sub
Sub EnsureParamsSameInAllModelStates(oDoc As Document, oParamNames As List(Of String))
If oDoc Is Nothing Then Return
If (Not TypeOf oDoc Is AssemblyDocument) AndAlso (Not TypeOf oDoc Is PartDocument) Then Return
If oParamNames Is Nothing OrElse oParamNames.Count = 0 Then Return
oDoc.Update2(True) 'may, or may not be needed, but recommended
If oDoc.ComponentDefinition.IsModelStateMember Then
oDoc = oDoc.ComponentDefinition.FactoryDocument
End If
Dim oMSs As ModelStates = oDoc.ComponentDefinition.ModelStates
If oMSs.Count < 2 Then Return 'zero or only 1 ModelState, so nothing to do
Dim sPrimaryMSName As String = oMSs.Item(1).Name
'Dim sActiveMSName As String = oDoc.ModelStateName
Dim oMSTable As ModelStateTable = oMSs.ModelStateTable
Dim oPrimaryMSRow As ModelStateTableRow = oMSTable.TableRows.Item(sPrimaryMSName)
For Each sParamName As String In oParamNames
Dim oThisParamCol As ModelStateTableColumn = Nothing
For Each oCol As ModelStateTableColumn In oMSTable.TableColumns
If oCol.DisplayHeading = sParamName Then
oThisParamCol = oCol
Exit For
End If
Next oCol
If oThisParamCol Is Nothing Then Continue For
Dim oPrimaryParamCell As ModelStateTableCell = oPrimaryMSRow.Item(oThisParamCol)
For Each oRow As ModelStateTableRow In oMSTable.TableRows
If oRow Is oPrimaryMSRow Then Continue For
Dim oThisParamCell As ModelStateTableCell = oRow.Item(oThisParamCol)
Try : oThisParamCell.Value = oPrimaryParamCell.Value : Catch : End Try
Next oRow
Next sParamName
oDoc.Update2(True)
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)