Duplicate / Copy Layouts

Hi,

is there any node that duplicates an existing layout n times ?

if not, could you please help me write a python code that does exactly this ?

Many thanks.

Hi , here an example with Python

code (use PythonNet3)

import sys
import clr

# Add Assemblies for AutoCAD and Civil3D
clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')

# Import references from AutoCAD
from Autodesk.AutoCAD.Runtime import *
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.EditorInput import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *

# Import references from Civil3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

# The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN

adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor
db = adoc.Database

class CManager:
    """
    a custom context manager for Disposable Object
    """
    def __init__(self, obj):
        self.obj = obj
        
    def __enter__(self):
        return self.obj
        
    def __exit__(self, exc_type, exc_value, exc_tb):
        self.obj.Dispose()
        if exc_type:
            error = f"{exc_value} at line {exc_tb.tb_lineno}"
            raise ValueError( error)
        return self
        
        
        
layout_name = IN[0]

with adoc.LockDocument():
    with CManager(adoc.Database) as db:
        with CManager(db.TransactionManager.StartTransaction()) as t:
            layout_dict = t.GetObject(db.LayoutDictionaryId, OpenMode.ForRead)
            
            if layout_dict.Contains(layout_name):
                target_name = layout_name + "-Copy"
                # copy the layout via the global LayoutManager
                lm = LayoutManager.Current
                lm.CloneLayout(layout_name, target_name, lm.LayoutCount + 1)
                # OR
                # lm.CopyLayout(layout_name, target_name)
            t.Commit()

Many thanks Cyril,

This creates a single copy from a given layout, is there a way to enhance this by adding the number of duplications desired as an input ?

sure

import sys
import clr

# Add Assemblies for AutoCAD and Civil3D
clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')

# Import references from AutoCAD
from Autodesk.AutoCAD.Runtime import *
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.EditorInput import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *

# Import references from Civil3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

# The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN

adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor
db = adoc.Database

class CManager:
    """
    a custom context manager for Disposable Object
    """
    def __init__(self, obj):
        self.obj = obj
        
    def __enter__(self):
        return self.obj
        
    def __exit__(self, exc_type, exc_value, exc_tb):
        self.obj.Dispose()
        if exc_type:
            error = f"{exc_value} at line {exc_tb.tb_lineno}"
            raise ValueError( error)
        return self
        
        
        
layout_name_to_duplicate = IN[0]
new_names = IN[1]

with adoc.LockDocument():
    with CManager(adoc.Database) as db:
        with CManager(db.TransactionManager.StartTransaction()) as t:
            layout_dict = t.GetObject(db.LayoutDictionaryId, OpenMode.ForRead)
            
            if layout_dict.Contains(layout_name_to_duplicate):
                for target_name in new_names:
                    # copy the layout via the global LayoutManager
                    lm = LayoutManager.Current
                    lm.CloneLayout(layout_name_to_duplicate, target_name, lm.LayoutCount + 1)
                    # OR
                    # lm.CopyLayout(layout_name_to_duplicate, target_name)
            t.Commit()

Astonishing ! This does exactly that.

Thank you so much for your time and effort Cyril. :slightly_smiling_face: