Revit family parameter (FamilyParameter) has more information than model/element Parameter. Besides those common parameter properties like BuiltInParameterGroup, ParameterType, StorageType, and DisplayUnitType, the FamilyParameter also has something about whether it is for report purpose only (IsReporting), instance applicable or type applicable (IsInstance), formula assignable (CanAssignFormula), and so on.
In this post, let’s see how to collect the information of FamilyParameter with VB.NET from a family document and put all the scattered-around pieces together into a good place. Then the information from the same central place can be reused for any possible purposes.
Revit Parameter Organizer can organize various Revit parameters such as Shared Parameters, Family Parameters, Project Parameters and Built-in Parameter in many good ways.
The following help classes and methods will store and handle the FamilyParameter information of a whole Revit family document:
Public Class FamilyParameterInfo
Public Property Name() As String
Get
Return m_Name
End Get
Set(ByVal value As String)
m_Name = Value
End Set
End Property
Private m_Name As String
Public Property ElementID() As String
Get
Return m_ElementID
End Get
Set(ByVal value As String)
m_ElementID = Value
End Set
End Property
Private m_ElementID As String
Public Property GUID() As String
Get
Return m_GUID
End Get
Set(ByVal value As String)
m_GUID = Value
End Set
End Property
Private m_GUID As String
Public Property BuiltinID() As String
Get
Return m_BuiltinID
End Get
Set(ByVal value As String)
m_BuiltinID = Value
End Set
End Property
Private m_BuiltinID As String
Public Property Group() As BuiltInParameterGroup
Get
Return m_Group
End Get
Set(ByVal value As BuiltInParameterGroup)
m_Group = Value
End Set
End Property
Private m_Group As BuiltInParameterGroup
Public Property Type() As ParameterType
Get
Return m_Type
End Get
Set(ByVal value As ParameterType)
m_Type = Value
End Set
End Property
Private m_Type As ParameterType
Public Property Storage() As StorageType
Get
Return m_Storage
End Get
Set(ByVal value As StorageType)
m_Storage = Value
End Set
End Property
Private m_Storage As StorageType
Public Property Unit() As String
Get
Return m_Unit
End Get
Set(ByVal value As String)
m_Unit = Value
End Set
End Property
Private m_Unit As String
'DisplayUnitType doesn't work!
Public Property [Shared]() As Boolean
Get
Return m_Shared
End Get
Set(ByVal value As Boolean)
m_Shared = Value
End Set
End Property
Private m_Shared As Boolean
' Both but different handling!
Public Property Instance() As Boolean
Get
Return m_Instance
End Get
Set(ByVal value As Boolean)
m_Instance = Value
End Set
End Property
Private m_Instance As Boolean
' FamilyParameter Only!
Public Property Reporting() As Boolean
Get
Return m_Reporting
End Get
Set(ByVal value As Boolean)
m_Reporting = Value
End Set
End Property
Private m_Reporting As Boolean
' FamilyParameter Only!
Public Property FormulaDetermined() As Boolean
Get
Return m_FormulaDetermined
End Get
Set(ByVal value As Boolean)
m_FormulaDetermined = Value
End Set
End Property
Private m_FormulaDetermined As Boolean
' FamilyParameter Only!
Public Property CanAssignFormula() As Boolean
Get
Return m_CanAssignFormula
End Get
Set(ByVal value As Boolean)
m_CanAssignFormula = Value
End Set
End Property
Private m_CanAssignFormula As Boolean
Public Property [ReadOnly]() As Boolean
Get
Return m_ReadOnly
End Get
Set(ByVal value As Boolean)
m_ReadOnly = Value
End Set
End Property
Private m_ReadOnly As Boolean
End Class
Public Shared Function GetDUTString(ByVal p As FamilyParameter) As String
Dim unitType As String = String.Empty
Try
unitType = p.DisplayUnitType.ToString()
Catch
End Try
Return unitType
End Function
Public Shared Function GetFamilyParametersInfo(ByVal doc As Document) As List(Of FamilyParameterInfo)
Dim paramList As List(Of FamilyParameterInfo) = (From p In doc.FamilyManager.Parameters Select New FamilyParameterInfo() With { _
.Name = p.Definition.Name, _
.ElementID = p.Id.IntegerValue.ToString(), _
.GUID = If(TryCast(p.Definition, ExternalDefinition) IsNot Nothing, TryCast(p.Definition, ExternalDefinition).GUID.ToString(), String.Empty), _
.BuiltinID = If(TryCast(p.Definition, InternalDefinition) IsNot Nothing, TryCast(p.Definition, InternalDefinition).BuiltInParameter.ToString(), String.Empty), _
.Group = p.Definition.ParameterGroup, _
.Type = p.Definition.ParameterType, _
.Storage = p.StorageType, _
.Unit = GetDUTString(p), _
.Shared = TryCast(p.Definition, ExternalDefinition) IsNot Nothing, _
.Instance = p.IsInstance, _
.Reporting = p.IsReporting, _
.FormulaDetermined = p.IsDeterminedByFormula, _
.CanAssignFormula = p.CanAssignFormula, _
.ReadOnly = p.IsReadOnly _
}).ToList()
Return paramList
End Function
And the following code will convert the informative object List into a single string:
Public Function ParametersInfoToCSVString(ByVal infoList As List(Of FamilyParameterInfo), ByRef title As String) As String
Dim sb As New StringBuilder()
Dim propInfoArrary As PropertyInfo() = GetType(FamilyParameterInfo).GetProperties()
For Each pi As PropertyInfo In propInfoArrary
title += pi.Name + ","
Next
title = title.Remove(title.Length - 1)
For Each info As FamilyParameterInfo In infoList
For Each pi As PropertyInfo In propInfoArrary
Dim obj As Object = info.GetType().InvokeMember(pi.Name, BindingFlags.GetProperty, Nothing, info, Nothing)
sb.Append((If(obj Is Nothing, String.Empty, obj.ToString())) & ",")
Next
sb.Remove(sb.Length - 1, 1).Append(Environment.NewLine)
Next
Return sb.ToString()
End Function
Then we can write all the FamilyParameter information of an opened family document to a CSV file.
…
If (CachedDoc.IsFamilyDocument) Then
Dim famParamsInfo As List(Of FamilyParameterInfo) = GetFamilyParametersInfo(CachedDoc)
Using sw As New StreamWriter("c:\FamilyParametersInfo.csv")
Dim title As String = String.Empty
Dim rows As String = ParametersInfoToCSVString(famParamsInfo, title)
sw.WriteLine(title)
sw.Write(rows)
End Using
End If
…
Finally the CSV file can be read into a spreadsheet of Excel.
From the output, we can notice something that is not obvious in the Revit FamilyParameter API.
- A FamilyParameter can be neither a built-in parameter (as indicated by the INVALID value of the BuiltInParameter enumeration) nor a shared Parameter (as indicated by the null ExternalDefinition or empty GUID)!
- The sign of the ElementId integer value of the FamilyParameter can be used to indicate whether it has a valid BuiltInParameter value or not!
- The IsDeterminedByFormula seems to always return FALSE or has nothing to do with the CanAssignFormula property!
The informative object list can be used for any other purposes as well for sure.
FamilyParameter Infoer of RevitAddinWizard can help do all of these in a configurable and flexible way in either C# or VB.NET.
Recent Comments