Trouble Inserting a Drawing Into my Drawing - Answered

I'm using this code to insert a drawing into my current drawing like a block. This worked in AutoCAD.
The drawing file exists, all the values that are passed check out good.
It crashes on the line:
Dim BlkId As ObjectId = podDB.Insert(BlockName, db, True)

If anyone has an answer, please let me know. This is getting very frustrating.

`Public Sub InsertBlock(ByVal InsPt As Point3d, ByVal BlockName As String, ByVal basename As String, ByVal explode As Boolean, ByVal blkRot As Double, ByVal scale As Double)

    Dim podDWG As Document = Application.DocumentManager.MdiActiveDocument
    Dim podDB As Database = podDWG.Database

    Using insBlkTrans As Transaction = podDB.TransactionManager.StartTransaction
        Try
            Dim podBT As BlockTable = TryCast(insBlkTrans.GetObject(podDB.BlockTableId, OpenMode.ForRead), BlockTable)
            Dim podBTR As BlockTableRecord = TryCast(insBlkTrans.GetObject(podBT(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)

            If podBT.Has(basename) Then
                Dim myBlockRef As New BlockReference(InsPt, podBT(basename))
                myBlockRef.Rotation = blkRot
                myBlockRef.ScaleFactors = New Scale3d(scale, scale, scale)
                podBTR.AppendEntity(myBlockRef)
                insBlkTrans.AddNewlyCreatedDBObject(myBlockRef, True)
                If explode Then
                    myBlockRef.ExplodeToOwnerSpace()
                    myBlockRef.Erase()
                    myBlockRef.DisableUndoRecording(False)
                    myBlockRef.DowngradeOpen()
                End If
                insBlkTrans.Commit()
            Else
                Try
                    Using db As Database = New Database(False, True)
                        db.ReadDwgFile(BlockName, FileShare.Read, True, Nothing)
                        Dim BlkId As ObjectId = podDB.Insert(BlockName, db, True)      **'<-- Crashes here --**
                        Dim bt As BlockTable = insBlkTrans.GetObject(podDB.BlockTableId, OpenMode.ForRead, True)
                        Dim btr As BlockTableRecord = TryCast(insBlkTrans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite, True), BlockTableRecord)
                        Dim bref As BlockReference = New BlockReference(InsPt, BlkId) With {
                            .Rotation = blkRot,
                            .ScaleFactors = New Scale3d(scale, scale, scale)
                        }
                        btr.AppendEntity(bref)
                        insBlkTrans.AddNewlyCreatedDBObject(bref, True)
                        If explode Then
                            bref.ExplodeToOwnerSpace()
                            bref.Erase()
                            bref.DisableUndoRecording(False)
                            bref.DowngradeOpen()
                        End If
                        If bt.Has("") And Not bt.Has(basename) Then
                            Dim bad As BlockTableRecord = insBlkTrans.GetObject(bt(""), OpenMode.ForWrite, True)
                            bad.Name = basename
                            bad.Dispose()
                        End If
                        insBlkTrans.Commit()
                    End Using
                Catch ex As Exception
                    MsgBox(ex.ToString)
                End Try
            End If
            insBlkTrans.Dispose()
        Catch ex As Exception
            MsgBox(ex.ToString, MsgBoxStyle.Information)
        End Try
    End Using
End Sub`

Comments

  • I ran into the same thing. I reported it and think its still a bug. I'll review my support request on this.

  • Hi James,
    Thanks for looking.

  • I can't seem to find that support request, I must not have done it.
    I need that ability bad too.

  • MGorecki
    edited August 2020

    Hi James,
    I believe I have an answer. It comes from a very smart man named Norman Yuan.
    I was sending the entire path and drawing name (including ".dwg") to the line that crashed. It only wants the drawing name without the ".dwg".
    Since the ReadDwgFile(BlockName....) gets the full path and drawing name, you only need to use the drawing name for the Dim BlkId line as shown below.
    The basename is just the drawing name without the ".dwg"
    Else Try Using db As Database = New Database(False, True) db.ReadDwgFile(BlockName, FileShare.Read, True, Nothing) Dim BlkId As ObjectId = podDB.Insert(basename, db, True)

    I hope that also works for your code. Please let me know if it did.

    Best regards,
    Mark

  • James Maeding
    edited August 2020

    oh, Norman Yuan. Yes, he helped me figure out my template for "long processing progress dialog". I literally was just working on a function using that!
    I'll test some things right now, I would love to discover I am the problem.

  • I looked into my code, and I may have a different issue.
    Your problem was the block was not in the drawing yet.
    Mine is actually worse because I can't get bcad to pull the definition in.
    I'll do the support request.

  • ignore this post, the formatting won't behave

  • James Maeding
    edited August 2020

    ok, so two issue I found, and I would say both are bugs you must work around.
    You already found the "base name" issue, but may run into more later.

    First, when you do this:
    Database tmpDb = new Database(false, true);
    you do need false, true.
    It works with true, true for acad, but not for bcad.
    Turns out false, true works for both.

    Second, it seems bcad does not like this when block name is same as dwg name.
    db.Insert(bName, tmpDb, true);
    What I mean is when you have a symbol called "bub.dwg" and want to insert it as the block "bub".

    It only likes this for such a case:
    db.Insert(bName, bName, tmpDb, true);

    so I have code like this now to switch between acad and bcad in same code file:
    (pound sign)if ACAD
    db.Insert(bName, tmpDb, true);
    (pound sign)endif
    (pound sign)if BCAD
    db.Insert(bName, bName, tmpDb, true);
    (pound sign)endif

    if you have not used project vars like ACAD and BCAD, look into them as you can have one code file with different statements depending on the project. You will have one project for acad and bcad, but same .cs code file in each.
    There is no comparison to maintaining multiple full .cs files, that would be crazy.
    thx

  • Hi James,
    Thanks for the info. I had some additional trouble with bringing a dwg into the drawing. Here is the updated code that works pretty well.

    `Public Sub InsertBlock(ByVal InsPt As Point3d, ByVal BlockName As String, ByVal basename As String,
                           ByVal explode As Boolean, ByVal rotation As Double, ByVal scale As Double)
    
        Dim podDwg As Document = Application.DocumentManager.MdiActiveDocument
        Dim podDB As Database = podDwg.Database
        Dim podED As Editor = podDwg.Editor
        Dim podBT As BlockTable
        Dim podBTR As BlockTableRecord
    
        Using podDwg.LockDocument()
            Using myTrans As Transaction = podDB.TransactionManager.StartTransaction()
                podBT = TryCast(podDwg.Database.BlockTableId.GetObject(OpenMode.ForRead), BlockTable)
                If podBT.Has(basename) Then
                    podBTR = TryCast(podBT(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite), BlockTableRecord)
                    Dim myBlockRef As New BlockReference(InsPt, podBT(basename))
                    myBlockRef.Rotation = rotation
                    myBlockRef.ScaleFactors = New Scale3d(scale, scale, scale)
                    podBTR.AppendEntity(myBlockRef)
                    myTrans.AddNewlyCreatedDBObject(myBlockRef, True)
                    If explode Then
                        myBlockRef.ExplodeToOwnerSpace()
                        myBlockRef.Erase()
                        myBlockRef.DisableUndoRecording(False)
                        myBlockRef.DowngradeOpen()
                    End If
                Else
                    Try
                        Using db As Database = New Database(False, True)
                            db.ReadDwgFile(BlockName, FileShare.Read, True, Nothing)
                            Using tr As Transaction = podDwg.TransactionManager.StartTransaction()
     -----The next 6 lines helped -----
                                Dim blkName As String = SymbolUtilityServices.GetBlockNameFromInsertPathName(BlockName)
                                Dim BlkId As ObjectId = podDB.Insert(blkName, db, True)
                                If BlkId.IsNull Then
                                    podED.WriteMessage(vbLf & "Failed to insert block")
                                    Return
                                End If
                                Dim bt As BlockTable = myTrans.GetObject(podDB.BlockTableId, OpenMode.ForRead, True)
                                Dim btr As BlockTableRecord = CType(tr.GetObject(podDB.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
                                Dim bref As BlockReference
                                bref = New BlockReference(InsPt, BlkId)
                                bref.Rotation = rotation
                                bref.ScaleFactors = New Scale3d(scale, scale, scale)
                                btr.AppendEntity(bref)
                                tr.AddNewlyCreatedDBObject(bref, True)
                                If explode Then
                                    bref.ExplodeToOwnerSpace()
                                    bref.Erase()
                                    bref.DisableUndoRecording(False)
                                    bref.DowngradeOpen()
                                End If
                                If bt.Has("") And Not bt.Has(basename) Then
                                    Dim bad As BlockTableRecord = myTrans.GetObject(bt(""), OpenMode.ForWrite, True)
                                    bad.Name = basename
                                    bad.Dispose()
                                End If
                                tr.Commit()
                            End Using
                        End Using
                    Catch ex As Exception
                        MsgBox(ex.ToString)
                    End Try
                End If
                myTrans.Commit()
            End Using
        End Using
    
    End Sub'
    
  • @MGorecki
    nice, some stuff in there I never use like DisableUndoRecording.
    Handy dandy.