GetBlockReferenceIds Problems

GetBlockReferenceIds Problems

HJohn1
Advocate Advocate
3,235 Views
8 Replies
Message 1 of 9

GetBlockReferenceIds Problems

HJohn1
Advocate
Advocate

I am trying to call the BlockTableRecord GetBlockRefenceIds function to get a list of all BlockRefences on that a Layout, but not matter what I try it always returns 0.  Here is what my test looks like:  A drawing with two PaperSpace layouts each with a few BlockReferences, in addtion some more BlockReferences are in the ModelSapce.  Here is my code:

 

 db = HostApplicationServices.WorkingDatabase

 blt = CType(Tran.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)

 btr = CType(Tran.GetObject(db.CurrentSpaceId, OpenMode.ForRead), BlockTableRecord)

 IdList = btr.GetBlockReferenceIds(True, True)

 If IdList.Count > 0 Then
    Stop
 End If

 I am setting the current layout before executing the code.  It does not matter if I change it and instead of using "db.CurrentSpaceId" I use "blt(BlockTableRecord.ModelSpace) or .PaperSpace.  This function always returns 0.  Please help before I go nuts.

0 Likes
3,236 Views
8 Replies
Replies (8)
Message 2 of 9

HJohn1
Advocate
Advocate

Here is a bit more info about my post.  The reason I need to do this is to get the newest BlockReference in the Layout.  There could be any number of them, but I am interested only on the last one added to the Layout.  In VBA I would do something like the code shown below to get the last BlockRef added to the Layout.  Hope this helps to understand what I am doing and perhaps to get better help.  TIA

 

Public Function GetNewestBlock(ByVal bname As String) As AcadBlockReference
Dim b As AcadBlockReference
Dim blayout As AcadBlock
Dim i As Integer
Dim e As AcadEntity

Set blayout = ThisDrawing.ActiveLayout.Block

For i = blayout.Count - 1 To 0 Step -1
    
    Set e = blayout.Item(i)
    
    If TypeOf e Is AcadBlockReference Then
    
        Set b = e
        
        If b.Name = bname Then
        Set GetNewestBlock = b
        Exit For
        End If
        
    End If
    
Next i


End Function

 

0 Likes
Message 3 of 9

_gile
Consultant
Consultant

Hi,

 

The BlockTableRecord.GetBlockRefenceIds methods Returns a list of BlockReferences that reference this BlockTableRecord.

The way you use it, you're trying to ge the ModelSpace references in the drawaing...

 

Use a filtered selection set instead :

 

TypedValue[] filter = new TypedValue[2] {new TypedValue(0, "INSERT"), new TypedValue(410, "model")};

PromptSelectionResult psr = ed.GetSelection(new SelectionFilter(filter));

if (psr.Status != PromptStatus.OK) return;



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 4 of 9

_gile
Consultant
Consultant

You can do it the same way as you did in VBA:

- step through the space BlockTableRecord

- get the entities from ObjectIds

- evaluate if it's a BlockReference and if so set the variable...

 

Or, using the SelectionSet way and comparing the BlockReferences Handles (the greatest is the newest).



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 5 of 9

HJohn1
Advocate
Advocate

_gile

 

Thank you very much and again and again.  I was not aware that one could use the code 410 in SelectionSets.  Up to very recently I was using AC2007 VBA and code 410 was not allowed in SelectionSets.  This opens up to a whole new approach. 

 

0 Likes
Message 6 of 9

wang890
Collaborator
Collaborator

hey guys

just thought i expand the problem here instead of posting a new one since this is similar.

 

i am trying to insert all the blocks in an empty drawing which there is nothing inserted just in the dwg memory.

 

i do the same thing and it gives me 0 blocks.

 

i am trying to insert each block into modelspace without asking which block. i'll do the coordinate calculation. this is for creating a table of blocks. but there are so many blocks and i don't want to insert one by one.

 

Public

SubInsertBlock()

 

Dim db AsDatabase = HostApplicationServices.WorkingDatabase()

 

Dim id AsObjectId

 

Using trans AsTransaction = db.TransactionManager.StartTransaction()

 

TryDim bt AsBlockTable = trans.GetObject(db.BlockTableId, OpenMode.ForWrite)

 

Dim btr AsBlockTableRecord = trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)

 

Dim ed AsEditor = Application.DocumentManager.MdiActiveDocument.Editor

 

Dim oBlock AsBlockReference

 

Dim y AsDoubleForEach id In btr.GetBlockReferenceIds(False, False)

 

Dim oAcadEntity AsEntity = trans.GetObject(id, OpenMode.ForWrite)

 

IfTypeOf (oAcadEntity) Is BlockReference Then'get block object, check each block

oBlock =

CType(oAcadEntity, BlockReference)

 

If oBlock.Name <> "_None"ThenDim oPoint3D AsNewPoint3d(0, y, 0)

 

Dim insert AsNewBlockReference(oPoint3D, oBlock.Id)

trans.AddNewlyCreatedDBObject(insert,

True)

y -= 10

EndIfEndIfNext

trans.Commit()

Catch ex AsException

MsgBox(

"Error: "+ ex.Message)

 

EndTryEndUsingEndSub

Stantec
Dell Precision 5530, Prism M320PU, C3D 14/17/19
0 Likes
Message 7 of 9

jeff
Collaborator
Collaborator

Does the empty drawing contain the blocks(definitions)?

In a empty there will be no blockreferences you need to create them, kind of like you did but skip the GetBlockReferenceIds part and just use BlockTablesRecord Id and check if layout, since it is empty I am guessing no anonymous and xref's etc....................

 

and GetBlockReferenceIds(false, false)------having the first argument set to false will only return nested block references.

You can also find your answers @ TheSwamp
0 Likes
Message 8 of 9

jeff
Collaborator
Collaborator

Here is a example and see how it itereates the blocktable using the definitions which are BlockTableRecords.

 

 <CommandMethod("InsertAllBlocks")> _
        Public Sub InsertAllBlocks()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor

            Using trx As Transaction = db.TransactionManager.StartTransaction()

                Dim bt As BlockTable = trx.GetObject(db.BlockTableId, OpenMode.ForRead)
                Dim modelBtr As BlockTableRecord = trx.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)

                Dim Xval As Double = 0
                Dim Yval As Double = 100
                Dim counter As Integer = 0

                For Each objId As ObjectId In bt
                    Dim btr As BlockTableRecord = trx.GetObject(objId, OpenMode.ForRead)

                    If btr.IsLayout Then
                        Continue For
                    End If

                    Dim bref As New BlockReference(New Point3d(Xval, Yval, 0), objId)
                    modelBtr.AppendEntity(bref)
                    trx.AddNewlyCreatedDBObject(bref, True)

                    If Not counter = 10 Then
                        counter += 1
                        Xval += 10
                    Else
                        counter = 0
                        Xval = 0
                        Yval -= 10
                    End If
                Next


                trx.Commit()
            End Using
        End Sub

 

You can also find your answers @ TheSwamp
0 Likes
Message 9 of 9

wang890
Collaborator
Collaborator

good morning Jeff:

 

this thing work awesome.

 

thank you very much and have a nice weekend.

Stantec
Dell Precision 5530, Prism M320PU, C3D 14/17/19
0 Likes