Copying Views and Sheets to another project

Hi all,

I am trying to create a pyrevit script that will copy drafting views and sheets from one project to another. I started with the views but it doesn’t seem to be copying and I’m not sure whats going wrong.

from pyrevit import script, revit, DB, forms
from System.Collections.Generic import List

docTo = revit.doc

docFrom = forms.select_open_docs(title = 'Select a document', button_name = 'Select', width = 500, multiple = False)

if not docFrom:
  script.exit()
elif docFrom.IsFamilyDocument:
  forms.alert("Must choose a non-family document", title = "Script Cancelled")

views = DB.FilteredElementCollector(docFrom).OfCategory(DB.BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()

eles_unsorted = [v for v in views]
eles_sorted = sorted(eles_unsorted, key = lambda x: x.Name)

class ElementToCopy(forms.TemplateListItem):
  @property
  def name(self):
    return self.item.Name
  
options_copy = [ElementToCopy(e) for e in eles_sorted]
eles_copy = forms.SelectFromList.show(options_copy, title = 'Select elements', width = 500, button_name = 'Copy', multiselect = True)

if not eles_copy:
  script.exit()

ids = [e.Id for e in eles_copy]
ids_copy = List[DB.ElementId](ids)
cpOpts = DB.CopyPasteOptions()
tfrm = DB.Transform.Identity

with revit.Transaction('Copy View Contents',doc=docTo,swallow_errors=True):
    DB.ElementTransformUtils.CopyElements(docFrom, ids_copy, docTo, None, cpOpts)

Thanks

Hi @rivindub,

Start by removing the swallow_errors=True argument from the Transaction handler so that you get some error traceback.

You could also use the following method:

from pyrevit.revit import create
from pyrevit.revit import Transaction

with Transaction("transaction name", doc):
    create.copy_elements(element_ids, src_doc, dest_doc)

Here are a few examples:

Hi @Jean-Marc,

Thanks for the reply and examples. However, none of these seem to be what I’m looking for.

I want to copy the actual views from one document to another.

Something similar to this Insert button is already in Revit. But I don’t want the user to have to click and select the source file they want to copy across from. I want to make the source file static and then let the user choose which views they want to import from a list.

Something like this which will prompt the user to choose from all the views and sheets and schedules etc.

Thanks

Hello,

Thank you for taking the time to post about this. I am working on something very similar as well. Were you able to find the solution how to import the 2d views from another project into your current project?

Have you tried asking an LLM ? This (untested!) seems promising:

from pyrevit import forms, DB, revit, script
from pyrevit.framework import List

MY_TEMPLATE = r"C:\template.rvt"

# --------------------------------------------------------
# Open template document
# --------------------------------------------------------

app = revit.doc.Application

model_path = DB.ModelPathUtils.ConvertUserVisiblePathToModelPath(MY_TEMPLATE)
open_opts = DB.OpenOptions()

source_doc = app.OpenDocumentFile(model_path, open_opts)
dest_doc = revit.doc

# --------------------------------------------------------
# Filter function for selectable views
# --------------------------------------------------------

def my_filterfunc(view):
    # Drafting Views
    if isinstance(view, DB.ViewDrafting):
        return True

    # Schedules (exclude revision schedules)
    if isinstance(view, DB.ViewSchedule) and not view.IsTitleblockRevisionSchedule:
        return True

    return False


# --------------------------------------------------------
# Select views from TEMPLATE doc
# --------------------------------------------------------

views_to_copy = forms.select_views(
    title='Select Views to Copy',
    doc=source_doc,
    filterfunc=my_filterfunc
)

if not views_to_copy:
    forms.alert("No views selected.")
    source_doc.Close(False)
    script.exit()

# --------------------------------------------------------
# Copy views
# --------------------------------------------------------

ids = List[DB.ElementId]()
for v in views_to_copy:
    ids.Add(v.Id)

options = DB.CopyPasteOptions()

with revit.Transaction("Copy Views From Template"):
    DB.ElementTransformUtils.CopyElements(
        source_doc,
        ids,
        dest_doc,
        None,
        options
    )

forms.alert("Views copied successfully!")

# Optional: close template without saving
source_doc.Close(False)