@j_weber
That's a more complex thing to do since all the selected parts can have different materials. Also if a subassembly is selected you'd have to traverse it and then if it contains a subassembly you'd have to traverse that as well to get all the part occurrences and their materials.
I added it to the code.
A warning though, if too many occurrences are selected the entire message box will not fit on the screen 😄
Sub Main
Dim oAsm As AssemblyDocument = ThisDoc.Document
Dim oMsg As String = "Components:"
Dim oSelSet As SelectSet = oAsm.SelectSet
Dim UoM As UnitsOfMeasure = oAsm.UnitsOfMeasure
Dim totMass As Double = 0
Dim oList As New List(Of ComponentOccurrence)
For Each oObj As Object In oSelSet
If TypeOf (oObj) Is ComponentOccurrence Then oList.Add(oObj)
Next
Dim noSelection As Boolean = False
If oList.Count = 0
noSelection = True
For Each oOcc As ComponentOccurrence In oAsm.ComponentDefinition.Occurrences.AllLeafOccurrences
If oOcc.Visible
totMass = totMass + oOcc.MassProperties.Mass
oMsg = getLeafOccs(oOcc, oMsg, UoM)
End If
Next
Else
For Each oOcc As ComponentOccurrence In oList
Dim parentSelected As Boolean = False
'Make sure something isn't selected twice (subassembly and occurrence in subassembly both selected)
For Each oParentOcc As ComponentOccurrence In oOcc.OccurrencePath
If oList.OfType(Of ComponentOccurrence).Where(Function(x As ComponentOccurrence) x.Definition Is oParentOcc.Definition _
AndAlso x.Definition IsNot oOcc.Definition).Count > 0 Then parentSelected = True
Next
'--------------------------------------------------------------------------------------------------
If parentSelected = False
totMass = totMass + oOcc.MassProperties.Mass
oMsg = getLeafOccs(oOcc, oMsg, UoM)
End If
Next
End If
MessageBox.Show(If (noSelection, "Total mass of visible components", "Total mass of selected components") _
& vbCrLf & UoM.GetStringFromValue(totMass, UoM.MassUnits) & vbCrLf & vbCrlf & oMsg, _
"Total mass", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Function getLeafOccs(oOcc As ComponentOccurrence, oMsg As String, UoM As UnitsOfMeasure) As String
If TypeOf (oOcc.Definition) Is PartComponentDefinition
oMsg = oMsg & vbCrLf & oOcc.Name & ": " & oOcc.Definition.Document.ActiveMaterial.DisplayName _
& " - " & UoM.GetStringFromValue(oOcc.MassProperties.Mass, UoM.MassUnits)
Else
For Each subOcc As ComponentOccurrence In oOcc.SubOccurrences
oMsg = getLeafOccs(subOcc, oMsg, UoM)
Next
End If
Return oMsg
End Function