# Export family types as text node?

**URL:** <https://forum.dynamobim.com/t/export-family-types-as-text-node/89333>\
**Category:** Uncategorized\
**Created:** [May 8, 2023, 2:16am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333 "2023-05-08T02:16:46Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![vanman](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/vanman/32/20881_2.png) [@vanman](https://forum.dynamobim.com/u/vanman)\
**Post date:** [May 8, 2023, 2:16am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/1 "2023-05-08T02:16:46Z")

</div>

Hi, is there anything to export family types as text?  
 ![image](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/a/1/a1471cee14ce32d7373f3402d40d5e4b6555e6fa.png)

---

<div class="post-metadata">

**Author:** ![SeanP](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/seanp/32/42560_2.png) [@SeanP](https://forum.dynamobim.com/u/SeanP)\
**Post date:** [May 8, 2023, 3:04am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/2 "2023-05-08T03:04:05Z")

</div>

Like a type catalog?

> [@Custom Family Type Catalog Exporter](https://forum.dynamobim.com/t/custom-family-type-catalog-exporter/50633/10):
>
> Ok, so here is what I have come up with, and what is still not working just right. I exported a Type Catalog from Revit directly and it was actually encoded as UTF-16LE This export maintained special characters / letter as I expected, but broke for Parameter Names / Values with commas. I refactored to encapsulate either of those values when they had a comma I refactored the write to use the codecs class rather than the stream writer. This enables us to encode as we want to the UT…

---

<div class="post-metadata">

**Author:** ![vanman](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/vanman/32/20881_2.png) [@vanman](https://forum.dynamobim.com/u/vanman)\
**Post date:** [May 8, 2023, 3:37am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/3 "2023-05-08T03:37:17Z")

</div>

I think if thats the right terminology 😅 so when people import a family the dialog box comes up with types to choose from. I’ve made a ton of door families. Keen to not export the type catalog one by one 🙂

---

<div class="post-metadata">

**Author:** ![vanman](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/vanman/32/20881_2.png) [@vanman](https://forum.dynamobim.com/u/vanman)\
**Post date:** [May 8, 2023, 4:01am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/4 "2023-05-08T04:01:41Z")

</div>

Cool Ill try background open stuff and use this 🤔 although need it to create a text file

---

<div class="post-metadata">

**Author:** ![SeanP](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/seanp/32/42560_2.png) [@SeanP](https://forum.dynamobim.com/u/SeanP)\
**Post date:** [May 8, 2023, 4:24am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/5 "2023-05-08T04:24:26Z")

</div>

Yes, type catalog. The problem is that Revit won’t export most custom shared parameters by default. That’s what I shared was a method to pick any parameters to use.

---

<div class="post-metadata">

**Author:** ![vanman](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/vanman/32/20881_2.png) [@vanman](https://forum.dynamobim.com/u/vanman)\
**Post date:** [May 10, 2023, 2:05am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/6 "2023-05-10T02:05:40Z")

</div>

Thanks Sean, getting this error for some reason. Your right, typical Revit catalog isnt working with shared parameters. I’ve made 200 doors with like 2500 types. Might be a waste of time if I cant get working catalogs into the library with them 🫠 although Ill try work on making an excel export or something that may work.  
 ![image](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/f/6/f6c4173f58768f6c070cb342d52e0c85e4379055.jpeg)

---

<div class="post-metadata">

**Author:** ![SeanP](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/seanp/32/42560_2.png) [@SeanP](https://forum.dynamobim.com/u/SeanP)\
**Post date:** [May 10, 2023, 2:38am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/7 "2023-05-10T02:38:34Z")

</div>

What version of Revit?

---

<div class="post-metadata">

**Author:** ![vanman](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/vanman/32/20881_2.png) [@vanman](https://forum.dynamobim.com/u/vanman)\
**Post date:** [May 10, 2023, 2:49am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/8 "2023-05-10T02:49:21Z")

</div>

22, dynamo 2.10

---

<div class="post-metadata">

**Author:** ![SeanP](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/seanp/32/42560_2.png) [@SeanP](https://forum.dynamobim.com/u/SeanP)\
**Post date:** [May 10, 2023, 2:57am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/9 "2023-05-10T02:57:08Z")

</div>

Ok, that is after the SpecType change so yeah the DUT isn’t going to work. I may try to see if I can refactor, but wouldn’t be at least till tomorrow.

> [@DisplayUnitType not defined error](https://forum.dynamobim.com/t/displayunittype-not-defined-error/63998/2):
>
> They changed the API which would have an affect on this in 2022.

I don’t have python available, but here is my C# which should be easy enough to port.

```auto
namespace RDGRevit.Commands
{
	[Transaction(TransactionMode.Manual)]
	class FamilyTypeCatalogExport : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Document doc = commandData.Application.ActiveUIDocument.Document;
			List<FamilyParameter> usedParams = new List<FamilyParameter>();
			FamilyParameterSet famParams = doc.FamilyManager.Parameters;
			Units famUnits = doc.GetUnits();
			FormatOptions len = famUnits.GetFormatOptions(SpecTypeId.Length);
			List<string> output = new List<string>();
			SaveFileDialog fsd = new SaveFileDialog
			{
				Filter = "Text File | *.txt",
				DefaultExt = "txt",
				OverwritePrompt = true,
				FileName = doc.Title
			};
			if(fsd.ShowDialog() == DialogResult.OK)
			{
				string path = fsd.FileName;
				FamilyTypeSet famTypes = doc.FamilyManager.Types;

				foreach(FamilyType type in famTypes)
				{
					foreach(FamilyParameter param in famParams)
					{
						if(!param.IsDeterminedByFormula)
						{
							if(type.HasValue(param))
							{
								if(!usedParams.Contains(param))
								{
									usedParams.Add(param);
								}
							}
						}
					}
				}
				string variables = "";
				foreach(FamilyParameter param in usedParams)
				{
					ForgeTypeId pType = param.Definition.GetDataType();
					string pName = param.Definition.Name;

					if(pType == SpecTypeId.Length)
					{
						variables += "," + pName + "##LENGTH##FEET";
					}
					else if(pType == SpecTypeId.Area)
					{
						variables += "," + pName + "##AREA##SQUARE_FEET";
					}
					else if(pType == SpecTypeId.Volume)
					{
						variables += "," + pName + "##VOLUME##CUBIC_FEET";
					}
					else if(pType == SpecTypeId.Slope)
					{
						variables += "," + pName + "##SLOPE##SLOPE_DEGREES";
					}
					else if(pType == SpecTypeId.Angle)
					{
						variables += "," + pName + "##ANGLE##DECIMAL DEGREES";
					}
					else if(pType == SpecTypeId.Currency)
					{
						variables += "," + pName + "##CURRENCY##CURRENCY";
					}
					else
					{
						variables += "," + pName + "##OTHER##";
					}
				}
				output.Add(variables);
				foreach(FamilyType famType in famTypes)
				{
					string typeString = "";
					typeString += famType.Name;
					foreach(FamilyParameter param in usedParams)
					{
						ForgeTypeId pt = param.Definition.GetDataType();
						StorageType storeType = param.StorageType;
						string value = string.Empty;
						if(storeType == StorageType.Double)
						{
							if(pt == SpecTypeId.Angle && famType.AsDouble(param) is double angle)
							{
								value = UnitUtils.ConvertFromInternalUnits(angle, UnitTypeId.Degrees).ToString();
							}
							else if(pt == SpecTypeId.Slope && famType.AsDouble(param) is double slope)
							{
								value = UnitUtils.ConvertFromInternalUnits(slope, UnitTypeId.SlopeDegrees).ToString();
							}
							else
							{
								value = famType.AsDouble(param).ToString();
							}
						}
						else if(storeType == StorageType.Integer)
						{
							value = famType.AsInteger(param).ToString();
						}
						else if(storeType == StorageType.String)
						{
							value = famType.AsString(param);
						}
						else if(storeType == StorageType.ElementId)
						{
							ElementId eId = famType.AsElementId(param);
							if(doc.GetElement(eId) is Element elem)
							{
								value = elem.Name;
							}
						}
						typeString += "," + value;
					}
					output.Add(typeString);
				}
				using(StreamWriter sw = new StreamWriter(path))
				{
					foreach(var line in output)
					{
						sw.WriteLine(line);
					}
				}
			}
			return Result.Succeeded;
		}
	}
}

```

---

<div class="post-metadata">

**Author:** ![vanman](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/vanman/32/20881_2.png) [@vanman](https://forum.dynamobim.com/u/vanman)\
**Post date:** [May 10, 2023, 3:18am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/10 "2023-05-10T03:18:07Z")

</div>

Thanks Sean! appreciate it. I can upgrade to R23 if that would solve the issue too. Will try your C sharp in the mean time 🙂

---

<div class="post-metadata">

**Author:** ![SeanP](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/seanp/32/42560_2.png) [@SeanP](https://forum.dynamobim.com/u/SeanP)\
**Post date:** [May 10, 2023, 3:20am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/11 "2023-05-10T03:20:53Z")

</div>

No, the code in my old graph is outdated after 2021, so it won’t work in anything newer than 2022 unless you modify it.

---

<div class="post-metadata">

**Author:** ![vanman](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/vanman/32/20881_2.png) [@vanman](https://forum.dynamobim.com/u/vanman)\
**Post date:** [May 10, 2023, 4:17am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/13 "2023-05-10T04:17:57Z")

</div>

I’m actually not sure what to do with C sharp and dynamo sorry… Not sure what port means too 😅

```auto
#Sean Page, 2021
import clr

clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager

clr.AddReference('System')
from System.Collections.Generic import List
from System import *
from System.IO import StreamWriter
from System.Text import Encoding
import codecs
doc = DocumentManager.Instance.CurrentDBDocument
#Preparing input from dynamo to revit
path = IN[1]
#units = doc.GetUnits().GetFormatOptions(UnitType.UT_Length).DisplayUnits
famParams = IN[0]
output = []
famTypes = doc.FamilyManager.Types
#Set up the first line of the Type Catalog with the headers
variables = ''
for param in famParams:
	pType = param.Definition.ParameterType
	pName = param.Definition.Name
	#check to see if the parameter name has a comma and encapsulate with double quoates
	if pName.Contains(','):
		pName = '"'+pName+'"'
	if pType == ParameterType.Length:
		variables += "," + pName + "##LENGTH##FEET"
	elif pType == ParameterType.Area:
		variables += "," + pName + "##AREA##SQUARE_FEET"
	elif pType == ParameterType.Volume:
		variables += "," + pName + "##VOLUME##CUBIC_FEET"
	elif pType == ParameterType.Slope:
		variables += "," + pName + "##SLOPE##SLOPE_DEGREES"
	elif pType == ParameterType.Angle:
		variables += "," + pName + "##ANGLE##DECIMAL DEGREES"
	elif pType == ParameterType.Currency:
		variables += "," + pName + "##CURRENCY##CURRENCY"
	else:
		variables += "," + pName + "##OTHER##"
#Add the headers to the final output
output.Add(variables + '\r\n')
#Iterate each type and get the values for each parameter ased on its Storage Type and Parameter Type
for famType in famTypes:
	typeString = String.Empty
	typeString += famType.Name
	for param in famParams:
		pType = param.Definition.ParameterType
		sType = param.StorageType
		value = String.Empty
		if sType == StorageType.Double:
			if pType == ParameterType.Angle:
				value = UnitUtils.ConvertFromInternalUnits(famType.AsDouble(param),DisplayUnitType.DUT_DECIMAL_DEGREES).ToString()
			elif pType == ParameterType.Slope:
				value = UnitUtils.ConvertFromInternalUnits(famType.AsDouble(param),DisplayUnitType.DUT_SLOPE_DEGREES).ToString()
			else:
				value = famType.AsDouble(param).ToString()
		if sType == StorageType.Integer:
			value = famType.AsInteger(param).ToString()
		if sType == StorageType.String:
			value = famType.AsString(param)
		if sType == StorageType.ElementId:
			eid = famType.AsElementId(param)
			elem = doc.GetElement(eid)
			try:
				value = Element.Name. __get__ (elem)
			except:
				#This catches materials specifically that are "<Default>" and don't have a name
				value = String.Empty
		#Check for commas in the value and encapsulate with double quotes as needed
		if value.Contains(','):
			value = '"'+value+'"'
		#Add each value for each parameter
		typeString += ","+value
	#Add all values for each Family Type	
	output.Add(typeString + '\r\n')
outfile = codecs.open(path, 'w', encoding='utf-16-le')
try:
	#Write each line to a txt file while encoding for special characters
	for line in output:
		outfile.write(line)
	outfile.close()
	OUT = output
except:
	outfile.close()
	OUT = "Failed to Write File"

```

---

<div class="post-metadata">

**Author:** ![SeanP](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/seanp/32/42560_2.png) [@SeanP](https://forum.dynamobim.com/u/SeanP)\
**Post date:** [May 10, 2023, 11:25am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/14 "2023-05-10T11:25:22Z")

</div>

See if this will work. I have not tested it, but it should.

```auto
#Sean Page, 2023
import clr

clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager

clr.AddReference('System')
from System.Collections.Generic import List
from System import *
from System.IO import StreamWriter
from System.Text import Encoding
import codecs
doc = DocumentManager.Instance.CurrentDBDocument
#Preparing input from dynamo to revit
path = IN[1]
#units = doc.GetUnits().GetFormatOptions(UnitType.UT_Length).DisplayUnits
famParams = IN[0]
output = []
famTypes = doc.FamilyManager.Types
#Set up the first line of the Type Catalog with the headers
variables = ''
for param in famParams:
	pType = param.Definition.GetDataType()
	pName = param.Definition.Name
	#check to see if the parameter name has a comma and encapsulate with double quoates
	if pName.Contains(','):
		pName = '"'+pName+'"'
	if pType == SpecTypeId.Length:
		variables += "," + pName + "##LENGTH##FEET"
	elif pType == SpecTypeId.Area:
		variables += "," + pName + "##AREA##SQUARE_FEET"
	elif pType == SpecTypeId.Volume:
		variables += "," + pName + "##VOLUME##CUBIC_FEET"
	elif pType == SpecTypeId.Slope:
		variables += "," + pName + "##SLOPE##SLOPE_DEGREES"
	elif pType == SpecTypeId.Angle:
		variables += "," + pName + "##ANGLE##DECIMAL DEGREES"
	elif pType == SpecTypeId.Currency:
		variables += "," + pName + "##CURRENCY##CURRENCY"
	else:
		variables += "," + pName + "##OTHER##"
#Add the headers to the final output
output.Add(variables + '\r\n')
#Iterate each type and get the values for each parameter ased on its Storage Type and Parameter Type
for famType in famTypes:
	typeString = String.Empty
	typeString += famType.Name
	for param in famParams:
		pType = param.Definition.GetDataType()
		sType = param.StorageType
		value = String.Empty
		if sType == StorageType.Double:
			if pType == SpecTypeId.Angle:
				value = UnitUtils.ConvertFromInternalUnits(famType.AsDouble(param),UnitTypeId.Degrees).ToString()
			elif pType == SpecTypeId.Slope:
				value = UnitUtils.ConvertFromInternalUnits(famType.AsDouble(param),UnitTypeId.SlopeDegrees).ToString()
			else:
				value = famType.AsDouble(param).ToString()
		if sType == StorageType.Integer:
			value = famType.AsInteger(param).ToString()
		if sType == StorageType.String:
			value = famType.AsString(param)
		if sType == StorageType.ElementId:
			eid = famType.AsElementId(param)
			elem = doc.GetElement(eid)
			try:
				value = Element.Name. __get__ (elem)
			except:
				#This catches materials specifically that are "<Default>" and don't have a name
				value = String.Empty
		#Check for commas in the value and encapsulate with double quotes as needed
		if value.Contains(','):
			value = '"'+value+'"'
		#Add each value for each parameter
		typeString += ","+value
	#Add all values for each Family Type	
	output.Add(typeString + '\r\n')
outfile = codecs.open(path, 'w', encoding='utf-16-le')
try:
	#Write each line to a txt file while encoding for special characters
	for line in output:
		outfile.write(line)
	outfile.close()
	OUT = output
except:
	outfile.close()
	OUT = "Failed to Write File"

```

---

<div class="post-metadata">

**Author:** ![vanman](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/vanman/32/20881_2.png) [@vanman](https://forum.dynamobim.com/u/vanman)\
**Post date:** [May 10, 2023, 10:59pm UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/15 "2023-05-10T22:59:01Z")

</div>

Thanks Sean! its throwing up the error below.  
 ![image](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/e/4/e456b19e02ae323a4a217c9064bb292d9b5f17a3.png)

---

<div class="post-metadata">

**Author:** ![SeanP](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/seanp/32/42560_2.png) [@SeanP](https://forum.dynamobim.com/u/SeanP)\
**Post date:** [May 10, 2023, 11:15pm UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/16 "2023-05-10T23:15:56Z")

</div>

Try to change any of the contains locations like this I guess.

`if pName.Contains(','):`

to

`if ',' in pName:`

---

<div class="post-metadata">

**Author:** ![vanman](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/vanman/32/20881_2.png) [@vanman](https://forum.dynamobim.com/u/vanman)\
**Post date:** [May 10, 2023, 11:48pm UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/17 "2023-05-10T23:48:52Z")

</div>

> [@SeanP](#):
>
> ```auto
> #Sean Page, 2023
> import clr
> 
> clr.AddReference('RevitAPI')
> from Autodesk.Revit.DB import *
> 
> clr.AddReference('RevitServices')
> import RevitServices
> from RevitServices.Persistence import DocumentManager
> 
> clr.AddReference('System')
> from System.Collections.Generic import List
> from System import *
> from System.IO import StreamWriter
> from System.Text import Encoding
> import codecs
> doc = DocumentManager.Instance.CurrentDBDocument
> #Preparing input from dynamo to revit
> path = IN[1]
> #units = doc.GetUnits().GetFormatOptions(UnitType.UT_Length).DisplayUnits
> famParams = IN[0]
> output = []
> famTypes = doc.FamilyManager.Types
> #Set up the first line of the Type Catalog with the headers
> variables = ''
> for param in famParams:
> pType = param.Definition.GetDataType()
> pName = param.Definition.Name
> #check to see if the parameter name has a comma and encapsulate with double quoates
> if pName.Contains(','):
> pName = '"'+pName+'"'
> if pType == SpecTypeId.Length:
> variables += "," + pName + "##LENGTH##FEET"
> elif pType == SpecTypeId.Area:
> variables += "," + pName + "##AREA##SQUARE_FEET"
> elif pType == SpecTypeId.Volume:
> variables += "," + pName + "##VOLUME##CUBIC_FEET"
> elif pType == SpecTypeId.Slope:
> variables += "," + pName + "##SLOPE##SLOPE_DEGREES"
> elif pType == SpecTypeId.Angle:
> variables += "," + pName + "##ANGLE##DECIMAL DEGREES"
> elif pType == SpecTypeId.Currency:
> variables += "," + pName + "##CURRENCY##CURRENCY"
> else:
> variables += "," + pName + "##OTHER##"
> #Add the headers to the final output
> output.Add(variables + '\r\n')
> #Iterate each type and get the values for each parameter ased on its Storage Type and Parameter Type
> for famType in famTypes:
> typeString = String.Empty
> typeString += famType.Name
> for param in famParams:
> pType = param.Definition.GetDataType()
> sType = param.StorageType
> value = String.Empty
> if sType == StorageType.Double:
> if pType == SpecTypeId.Angle:
> value = UnitUtils.ConvertFromInternalUnits(famType.AsDouble(param),UnitTypeId.Degrees).ToString()
> elif pType == SpecTypeId.Slope:
> value = UnitUtils.ConvertFromInternalUnits(famType.AsDouble(param),UnitTypeId.SlopeDegrees).ToString()
> else:
> value = famType.AsDouble(param).ToString()
> if sType == StorageType.Integer:
> value = famType.AsInteger(param).ToString()
> if sType == StorageType.String:
> value = famType.AsString(param)
> if sType == StorageType.ElementId:
> eid = famType.AsElementId(param)
> elem = doc.GetElement(eid)
> try:
> value = Element.Name. __get__ (elem)
> except:
> #This catches materials specifically that are "<Default>" and don't have a name
> value = String.Empty
> #Check for commas in the value and encapsulate with double quotes as needed
> if value.Contains(','):
> value = '"'+value+'"'
> #Add each value for each parameter
> typeString += ","+value
> #Add all values for each Family Type	
> output.Add(typeString + '\r\n')
> outfile = codecs.open(path, 'w', encoding='utf-16-le')
> try:
> #Write each line to a txt file while encoding for special characters
> for line in output:
> outfile.write(line)
> outfile.close()
> OUT = output
> except:
> outfile.close()
> OUT = "Failed to Write File"
> 
> ```
> 
> [52\_Hinge 2\_Two Way Opposing.rfa](https://forum.dynamobim.com/uploads/short-url/n8DUX7VkwsNDmnY5hNOQ0H761s3.rfa) (1.5 MB)  
> [Export Family Type Catalog.dyn](https://forum.dynamobim.com/uploads/short-url/ypW1EqRMSk9OPnaTwOkPbZOmQJ.dyn) (49.7 KB)

I think its this part

```auto
#Check for commas in the value and encapsulate with double quotes as needed
		if value.Contains(','):
			value = '"'+value+'"'

```

![image](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/1/a/1a235133d9fcb92ededb8c3ac125cca0643724f5.png)

---

<div class="post-metadata">

**Author:** ![vanman](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/vanman/32/20881_2.png) [@vanman](https://forum.dynamobim.com/u/vanman)\
**Post date:** [May 11, 2023, 5:16am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/18 "2023-05-11T05:16:45Z")

</div>

Smart fella at work helped me. Have to open and save the text file after making it or it dosnt work. Get cannot parse column header error. Which after making 200 text files isnt going to be great.

Other thing was changing units to metric and needed to input doc.

```auto
#Sean Page, 2023
import clr

clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager

clr.AddReference('System')
from System.Collections.Generic import List
from System import *
from System.IO import StreamWriter
from System.Text import Encoding
import codecs
doc = IN[2]
#Preparing input from dynamo to revit
path = IN[1]
#units = doc.GetUnits().GetFormatOptions(UnitType.UT_Length).DisplayUnits
famParams = IN[0]
output = []
famTypes = doc.FamilyManager.Types
#Set up the first line of the Type Catalog with the headers
variables = " "
for param in famParams:
	pType = param.Definition.GetDataType()
	pName = param.Definition.Name
	#check to see if the parameter name has a comma and encapsulate with double quoates
	if ',' in pName:
		pName = '"'+pName+'"'
	if pType == SpecTypeId.Length:
		variables += "," + pName + "##LENGTH##MILLIMETERS"
	elif pType == SpecTypeId.Area:
		variables += "," + pName + "##AREA##SQUARE_MILLIMETERS"
	elif pType == SpecTypeId.Volume:
		variables += "," + pName + "##VOLUME##CUBIC_MILLIMETERS"
	elif pType == SpecTypeId.Slope:
		variables += "," + pName + "##SLOPE##SLOPE_DEGREES"
	elif pType == SpecTypeId.Angle:
		variables += "," + pName + "##ANGLE##DEGREES"
	elif pType == SpecTypeId.Currency:
		variables += "," + pName + "##CURRENCY##CURRENCY"
	else:
		variables += "," + pName + "##OTHER##"

trimmedvar = variables[1:]
variables = trimmedvar
#Add the headers to the final output
output.Add(variables + '\r\n')
#Iterate each type and get the values for each parameter ased on its Storage Type and Parameter Type
for famType in famTypes:
	typeString = String.Empty
	typeString += famType.Name
	for param in famParams:
		pType = param.Definition.GetDataType()
		sType = param.StorageType
		value = String.Empty
		if sType == StorageType.Double:
			if pType == SpecTypeId.Angle:
				value = UnitUtils.ConvertFromInternalUnits(famType.AsDouble(param),UnitTypeId.Degrees).ToString()
			elif pType == SpecTypeId.Slope:
				value = UnitUtils.ConvertFromInternalUnits(famType.AsDouble(param),UnitTypeId.SlopeDegrees).ToString()
			else:
				value = famType.AsDouble(param).ToString()
		if sType == StorageType.Integer:
			value = famType.AsInteger(param).ToString()
		if sType == StorageType.String:
			value = famType.AsString(param)
		if sType == StorageType.ElementId:
			eid = famType.AsElementId(param)
			elem = doc.GetElement(eid)
			try:
				value = Element.Name. __get__ (elem)
			except:
				#This catches materials specifically that are "<Default>" and don't have a name
				value = String.Empty
		#Check for commas in the value and encapsulate with double quotes as needed
		try:
			if	',' in value:
				value = '"'+value+'"'
		except:
			#This catches materials specifically that are "<Default>" and don't have a name
			value = String.Empty
		#Add each value for each parameter
		typeString += ","+value.ToString()
	#Add all values for each Family Type	
	output.Add(typeString + '\r\n')
outfile = codecs.open(path, 'w', encoding='utf-16-le')
try:
	#Write each line to a txt file while encoding for special characters
	for line in output:
		outfile.write(line)
	outfile.close()
	OUT = output
except:
	outfile.close()
	OUT = "Failed to Write File"

```

---

<div class="post-metadata">

**Author:** ![SeanP](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/seanp/32/42560_2.png) [@SeanP](https://forum.dynamobim.com/u/SeanP)\
**Post date:** [May 11, 2023, 1:37pm UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/19 "2023-05-11T13:37:17Z")

</div>

Here is the graph that is working for me on your Family.

[Selected Family Type Catalog Metric.dyn](https://forum.dynamobim.com/uploads/short-url/ynC8iICEr8jLEBxfbg12RnsF0N0.dyn) (37.6 KB)

Selection of Parameters in the family.

 ![image](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/2/8/28f6c73491da473f76dd3ff4cbc6d91b8b5d003b.png)

Here is the catalog available for selection.

 ![image](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/9/d/9d25d682dcfe45515f401baae8778f0cff2acdfd.png)

Looks like it throws warnings when it can’t find the materials.

 ![image](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/a/1/a19cdcdff365769da015ca52d1a2f80b412344d4.png)

---

<div class="post-metadata">

**Author:** ![vanman](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/vanman/32/20881_2.png) [@vanman](https://forum.dynamobim.com/u/vanman)\
**Post date:** [May 14, 2023, 2:02am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/20 "2023-05-14T02:02:20Z")

</div>

This is great thanks Sean! Turned it into a node and exported 200 family catalogs 🙂 Just wondering if theres a way to get the types ordered when importing?

---

<div class="post-metadata">

**Author:** ![SeanP](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/seanp/32/42560_2.png) [@SeanP](https://forum.dynamobim.com/u/SeanP)\
**Post date:** [May 14, 2023, 2:34am UTC](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333/21 "2023-05-14T02:34:46Z")

</div>

If you sorted the famParams list before iterating.

[Next page](https://forum.dynamobim.com/t/export-family-types-as-text-node/89333.md?page=2)
