4 Posts
0 Kudos
Registered: ‎04-19-2012
Post 1 of 5

Filter on Attributes

845 Views, 4 Replies
04-19-2012 01:40 PM

I'm new to this and would like a little help. I am wanting to act on all the attribute definitions in a drawing. All are on the layer "P_ATTR". I can filter out everything except what is on that layer but there are other entities on that layer besides the att defs. The only way I have found (so far) is to test each entity for "AcDbAttributeDefinition" and exclude everything else.


Here is the code I used to filter on the layer:


Dim myTVs(0) AsTypedValue

myTVs(0) = NewTypedValue(DxfCode.LayerName, "P_ATTR")

Dim myFilter AsNewSelectionFilter(myTVs)

Dim myPSR AsPromptSelectionResult = myEd.SelectAll()


Question 1: Is there a filter I can add to return just the attribute definitions?


Question 2: Is there a list someplace that shows all the things that can be put into the DxfCode.xxxx statement? I have spent hours on the web looking for some additional info. I know there is a reference to the DXF guide but nothing in that guide looks like the statement I used. I found a few examples on that syntax but can't find much else.


Thanks, Mark






Valued Mentor
341 Posts
53 Kudos
Registered: ‎05-12-2009
Post 2 of 5

Re: Filter on Attributes

04-19-2012 02:25 PM in reply to: Mark-k5xh

You can filter using the ObjectId's ObjectClass property and see if they are Attributes.


Here is a really nice way that TonyT recently shared



Are you wanting AttributrDefinitions or AttributeReferences?


You can also find your answers @ TheSwamp
*Expert Elite*
2,142 Posts
255 Kudos
Registered: ‎04-29-2006
Post 3 of 5

Re : Filter on Attributes

04-19-2012 02:53 PM in reply to: Mark-k5xh



If I don't misunderstand, you want to select attribute definition directly inserted in model (or paper) space.


So just filter on the entity type using DxfCode.Start (0) and the entity DxfName ("ATTDEF")

new TypedValue(0, "ATTDEF")



IMO, the more complete documentation about selection filters is in the LISP documentation :

Using the AutoLISP Language > Using AutoLISP to Manipulate AutoCAD Objects > Selection Set HandlingSelection Set Filter Lists and related topics.

Just think array of TypedValue instead of dotted pair list.

Gilles Chanteau
*Expert Elite*
1,569 Posts
171 Kudos
Registered: ‎10-08-2008
Post 4 of 5

Re: Filter on Attributes

04-20-2012 01:36 AM in reply to: Mark-k5xh

Here is quick sample how to do it,

