Reload families in revit using dynamo/Pyhton


Good evening, everyone! I’m new to Dynamo/Python and I’ve developed a Dynamo-Python script to load/reload multiple families in Revit by searching through a specific folder. However, I’d like to make a modification to this script so that it only reloads the families that already exist in the project, rather than loading all the families from a specific folder. I’ve tried using Revit’s ‘purge’ tool, but the drawback is that it deletes the types of families in the project. I want to keep the types of families that are already in Revit!
Here are the Python code snippets for the nodes.
WindowsForm Create :

import clr
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')
clr.AddReference('RevitAPI')
from System.Drawing import Size, Color, SolidBrush, Rectangle, Point
from System.Windows.Forms import *
from System.IO import Directory, SearchOption
from Autodesk.Revit.DB import IFamilyLoadOptions, Document

class FamilyOption(IFamilyLoadOptions):
    def OnFamilyFound(self, familyInUse, overwriteParameterValues):
        overwriteParameterValues = True
        return True

    def OnSharedFamilyFound(self, sharedFamily, familyInUse, source, overwriteParameterValues):
        return True

class TESForm(Form):
    def __init__(self):
        self.Text = "Families Loader/ReLoader"
        self.Width = 500
        self.Height = 310
        self.MaximizeBox = False
        self.MinimizeBox = False
        self.ControlBox = False
        self.FormBorderStyle = FormBorderStyle.FixedSingle
        self.ShowIcon = False
        self.StartPosition = FormStartPosition.CenterScreen
        self.TopMost = True
        self.values = []

        self.label = Label()
        self.label.Text = "--- NO PATH FOUND ---"
        self.label.Location = Point(20, 13)
        self.label.Height = 30
        self.label.Width = 290
        self.label.ForeColor = Color.Red

        self.button = Button()
        self.button.Text = "Nothing to reload"
        self.button.Width = 330
        self.button.Location = Point(20, 230)
        self.button.Click += self.setclose
        self.button.Enabled = False

        self.button0 = Button()
        self.button0.Text = "Browse..."
        self.button0.Width = 100
        self.button0.Location = Point(360, 10)
        self.button0.Click += self.OnClickedFile

        self.button1 = Button()
        self.button1.Text = "Exit"
        self.button1.Width = 100
        self.button1.Location = Point(360, 230)
        self.button1.Click += self.setexit

        self.list = ListBox()
        self.list.Size = Size(440, 150)
        self.list.Location = Point(20, 50)
        self.list.SelectionMode = SelectionMode.MultiExtended

        self.check = CheckBox()
        self.check.Location = Point(20, 205)
        self.check.Text = 'Select all'
        self.check.Width = 70
        self.check.Enabled = False
        self.check.CheckedChanged += self.checkedChanged

        self.Controls.Add(self.label)
        self.Controls.Add(self.button)
        self.Controls.Add(self.button0)
        self.Controls.Add(self.button1)
        self.Controls.Add(self.list)
        self.Controls.Add(self.check)

    def setclose(self, sender, event):
        for idx in self.list.SelectedIndices:
            self.values.append(self.list.Items[idx])
        self.Close()

    def setexit(self, sender, event):
        self.values = 'Exit'
        self.Close()

    def checkedChanged(self, sender, args):
        if sender.Checked:
            for i in range(self.list.Items.Count):
                self.list.SetSelected(i, True)
        else:
            self.list.ClearSelected()
            self.list.SetSelected(0, True)

    def OnClickedFile(self, sender, events):
        dialog = FolderBrowserDialog()
        if dialog.ShowDialog(self) == DialogResult.OK:
            self.label.Text = dialog.SelectedPath
            if Directory.Exists(dialog.SelectedPath):
                files = Directory.GetFiles(dialog.SelectedPath, '*.rfa', SearchOption.AllDirectories)
                for file in files:
                    self.list.Items.Add(file)
            self.list.SetSelected(0, True)
            self.button.Enabled = True
            self.check.Enabled = True
            self.label.ForeColor = Color.Blue
            self.button.Text = "Load/ReLoad Families from path"
        else:
            self.list.Items.Clear()
            self.button.Enabled = False
            self.label.ForeColor = Color.Red
            self.button.Text = "Nothing to reload"
            self.check.Enabled = False

form = TESForm()
form.ShowDialog()
result = form.values
OUT = result

FamReloader :

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

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument

elements = IN[0]

class FamilyOption(IFamilyLoadOptions) :
 def OnFamilyFound(self, familyInUse, overwriteParameterValues) :
  overwriteParameterValues = True
  return True

 def OnSharedFamilyFound(self, sharedFamily, familyInUse, source, overwriteParameterValues) :
  return True

if IN[0] != 'Exit':
 TransactionManager.Instance.EnsureInTransaction(doc)
 try:
  for element in elements :
   doc.LoadFamily(element, FamilyOption())
   OUT = 'Families was loaded/reloaded'
 except:
  pass
 TransactionManager.Instance.TransactionTaskDone()
else:
 OUT = 'Exit'

I would like you to help me with this Dynamo/Python script to only reload the families that are already existing in a Revit project.
Thank you and have a good evening

1 Like

Make sure you format any code as preformatted text (</>) so it maintains its structure.

I would suggest getting all families in the project and comparing that list of names to the file names in the target folder. Then you can choose to load or skip based on matches.

1 Like

Good morning ! thank you for your answer, that means that I cannot directly make a modification to the python codes of these nodes directly, I have to change the sokution to be able to do this?

I don’t follow. You could automate all of this with python.