I would like to run ATTSYNC on a directory containing multiple DWGs. I have a python script that should do the following:
Get the DWG Files in the Directory
Open up DWG and run the ATTSYNC command by sending a string to the command line
Save and Close DWG
Open up next DWG and follow same process
The script runs fine with no errors and I can tell that it is cycling through and opening each DWG. But the command is not successful. I can tell that the DWGs in the directory are not saved by the Python script so that could be the first issue. Any reason why my script below is not saving the DWGs when closing?
# Load the Python Standard and DesignScript Libraries
import clr
import os
# 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 Autodesk.AutoCAD.ApplicationServices.Application as acapp
# 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 Autodesk.AutoCAD.ApplicationServices.DocumentCollectionExtension
# Import references from Civil3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *
#bring in folder path where .dwg files are located
directory = IN[0]
#get list of files in folder path
fileList = os.listdir(directory)
#remove any files that do not have extension .dwg
fileList2 = [f for f in fileList if ".dwg" in f]
#create list of file paths
pathList = [directory+"\\"+f for f in fileList if ".dwg" in f ]
#Open Document For Write
for path in pathList:
adoc = DocumentCollectionExtension.Open(acapp.DocumentManager, path, False)
acapp.DocumentManager.CurrentDocument = adoc
with adoc.LockDocument():
with adoc.Database as db:
with db.TransactionManager.StartTransaction() as t:
# Code between here
command = "ATTSYNC\nN\nTITLE PAC\n"
adoc.SendStringToExecute(command, True, False, False)
# Code between here
t.Commit()
pass
#Save and Close
if adoc:
DocumentExtension.CloseAndSave(adoc, path)
# Assign your output to the OUT variable.
OUT = pathList
As far as I know, commands can only work on the active document (source: when I try typing line it only works on the document in the UI). So you will need to change the document in the active user interface and then send the command. I think this can be done, but I am not sure Python will expose it. It would likely be a big lift if possible.
Running the above script opens up each DWG individually and runs the ATTSYNC command. Maybe Iām not understanding what you mean by set āactiveā but I can see the process happening live on my screen as the script cycles through DWGs. Is a document that is opened up not the active document?
It is possible to programmatically mimic the ATTSYNC command - see here for versions in C# and VB .NET BLOCK Routines. To process a folder would require side loading each file database and processing
Other options would include using the python subprocess library to run a script with acadcoreconsole.exe or writing a dos/powershell script
I might be having the issue that you earlier suggested but Iām not sure. I do know for sure that the script is not saving each DWG before closing out so seems to be a problem there. Once I can get the script to save the DWGs then I will be able to diagnose if there is an issue sending the files to command if that makes sense
Could you send QSAVE via command?
Also prefixing commands with _.like this _.ATTSYNC will ensure Autocad uses internal āEnglishā version of command
I think Iāve worked it out
You are locking the application document for the database transaction and then trying to run a command via the application api.
Remove the transaction wrapper as this is not required
[Edit] It was also if adoc: testing as False
Hereās the script with some modifications. Iāve cleaned up some of the imports and rewritten the pathlist comprehension. (Just becauseā¦)
I did quite a few tests of other ways to save the document and the original works ok.
The biggest issue is the line if adoc: as this returns False - yes, hard to believe - I also assumed that any python object tests as True unless it is empty, equal to zero or None.
An alternative could be to use a parameter that returns a boolean such as adoc.IsActive: or just remove the line altogether.
# Load the Python Standard and DesignScript Libraries
import clr
import os
# import time # If required - see below
# Add Assemblies for AutoCAD
clr.AddReference("AcMgd")
clr.AddReference("AcCoreMgd")
# Import references from AutoCAD
from Autodesk.AutoCAD.Runtime import *
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.ApplicationServices import Application as acapp
# bring in folder path where .dwg files are located
directory = IN[0]
# get list of files in folder path
if os.path.isdir(directory):
pathlist = [
os.path.join(directory, f)
for f in os.listdir(directory)
if f.lower().endswith(".dwg")
]
# Open Document For Write
for path in pathlist:
adoc = DocumentCollectionExtension.Open(acapp.DocumentManager, path, False)
acapp.DocumentManager.CurrentDocument = adoc
# time.sleep(3) # Pause as doc loads if required
command = "_.ATTSYNC\nN\nTITLE PAC\n"
adoc.SendStringToExecute(command, True, False, False)
# Save and Close
if adoc.IsActive:
DocumentExtension.CloseAndSave(adoc, path)
# Assign your output to the OUT variable.
OUT = pathlist
Will it be the part of a larger script or the only purpose is the attsync?
Wouldnāt it be more convinient using a simple lisp and the batch save utility?
I am trying to replicate this program but I get this error, anyone know what it means? āWarning: ModuleNotFoundError : No module named āAutodesk.AutoCAD.ApplicationServices.Applicationā; āAutodesk.AutoCAD.ApplicationServicesā is not a packageā