Hi,
I have a function that copy a block into another. First, you select the block to be replace and after you select the replacement block.
It works fine except for one thing : the first time copy works fine but if I choose to take the block that has just been replace, it's going to say that the attribute has been erase (I know that in my code I do erase the attribute but if I don't I will keep the ''old'' attrbiutes). If I close the drawing and open it again, I will be able to do the copy without having this message so it's probably not much that I forgot to do but I don't see what. Thanks for any help !
private void btnCopyBlock_Click(object sender, EventArgs e)
{
Document doc = AcadApp.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
TypedValue[] values = new TypedValue[] { new TypedValue((int)DxfCode.Start, "INSERT") };
SelectionFilter filter = new SelectionFilter(values);
PromptSelectionOptions SelOpts = new PromptSelectionOptions();
SelOpts.AllowDuplicates = false;
SelOpts.MessageForAdding = MB.rmM.GetString("SelObj");
SelOpts.MessageForRemoval = MB.rmM.GetString("RemObj");
Utils.SetFocusToDwgView();
PromptSelectionResult res = ed.GetSelection(SelOpts, filter);
if (res.Status != PromptStatus.OK) return;
PromptEntityOptions peo = new PromptEntityOptions(MB.rmM.GetString("SelBlock"));
peo.SetRejectMessage(MB.rmM.GetString("SelNoBlock"));
peo.AllowNone = false;
peo.AddAllowedClass(typeof(BlockReference), false);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK) return;
DocumentLock loc = doc.LockDocument();
using (Transaction tr = doc.Database.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(doc.Database.BlockTableId, OpenMode.ForRead);
// replacement block
BlockReference blkR = (BlockReference)tr.GetObject(per.ObjectId, OpenMode.ForRead);
BlockTableRecord btNr = (BlockTableRecord)tr.GetObject(bt[blkR.Name], OpenMode.ForRead);
//
SelectionSet ss = res.Value;
ObjectId[] idArray = ss.GetObjectIds();
foreach (ObjectId id in idArray)
{
SortedList<string, string> attLst = new SortedList<string, string>();
BlockReference blk = (BlockReference)tr.GetObject(id, OpenMode.ForWrite);
// attributes from the block to be replace
foreach (ObjectId attId in blk.AttributeCollection)
{
AttributeReference att = (AttributeReference)tr.GetObject(attId, OpenMode.ForWrite);
att.Erase(true);
}
// attributes from the replacement block
foreach (ObjectId attId in blkR.AttributeCollection)
{
AttributeReference att = (AttributeReference)tr.GetObject(attId, OpenMode.ForRead);
if (!attLst.ContainsKey(att.Tag)) attLst.Add(att.Tag, att.TextString);
}
blk.BlockTableRecord = btNr.ObjectId;
if (btNr.HasAttributeDefinitions)
{
IEnumerator Ie = btNr.GetEnumerator();
while (Ie.MoveNext())
{
try
{
DBObject obj = tr.GetObject((ObjectId)Ie.Current, OpenMode.ForRead, false);
if (obj.GetType() == typeof(AttributeDefinition))
{
AttributeDefinition attDef = (AttributeDefinition)obj;
AttributeReference attRef = new AttributeReference();
attRef.SetDatabaseDefaults();
attRef.Layer = attDef.Layer;
attRef.SetAttributeFromBlock(attDef, blk.BlockTransform);
attRef.Position = attDef.Position.TransformBy(blk.BlockTransform);
attRef.Position = attDef.Position;
if (attLst.ContainsKey(attDef.Tag)) attRef.TextString = attLst[attDef.Tag];
//Add the attribute reference to the block ref
blk.AttributeCollection.AppendAttribute(attRef);
tr.AddNewlyCreatedDBObject(attRef, true);
}
}
catch (System.Exception ex) { MessageBox.Show(ex.ToString()); }
}
}
}
tr.Commit();
}
loc.Dispose();
Utils.PostCommandPrompt();
}