The code below doesn't work 100%. It doesn't give an error while running and the block is properly inserted in the layout, but when I audit the drawing it results in 1 error:
Auditing Entities Pass 1
Pass 1 1000 objects audited
Invalid block name "" found.
Changed to "AUDIT_I_100912220115-0".
Pass 1 1300 objects audited
Auditing Entities Pass 2
Pass 2 1300 objects audited
When i insert the renamed block "AUDIT_I_100912220115-0" it is the block test.dwg that is inserted with the program.
CommandMethod("isb")> _ Public Sub isb() InsertBlockpaper(New Geometry.Point3d(0, 0, 0), "C:\test.dwg", False, 0, 2) End Sub Public Function InsertBlockpaper(ByVal InsPt As Geometry.Point3d, ByVal BlockName As String, ByVal expl As Boolean, ByVal rotation As Double, ByVal schaal As Integer) As DatabaseServices.ObjectId Dim myDB As DatabaseServices.Database Dim myDwg As Document myDwg = Application.DocumentManager.MdiActiveDocument myDB = myDwg.Database Dim ed As Editor = myDwg.Editor Dim tr As Transaction = myDwg.TransactionManager.StartTransaction Try Dim dwgName As String dwgName = HostApplicationServices.Current.FindFile(BlockName, myDB, FindFileHint.Default) Dim db As Database = New Database(False, False) db.ReadDwgFile(dwgName, IO.FileShare.Read, True, "") Dim BlkId As ObjectId BlkId = myDB.Insert(dwgName, db, False) Dim bt As BlockTable = tr.GetObject(myDB.BlockTableId, OpenMode.ForRead, True) Dim btr As BlockTableRecord = tr.GetObject(bt(BlockTableRecord.PaperSpace), OpenMode.ForWrite, True) Dim bref As BlockReference = New BlockReference(InsPt, BlkId) bref.Rotation = rotation bref.ScaleFactors = New Geometry.Scale3d(schaal, schaal, schaal) btr.AppendEntity(bref) tr.AddNewlyCreatedDBObject(bref, True) If expl Then bref.ExplodeToOwnerSpace() bref.Erase() End If tr.Commit() tr.Dispose() 'recent toegevoegd correct ? Catch ex As Exception MsgBox(ex.ToString) End Try End Function
Solved! Go to Solution.
Solved by kdub_nz. Go to Solution.
Solved by fallright. Go to Solution.
Try this code instead seems to working good for me (A2009)
Don't forget to include LockDocument otherwise you will be
get 'eLockViolation' exception
I would avoid using FindFile, better yet to use function
File.Exists from System.IO namespace:
<CommandMethod("ISB", CommandFlags.Session)> _ Public Sub isb() InsertBlockpaper(New Point3d(0, 0, 0), "C:\Users\Олег\Programming\FORUMS\Augi\tag.dwg", False, 0, 2) End Sub Public Function InsertBlockpaper(ByVal InsPt As Point3d, ByVal BlockName As String, ByVal expl As Boolean, ByVal rotation As Double, ByVal schaal As Integer) As ObjectId If Not File.Exists(BlockName) Then Return ObjectId.Null End If Dim myDB As Database Dim myDwg As Document myDwg = Application.DocumentManager.MdiActiveDocument Using docloc As DocumentLock = myDwg.LockDocument myDB = myDwg.Database Dim ed As Editor = myDwg.Editor Using tr As Transaction = myDwg.TransactionManager.StartTransaction Try Using db As Database = New Database(False, True) db.ReadDwgFile(BlockName, IO.FileShare.Read, True, "") Dim BlkId As ObjectId BlkId = myDB.Insert(BlockName, db, True) Dim bt As BlockTable = tr.GetObject(myDB.BlockTableId, OpenMode.ForRead, True) Dim btr As BlockTableRecord = tr.GetObject(bt(BlockTableRecord.PaperSpace), OpenMode.ForWrite, True) Dim bref As BlockReference = New BlockReference(InsPt, BlkId) bref.Rotation = rotation bref.ScaleFactors = New Scale3d(schaal, schaal, schaal) btr.AppendEntity(bref) tr.AddNewlyCreatedDBObject(bref, True) If expl Then bref.ExplodeToOwnerSpace() bref.Erase() End If tr.Commit() End Using Catch ex As Autodesk.AutoCAD.Runtime.Exception MsgBox(ex.ToString) End Try End Using End Using End Function
~'J'~
BillZndl : I've tried your suggestion but bref.name is a read-only property. How can I change this ?
Hallex: I'v'e tried your code, but it gives the same error when auditing.
I think that the sollution is the combination of both suggestions? Only, I don't know how ?
Enjoy 🙂
Public Function InsertBlockpaper(ByVal InsPt As Point3d, ByVal BlockName As String, ByVal expl As Boolean, ByVal rotation As Double, ByVal schaal As Integer) As ObjectId If Not File.Exists(BlockName) Then Return ObjectId.Null End If Dim myDB As Database Dim myDwg As Document myDwg = Application.DocumentManager.MdiActiveDocument Using docloc As DocumentLock = myDwg.LockDocument myDB = myDwg.Database Dim ed As Editor = myDwg.Editor Using tr As Transaction = myDwg.TransactionManager.StartTransaction Try Using db As Database = New Database(False, True) db.ReadDwgFile(BlockName, IO.FileShare.Read, True, "") Dim BlkId As ObjectId BlkId = myDB.Insert(BlockName, db, True) Dim bt As BlockTable = tr.GetObject(myDB.BlockTableId, OpenMode.ForRead, True) Dim btr As BlockTableRecord = tr.GetObject(bt(BlockTableRecord.PaperSpace), OpenMode.ForWrite, True) Dim bref As BlockReference = New BlockReference(InsPt, BlkId) bref.Rotation = rotation bref.ScaleFactors = New Scale3d(schaal, schaal, schaal) btr.AppendEntity(bref) tr.AddNewlyCreatedDBObject(bref, True) If expl Then bref.ExplodeToOwnerSpace() bref.Erase() bref.DisableUndoRecording(False) bref.DowngradeOpen() End If If bt.Has("") Then Dim bad As BlockTableRecord = tr.GetObject(bt(""), OpenMode.ForWrite, True) bad.Erase() bad.Dispose() End If tr.Commit() End Using Catch ex As Autodesk.AutoCAD.Runtime.Exception MsgBox(ex.ToString) End Try End Using End Using End Function
~'J'~
Don't know, i'm fairly new to this but if you are getting bad block references,
there must be something else wrong.
I've been using this to redefine blocks with no trouble.
Sorry, it's C#.
using (Transaction transaction = document.TransactionManager.StartTransaction()) { Database database2 = new Database(false, false); database2.ReadDwgFile(ofd.Filename, System.IO.FileShare.ReadWrite, true, ""); ObjectId id = database.Insert(BlkNm, database2, false); BlockTable table = (BlockTable)transaction.GetObject(database.BlockTableId, OpenMode.ForRead); BlockTableRecord record = (BlockTableRecord)transaction.GetObject(table[BlockTableRecord.ModelSpace], OpenMode.ForWrite); BlockReference reference = new BlockReference(point.Value, table[BlkNm]); record.AppendEntity(reference); transaction.AddNewlyCreatedDBObject(reference, true); ObjectIdCollection blockReferenceIds = record.GetBlockReferenceIds(false, false); if (blockReferenceIds.Count > 0) { foreach (ObjectId id2 in blockReferenceIds) { BlockReference BlkRef = (BlockReference)transaction.GetObject(id2, OpenMode.ForWrite); BlkRef.RecordGraphicsModified(true); } editor.WriteMessage("\n BlockReference: " + BlkNm + " Redefined. \n"); } editor.UpdateScreen(); database2.Dispose(); transaction.Commit(); editor.WriteMessage("\nBlockReference: " + BlkNm + " Inserted.\n"); } //using } //try block.
Hallex, I appreciate your help, but this code doesn't insert the dwg because the name of bt is always "" (I 've checked is with a msgbox command).
In fact the code inserts a block (with no name) and then the code erases the block because it doesn't have a name.
This is strange, on my machine the drawing inserts in PaperSpace as it is needs
and all the blocks were imported from other drawing too
I can see them all in 'Insert dialog window'
The auditing do not show any errors as well
(Tested on A2009 only)
~'J'~
Try this one instead, working good for me as well
I just renamed this bad block
Public Function InsertBlockpaper(ByVal InsPt As Point3d, ByVal BlockName As String, ByVal expl As Boolean, ByVal rotation As Double, ByVal schaal As Integer) As ObjectId If Not File.Exists(BlockName) Then Return ObjectId.Null End If Dim myDB As Database Dim myDwg As Document myDwg = Application.DocumentManager.MdiActiveDocument Using docloc As DocumentLock = myDwg.LockDocument myDB = myDwg.Database Dim ed As Editor = myDwg.Editor Using tr As Transaction = myDwg.TransactionManager.StartTransaction Try Using db As Database = New Database(False, True) db.ReadDwgFile(BlockName, IO.FileShare.Read, True, "") Dim BlkId As ObjectId BlkId = myDB.Insert(BlockName, db, True) Dim bt As BlockTable = tr.GetObject(myDB.BlockTableId, OpenMode.ForRead, True) Dim btr As BlockTableRecord = tr.GetObject(bt(BlockTableRecord.PaperSpace), OpenMode.ForWrite, True) Dim bref As BlockReference = New BlockReference(InsPt, BlkId) bref.Rotation = rotation bref.ScaleFactors = New Scale3d(schaal, schaal, schaal) btr.AppendEntity(bref) tr.AddNewlyCreatedDBObject(bref, True) If expl Then bref.ExplodeToOwnerSpace() bref.Erase() End If If bt.Has("") Then Dim bad As BlockTableRecord = tr.GetObject(bt(""), OpenMode.ForWrite, True) bad.Name = "GoodBlock" End If tr.Commit() End Using Catch ex As Autodesk.AutoCAD.Runtime.Exception MsgBox(ex.ToString) End Try End Using End Using End Function
~'J'~
A very good chance thet the code is fine and that you are trying to insert a dwg "x" that has a block within it called "x". This is a nono
Agreed, thanks for the good point
Regards,
~'J'~
I've changed my code taking into account of all previous remarks. Now my code works (in attach the code for everyone who wants to use it). I consider this problem as resolved. I leave this message a few days open and than I mark this as solved.
<CommandMethod("isb")> _ Public Sub isb() InsertBlockpaper(New Point3d(0, 0, 0), "C:\test.dwg", "test", False, 0, 2) End Sub Public Sub InsertBlockpaper(ByVal InsPt As Point3d, ByVal BlockName As String, ByVal basisnaam As String, ByVal expl As Boolean, ByVal rotation As Double, ByVal schaal As Integer) Dim myTransMan As DatabaseServices.TransactionManager Dim myTrans As DatabaseServices.Transaction Dim myDwg As Document Dim myBT As BlockTable Dim myBTR As BlockTableRecord myDwg = Application.DocumentManager.MdiActiveDocument myTransMan = myDwg.TransactionManager myTrans = myTransMan.StartTransaction myBT = myDwg.Database.BlockTableId.GetObject(OpenMode.ForRead) If myBT.Has(basisnaam) Then myBTR = myBT(BlockTableRecord.PaperSpace).GetObject(OpenMode.ForWrite) Dim myBlockRef As New DatabaseServices.BlockReference(InsPt, myBT(basisnaam)) myBlockRef.Rotation = rotation myBlockRef.ScaleFactors = New Geometry.Scale3d(schaal, schaal, schaal) myBTR.AppendEntity(myBlockRef) myTrans.AddNewlyCreatedDBObject(myBlockRef, True) If expl Then myBlockRef.ExplodeToOwnerSpace() myBlockRef.Erase() myBlockRef.DisableUndoRecording(False) myBlockRef.DowngradeOpen() End If myTrans.Commit() Else If Not File.Exists(BlockName) Then MsgBox(BlockName & " not found...") Else Dim myDB As Database myDB = myDwg.Database Try Using db As Database = New Database(False, True) db.ReadDwgFile(BlockName, IO.FileShare.Read, True, "") Dim BlkId As ObjectId BlkId = myDB.Insert(BlockName, db, True) Dim bt As BlockTable = myTrans.GetObject(myDB.BlockTableId, OpenMode.ForRead, True) Dim btr As BlockTableRecord = myTrans.GetObject(bt(BlockTableRecord.PaperSpace), OpenMode.ForWrite, True) Dim bref As BlockReference bref = New BlockReference(InsPt, BlkId) bref.Rotation = rotation bref.ScaleFactors = New Scale3d(schaal, schaal, schaal) btr.AppendEntity(bref) myTrans.AddNewlyCreatedDBObject(bref, True) If expl Then bref.ExplodeToOwnerSpace() bref.Erase() bref.DisableUndoRecording(False) bref.DowngradeOpen() End If If bt.Has("") And Not bt.Has(basisnaam) Then Dim bad As BlockTableRecord = myTrans.GetObject(bt(""), OpenMode.ForWrite, True) bad.Name = basisnaam bad.Dispose() End If myTrans.Commit() End Using Catch ex As Autodesk.AutoCAD.Runtime.Exception MsgBox(ex.ToString) End Try End If End If myTrans.Dispose() myTransMan.Dispose() End Sub
A note for anyone following along
the Path in VB.net
"C:\test.dwg"
will need to be changed in C# to :
"C:\\test.dwg"
from : http://msdn.microsoft.com/en-us/library/system.io.path.aspx
In members that accept a path, the path can refer to a file or just a directory. The specified path can also refer to a relative path or a Universal Naming Convention (UNC) path for a server and share name. For example, all the following are acceptable paths:
"c:\\MyDir\\MyFile.txt" in C#, or "c:\MyDir\MyFile.txt" in Visual Basic.
"c:\\MyDir" in C#, or "c:\MyDir" in Visual Basic.
"MyDir\\MySubdir" in C#, or "MyDir\MySubDir" in Visual Basic.
"\\\\MyServer\\MyShare" in C#, or "\\MyServer\MyShare" in Visual Basic.
// Called Kerry in my other life.
Everything will work just as you expect it to, unless your expectations are incorrect.
class keyThumper<T> : Lazy<T>; another Swamper
Hello
Could someone smart explain me how to insert a external drawing into my drawing.
(command:insert "C:\block\block.dwg" ...)
Insert it as a block.
I have a drawing in "c:\block\block.dwg" and I need to insert it in a current drawing, but i don't find the direction to do it.
I Had encountered some codes that do it, but I copy and test and gives me some problems, do you have a book or site where I can find the solution...
Thanks in advance...