Run a batch process to Turn Layers On/Off for a set of Drawings in Folder, Civil 3D/AutoCAD _Dynamo_Python

I am trying to run a batch process for a set of Drawing files in a folder, trying to turn CAD Layers ON/OFF in Civil 3D. Somehow the script is failing. I am using a couple of references similar to this one below:

https://forum.dynamobim.com/t/changing-the-visibility-of-layers-in-a-viewport-vp-freeze/74979

The Python Code below, I used a couple of sourced references as below, but its failing in the function

i = t.GetObject(lt[layer], OpenMode.ForWrite)

where I try to get the Layer Object. The layers are fed as layerNames Strings, as seen in the Dynamo Graph

"""
"""
Copyright 2020 Autodesk, Inc. All rights reserved.

This file is part of the Civil 3D Python Module.

"""
# __author__ = 'Paolo Emilio Serra - paolo.serra@autodesk.com'
# __copyright__ = '2020'
# __version__ = '1.0.0'

import clr

# Add Assemblies for AutoCAD and Civil 3D APIs
clr.AddReference('acmgd')
clr.AddReference('acdbmgd')
clr.AddReference('accoremgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')
clr.AddReference('AeccPressurePipesMgd')
clr.AddReference('acdbmgdbrep')
clr.AddReference('System.Windows.Forms')
clr.AddReference('AutoCADNodes')
clr.AddReference('Civil3DNodes')

# Add standard Python references
import sys
sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib')
import os
import math

import logging
import tempfile

from logging import error

FORMAT = '[%(asctime)-15s] %(levelname)s: %(module)s.%(funcName)s %(message)s'
logging.basicConfig(filename=os.path.join(tempfile.gettempdir(), 'D4C3D.log'), level=logging.DEBUG, format=FORMAT, datefmt='%Y/%m/%d %I:%M:%S')

# Add references to manage arrays, collections and interact with the user
from System import *
from System.IO import *
from System.Collections.Specialized import *
from System.Windows.Forms import MessageBox

# Create an alias to the Autodesk.AutoCAD.ApplicationServices.Application class


# 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 for PropertySets
from Autodesk.Aec.PropertyData import *
from Autodesk.Aec.PropertyData.DatabaseServices import *

# Import references for Civil 3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

# Import AutoCAD and Civil 3D Dynamo Nodes
import Autodesk.AutoCAD.DynamoNodes as DA
import Autodesk.Civil.DynamoNodes as DC

from Autodesk.AutoCAD.ApplicationServices import Application as acapp

from Autodesk.AutoCAD.ApplicationServices import DocumentCollectionExtension
from Autodesk.AutoCAD.ApplicationServices import DocumentExtension

# Useful link
# http://www.theswamp.org/index.php?topic=37686.0


def set_layer_on_off_for_dwgs(path, layers, bool):
	# """
	# Loads the document in the application.
	# Searches the new block, in case it is missing it will load it.
	# Searches the BlockReferences of the old block and deletes them.
	# Creates a new BlockReference at location with the new Block.
	# Rotates the new block Reference.
	# Saves the Document and closes it.
	
	# @path: The path to the document
	# @returns: True if successful, otherwise False
	# """
    if path is None or layers is None or bool is None:
        return False
    
    adoc = DocumentCollectionExtension.Open(acapp.DocumentManager, path, False)  # Open for Write

    acapp.DocumentManager.CurrentDocument = adoc
    editor = adoc.Editor
    
    if adoc is None:
        return False

    ret = True
    errorReport = None
    name = []
    global lt
    global lt_test

    with adoc.LockDocument():
        with adoc.Database as db:
            with db.TransactionManager.StartTransaction() as t:                    
                        
                for layer in layers:  
                    lt = t.GetObject(db.LayerTableId, OpenMode.ForWrite)  # Get Layers  
                    try:
                        if lt.Has(layer):
                            i = t.GetObject(lt[layer], OpenMode.ForWrite)
                            i.IsOff=True
                            name.append(i.Name)

                    # Error Handling
                    except:
                        import traceback	

				# t.AddNewlyCreatedDBObject(bref, True)  # Add to Database
                t.Commit()  # Commit the changes
    
    # if errorReport == None:
    #     return name
    #     # return get_layer
    # else:
    #     return errorReport


    if adoc: 
        DocumentExtension.CloseAndSave(adoc, path)
    return  ret




def main(folder, layers, bool):
	# """
	# Gets all the DWGs in at the folder path recursively.
	# Opens each file, removes the old block references, creates a new block reference, saves the file.
	# Writes a log file of the files that are processed in %temp%\D4C3D.log
	
	# @folder: The path to folder containing DWGs	
	# @returns: A Dictionary of successes and failures
	# """
	
	# If critical inputs are missing returns the insturctions
    if folder is None or layers is None or bool is None:
        return main.__doc__
	
	# Initialize dictionary
    ret = {}
    ret['Success'] = []
    ret['Failure'] = []
    
    dwgs = []
    res = []
    
    adoc = acapp.DocumentManager.MdiActiveDocument
    
	
	# Get DWGs
    for dirpath, dnames, fnames in os.walk(folder):
        for f in fnames:
            if f.endswith('.dwg'):
                dwgs.append(os.path.join(dirpath, f))  # create the references to the DWG files in the folder and subfolders
	
	# Process DWGs
    for dwg in dwgs:
        try:
            res = set_layer_on_off_for_dwgs(dwg, layers, bool)
            if res:
                ret.setdefault('Success', []).append(dwg)  # populate the dictionary
                logging.info('File processed correctly {}'.format(dwg))
            else:
                ret.setdefault('Failure', []).append(dwg)
                logging.error('File not processed {}'.format(dwg))
        # except Exception() as ex:
        #     logging.exception('{}\n{}'.format(dwg, ex.message))  # add exception to log file
        except:
            pass
            
    acapp.DocumentManager.CurrentDocument = adoc

    # for dwg in dwgs:
        
    #     res = set_layer_on_off_for_dwgs(dwg,layers, bool)
       
    #     # if res:
    #     #         ret.setdefault('Success', []).append(dwg)
    # acapp.DocumentManager.CurrentDocument = adoc
    
    return ret


OUT = main(IN[0], IN[1], IN[2]), lt # Using most of the default values for brevity


Please suggest the way forward and the issue.

Hi @roshan.kerketta ,

If you are trying to turn layers on/off in a drawing (not talking about turning layers on/off in already existing viewports) you should really take a look at the “External” nodes of the Camber package.

@mzjensen created some awesome nodes to work with multiple AutoCAD drawings at the same time!

Thank you @Daan , but I am currently targeting usage of Python Scripts as I cannot use packages for the solution. Also if you could provide some suggestions for the Python Script.