I am going to preface this with the fact I am VERY new to .NET programming.
I am trying to migrate a tool I created from VBA to VB.NET, and have run into a problem that I am surprisingly unable to figure out with Google.
What my tool does it collect information from a litany of attributed blocks and outputs this information, in a very specific format, into an Excel spreadsheet. From there I can edit a bunch of things, then it all goes back into the blocks. In VBA this is INSANELY slow, as it has to check every single entity to see if it is a block, but in .NET, I can start out by searching JUST for blocks, and this should speed things up a lot.
My problem: How do I read attributes from a named block (lets say it is ALWAYS called "TEST_BLOCK").
I found some sample code, but it unfortunately gets a bit cloudy because it CREATES a block then edits it, so I am having a problem establishing something that I can use the .attributecollection "thing" on.
Here's what I tried.
From a BlockTable type variable, I can get an ObjectID using the block name
With the ObjectID, I can get a BlockTableRecord
I am trying to get from BlockTableRecord to BlockReference, because BlockReference is where I can get .AttributeCollection, and then I can get the .ObjectID, .DBObject, .AttributeReference, then .Tag and .TextString
"important" code looks something like this (note: commented line is illegal):
Code:
' define the variable that holds all the blocks
Dim acBlkTbl As BlockTable = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
' define the "record ID to process" variable (default: null)
Dim blkRecId As ObjectId = ObjectId.Null
' if block exists, define it as the "record ID to process"
If acBlkTbl.Has("TEST_BLOCK") Then
blkRecId = acBlkTbl("TEST_BLOCK")
End If
' if we found our block/record ID, then we need to process it
If blkRecId <> ObjectId.Null Then
' define a variable to hold the block's table record
Dim acBlkTblRec As BlockTableRecord
acBlkTblRec = acTrans.GetObject(blkRecId, OpenMode.ForRead)
' if the block's record has attributes (will account for "illegal" blocks) ...
If acBlkTblRec.HasAttributeDefinitions Then
' This line below is illegal :(
Dim acBlkRef As BlockReference = acTrans.GetObject(acBlkTblRec.Id, OpenMode.ForRead)
Dim attCol As AttributeCollection = acBlkRef.AttributeCollection
For Each objID As ObjectId In attCol
Dim dbObj As DBObject = acTrans.GetObject(objID, OpenMode.ForRead)
Dim acAttRef As AttributeReference = dbObj
MsgBox("Tag " & acAttRef.Tag & vbCrLf & "Value: " & acAttRef.TextString & vbCrLf)
Next
Else
MsgBox("Drawing has an illegal 'TEST_BLOCK' block")
End If
Else
MsgBox("No block with name TEST_BLOCK found")
End If
It seems I don't quite get the "logic" of how you find blocks, and the way that my old code worked is too different for me to figure out how to segue, given my current knowledge.
In VBA, it goes AcadEntity->BlockReference ... but many of my drawings have 1 million+ entities, so this takes a very long time.