.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Insert Block Reference in Paper Space

3 REPLIES 3
SOLVED
Reply
Message 1 of 4
RodWing
2252 Views, 3 Replies

Insert Block Reference in Paper Space

Using ACAD 2014, VB.NET code.

 

I am attempting to develop an app that has to insert block references into the active Paper Space layout. I've found numerous code examples for inserting blocks, including the recent one in this forum. Through various iterations of my code I still have not been successful. The code works for inserting blocks in Model space. The odd part about the Model space functionality is that I have to save and exit the drawing, then reopen it for the block to appear.

 

My function is included below. You will see the variations I have tried preceeded by the comments #Attempt 1, #Attempt 2, and #Attempt 3.

 

Thanks for any help you can provide.

 

    Public Function InsertBlock(ByVal BlockName As String, ByVal ptPosition As Point3d, Optional ByVal inPaperSpace As Boolean = False, Optional ByVal LayoutName As String = "") As Boolean
        ' Get the current database and start a transaction
        Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
        Dim acCurDb As Autodesk.AutoCAD.DatabaseServices.Database

        acCurDb = Application.DocumentManager.MdiActiveDocument.Database

        InsertBlock = False

        Using acLckDocCur As DocumentLock = acDoc.LockDocument
            Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
                ' Open the Block table for read
                Dim acBlkTbl As BlockTable
                acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)

                Dim blkRecId As ObjectId = ObjectId.Null

                If acBlkTbl.Has(BlockName) Then
                    blkRecId = acBlkTbl(BlockName)
                Else
                    Exit Function
                End If

                ' Insert the block reference into the current space
                If blkRecId <> ObjectId.Null Then
                    Using acBlkRef As New BlockReference(New Point3d(0, 0, 0), blkRecId)
                        With acBlkRef
                            .SetDatabaseDefaults()
                            .Visible = True
                            .Position = ptPosition
                            .ScaleFactors = New Autodesk.AutoCAD.Geometry.Scale3d(10, 10, 10)
                            .Rotation = 0
                        End With

                        Dim acBlkTblRec As BlockTableRecord

                        'Attempt #1
                        'acBlkTblRec = acTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForWrite)

                        'Attempt #2
                        If inPaperSpace Then
                            'acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.PaperSpace), OpenMode.ForWrite)

                            'Attempt #3
                            If LayoutName.Length = 0 Then
                                Exit Function
                            End If

                            Dim loMgr As LayoutManager = LayoutManager.Current
                            Dim loID As ObjectId = loMgr.GetLayoutId(LayoutName)
                            Dim lo As Layout = acTrans.GetObject(loID, OpenMode.ForRead)
                            acBlkTblRec = acTrans.GetObject(lo.BlockTableRecordId, OpenMode.ForWrite)
                        Else
                            acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
                        End If

                        acBlkTblRec.AppendEntity(acBlkRef)
                        acTrans.AddNewlyCreatedDBObject(acBlkRef, True)
                    End Using
                End If

                ' Save the new object to the database
                acTrans.Commit()

                ' Dispose of the transaction
                InsertBlock = True
            End Using
        End Using
    End Function

 

3 REPLIES 3
Message 2 of 4
SENL1362
in reply to: RodWing

i don't see any immediate problems while reading the code.
Is the layout existing and initialized?
Message 3 of 4
SENL1362
in reply to: SENL1362

Just wrote this sample which inserted a simple block in the uninitialised Layout1.

Hope this might help you find you're problem.

Also simplified the call to InsertBlock a bit, if layoutName=="" then insert into Modelspace.

Tip: You also might add rotation, scale and a list of attributes to increase usability

 

 

        [CommandMethod("TestInsert")]
        public void TestInsert()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            string blockName = "Block1";
            Point3d insPnt = new Point3d(10, 10, 0);
            string layoutName = "Layout1";

            try
            {
                InsertBlock(db, layoutName, blockName, insPnt);
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\n {0}", ex.Message);
            }
        }

        public bool InsertBlock(Database db, string layoutName, string blockName, Point3d insPnt)
        {
            LayoutManager layoutManager = LayoutManager.Current;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (!bt.Has(blockName))
                    return false;
                ObjectId blkId=bt[blockName];

                BlockTableRecord btr = null;
                if (string.IsNullOrEmpty(layoutName))
                    btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
                else
                {
                    ObjectId layoutId = layoutManager.GetLayoutId(layoutName);
                    Layout layout = (Layout)tr.GetObject(layoutId, OpenMode.ForRead);
                    btr = (BlockTableRecord)tr.GetObject(layout.BlockTableRecordId, OpenMode.ForRead);
                }

                BlockReference blkRef = new BlockReference(insPnt, blkId);
                btr.UpgradeOpen();
                btr.AppendEntity(blkRef);
                tr.AddNewlyCreatedDBObject(blkRef, true);
                tr.Commit();
            }
            return true;
        }

 

 

Message 4 of 4
RodWing
in reply to: SENL1362

The layouts are initialized. 

 

The block I was testing has multiple visibility states. When I switched to a block with no visibilty states defined it ran perfectly. Now I have to use more if my google skills to find some examples to deal with inserting dynamic blocks. 

 

Thanks for your help.

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost