It is another challenge to set values of Revit family parameters (FamilyParameter).
As introduced before, the FamilyParameter does not have a value property. In order to get the FamilyParameter value for each FamilyType, a method from the groups of AsInteger(), AsDouble(), AsString(), and AsElementId() has to be called based on the StorageType of the FamilyParameter.
So as to set the FamilyParameter value of a specific FamilyType, we have to call the Set() method from another different place, FamilyManager. However, there are still some other issues. The method only accepts FamilyParameter and value arguments but not FamilyType one, so a FamilyParameter value can only be assigned to the current family type (FamilyType) by default.
If we’d like to set the FamilyParameter value of a non current FamilyType, some extra work needs be done. The workaround is to store the FamilyManager.CurrentType somewhere, switch the CurrentType temporarily to the one of interest, set FamilyParameter values, and finally switch the CurrentType back to the original one.
Revit Parameter Organizer can organize various Revit parameters such as Shared Parameters, Family Parameters, Project Parameters and Built-in Parameter in many good ways.
In this post, let’s see how to address all these issues with some real nice VB.NET code. The following help methods can set kinds of FamilyParameter values in all different situations:
Public Shared Function RawConvertSetToList(Of T)(ByVal setVar As IEnumerable) As List(Of T)
Dim list As List(Of T) = (From p In setVar Select p)
Return List
End Function
Public Shared Function RawFindFamilyParameter(ByVal fm As FamilyManager, ByVal parameterName As String) As FamilyParameter
Dim fp As FamilyParameter = RawConvertSetToList(Of FamilyParameter)(fm.Parameters).FirstOrDefault(Function(e) e.Definition.Name.Equals(parameterName, StringComparison.CurrentCultureIgnoreCase))
If fp Is Nothing Then
Throw New Exception("Invalid ParameterName Input!")
End If
Return fp
End Function
Public Shared Function RawFindFamilyType(ByVal fm As FamilyManager, ByVal familyTypeName As String) As FamilyType
Dim famType As FamilyType = RawConvertSetToList(Of FamilyType)(fm.Types).FirstOrDefault(Function(e) e.Name.Equals(familyTypeName, StringComparison.CurrentCultureIgnoreCase))
If famType Is Nothing Then
Throw New Exception("Invalid FamilyTypeName Input!")
End If
Return famType
End Function
Public Shared Sub RawSetFamilyParameterValue(ByVal fm As FamilyManager, ByVal familyTypeName As String, ByVal parameterName As String, ByVal value As Object)
RawSetFamilyParameterValue(fm, RawFindFamilyType(fm, familyTypeName), RawFindFamilyParameter(fm, parameterName), value)
End Sub
Public Shared Sub RawSetFamilyParameterValue(ByVal fm As FamilyManager, ByVal ft As FamilyType, ByVal parameterName As String, ByVal value As Object)
RawSetFamilyParameterValue(fm, ft, RawFindFamilyParameter(fm, parameterName), value)
End Sub
Public Shared Sub RawSetFamilyParameterValue(ByVal fm As FamilyManager, ByVal familyTypeName As String, ByVal fp As FamilyParameter, ByVal value As Object)
RawSetFamilyParameterValue(fm, RawFindFamilyType(fm, familyTypeName), fp, value)
End Sub
Public Shared Sub RawSetFamilyParameterValue(ByVal fm As FamilyManager, ByVal ft As FamilyType, ByVal fp As FamilyParameter, ByVal value As Object)
Dim curFamType As FamilyType = fm.CurrentType
fm.CurrentType = ft
Try
Select Case fp.StorageType
Case StorageType.None
Exit Select
Case StorageType.Double
If value.GetType().Equals(GetType(String)) Then
fm.Set(fp, Double.Parse(TryCast(value, String)))
Else
fm.Set(fp, Convert.ToDouble(value))
End If
Exit Select
Case StorageType.Integer
If value.GetType().Equals(GetType(String)) Then
fm.Set(fp, Integer.Parse(TryCast(value, String)))
Else
fm.Set(fp, Convert.ToInt32(value))
End If
Exit Select
Case StorageType.ElementId
If value.GetType().Equals(GetType(Autodesk.Revit.DB.ElementId)) Then
fm.Set(fp, TryCast(value, Autodesk.Revit.DB.ElementId))
ElseIf value.GetType().Equals(GetType(String)) Then
fm.Set(fp, New Autodesk.Revit.DB.ElementId(Integer.Parse(TryCast(value, String))))
Else
fm.Set(fp, New Autodesk.Revit.DB.ElementId(Convert.ToInt32(value)))
End If
Exit Select
Case StorageType.String
fm.Set(fp, value.ToString())
Exit Select
End Select
Catch
Throw New Exception("Invalid Value Input!")
Finally
fm.CurrentType = curFamType
End Try
End Sub
The following test code can be used to set some FamilyParameter values of some FamilyType objects in a family document, desk.rfa, for example:
…
If CachedDoc.IsFamilyDocument Then
Dim fm As FamilyManager = CachedDoc.FamilyManager
RawSetFamilyParameterValue(fm, "60"" x 30""", "Leg Height", 0.77)
RawSetFamilyParameterValue(fm, RawConvertSetToList(Of FamilyType)(fm.Types)(0), "Depth", 2.22)
RawSetFamilyParameterValue(fm, "60"" x 30""", RawFindFamilyParameter(fm, "URL"), "http://spiderinnet.typepad.com")
RawSetFamilyParameterValue(fm, RawConvertSetToList(Of FamilyType)(fm.Types)(1), RawConvertSetToList(Of FamilyParameter)(fm.Parameters).First(Function(e) e.StorageType = StorageType.String), "The first family parameter having the String StorageType.")
End If
…
FamilyParameter Value Writer of RevitAddinWizard can help do all of these in a configurable and flexible way in C# or VB.NET.
Recent Comments