CopyElements Method Overload in Python

Hello,

I am trying to use the ElementTransformUtils.CopyElements method but specifically the View, ICollection<ElementId>, View, Transform, CopyPasteOptions overload. When I use the method with the arguments ViewSheet, ICollection<ElementId>, ViewSheet, I get an error saying expecting Document, got ViewSheet.

I am working in Revit 2018 with Dynamo 2.0.3. As far as I can tell, ViewSheet should work as a valid argument for the overload I am going for. Does anyone know what the issue would be?

Python snippet:

n_restId = ElementTransformUtils.CopyElements(o_sht, o_restId, n_sht)

where o_sht is the original ViewSheet with elements, o_restId is a list of ElementId for elements on o_sht, and n_sht is the destination ViewSheet.

I can add the rest of the python code if needed but 90% of it is irrelevant and pretty long.

Edit: Side question, I was trying to return the actual Autodesk.Revit.Exceptions class that it springs up but instead, the exception is an IronPython exception. How would I go about returning the Autodesk exception class in the try; except: statement?

You are only providing 3 arguments, so it is wrongly assuming that you are trying to use (Document, ICollection, CopyPasteOptions) as your overloads. Try this instead:

n_restId = ElementTransformUtils.CopyElements(o_sht, 
                                              o_restId, 
                                              n_sht, 
                                              None, 
                                              CopyPasteOptions())

If your list of ElementIds isn’t already a .NET List, make sure to do so like this:

from System.Collections.Generic import List
o_restIdList = List[ElementId](o_restId)

As for handling native Revit exceptions, I haven’t tried to do that yet in my workflow, but you may be able to import from the Autodesk.Revit.Exceptions namespace and handle the native exceptions directly.

3 Likes

So the CopyPasteOptions() arg was the problem. I had tried it using:

n_restId = ElementTransformUtils.CopyElements(o_sht, o_restId, n_sht, None, None)

for some reason thinking that it would default to an empty copypasteoptions if the arg was a null. When I ran it, it gave me the same error so I didn’t think twice :rofl: Thank you!

As for the exceptions, I have imported them to try and use their properties but thats when I found out that using

try:
     something
except Exception as e:
    e.GetType()

e returns some IronPython exception+base exception so I didn’t know how to get the Revit exception from it.

Just ran a small test for catching native Revit exceptions–it’s possible! See below:

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import FilteredElementCollector, ElementId
from Autodesk.Revit.Exceptions import ArgumentException

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

doc = DocumentManager.Instance.CurrentDBDocument

try:
	fec = FilteredElementCollector(doc, ElementId.InvalidElementId)
except ArgumentException:
	OUT = 'caught'

I think what’s happening when you use the more generic Exception class, you’re just casting the native Revit exception to a generic IronPython exception.

1 Like

Does this mean I can’t use a catchall except statement for exceptions like the generic IronPython one? As in I would need except for each type of exception? I mostly just wanted to return certain properties of the API exception’s class.

Actually, if you catch the generic .NET System.Exception you can then access the appropriate members.

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import FilteredElementCollector, ElementId

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

import System

doc = DocumentManager.Instance.CurrentDBDocument

try:
	fec = FilteredElementCollector(doc, ElementId.InvalidElementId)
except System.Exception as e:
	OUT = e.Message
2 Likes