I am trying to automate some tasks in AutoCAD using Python and pywin32
. AutoCAD version is 2018.
I have tried to follow the method shown here in the AutoCAD documentation: http://help.autodesk.com/view/ACD/2018/ENU/?guid=GUID-A5B6ACC4-DCD8-4FE2-AB06-D3C3C349475B
I want to select a specific block, and then edit some of its attributes.
My code:
acad = win32com.client.Dispatch("AutoCAD.Application")
acad.ActiveDocument = acad.Documents.Open(os.path.normpath(os.path.join(baseDir,filename)))
time.sleep(2)
doc = acad.ActiveDocument # Document object
entity = doc.Blocks.Item('TTLB ATTRIBUTES')
print entity.Name
print entity.HasAttributes
This correctly prints the block name, but attempting to access the HasAttributes
property causes this error:
AttributeError: Item.HasAttributes
If I change the code to simply walk through all the objects, then it works:
acad = win32com.client.Dispatch("AutoCAD.Application")
acad.ActiveDocument = acad.Documents.Open(os.path.normpath(os.path.join(baseDir,filename)))
time.sleep(2)
doc = acad.ActiveDocument # Document object
for entity in doc.PaperSpace:
if entity.EntityName == 'AcDbBlockReference':
if entity.Name == 'TTLB ATTRIBUTES':
print entity.Name
print entity.HasAttributes
I don't understand why the second one works and the first one doesn't. When I read the documentation, it seems like they should both be finding the same object.
When invoking the Item
method on the Blocks collection, you are obtaining a Block Definition object (AcDbBlockTableRecord
), which is a container for the set of objects constituting the block geometry and does not have the HasAttributes
property.
Whereas, when iterating over the objects held by the Paperspace Collection (which is itself a type of Block Definition), you are encountering Block Reference objects (AcDbBlockReference
), which do have the HasAttributes
property.
Consider that the Block Definition is essentially the "blueprint" for the block, and each Block Reference is an instance displaying the objects found within the block definition, at a specific position, scale, rotation & orientation in the drawing.
Attributes also have Attribute Definitions within the Block Definition, and corresponding Attribute References attached to each Block Reference. Such attribute references may then hold different text content for each block reference inserted in the drawing.
Aside, interestingly, attribute references may also be programmatically attached to a block reference independently of the block definition, however, this is not permitted when operating AutoCAD using the standard out-of-the-box front end.
With the above information, you will need to iterate over the block references found within the relevant layout container, and, if the block reference meets your criteria, iterate over the set of attribute references held by the block reference (which you can obtain using the GetAttributes
method), changing the Textstring
property of those attributes which meet your criteria.