Hello everyone,
I'm trying to edit and update Tag's string of the specific blocks by the block name. when I run it, autocad hangs and closes.
Thanks in advance.
using (Transaction acTrans = db.TransactionManager.StartTransaction())
{
BlockTable acBlkTbl;
acBlkTbl = acTrans.GetObject(db.BlockTableId,
OpenMode.ForRead) as BlockTable;
BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
OpenMode.ForWrite) as BlockTableRecord;
var blockDef = (BlockTableRecord)acTrans.GetObject(acBlkTbl["BlockGHR"], OpenMode.ForRead);
foreach (ObjectId id in acBlkTblRec)
{
Entity ent = acTrans.GetObject(id, OpenMode.ForRead) as Entity;
BlockReference br = ent as BlockReference;
if (br.Name == "BlockGHR")
{
foreach (ObjectId attId in br.AttributeCollection)
{
DBObject obj = acTrans.GetObject(attId, OpenMode.ForRead) as DBObject;
AttributeReference ar = obj as AttributeReference;
tagatt = ar.Tag.ToUpper();
if (tagatt == "AT_DATA_DESC3_S_N")
{
ar.UpgradeOpen();
ar.TextString = "Plan031";
}
ar.UpgradeOpen();
}
}
}
acTrans.Commit();
}
Solved! Go to Solution.
Solved by norman.yuan. Go to Solution.
Firstly, your question and your code do DIFFERENT THINGS! The title of your post says "Update... of block defenation", where by "defenation", I assume you meant for "definition". That is, the title says to update an attribute AttributeDefinition) in a block definition, while your code changes an attribute (AttributeReference!) in a BlockReference; Also, you ask about changing attribute's Tag, but your code changes attribute's value.
So, not sure what you really want to do, or whether you fully understand the differences between block definition and block reference, between attribute definition and attribute reference.
As for the code crashing AutoCAD, it is this line of code is offensive:
if (br.Name=="...")
in the following snippet
foreach (ObjectId id in acBlkTblRec)
{
Entity ent = acTrans.GetObject(id, OpenMode.ForRead) as Entity;
BlockReference br = ent as BlockReference;
if (br.Name=="...")
...
In your "foreach..." loop to go through each entity in the ModelSpace, if not all entities in the ModelSpace is a block reference, then this line:
BlockReference br = ent As BlockReference
would assign "br" to null. Thus, next line would cause exception, which, if not handled/caught, would crash AutoCAD. That is, your code would work ONLY the ModelSpace has ONLY block references in it.
You need to test if the entity is a BlockReference or not in each loop.
You can do it this way:
foreach (ObjectId id in acBlkTblRec)
{
if (id.ObjectClass.DxfName.ToUpper()=="INSERT")
{
var br=(BlockReference)acTRans.GetObject(id, OpenMode,ForRead);
...
}
}
Or, you can:
foreach (ObjectId id in acBlkTblRec)
{
var br=acTRans.GetObject(id, OpenMode,ForRead) As BlockReference;
if (br != null)
{
...
}
}
}
Norman Yuan
Sometimes Autocad also crash if you don't lock the document.
using (DocumentLock acLckDoc = doc.LockDocument()) { ... }
ar.UpgradeOpen() is also unneccessary btw.
Thank you so much,
You were right, I was wrong. Question has been corrected.
I added this line code and the problem has been resolved :
if (br != null)
Can't find what you're looking for? Ask the community or share your knowledge.