see if that helps

        public void SelectByAttributes()
            ObjectIdCollection blkcoll = new ObjectIdCollection();
            //block name
            string blkname = "MyBlock";//<-- change the block name here
            // tag name to search for 
            string atag = "BLOCK_NAME";//<-- change the attribute tag here, case-sensitive for selection filter!
            //new attribute value
            string newval = "Foo";//<-- change the new attribute value here
            // get active drawing
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            // get document editor
            Editor ed = doc.Editor;
            //get document database
            Database db = doc.Database;

            // build selection filter 
            // to select all attributed blocks by its name in the Model space:
            SelectionFilter sfilter = new SelectionFilter(new TypedValue[] 
           new TypedValue (-4,"<AND"),
           new TypedValue(410, "Model"),
            new TypedValue((int)DxfCode.BlockName,blkname),
           new TypedValue((int)DxfCode.HasSubentities,1),
            new TypedValue (-4,"AND>")

            // request for blocks to be selected all in the  model space 
            PromptSelectionResult res = ed.SelectAll(sfilter);
                //check on valid selection result
                if (res.Status == PromptStatus.OK)
                    //display result
                    ed.WriteMessage("\n--->  Selected {0} objects", res.Value.Count);// debug only, maybe removed
                    //get object transaction 
                    using (Transaction tr = doc.TransactionManager.StartTransaction())
                        ObjectId[] ids = res.Value.GetObjectIds();

                        //iterate through the selection set
                        foreach (ObjectId id in ids)
                            if (id.IsValid && !id.IsErased)
                                Entity ent = tr.GetObject(id, OpenMode.ForRead, false) as Entity;
                                ed.WriteMessage("\n--->  {0}", ent.GetRXClass().DxfName);// debug only, maybe removed
                                //cast entity as BlockReference
                                BlockReference bref = ent as BlockReference;
                                if (bref != null)
                                    foreach (ObjectId aid in bref.AttributeCollection)
                                        Entity subent = tr.GetObject(aid, OpenMode.ForRead, false) as Entity;
                                        if (subent.GetType() == typeof(AttributeReference))
                                            //cast entity as AttributeReference
                                            AttributeReference atref = subent as AttributeReference;

                                            if (atref != null)
                                                // check on desired tag name
                                                if (atref.Tag == atag)
                                                    atref.TextString = newval;

            catch (System.Exception ex)

 And here is the same on VB.Net:

        <CommandMethod("chatts")> _
        Public Sub SelectByAttributes()
            Dim blkcoll As New ObjectIdCollection()
            'block name
            Dim blkname As String = "MyBlock" '<-- change the block name here
            ' tag name to search for 
            Dim atag As String = "TAG1"  '<-- change the attribute tag here
            'new attribute value
            Dim newval As String = "Value1"  '<-- change the new attribute value here
            ' get active drawing
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            ' get document editor
            Dim ed As Editor = doc.Editor
            'get document database
            Dim db As Database = doc.Database

            ' build selection filter 
            ' to select all attributed blocks by its name in the Model space:

            Dim sfilter As New SelectionFilter(New TypedValue() {New TypedValue(-4, "<AND"), New TypedValue(410, "Model"), New TypedValue(CInt(DxfCode.BlockName), blkname), New TypedValue(CInt(DxfCode.HasSubentities), 1), New TypedValue(-4, "AND>")})

            ' request for blocks to be selected all in the  model space 
            Dim res As PromptSelectionResult = ed.SelectAll(sfilter)
                'check on valid selection result
                If res.Status = PromptStatus.OK Then
                    'display result
                    ed.WriteMessage(vbLf & "--->  Selected {0} objects", res.Value.Count)' debug only, maybe removed
                    'get object transaction 
                    Using tr As Transaction = doc.TransactionManager.StartTransaction()
                        Dim ids As ObjectId() = res.Value.GetObjectIds()

                        'iterate through the selection set
                        For Each id As ObjectId In ids
                            If id.IsValid AndAlso Not id.IsErased Then
                                Dim ent As Entity = TryCast(tr.GetObject(id, OpenMode.ForRead, False), Entity)
                                ed.WriteMessage(vbLf & "--->  {0}", ent.GetRXClass().DxfName) ' debug only, maybe removed
                                'cast entity as BlockReference
                                Dim bref As BlockReference = TryCast(ent, BlockReference)
                                If bref IsNot Nothing Then
                                    For Each aid As ObjectId In bref.AttributeCollection
                                        Dim subent As Entity = TryCast(tr.GetObject(aid, OpenMode.ForRead, False), Entity)
                                        If TypeOf subent Is AttributeReference Then
                                            'cast entity as AttributeReference
                                            Dim atref As AttributeReference = TryCast(subent, AttributeReference)

                                            If atref IsNot Nothing Then
                                                ' check on desired tag name
                                                If atref.Tag = atag Then
                                                    atref.TextString = newval
                                                End If
                                            End If
                                        End If
                                End If
                            End If

                    End Using
                End If
            Catch ex As System.Exception
            End Try
        End Sub



4 Posts
0 Kudos
Registered: ‎04-19-2012
Post 5 of 5

Re: Filter on Attributes

04-23-2012 12:26 PM in reply to: Mark-k5xh

Many thanks!


The "new TypedValue(0, "ATTDEF")" worked. I thought I had tried this early in my attempts but I must have typed something wrong.




Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Are you interested in helping shape the future of the Autodesk Community? To participate in this brief usability study, please click here. Your time and input is greatly appreciated!