Access more then one document in single python?

Dear All,

I want to copy elements from source document to target document and after that delete elements in source.
for that I tried,

TransactionManager.Instance.EnsureInTransaction(targetDoc)
result = Autodesk.Revit.DB.ElementTransformUtils.CopyElements(srcDoc, ids, targetDoc, None, None)
TransactionManager.Instance.TransactionTaskDone()

TransactionManager.Instance.EnsureInTransaction(srcDoc)
sourceDoc.Delete(ids)
TransactionManager.Instance.TransactionTaskDone()

When I try this Code, Python returns this error message,

forbidden because the document has no open transaction.

Does anyone know, how I can work in two documents in single python script?

Thanks!

Hi @st142136,

Is your source document a linked document? I don’t believe you can delete element in a linked document or modify it in anyway. (Someone will correct me if I’m wrong I’m sure)

You can copy elements though with the ElementTransformUtils class with the method CopyElements().

Cheers,
Dan

1 Like

Hi Daniel,

No They are two different RVT Project Files.

Regards,

OK, you are on the right path, but what you missed is the fact that you cannot use the same DocumentManager method for opening a transaction in an external document. I don’t think that it was coded with that possibility in mind, and it just doesn’t handle it well.

Here’s how to do it. Here’s my document 1:

I am just copying the walls that are in it. I will take the whole thing, and paste it into the document 2:

Result:

Python code:

# Copyright(c) 2017, Konrad K Sobon
# @arch_laboratory, http://archi-lab.net

# Import Element wrapper extension methods
import clr
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)

RunIt = IN[1]

class CustomCopyHandler(IDuplicateTypeNamesHandler):
	def OnDuplicateTypeNamesFound(self, args):
		return DuplicateTypeAction.UseDestinationTypes

try:
	if RunIt:
		# First copy elements into current document
		TransactionManager.Instance.EnsureInTransaction(doc)
		errorReport = None
		fileDoc = app.OpenDocumentFile(IN[0])
		walls = FilteredElementCollector(fileDoc).OfClass(Wall).ToElementIds()
		trans = Autodesk.Revit.DB.Transform.Identity
		co = CopyPasteOptions()
		co.SetDuplicateTypeNamesHandler(CustomCopyHandler())
		newIds = ElementTransformUtils.CopyElements(fileDoc, walls, doc, trans, co)
		output = []
		if newIds != None:
			for i in newIds:
				output.append(doc.GetElement(i).ToDSType(False))
		TransactionManager.Instance.TransactionTaskDone()
		
		# Secondly delete copied elements from the original document
		# only if all of them were copied over
		if len(walls) == len(newIds): 
			trans = Transaction(fileDoc, "DeleteElements")
			trans.Start()
			fileDoc.Delete(walls)
			trans.Commit()
			fileDoc.Close()
	else:
		errorReport = "Set Run it to true!"
except:
	# if error accurs anywhere in the process catch it
	import traceback
	errorReport = traceback.format_exc()

#Assign your output to the OUT variable
if errorReport == None:
	OUT = output
else:
	OUT = errorReport

Good luck!

5 Likes

Thank you Konrad & Sorry for my delayed response.
I will try you suggestion. This will work better than I planed. :slight_smile:

Regards,