I've seen lots of examples in this forum that do something similar, and a few google examples, but not many of them are similar - nor do any of them do specifically what I want. Some of them use deep clone, some of them use a wblockClone method, others iterate throught the sub objects of an external database and construct a new block.
I am making a program that will insert a block. My hope is that I can check if the block table has the block, and if not insert the block definition from an external file.
Below are three mangled attempts at doing this (all of which end up in run-time errors despite the try-catch statements).
My ideal result is:
If BT.Has("MyBlock") then
' Go about my business
Else
InsertBlock("Myfile.dwg","MyBlock")
end if
<CommandMethod("Test")> _ Public Shared Sub Test() CopyBlockDef3("C:\myBlock.dwg", MySettings.BlockName) End Sub Public Shared Sub CopyBlockDef3(ByVal blockFile As String, ByVal blockName As String) Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim ed As Editor = doc.Editor Dim db As Database = HostApplicationServices.WorkingDatabase Dim extDB As New Database(False, True) extDB.ReadDwgFile(blockFile, IO.FileShare.Read, True, "") Try Using tr As Transaction = db.TransactionManager.StartTransaction Using extTr As Transaction = extDB.TransactionManager.StartTransaction Dim bt As BlockTable = db.BlockTableId.GetObject(OpenMode.ForWrite) Dim extBT As BlockTable = extDB.BlockTableId.GetObject(OpenMode.ForRead) Dim id As ObjectId = db.Insert(blockName, extDB, False) tr.Commit() extTr.Dispose() End Using End Using db.Dispose() Catch ex As Autodesk.AutoCAD.Runtime.Exception MsgBox(ex.Message & vbCr & ex.StackTrace) End Try End Sub Public Shared Sub CopyBlockDef2(ByVal blockFile As String, ByVal blockName As String) Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim ed As Editor = doc.Editor Dim db As Database = HostApplicationServices.WorkingDatabase Dim extDB As New Database(False, True) extDB.ReadDwgFile(blockFile, IO.FileShare.Read, True, "") Try Using tr As Transaction = db.TransactionManager.StartTransaction Using extTr As Transaction = extDB.TransactionManager.StartTransaction Dim bt As BlockTable = db.BlockTableId.GetObject(OpenMode.ForWrite) Dim extBT As BlockTable = extDB.BlockTableId.GetObject(OpenMode.ForRead) If extBT.Has(blockName) Then extDB.WblockCloneObjects(New ObjectIdCollection(New ObjectId() {extBT(blockName)}), db.BlockTableId, New IdMapping(), DuplicateRecordCloning.Replace, False) End If tr.Commit() extTr.Abort() End Using End Using db.Dispose() Catch ex As Autodesk.AutoCAD.Runtime.Exception MsgBox(ex.Message & vbCr & ex.StackTrace) End Try End Sub Public Shared Sub CopyBlockDef(ByVal blockFile As String, ByVal blockName As String) Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim ed As Editor = doc.Editor Dim db As Database = HostApplicationServices.WorkingDatabase Dim extDB As New Database(False, True) extDB.ReadDwgFile(blockFile, IO.FileShare.Read, True, "") Try Using tr As Transaction = db.TransactionManager.StartTransaction Using extTr As Transaction = extDB.TransactionManager.StartTransaction Dim bt As BlockTable = db.BlockTableId.GetObject(OpenMode.ForRead) Dim extBT As BlockTable = extDB.BlockTableId.GetObject(OpenMode.ForRead) Dim objIds As ObjectIdCollection = New ObjectIdCollection() objIds.Add(extBT.Item(blockName)) Dim idMap As IdMapping = New IdMapping db.DeepCloneObjects(objIds, db.CurrentSpaceId, idMap, False) 'For Each idP As IdPair In idMap ' Dim copyent As Entity = CType(tr.GetObject(idP.Value, OpenMode.ForRead), Entity) 'Next ed.Regen() db.Dispose() tr.Commit() End Using End Using Catch ex As Autodesk.AutoCAD.Runtime.Exception MsgBox(ex.Message & vbCr & ex.StackTrace) End Try End Sub
Solved! Go to Solution.
Solved by chiefbraincloud. Go to Solution.
Looks like I should have tried just one more search before posting. The article linked below contains a very helpful class that seems to work great (even after being converted to VB.Net from an online converter.
Looks like i was close on some of my attempts, but they still need work on transaction and object management.
Try this version, with un-needed stuff removed, (and I think the primary problem, don't dispose the working database)
Public Shared Sub CopyBlockDef3(ByVal blockFile As String, ByVal blockName As String)
Dim db As Database = HostApplicationServices.WorkingDatabase
Dim extDB As New Database(False, True)
extDB.ReadDwgFile(blockFile, IO.FileShare.Read, True, "")
Try
Dim id As ObjectId = db.Insert(blockName, extDB, False)
Catch ex As Autodesk.AutoCAD.Runtime.Exception
MsgBox(ex.Message & vbCr & ex.StackTrace)Finally
extDB.CloseInput(True)
extDB.Dispose
End Try
End Sub