Hi, I am trying to create a function that will send a specific block to the bottom of the draworder. It should be simple, but I can't work it out.
The code should loop through all blocks in paperspace, and if their name contains "keymap" send them to the back. For some reason the only block refrence the code finds is the paperspace block reference itself. (When I step through I see that only one block reference name is checked = "*paper_space", the other block references don't seem to exist.
Here's the code:
<Autodesk.AutoCAD.Runtime.CommandMethod("TEST_1")>
Public Sub TEST_1()
Dim doc As Document = DocumentManager.CurrentDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Try
Using trans As Transaction = db.TransactionManager.StartTransaction()
Dim bt As BlockTable = trans.GetObject(db.BlockTableId, OpenMode.ForRead)
For Each r As ObjectId In bt
Dim btr As BlockTableRecord = trans.GetObject(r, OpenMode.ForRead)
If btr.IsLayout And btr.Name.ToLower.Contains("paper") Then
For Each entID In btr
Dim ent = TryCast(trans.GetObject(entID, OpenMode.ForRead), BlockReference)
If Not ent = Nothing Then
If ent.BlockName.ToLower.Contains("keymap") Then
Dim OBJid As New ObjectIdCollection()
OBJid.Add(entID)
Dim dot As DrawOrderTable = trans.GetObject(btr.DrawOrderTableId, OpenMode.ForWrite)
dot.MoveToBottom(OBJid)
End If
End If
Next
End If
Next
End Using
Catch ex As Exception
Throw ex
End Try
End Sub
(attached is the drawing I tested the code on - It contains the block in Layout1)
Any help would be appreciated.
Solved! Go to Solution.
Solved by norman.yuan. Go to Solution.
Do you understand how blocks work? You are searching for block definitions, not a BlockReference, which is what the INSERT command places.
I'm sorry - I probably don't understand blocks properly.
I thought that each block is stored as a record in the BlockTable, and when that block is inserted - for example, into model-space - a block reference is added to the model-space block table record. (I had also, assumed that a block reference was a type that inherited the Entity class)
I would be very appreciative if you could explain to me where I went wrong. I am trying to learn the .Net api (coming from a more programming background) and have found numerous examples online, but am still having trouble understanding some fundamentals.
(I did see that I can search for blocks by as following: EntID.ObjectClass.DxfName="INSERT", but from what I read this is not the recommended method, because it exposes the COM object as opposed to using the api methods.)
Thanks
the error lies in this line of code:
If ent.BlockName.ToLower.Contains("keymap") Then
BlockName property refers to the entity's owner block's name (e.g. PaperSpace block name). it should be:
If ent.Name.ToLower.Contains("...") Then
ASSUMING the block IS NOT A DYANMIC block.
Also, in case the layout have multiple block references you want to set DrawOrder, you should collect all possible ObjectIds in the For Each loop and set the DrawOrder after the loop, if the ObjectIdCollection.Count > 0:
If btr.IsLayout And btr.Name.ToLower.Contains("paper") Then
Dim OBJid As New ObjectIdCollection()
For Each entID In btr
Dim ent = TryCast(trans.GetObject(entID, OpenMode.ForRead), BlockReference)
If ent = Nothing Then Continue
If ent.Name.ToLower.Contains("keymap") Then
OBJid.Add(entID)
End If
Next
If OBJid.Count > 0 Then
Dim dot As DrawOrderTable = trans.GetObject(btr.DrawOrderTableId, OpenMode.ForWrite)
dot.MoveToBottom(OBJid)
End If
End If
Norman Yuan
I'm sorry, I'm real busy at the moment and I didn't thoroughly read your code. Thankfully @norman.yuan has you covered.
Can't find what you're looking for? Ask the community or share your knowledge.