Setting the Weight for iPart Members

There was a question posted on the customization newsgroup that I spent a little time investigating and think the answer might be of general interest.  The objective is to have a column in the iPart table that has the weight for that member.  I wasn’t able to figure out a way to do this with built-in functionality in Inventor but it turned out it isn’t too difficult to write a program to accomplish the task.  Although the program and description below is specific to the weight of a part, it could be modified to handle other part information that you want to associate with an iPart member.

First, let’s look at the iPart factory to see what needs to exist for the program to function correctly.  The only thing special is that I created a custom iProperty called “Weight” and added that as one of the iProperties that I want to set from the table.  It didn’t have to be an iProperty and could have been an “Other” value but using an iProperty provides the most flexibility for using the value elsewhere in Inventor.  For example, in the the drawing.  The picture below shows the iPart table after setting it up with this iProperty.  The values for this new column are empty.

iPartTable

Now we need to assign the correct weight for each row to the weight column.  If you had to this manually you would:

  1. Activate a member.
  2. Run the iProperties command
  3. Go to the “Physical” tab of the iProperties dialog.
  4. Click the “Update” button on the “Physical” tab.
  5. Select and Copy the “Mass” field.
  6. Open the iPart table and paste the mass value into the table for the correct row.
  7. Close the iPart table.
  8. Repeat steps 1 to 7 for every row in the table.

As you can see this is very tedious and prone to errors.  Instead of manually going through these steps they can be automated using Inventor’s programming interface.  Below is a VBA macro that will do the work.

Public Sub UpdateWeightOfiParts()
    ‘ Get the active document.  This assumes it is a part.
    Dim oPartDoc As PartDocument
    Set oPartDoc = ThisApplication.ActiveDocument

    ' Check that this part is an iPart factory.
    If Not oPartDoc.ComponentDefinition.IsiPartFactory Then
        MsgBox "This part must be an iPart factory."
        Exit Sub
    End If

    Dim oFactory As iPartFactory
    Set oFactory = oPartDoc.ComponentDefinition.iPartFactory

    ' Check that there's a "Weight" column in the iPart table,

    ' and get its index in the table.
    Dim iWeightColumnIndex As Long
    iWeightColumnIndex = GetColumnIndex(oFactory, "Weight")
    If iWeightColumnIndex = -1 Then
        MsgBox "The column ""weight"" does not exist in the table."
        Exit Sub
    End If

    ' Iterate through the rows
    Dim oRow As iPartTableRow
    For Each oRow In oFactory.TableRows
        ' Make this the active row so the model will recompute.
        oFactory.DefaultRow = oRow

        ' Get the weight.
        Dim dWeight As Double
        dWeight = oPartDoc.ComponentDefinition.MassProperties.Mass

        ' Convert it to current mass units defined by the document.
        Dim strWeight As String
        strWeight = oPartDoc.UnitsOfMeasure.GetStringFromValue( _ 
                                dWeight, kDefaultDisplayMassUnits)

        ' Set the row value for the weight column.
        oRow.Item(iWeightColumnIndex).Value = strWeight
    Next
End Sub

’ Function that given a factory and the name or a column will return
’ the index number of the column, if it’s found in the factory’s
’ table.  If the column is not found it returns –1.  The comparison
’ of the name is done in a case insensitive way.
Private Function GetColumnIndex(ByVal Factory As iPartFactory, _ 
                                ByVal ColumnName As String) As Long
    ‘ Iterate through all of the columns looking for a
    ‘ match to the input name.
    Dim i As Long
    For i = 1 To Factory.TableColumns.Count
        Dim oColumn As iPartTableColumn
        Set oColumn = Factory.TableColumns.Item(i)

        ‘ Compare this column with the input name.
        If LCase(oColumn.DisplayHeading) = LCase(ColumnName) Then
            ' A matching column was found so exit.
            GetColumnIndex = i
            Exit Function
        End If
    Next

    ' The column wasn't found so return -1.
    GetColumnIndex = -1
End Function

The program is essentially performing the same steps that would be required to do this manually.  It’s just able to do it much faster and without any mistakes.  After running the macro on my factory the table now looks like this.

iPartTableAfter

It’s also important to recognize that the weight is a snapshot of the weight at the time the macro was run.  If the part is modified (for example, a new feature is added) or table values are edited that affect the part geometry, the weight will no longer be correct and the macro will need to be run again to update the weight column.


Comments

3 responses to “Setting the Weight for iPart Members”

  1. So in my opinion this just needs to be behand the save button. You even check if this an ipart so you leave the message out and you never have any issue right?

  2. jbaena Avatar
    jbaena

    Hi,Brian
    Thank you very much, excellent macro. I was needing this function a long time ago.
    I built from your source code, another version, but with some modifications:
    – For iAssemblies too.
    – Included the area field (for painting, m²)
    – A toolbar for with two buttons for each function.
    I left the units for area as “ul”, because Inventor API doesn’t have explicit square units (m²) only (m m).
    If somebody need this macro, please send me a message.
    Cheers!

  3. jeggert Avatar
    jeggert

    Is there a way to add an iPart Column through the API?

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading