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

How to get Attributes collectiion?

9 REPLIES 9
Reply
Message 1 of 10
Khalique
1385 Views, 9 Replies

How to get Attributes collectiion?

Hi,
I am a dotnet developer and new to Autocad.
I am using Visual Studio 2003 and Autocad 2005.
In my project, the reference I created give me access to:
Autodesk.AutoCAD.Interop and
Autodesk.AutoCAD.Interop.Common
The project that I am working on requires me to open a drawing and to verify the existance of certain Blocks and their Attributes. The name of the Blocks and the Attributes that I want to search for are known.
I can get the application object, active document and Blocks collection and find the block that I am looking for. However, I am unable to get the Attributes collection. The block object does not give me any method like, for example, GetAttributes.
Following is an example of how I my code looks like.

AcadApplication _app = new AcadApplication();
_app.Documents.Open(DrawingFileName, false, "");
AcadDocument _doc = _app.ActiveDocument;
AcadBlocks _blocks = _doc.Blocks;
foreach(AcadBlock _block in _blocks)
{
if(_block.Name.Equals("MYBLOCK"))
{
//here _block object provides me
//several properties and methods but
//I am unable to find a way get
//Attributes collection
}
}
//
Any help is highly appreciated
TIA
kr
9 REPLIES 9
Message 2 of 10
Anonymous
in reply to: Khalique

AcadBlockReference not AcadBlock. Here is some example code from AutoCAD's
ActiveX and VBA Developer's Guide. It's in VBA but should be easy to port to
C# if you're using COM Interop.

~tjr

///////////////////////CODE///////////////////////////////////////////
Sub Ch10_GettingAttributes() ' Create the block Dim blockObj As
AcadBlock Dim insertionPnt(0 To 2) As Double insertionPnt(0) = 0
insertionPnt(1) = 0 insertionPnt(2) = 0 Set blockObj =
ThisDrawing.Blocks.Add _ (insertionPnt,
"TESTBLOCK") ' Define the attribute definition Dim attributeObj As
AcadAttribute Dim height As Double Dim mode As Long Dim prompt As
String Dim insertionPoint(0 To 2) As Double Dim tag As String Dim
value As String height = 1# mode = acAttributeModeVerify prompt =
"Attribute Prompt" insertionPoint(0) = 5 insertionPoint(1) = 5
insertionPoint(2) = 0 tag = "Attribute Tag" value = "Attribute Value"
' Create the attribute definition object on the block Set attributeObj =
blockObj.AddAttribute _ (height, mode, prompt, _
insertionPoint, tag, value) ' Insert the block Dim blockRefObj
As AcadBlockReference insertionPnt(0) = 2 insertionPnt(1) = 2
insertionPnt(2) = 0 Set blockRefObj = ThisDrawing.ModelSpace.InsertBlock
_ (insertionPnt, "TESTBLOCK", 1, 1, 1, 0) ZoomAll
' Get the attributes for the block reference Dim varAttributes As Variant
varAttributes = blockRefObj.GetAttributes ' Move the attribute tags
and values into a ' string to be displayed in a Msgbox Dim
strAttributes As String strAttributes = "" Dim I As Integer For I =
LBound(varAttributes) To UBound(varAttributes) strAttributes =
strAttributes + " Tag: " + _ varAttributes(I).TagString
+ vbCrLf + _ " Value: " + varAttributes(I).textString
Next MsgBox "The attributes for blockReference " + _
blockRefObj.Name & " are: " & vbCrLf _ & strAttributes
' Change the value of the attribute ' Note: There is no SetAttributes.
Once you have the ' variant array, you have the objects. ' Changing
them changes the objects in the drawing. varAttributes(0).textString =
"NEW VALUE!" ' Get the attributes again Dim newvarAttributes As
Variant newvarAttributes = blockRefObj.GetAttributes ' Again,
display the tags and values strAttributes = "" For I =
LBound(varAttributes) To UBound(varAttributes) strAttributes =
strAttributes + " Tag: " + _
newvarAttributes(I).TagString + vbCrLf + _ " Value: " +
newvarAttributes(I).textString Next MsgBox "The attributes for
blockReference " & _ blockRefObj.Name & " are: " & vbCrLf _
& strAttributesEnd
Sub///////////////////////CODE///////////////////////////////////////////



wrote in message news:5013028@discussion.autodesk.com...
Hi,
I am a dotnet developer and new to Autocad.
I am using Visual Studio 2003 and Autocad 2005.
In my project, the reference I created give me access to:
Autodesk.AutoCAD.Interop and
Autodesk.AutoCAD.Interop.Common
The project that I am working on requires me to open a drawing and to verify
the existance of certain Blocks and their Attributes. The name of the Blocks
and the Attributes that I want to search for are known.
I can get the application object, active document and Blocks collection and
find the block that I am looking for. However, I am unable to get the
Attributes collection. The block object does not give me any method like,
for example, GetAttributes.
Following is an example of how I my code looks like.

AcadApplication _app = new AcadApplication();
_app.Documents.Open(DrawingFileName, false, "");
AcadDocument _doc = _app.ActiveDocument;
AcadBlocks _blocks = _doc.Blocks;
foreach(AcadBlock _block in _blocks)
{
if(_block.Name.Equals("MYBLOCK"))
{
//here _block object provides me
//several properties and methods but
//I am unable to find a way get
//Attributes collection
}
}
//
Any help is highly appreciated
TIA
kr
Message 3 of 10
Khalique
in reply to: Khalique

Thanks for your reply.
As I was away all day yesterday, I could not reply back on time.
I have also looked at BlockReference object because I saw a Method GetAttribute() in the list. But I have not found a way to obtain a BlockReference object for the existing blocks in a drawing.
The example you quoted is one that inserts a new block by calling
ThisDrawing.ModelSpace.InsertBlock
and thus gets back the BlockReference object as a return value. My question is how can I get a BlockReference object for an existing block in a drawing?
If you think that I am not explaining the problem correctly, let me know. As I mentioned earlier, I am new to AutoCAD.
Thank you all.
This group seems to be the only help available on the topic.
kr
Message 4 of 10
Anonymous
in reply to: Khalique

Here's an example of something I did similiar in VBA. You should easily be
able to convert this to C#.

Note: This may not be the best way to do it but it certianly works.

Hope this helps,
Tim

********CODE********
Public Sub CountCat()
'variables
Dim aeEntity As AcadEntity
Dim varAttRef As Variant
Dim Found As Boolean
Dim i As Integer
Dim U As Integer
Dim P As Integer
Dim X As Integer
Dim tpPartNo As TPart
Dim tbPartList() As TPart
Dim strPart(9) As String

strPart(0) = "PART"
strPart(1) = "PART1"
strPart(2) = "PART2"
strPart(3) = "PART3"
strPart(4) = "PART4"
strPart(5) = "PART5"
strPart(6) = "PART6"
strPart(7) = "PART7"
strPart(8) = "PART8"
strPart(9) = "PART9"

ReDim tbPartList(0) As TPart
tbPartList(0).Qty = 0
tbPartList(0).PartNo = "-"

For Each aeEntity In ThisDrawing.ModelSpace
'loops through every entity in modelspace
If TypeOf aeEntity Is AcadBlockReference Then
'checks to see if it's a block
varAttRef = aeEntity.GetAttributes
'sets varAttref to the attributes of the block
For i = LBound(varAttRef) To UBound(varAttRef)
'loops through all attributes of the block
For U = 0 To 9
'loops through the possible part tags
If varAttRef(i).TagString = strPart(U) Then
'if the attribute tag equals on of the part tags
For P = LBound(tbPartList) To UBound(tbPartList)
'loops through all of the part numbers that I already have
Found = False
'resets found
If tbPartList(P).PartNo = varAttRef(i).TextString
Then 'checks to see if the
text strings match
tbPartList(P).Qty = tbPartList(P).Qty + 1
'if they match it add's 1 to the quantity
Found = True
'sets the found value to true
Exit For
'exit's loop
End If
Next P
If Not Found And varAttRef(i).TextString <> vbNullString
Then
ReDim Preserve tbPartList(LBound(tbPartList) To
UBound(tbPartList) + 1) As TPart 'adds a new number to partlist
tbPartList(UBound(tbPartList)).Qty = 1
'gives the new item a quantity of 1
tbPartList(UBound(tbPartList)).PartNo =
varAttRef(i).TextString 'sets the part
number
End If
End If
Next U
Next i
End If
Next aeEntity
Call SortPart(tbPartList)
For X = 1 To UBound(tbPartList)
frmMatList.lbExtraItems.AddItem tbPartList(X).Qty & "|" &
tbPartList(X).PartNo & "|" & GetCatInfo(tbPartList(X).PartNo)
Next X
End Sub

********CODE********

wrote in message news:5014891@discussion.autodesk.com...
Thanks for your reply.
As I was away all day yesterday, I could not reply back on time.
I have also looked at BlockReference object because I saw a Method
GetAttribute() in the list. But I have not found a way to obtain a
BlockReference object for the existing blocks in a drawing.
The example you quoted is one that inserts a new block by calling
ThisDrawing.ModelSpace.InsertBlock
and thus gets back the BlockReference object as a return value. My question
is how can I get a BlockReference object for an existing block in a drawing?
If you think that I am not explaining the problem correctly, let me know. As
I mentioned earlier, I am new to AutoCAD.
Thank you all.
This group seems to be the only help available on the topic.
kr
Message 5 of 10
Anonymous
in reply to: Khalique

Dang. My inline comments got all messed up when I posted. Please let me know
if you can't read it.

Tim

"Tim Riley" wrote in message
news:5015219@discussion.autodesk.com...
Here's an example of something I did similiar in VBA. You should easily be
able to convert this to C#.

Note: This may not be the best way to do it but it certianly works.

Hope this helps,
Tim

********CODE********
Public Sub CountCat()
'variables
Dim aeEntity As AcadEntity
Dim varAttRef As Variant
Dim Found As Boolean
Dim i As Integer
Dim U As Integer
Dim P As Integer
Dim X As Integer
Dim tpPartNo As TPart
Dim tbPartList() As TPart
Dim strPart(9) As String

strPart(0) = "PART"
strPart(1) = "PART1"
strPart(2) = "PART2"
strPart(3) = "PART3"
strPart(4) = "PART4"
strPart(5) = "PART5"
strPart(6) = "PART6"
strPart(7) = "PART7"
strPart(8) = "PART8"
strPart(9) = "PART9"

ReDim tbPartList(0) As TPart
tbPartList(0).Qty = 0
tbPartList(0).PartNo = "-"

For Each aeEntity In ThisDrawing.ModelSpace
'loops through every entity in modelspace
If TypeOf aeEntity Is AcadBlockReference Then
'checks to see if it's a block
varAttRef = aeEntity.GetAttributes
'sets varAttref to the attributes of the block
For i = LBound(varAttRef) To UBound(varAttRef)
'loops through all attributes of the block
For U = 0 To 9
'loops through the possible part tags
If varAttRef(i).TagString = strPart(U) Then
'if the attribute tag equals on of the part tags
For P = LBound(tbPartList) To UBound(tbPartList)
'loops through all of the part numbers that I already have
Found = False
'resets found
If tbPartList(P).PartNo = varAttRef(i).TextString
Then 'checks to see if the
text strings match
tbPartList(P).Qty = tbPartList(P).Qty + 1
'if they match it add's 1 to the quantity
Found = True
'sets the found value to true
Exit For
'exit's loop
End If
Next P
If Not Found And varAttRef(i).TextString <> vbNullString
Then
ReDim Preserve tbPartList(LBound(tbPartList) To
UBound(tbPartList) + 1) As TPart 'adds a new number to partlist
tbPartList(UBound(tbPartList)).Qty = 1
'gives the new item a quantity of 1
tbPartList(UBound(tbPartList)).PartNo =
varAttRef(i).TextString 'sets the part
number
End If
End If
Next U
Next i
End If
Next aeEntity
Call SortPart(tbPartList)
For X = 1 To UBound(tbPartList)
frmMatList.lbExtraItems.AddItem tbPartList(X).Qty & "|" &
tbPartList(X).PartNo & "|" & GetCatInfo(tbPartList(X).PartNo)
Next X
End Sub

********CODE********

