Hi,
Drawing contains a block with "BlkName". I want to insert blockreferences of this existing block using .Net. I gone through the help and some other threads. All shows how to insert a new block and then use the BlockID returned by the insert function. In my case I only have the block name and there is no Block id. How to get it or how to create a block reference of an existing block?
Regards,
Shijith
Solved! Go to Solution.
Solved by Hallex. Go to Solution.
Try this sample code,
add to namespace declarations:
using Autodesk.AutoCAD.Internal;
public void testInsertBlock() { string blockName = "BlockName";//<-- block name to be inserted Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; Database db = doc.Database; DocumentLock doclock = doc.LockDocument(); using (doclock) { Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { try { BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; if (!bt.Has(blockName)) { ed.WriteMessage("\nBlock \"{0}\" does not exist", blockName); return; } ObjectId blkID = bt[blockName]; ed.WriteMessage("\nBlock \"{0}\" does exist, ObjectId is: {1}", blockName, blkID); PromptPointOptions ptOpt = new PromptPointOptions("\nSpecify a block position : "); PromptPointResult res = ed.GetPoint(ptOpt); if (res.Status != PromptStatus.OK) { if (res.Status == PromptStatus.Cancel) { ed.WriteMessage("\nInterrupted by user. Exit.."); return; } else { ed.WriteMessage("\nError on specifying a point.Exit..."); return; } } Point3d pt = res.Value; BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord; BlockTableRecord btrec = tr.GetObject(blkID, OpenMode.ForRead) as BlockTableRecord; BlockReference bref = new BlockReference(pt, blkID); bref.SetDatabaseDefaults(); if (btrec.Annotative == AnnotativeStates.True) { ObjectContextManager ocm = db.ObjectContextManager; ObjectContextCollection occ = ocm.GetContextCollection("ACDB_ANNOTATIONSCALES"); ObjectContexts.AddContext(bref, occ.CurrentContext); } Matrix3d mat = Matrix3d.Identity; bref.TransformBy(mat); btr.AppendEntity(bref); tr.AddNewlyCreatedDBObject(bref, true); if (btrec.HasAttributeDefinitions) { Autodesk.AutoCAD.DatabaseServices.AttributeCollection atcoll = bref.AttributeCollection; foreach (ObjectId subid in btrec) { Entity ent = (Entity)subid.GetObject(OpenMode.ForRead); AttributeDefinition attDef = ent as AttributeDefinition; if (attDef != null) { //ed.WriteMessage("\nValue: " + attDef.TextString);// for debug only AttributeReference attRef = new AttributeReference(); attRef.SetDatabaseDefaults(); attRef.SetAttributeFromBlock(attDef, bref.BlockTransform); attRef.Position = attDef.Position.TransformBy(bref.BlockTransform); attRef.Tag = attDef.Tag; attRef.AdjustAlignment(db); atcoll.AppendAttribute(attRef); tr.AddNewlyCreatedDBObject(attRef, true); } } } tr.Commit(); } catch (Autodesk.AutoCAD.Runtime.Exception ex) { ed.WriteMessage(("AutoCAD Exception: " + ex.Message + "\n" + ex.StackTrace)); } catch (System.Exception ex) { ed.WriteMessage(("Sytem Exception: " + ex.Message + "\n" + ex.StackTrace)); } finally { // optional message } } } }
Hi Hallex,
Thanks man it worked. I am actualy looking for this portion of the code "blkId = bt[bname];". I got the "has" but didn't find the item collection. I never thought about bt[]. Thanks again.
Is it required to have the code for attributes? is it nesessory or a better idea?
With Thanks
Shijith
This line of code is answer:
if (btrec.HasAttributeDefinitions)
{
// add attribute here
}
//otherwise this code will be ignored and you
go further usual way
Glad you got it to work btw