Hey guys,
Just wondering how I would be able to get a unique ID of a block?
Currently I tried all the properties of a block table record that resemble anything to do with an ID like btr.objectID and btr.ID although copies of blocks have the same ID as the original and the copies contain different attribute values so I wish to access the copies by just feeding in one ID (that I have grabbed from every block in the drawing and put into an array).
Is there a number that is unique to every individual block is essentially what I'm asking, and if so, how do I access it?
Cheers!
Solved! Go to Solution.
Solved by Alfred.NESWADBA. Go to Solution.
Hi,
>> I tried all the properties of a block table record
>> Is there a number that is unique to every individual block
Please don't mix up "BlockTableRecord" and "BlockReference"!
BlockTableRecord is the definition how a symbol is defined
BlockReference is then the inserted object (in ModelSpace or PaperSpace or within anther BlockTableRecord).
And for any item in the DWG-database you have the ObjectID and the Handle.Value that is the unique identifier of an object within the database. IMPORTANT: it's only unique within one drawing, in two drawings you may have the same ObjectID or Handle.
- alfred -
Ahh thank you Alfred! I did get them confused.
So my current code feeds in the btr.id, find the attribute category then adds the value to the array:
Public Sub match_nonconstant_to_blockgrouparray(ByVal blkid As Object)
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
Dim db As Database = HostApplicationServices.WorkingDatabase
Dim tr As Transaction = db.TransactionManager.StartTransaction()
Try
Dim btr As BlockTableRecord = TryCast(blkid.GetObject(OpenMode.ForRead), BlockTableRecord)
Dim ids As ObjectIdCollection = btr.GetBlockReferenceIds(True, True)
Dim btrId As ObjectId
For Each btrId In ids
Dim blkref As BlockReference = TryCast(btrId.GetObject(OpenMode.ForRead, False), BlockReference)
Dim attCol As AttributeCollection = blkref.AttributeCollection
For Each attId As ObjectId In attCol
Dim attRef As AttributeReference = DirectCast(tr.GetObject(attId, OpenMode.ForRead), AttributeReference)
If attRef.Tag.ToUpper = "CATEGORY" Then
blockgrouparray(z) = attRef.TextString
End If
Next
Next
Catch ex As Autodesk.AutoCAD.Runtime.Exception
ed.WriteMessage(("Exception: " + ex.Message))
Finally
tr.Dispose()
End Try
End Sub
Would I change the code so that it just skips the whole blkid part? So its like this:
Public Sub match_nonconstant_to_blockgrouparray(ByVal blkref As Object)
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
Dim db As Database = HostApplicationServices.WorkingDatabase
Dim tr As Transaction = db.TransactionManager.StartTransaction()
Try
Dim attCol As AttributeCollection = blkref.AttributeCollection
For Each attId As ObjectId In attCol
Dim attRef As AttributeReference = DirectCast(tr.GetObject(attId, OpenMode.ForRead), AttributeReference)
If attRef.Tag.ToUpper = "CATEGORY" Then
blockgrouparray(z) = attRef.TextString
End If
Next
Catch ex As Autodesk.AutoCAD.Runtime.Exception
ed.WriteMessage(("Exception: " + ex.Message))
Finally
tr.Dispose()
End Try
End Sub
Many thanks,
HD
Okay so I just figured out my issue there, I was bringing in the blkref as an Object type rather than a Block Reference type.
Now, my next question is, since looking at constant attributes requires you to look at the block table record and cycle through the attribute definitions, how can I find a block's constant by feeding into a function, the block reference ID?
Currently I am feeding in the btr.ID with this function:
Public Sub match_constant_to_blockgrouparray(ByVal blkid As Object)
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
Dim db As Database = HostApplicationServices.WorkingDatabase
Dim tr As Transaction = db.TransactionManager.StartTransaction()
Try
Dim btr As BlockTableRecord = TryCast(blkid.GetObject(OpenMode.ForRead), BlockTableRecord)
For Each id As ObjectId In btr
Dim ad As AttributeDefinition = TryCast(tr.GetObject(id, OpenMode.ForRead), AttributeDefinition)
If ad IsNot Nothing Then
If ad.Constant = True Then
If ad.Tag.ToUpper = "CATEGORY" Then
blockgrouparray(z) = ad.TextString
End If
End If
End If
Next
Catch ex As Autodesk.AutoCAD.Runtime.Exception
ed.WriteMessage(("Exception: " + ex.Message))
Finally
tr.Dispose()
End Try
End Sub
Many Thanks,
HD
Hi,
sorry, for me it's not clear what you want to do.
Can you describe it again with other words or by attaching a sample-drawing? With the sample-drawing we have the chance to talk about "blocknames" and "modelspace" so it's more clear and we don't get confused by BlockTableRecord and BlockReference, not by AttribtueDefinition and AttributeReference, ....
- alfred -
Sorry Alfred, I was able to figure out the answer the other day. What I meant was 'How do I feed in a block ref into a routine and get the attribute constant?' Before my routine that did this only used the block table record so I had to add in a Directcast to include the block table record.
Thanks again for your help!
HD