wrote in message news:5014891@discussion.autodesk.com...
Thanks for your reply.
As I was away all day yesterday, I could not reply back on time.
I have also looked at BlockReference object because I saw a Method
GetAttribute() in the list. But I have not found a way to obtain a
BlockReference object for the existing blocks in a drawing.
The example you quoted is one that inserts a new block by calling
ThisDrawing.ModelSpace.InsertBlock
and thus gets back the BlockReference object as a return value. My question
is how can I get a BlockReference object for an existing block in a drawing?
If you think that I am not explaining the problem correctly, let me know. As
I mentioned earlier, I am new to AutoCAD.
Thank you all.
This group seems to be the only help available on the topic.
kr
Message 6 of 10
Khalique
in reply to: Khalique

Yes, it did help me, Tim. Thanks a lot.
I could not guess that BlockReference is also an Entity!
Now I am able to find all the BlockReferences and pick the ones I want.
I can call GetAttributes method on selected BlockReference.
Now, I face another roadblock. The method GetAttribute returns an object of type ‘object’. In C#, you can not use that object as you intend to until you cast it to the right type (this has been the biggest problem for me so far working with the Autocad object model). So, I need to know what kind of object this method (GetAttributes) returns? I guess it should be a collection of AcadAttributeReference. I see that there is an AcadAttributeReference defined in the namespace but I could not find any collection of AcadAttributeReference. Here I need a little more help.
By the way, I referenced ‘AcSmComonents16 1.0 Type Library’ and ‘AutoCAD 2005 Type Library’ in my project. Do I have other options as far as these references are concerned?
I appreciate your help and the time you spent.
kr
Message 7 of 10
Anonymous
in reply to: Khalique

GetAttributes will return an Array of AcadAttributeReference's. From there
you need to loop through the array and access the properties of each
individual attribute. Something like:


AcadAttributeReference aar[] = blkref.GetAttributes();


You should only need a reference to "AutoCAD 2005 Type Library", you don't
need "AcSmComonents16 1.0 Type Library" unless you are working with Sheet
Sets.

~Tim

wrote in message news:5015371@discussion.autodesk.com...
Yes, it did help me, Tim. Thanks a lot.
I could not guess that BlockReference is also an Entity!
Now I am able to find all the BlockReferences and pick the ones I want.
I can call GetAttributes method on selected BlockReference.
Now, I face another roadblock. The method GetAttribute returns an object of
type 'object'. In C#, you can not use that object as you intend to until you
cast it to the right type (this has been the biggest problem for me so far
working with the Autocad object model). So, I need to know what kind of
object this method (GetAttributes) returns? I guess it should be a
collection of AcadAttributeReference. I see that there is an
AcadAttributeReference defined in the namespace but I could not find any
collection of AcadAttributeReference. Here I need a little more help.
By the way, I referenced 'AcSmComonents16 1.0 Type Library' and 'AutoCAD
2005 Type Library' in my project. Do I have other options as far as these
references are concerned?
I appreciate your help and the time you spent.
kr
Message 8 of 10
Khalique
in reply to: Khalique

Thanks for the tip about type library reference.
I have already tried to cast return value of GetAttribute to AcadAttributeReference[]. It throws an exception with the error message "the specified cast is not valid".
I have tried several things but no success.
kr
Message 9 of 10
Punisher
in reply to: Khalique

I am having trouble with a portion of the discussed info in my code

if (ent.GetType().FullName.Equals("Autodesk.AutoCAD.DatabaseServices.BlockReference"))
{
BlockReference br = (BlockReference)ent;
br.GetAttributes().............................this does not exist in the namespace of "...databaseservices"

Can someone tell me where I went wrong?
Message 10 of 10
Punisher
in reply to: Khalique

I found another thread that helped. This is what I worked up from that thread in my app. I hope this helps someone.

Entity ent = (Entity)trans.GetObject(id, OpenMode.ForRead, false);
if (ent.GetType().FullName.Equals("Autodesk.AutoCAD.DatabaseServices.BlockReference"))
{
try
{
BlockReference br = (BlockReference)ent;
AttributeCollection attCol = br.AttributeCollection;
foreach (ObjectId objid in attCol)
{
AttributeReference attRef = (AttributeReference)trans.GetObject(objid, OpenMode.ForRead, true);
ed.WriteMessage(attRef.TextString.ToString() + "\n");
}

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