Adding attributes to an existing block

I have an existing block that I would like to add one or more new attributes to using code. Although I've found several sites that have solutions, but I can't get any of them to work.
I search the existing block to see if it has a particular attribute, and if it doesn't then it executes the following code.

Private Sub addAtt2Blk(blkname As String, attTag As String, pnt3d As Point3d, attPrompt As String, attText As String, Ht As Double)
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
'https://forums.autodesk.com/t5/net/vb-net-block-with-attributes-problem/td-p/9865666
Dim blkRecId As ObjectId = ObjectId.Null
Using tr As Transaction = db.TransactionManager.StartTransaction()
Dim blkTbl As BlockTable
blkTbl = CType(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
Using blkTblRec As New BlockTableRecord
blkTblRec.Name = blkname
blkTblRec.Origin = New Point3d(0, 0, 0)
Using acAttDef As New AttributeDefinition
acAttDef.Position = pnt3d
acAttDef.Verifiable = True
acAttDef.Visible = True
acAttDef.Prompt = attPrompt
acAttDef.Tag = attTag
acAttDef.TextString = attText
acAttDef.Height = Ht
acAttDef.Justify = AttachmentPoint.MiddleCenter
acAttDef.LockPositionInBlock = True
blkTblRec.AppendEntity(acAttDef)
tr.GetObject(db.BlockTableId, OpenMode.ForWrite)
blkTbl.Add(blkTblRec)
tr.AddNewlyCreatedDBObject(blkTblRec, True)
End Using
End Using
tr.Commit()
End Using
End Sub

The code executes until line "blkTbl.add(blkTblRec)" where it throws an error:
An unhandled exception of type 'Teigha.Runtime.Exception' occured in Unknown Module.
eDuplicateRecordName.

I've double checked the attribute Tags in the block, and the Tag that I'm trying to add definitely doesn't exist.

Any help would be greatly appreciated.

Comments

  • avc
    avc
    edited June 2023
    This code creates a new block. You do not look for the old block in the block table, but create a new block in which you add only 1 object - an attribute.
    Naturally, you will not be able to add a new block with the same name as already in the drawing => eDuplicateRecordName
    The block table can give you the ID of an existing block by its name ( blkTbl[blkname] ). Then open the block for writing by this identifier. But it's better to first check if such a block exists.
    And besides, you didn't specify whether it's a constant attribute. If you want to create a mutable attribute then you will have to update all block references and add an AttributeReference everywhere.
    And you forgot to add a new attribute to the transaction.
  • Try this, link https://www.afralisp.net/archive/methods/list/addattribute_method.htm

    (defun c:addatt ( / blockname blocks blk pr tag val height pt)
    (setq blockname (cdr (assoc 2 (entget (car (entsel "\nSelect block: "))))))
    (setq pt '(55 55 0) ) ; maybe a getpoint
    (setq blocks (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))))
    (vlax-for blk blocks
    (if (= (vla-get-name blk) blockname)
    (progn
    (setq height 2)
    (setq mode (getvar "AFLAGS")
    pr (getstring "Prompt: ")
    tag (getstring "Tag: ")
    val (getstring "Initial value: ")
    )
    (vla-addattribute
    blk
    height
    mode
    pr
    (vlax-3d-point pt)
    tag
    val
    )
    )
    )
    )
    (command "attsync" "n" blockname "")
    (princ)
    )
    (c:addatt)


  • I guess I became somewhat tunnel visioned on this problem. Thanks, avc and ALANH for your input. Hopefully your suggestions and advice will help.
  • I will add an issue that could, at some point, become an issue. If you edit a block with attributes, and do something like change the size of an attribute, or just move it, the other pre-existing blocks are not updated. To force them to update, you use the attsync command.
  • (command "attsync" "n" blockname "") in code above.
  • See attached .LSP file.
    I use it to add one attribute by the name "SYSTEM" to multiple blocks.
    line 19 in the code hold the attribute name - you can change it manually.