- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I have been unsuccessful with trying to insert a block with attributes into a side database. I have been able to insert one successfully into an active database but not a side one. Here is my insert block code.
/// <summary> /// Inserts a block into the specified Space. /// </summary> /// <param name="blockName">Name of the block to insert.</param> /// <param name="insertionPoint">The insertion point of the block.</param> /// <param name="database">The database to work in.</param> /// <param name="space">The space to insert into</param> /// <param name="attributes">The attributes to set on the block.</param> /// <exception cref="System.ArgumentNullException">blockName;The block name cannot be empty</exception> /// <exception cref="Autodesk.AutoCAD.Runtime.Exception">The database cannot be null. /// or /// The block does not exist in the current database.</exception> /// <exception cref="Exception"> /// The block does not exist in the current database. /// </exception> public static void InsertBlock(string blockName, Point3d insertionPoint, Database database, Space space, Dictionary<string, string> attributes) { if (string.IsNullOrWhiteSpace(blockName)) { throw new ArgumentNullException("blockName", "The block name cannot be empty"); } if (database == null) { throw new Exception(ErrorStatus.NoDatabase, "The database cannot be null."); } using (var transaction = database.TransactionManager.TopTransaction) { if (transaction == null) { throw new Exception(ErrorStatus.NotTopTransaction); } var blockTable = (BlockTable)database.BlockTableId.GetObject(OpenMode.ForRead); if (!blockTable.Has(blockName)) { throw new Exception(ErrorStatus.NotInDatabase, "The block does not exist in the current database."); } var blockDefinition = (BlockTableRecord)blockTable[blockName].GetObject(OpenMode.ForRead); using (var blockReference = new BlockReference(insertionPoint, blockDefinition.ObjectId)) { try { BlockTableRecord currentSpace; if (space == Space.ModelSpace) { currentSpace = (BlockTableRecord)blockTable[BlockTableRecord.ModelSpace].GetObject(OpenMode.ForWrite); } else { currentSpace = (BlockTableRecord)blockTable[BlockTableRecord.PaperSpace].GetObject(OpenMode.ForWrite); } currentSpace.AppendEntity(blockReference); transaction.AddNewlyCreatedDBObject(blockReference, true); foreach (var objectId in blockDefinition) { var dbObject = objectId.GetObject(OpenMode.ForRead); var attributeDefinition = dbObject as AttributeDefinition; if ((attributeDefinition != null) && (!attributeDefinition.Constant)) { if (attributes.ContainsKey(attributeDefinition.Tag)) { using (var attributeReference = new AttributeReference()) { try { attributeReference.SetAttributeFromBlock(attributeDefinition, blockReference.BlockTransform); attributeReference.Position = attributeDefinition.Position.TransformBy(blockReference.BlockTransform); attributeReference.TextString = attributes[attributeDefinition.Tag]; blockReference.AttributeCollection.AppendAttribute(attributeReference); transaction.AddNewlyCreatedDBObject(attributeReference, true); } catch (Exception exception) { Log.Logger.Error(exception, "Unable to set attribute {Attribute} on block {blockName}", attributeDefinition.TextString, blockName); } } } } } } catch (Exception exception) { Log.Logger.Error(exception, "Unable to insert the block {blockName} into the drawing {fileName}.", blockName, database.Filename); throw new Exception(ErrorStatus.UnrecoverableErrors, string.Format("Unable to insert block {0} into {1}.", blockName, database.Filename), exception.InnerException); } } } }
Here are the commands to run the code.
/// <summary> /// Imports a block and inserts it into the current drawing. /// </summary> [CommandMethod("My Examples", "ImportAndInsertBlockIntoActiveDrawing", CommandFlags.Session)] public void ImportAndInsertBlockIntoActiveDrawingCSharpCommand() { var database = Active.Database; using (Active.Document.LockDocument()) using (var transaction = database.TransactionManager.StartTransaction()) { var objectId = BlockUtils.ImportBlock("test", @"C:\Users\kbrown\Desktop\TestBlock.dwg", database, DuplicateRecordCloning.Replace); if (objectId != ObjectId.Null) { var attributes = new Dictionary<string, string> { { "SCALE", "1/8\" = 1'-0\"" }, { "TITLE", "This is where the title block goes." } }; BlockUtils.InsertBlock("test", new Point3d(0, 0, 0), database, Space.PaperSpace, attributes); } else { MessageBox.Show("Unable to import the block.", "Import Error!"); } transaction.Commit(); } } /// <summary> /// Imports the block and inserts it into a side drawing. /// </summary> [CommandMethod("My Examples", "ImportAndInsertBlockIntoSideDrawing", CommandFlags.Session)] public void ImportAndInsertBlockIntoSideDrawingCSharpCommand() { const string FileName = @"C:\Users\kbrown\Desktop\TempTestDrawing.dwg"; var database = new Database(); database.ReadDwgFile(FileName, FileOpenMode.OpenForReadAndAllShare, true, string.Empty); database.SaveAs(FileName, DwgVersion.Current); using (var transaction = database.TransactionManager.StartTransaction()) { var objectId = BlockUtils.ImportBlock("test", @"C:\Users\kbrown\Desktop\TestBlock.dwg", database, DuplicateRecordCloning.Replace); if (objectId != ObjectId.Null) { var attributes = new Dictionary<string, string> { { "SCALE", "1/8\" = 1'-0\"" }, { "TITLE", "This is where the title block goes." } }; BlockUtils.InsertBlock("test", new Point3d(0, 0, 0), database, Space.PaperSpace, attributes); } transaction.Commit(); database.SaveAs(FileName, DwgVersion.Current); } }
As I mentioned before inserting into an active database works with no issues. Inserting into a side database will insert the block but no attributes. If i open the drawing afterwards and insert the block then the attributes work normal so i know that there is nothing wrong with my import function. (at least i belive that is a true statement).
Anyone have any ideas? Thanks.
Drawing with block to place on desktop. (Make sure to change filename string to point to correct location if downloading for testing.)
Solved! Go to Solution.