Export All Used Families in Project to Desktop

Ah, if all you’re looking to do is save out the family documents (guess I misinterpreted the question) you can try this python code, which is a work in progress. Feed in a list of families to save out, a target directory, and a boolean (true / false) to overwrite any which existing or not.

 '''
SAVE OUT FAMILY TO DIRECTORY
'''
__author__ = 'Jacob Samll'
__twitter__ = '@Jacob.W.Small'
__version__ ='1.0.0'

# Dynamo version - 2.0.3
# Revit version: 2019

#This takes a collection of families from the active document as input 0 and saves them as RFA files to the directory given at input 1, overwriting them acording to the boolean input 2. Only minimally tested, so proceed with caution

import sys
sys.path.append("C:\Program Files (x86)\IronPython 2.7\Lib")
#Saves a list of families in the active project to a given directory, using the family name as the file name
import clr #imports the common language runtime to the Iron Python Environment
clr.AddReference("RevitServices") #adds Revit Services library to the CLR
import RevitServices #brings the Revit Services library to the Iron Python environment
from RevitServices.Persistence import DocumentManager #bring the documnet manager module into the Iron Python environment
from RevitServices.Transactions import TransactionManager #brings the transaction manager into the Iron Python environment
clr.AddReference("RevitAPI") #adds the Revit API to the CLR
import Autodesk #imports the Autodesk library into the Iron Python environment
from Autodesk.Revit.DB import * #imports the entirety of the Revit.DB library - this could be made a bit more precise for increased efficiency
import traceback

##builds some of the consistent stuff before it begins to itterate over the list of inputs
doc = DocumentManager.Instance.CurrentDBDocument #sets the doc variable as the active document
families = UnwrapElement(IN[0]) #sets the base family variable to the contents of input 0
if not hasattr(families, '__iter__'): #checks if the input wasn't a list
families = [families] #if not, wraps the object in a list so we can ensure we've got something to iterate over
directory = IN[1] #sets the directory variable to the contents of input 1
filePaths = [directory+"\\"+family.Name+".rfa" for family in families] #builds a file path for each family by appending the directory to the family name an an rfa file extension.
overwrite = IN[2]
TransactionManager.Instance.ForceCloseTransaction() #closes any open transactions to be sure they don't prevent the code from executing
saveAsOptions = SaveAsOptions() #constructs a save as options object for use in the save as operation
saveAsOptions.OverwriteExistingFile = overwrite #sets the overwrite property for the just constructed save as options object to the value of input 2
resultSet = [] #builds an empty list to append the result message to.
i = 0 #sets the variable i to 0 to use as a means of iterating though the list of paths in sequence with the list of family documents

#personally I like really verbose messagint to users of code like this - adjust the messaging as you see fit
if overwrite:#if the value of input 2 is true performs the offset lines below
successMessage = " Saved out the family documnet.\n Overwrote any rfa with matching name.\n You can recover from the rfa backup \n in the same directory if such exists." #builds a meaningful success message for when this works with overwrite option set to false
else: #if the value of input 2 was not true performs the offset lines below
successMessage = " Saved the family document.\n No previously existing rfa at path." #builds a meaningful success message for when this works with the overwrite option set to false

#begins to itterate over the list of families
famDocs = [doc.EditFamily(family) for family in families] #gets the family document from the parent family
##there is likely a better way to do this via list comprehension, but I'm too tired to work it out right now - feel free to pass on any better ideas
for famDoc in famDocs: #begins a loop for each family document in the list of family documnets
try: #trys the offset lines below
famDoc.SaveAs(filePaths[i], saveAsOptions) #attempts to save the family document to the path at the matching index using the save as option
resultSet.append(families[i].Name+".rfa:\n"+successMessage) #appends the message to the result set
except: #if the above failed, does this
resultSet.append(families[i].Name+".rfa:\n File was not saved due to\n the following exception:\n "+traceback.format_exc().split("Exception: ")[-1].strip()) #appends the exception in what may consistently be a more human readible result... might want to test this more
i+=1 #increments the value of i by 1

OUT = resultSet #outputs the resultSet list to the Dynamo environment - you could push this as a message for the user

As noted aboe, this is still under development. Also it may be slightly over-commented as I’m using it in a presentation I have coming up, and I tend to over do my comments to begin with.