Hi Gile,
Sorry, in my code, the tr.commit line position has been misplaced unfortunately.
Now i have corrected the position and removed the blockref.ExplodeToOwnerSpace().
Now its working, thanks lot for your support.
I have another query for next process.
How to create new attribute with value for Particular Block(existing).
Thnks
Balaji
Hi Gile,
Sorry, in my code the tr.commit has been misplaced unfortunately, Now its corrected and I removed the blockref.ExplodeToOwnerSpace().
Now its working, Thanks log for your support.
I have another query for next process.
How to create new attribute with value to the particular block(Existing). Because if the particular block is avail without attributes, i have to create attribute and pass the value.
I have been searched in the forum and i got the blow urls for creating new attribute.
https://forums.autodesk.com/t5/net/adding-an-attribute-to-an-existing-block-question/td-p/2408670
https://stackoverflow.com/questions/33681348/autocad-net-add-attribute-to-block-definition
Some confussion there.
Please help me.
Thnks
Balaji
You can have a look here:
http://help.autodesk.com/view/OARX/2018/ENU/?guid=GUID-2107599E-9405-4D8B-A6DD-83D603B41568
Hi.
I just saw that Code and I have to say something.
Please use "using" everytime. That is helpful for the garbage Collection.
using(Transaction myTrans = myDB.TransactionManager.StartTransaction)
{
myTrans.Commit();
}
Please use allways Commit() even when you only read from Database. This is faster.
When you use "using" you dont need dispose because the garbage collection knows it.
Another think is: Please use the attribut method DowngradeOpen() to close the update.
Regards Jürgen
Can someone please explain what I'm doing incorrect here?
I have a test drawing with a block containing an attribute, this is nested into another block in the same drawing.
My goal is to mimic the burst function (have found an example on dev blog for this) I'm cleaning the file, bylayer etc and exploding if asked to, this part (see below) is called from the main program to deal with a block containing an attribute.
When I run, I note the program edits the same block twice. I assume this is as it's editing the actual block instance and not the actual block definition. This would make sense as if I were to edit the main definition it would update all the references in the drawing?
After running, the blocks do not display the attributes and say there are none when attsync etc but when I Block edit the attribute is included. Also if I insert a new instance the attribute is also included?
Can someone explain why is this and what is incorrect with my code below. How do I target the table reference for the block so all instances will update to remove the attribute?
There is something in this incorrect but for the life of me I cannot see what..
Public Function CleanAttributes(ByRef zBlkRef As BlockReference)
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim ed As Editor = doc.Editor
Dim db As Database = doc.Database
Using tr As Transaction = db.TransactionManager.StartTransaction()
Dim zBlkTbl As BlockTable = tr.GetObject(m_Database.BlockTableId, OpenMode.ForRead)
Dim zBlkTblRec As BlockTableRecord = DirectCast(tr.GetObject(zBlkRef.BlockTableRecord, OpenMode.ForRead), BlockTableRecord)
Dim zBlkCl As RXClass = RXClass.GetClass(GetType(BlockReference))
For Each attId As ObjectId In zBlkRef.AttributeCollection
Dim att As AttributeReference = DirectCast(tr.GetObject(attId, OpenMode.ForRead), AttributeReference)
Dim AcAr As AcadAttributeReference = att.AcadObject
Try
If att.HasFields = True Then
att.ConvertFieldToText()
Else
End If
If Not zBlkTbl.IsWriteEnabled = True Then
zBlkTbl.UpgradeOpen()
End If
If Not zBlkTblRec.IsWriteEnabled = True Then
zBlkTblRec.UpgradeOpen()
End If
Dim acText As DBText = New DBText()
acText.SetDatabaseDefaults()
acText.Position = att.Position
acText.Height = att.Height
acText.Rotation = att.Rotation
acText.Justify = att.Justify
acText.TextString = att.TextString
acText.Color = Color.FromColorIndex(ColorMethod.ByLayer, 256)
zBlkTblRec.AppendEntity(acText)
If Not att.IsWriteEnabled = True Then
att.UpgradeOpen()
End If
M_trans.AddNewlyCreatedDBObject(acText, True)
att.Erase(True)
zBlkRef.RecordGraphicsModified(True)
Catch exAtt As SystemException
m_Editor.WriteMessage(exAtt.StackTrace)
End Try
Next
zBlkRef.RecordGraphicsModified(True)
zBlkTbl.DowngradeOpen()
zBlkTblRec.DowngradeOpen()
tr.Commit()
End Using
End Function
The code you post only edit the attribute collection of the block reference which is passed as argument. It does nothing to the block definition (BlockTableRecord).
If you want to edit the block definition, you have to open the BlockTableRecord, replacing each AttributeDefinition with a text (containing the attribute default value: TextString) will affect all the inserted references (this needs to synchronize the attributes)
Ok thanks that kindof worked..
I followed your code example and run through the BTR. This worked and removed the Attribute but didn't insert the text. It appears that after using AutoCAD for 20 odd years, I've forgotten how a block works 🙂
I was trying to add the text from the attribute to the blockreferance but as these could differ throughout the drawing what I should really be doing is converting each instance to static text in the drawing.
This presents another problem, when reading the Attribute I'd need the real location relevant to World coordinates for each block in the drawing and not the local attribute definition in the blocktable.
Any Ideas how you do that?
I will still need to delete the block attributes so at least one hurdle overcome.