0

I have multiple autocad files with tons of blocks already defined. I would like to write a python script that for each file adds 3 new attributes to each block.

I tried the following code:

import win32com.client
import pandas as pd
from pyautocad import Autocad, aDouble

acad = win32com.client.Dispatch("AutoCAD.Application")

doc = acad.ActiveDocument  # Document object
for entity in acad.ActiveDocument.ModelSpace:
    name = entity.EntityName
    if name == 'AcDbBlockReference':
        HasAttributes = entity.HasAttributes
        if HasAttributes:
            entity.AddAttribute(50, 0, "test", aDouble(200, 100, 0), "TEST", "TEST TEXT")

Even if it should be in the pyautocad library, AddAttribute is not recognized apparently, indeed I receive the

AttributeError: <unknown>.AddAttribute. Did you mean: 'GetAttributes'?

I am not interested in getting attributes, I would like to define new ones. Probably I should use win32com library but i feel lost. Any suggestions to fix it?

UPDATE

Here the correct code:

from pyautocad import Autocad, aDouble

acad = Autocad(create_if_not_exists=True)
doc = acad.ActiveDocument
blocks = acad.ActiveDocument.Blocks
print(blocks.ObjectName, ' number elements: ', blocks.Count)
for block in blocks:
    block.addAttribute((50, 0, "test", aDouble(200, 100, 0), "TEST", "TEST TEXT")

Then, launch ATTSYNC

Bire
  • 3
  • 2
  • 1
    A quick scan of the AutoCad reference here: https://help.autodesk.com/view/OARX/2023/ENU/?guid=GUID-88EEBCA3-8AF5-4776-9D54-520B05AB9129 suggests that the iteration over the `ModelSpace` returns `BlockReference` objects and *not* `Block` objects. Only the latter has the `AddAttribute` method. I've never used AutoCAD, but the documentation suggests you have to iterate over the `BlockReference` to access the 'referred-to' objects (or use `Explode`): https://help.autodesk.com/view/OARX/2023/ENU/?guid=GUID-6D96780F-3EC6-447C-B341-0FE815BE9979 – DS_London May 05 '23 at 09:46
  • Do you have any clue about how access and iterate on the BlockReference? – Bire May 05 '23 at 17:55

1 Answers1

0

The AddAttribute method will create an Attribute Definition, which should belong to a Block Definition, not a Block Reference (which is one of potentially many instances of the definition inserted in the drawing at varying positions, scales, rotations & orientations).

As such, you should obtain the target Block Definition object from the Blocks Collection (acad.ActiveDocument.Blocks) and invoke the AddAttribute method on this container.

It may also be necessary to 'synchronise' the attributes held by block references with those found in the definition - this operation is performed by the standard ATTSYNC command in AutoCAD.

Lee Mac
  • 15,615
  • 6
  • 32
  • 80
  • Thank you for your clarification. So, i created blocks but I receive the ` AttributeError: .AddAttribute` . Sorry my remarks and code may seem banal, but I am absolutely new to autocad ` from pyautocad import aDouble import win32com.client acad = win32com.client.Dispatch("AutoCAD.Application") doc = acad.ActiveDocument # Document object blocks= acad.ActiveDocument.Blocks res = blocks.AddAttribute(50, 0, "test", aDouble(200, 100, 0), "TEST", "TEST TEXT") ` – Bire May 05 '23 at 12:01
  • You are invoking `AddAttribute` on the Blocks Collection, not a single block definition - you need to obtain the Block Definition from the Blocks Collection. – Lee Mac May 05 '23 at 12:11
  • Can you suggest me how to iterate inside the blocks collection for extracting the block definition? – Bire May 08 '23 at 09:20
  • I saw that my variable blocks is now a AcDbBlockTable, where I can apply the following methods https://help.autodesk.com/view/OARX/2023/ENU/?guid=OARX-RefGuide-__MEMBERTYPE_Methods_AcDbBlockTable , but I am still not succesfull in extracting the single block definitions succesfully. – Bire May 08 '23 at 15:24
  • You can either iterate over the block definitions using a `for` loop (e.g. `for block in acad.ActiveDocument.Blocks:`) or use the `item` method to obtain the block definition directly from the collection. – Lee Mac May 08 '23 at 22:38
  • So, my mistake was using win23.com library. If I call the autocad file with `acad = Autocad(create_if_not_exists=True)` it works, if I do it with `acad = win32com.client.Dispatch("AutoCAD.Application")` , even if the name of the object is correctly identified as a BlockTable, the type is unknown. Now I should see how to launch the ATTSYNC on my script. Thank you for your support. – Bire May 09 '23 at 08:02