.NET
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic to the Top
- Bookmark
- Subscribe
- Printer Friendly Page
Add Block When Other Drawings Are Open
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
I'm trying to add a block with an attribute to a drawing. The command works if there is only one drawing open, but when there are other open drawings then the block doesn't appear. Strangely if I select the block in the block editor and then close the block editor the block suddenly appears. Do you know what is causing the block to not appear when other drawings are open?
I included the code below. "s1" works but "s2" has the strange behavior of the block not being visible.
Thanks for any help,
Casey Joyce
[CommandMethod("s1")]
public void AddBlockWithAttributeToDestination_WithNoOtherDraw
var attributeValue = "1234";
var destination = Application.DocumentManager.MdiActiveDocument;
using (var transaction = destination.TransactionManager.StartTransaction()) {
addBlock(transaction, destination.Database, attributeValue);
transaction.Commit();
}
}
[CommandMethod("s2")]
public void AddBlockWithAttributeToDestination_WhileSourceDraw
// pretend user selects info from opened source drawing
var attributeValue = "1234";
// pretend user selects destination drawing from popup list
var destinationDrawing = @"c:\destination.dwg";
// add block to destination drawing
var destination = Application.DocumentManager.Open(destinationDrawin
using (var transaction = destination.TransactionManager.StartTransaction()) {
using (var key = destination.LockDocument()) {
addBlock(transaction, destination.Database, attributeValue);
}
transaction.Commit();
}
}
void addBlock(Transaction transaction, Database database, string attributeValue) {
// add block
var block = new BlockTableRecord() { Name = "SampleBlock" };
var table = transaction.GetObject(database.BlockTableId, OpenMode.ForWrite) as BlockTable;
var blockId = table.Add(block);
transaction.AddNewlyCreatedDBObject(block, true);
// add block reference
var blockReference = new BlockReference(Point3d.Origin, block.ObjectId);
var modelSpace = transaction.GetObject(table[BlockTableRecord.Model
modelSpace.AppendEntity(blockReference);
transaction.AddNewlyCreatedDBObject(blockReference
// set attribute definition
var definition = new AttributeDefinition(
new Point3d(1, 1, 0),
attributeValue,
"SampleAttribute",
"",
database.Textstyle);
block.AppendEntity(definition);
transaction.AddNewlyCreatedDBObject(definition, true);
// add attribute reference
var reference = new AttributeReference();
reference.SetAttributeFromBlock(definition, blockReference.BlockTransform);
blockReference.AttributeCollection.AppendAttribute
transaction.AddNewlyCreatedDBObject(reference, true);
}
Solved! Go to Solution.
Re: Add Block When Other Drawings Are Open
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
Maybe you should lock the document?
Using acLckDoc As DocumentLock = acNewDoc.LockDocument()
End Using
Re: Add Block When Other Drawings Are Open
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
Thanks for your response GTVic. I am using LockDocument in the s2 command, and that's the one that wasn't working.
Re: Add Block When Other Drawings Are Open
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
I think I am going to be able to get s2 to work by adding CommandFlags.Session. So far it looks like its working.
[CommandMethod("s2", CommandFlags.Session)]
Re: Add Block When Other Drawings Are Open
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
Sorry, didn't notice that, maybe because it was inside the transaction. I think that is a problem, the document should be locked before starting the transaction. That is the way it is documented in the Developer's Guide
CommandFlags.Session might mask the problem. The effect of "Session" is not clear but I take it that nothing else can happen in the application while this command is running and then perhaps there is no need for a lock and the lock being out of order doesn't cause a problem.
Re: Add Block When Other Drawings Are Open
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
I moved the LockDocument outside the transaction as you and the Developer Guide suggested, thanks. When I keep the CommandFlags.Session this seems to work fine. So unless I find a better way I guess I'll stick with this.
Just FYI:
Even with the lock on the outside of the transaction, the CommandFlags.Session is still required for me to get "s2" to work.
I tried removing the LockDocument all together to see if CommandFlags.Session would take care of it, but it throws an exception in that case.
Re: Add Block When Other Drawings Are Open
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
Maybe you need to lock the source drawing, if I'm understanding your code correctly.
This is my subroutine to copy block definitions from a template DWG to the current drawing using the clone method. I use it for updating block definitions or bringing in missing blocks.
Private Sub LoadBlocks()
Dim dm As DocumentCollection = Autodesk.AutoCAD.ApplicationServices.Application.D ocumentManager
Dim ed As Editor = dm.MdiActiveDocument.Editor
Dim destDb As Database = dm.MdiActiveDocument.Database
Dim sourceDb As Database = New Database(False, True)
Dim mapping As IdMapping = New IdMapping()
Dim blockIds As ObjectIdCollection = New ObjectIdCollection()
Dim s As String
Dim DisplayError As Boolean = False
Try
Using objLock As DocumentLock = AcadDoc.LockDocument()
Try
sourceDb.ReadDwgFile(Path.Combine(Path.Combine(Eng ToolsPath.FullName, "Source"), cboSource.Text), System.IO.FileShare.Read, True, "")
Try
Using Trans As Transaction = sourceDb.TransactionManager.StartTransaction()
Try
Dim bt As BlockTable = Trans.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, False)
Dim btr As BlockTableRecord
For Each btrId As ObjectId In bt
btr = Trans.GetObject(btrId, OpenMode.ForRead, False)
If lstItems.SelectedItems.Contains(btr.Name) Then
blockIds.Add(btrId)
End If
btr.Dispose()
Next
Catch ex As Autodesk.AutoCAD.Runtime.Exception
ed.WriteMessage(vbLf & "Error scanning for block definitions in source drawing: " & ex.Message & vbLf)
ed.UpdateScreen()
DisplayError = True
End Try
End Using
Catch ex As Autodesk.AutoCAD.Runtime.Exception
ed.WriteMessage(vbLf & "Error reading from source drawing: " & ex.Message & vbLf)
ed.UpdateScreen()
DisplayError = True
End Try
If Not DisplayError Then
Try
Using Trans As Transaction = destDb.TransactionManager.StartTransaction()
Try
sourceDb.WblockCloneObjects(blockIds, destDb.BlockTableId, mapping, DuplicateRecordCloning.Replace, False)
Trans.Commit()
Autodesk.AutoCAD.ApplicationServices.Application.D ocumentManager.MdiActiveDocument.AcadDocument.Rege n(1)
Catch ex As Autodesk.AutoCAD.Runtime.Exception
Trans.Abort()
ed.WriteMessage(vbLf & "Error transferring blocks to current drawing: " & ex.Message & vbLf)
ed.UpdateScreen()
DisplayError = True
End Try
End Using
Catch ex As Autodesk.AutoCAD.Runtime.Exception
ed.WriteMessage(vbLf & "Error transferring blocks to current drawing: " & ex.Message & vbLf)
ed.UpdateScreen()
DisplayError = True
End Try
End If
sourceDb.Dispose()
Catch ex As Autodesk.AutoCAD.Runtime.Exception
ed.WriteMessage(vbLf & "Error reading from source drawing: " & ex.Message & vbLf)
ed.UpdateScreen()
DisplayError = True
End Try
End Using
Catch ex As Autodesk.AutoCAD.Runtime.Exception
ed.WriteMessage(vbLf & "Error locking current drawing for update: " & ex.Message & vbLf)
ed.UpdateScreen()
DisplayError = True
End Try
lblError.Visible = DisplayError
End Sub
Re: Add Block When Other Drawings Are Open
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
BTW (Just checking) Do you actually want to open the document in the editor (i.e. does the user need to see and interact with it). If not, then it is a lot easier (and faster) to open a DWG file in a side database (using Database.ReadDwgFile) to modify it programmatically.
Stephen Preston
Autodesk Developer Network
Re: Add Block When Other Drawings Are Open
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
If you do want them to interact with it have you tried making it the active document first then add Block and BlockReference?
Re: Add Block When Other Drawings Are Open
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
Thanks for everybody's responses. I do need both the source and destination drawing open for the user to interact with. Using the CommandFlags.Session and locking the drawings is working for my situation (at least so far).
