.NET

Reply
Member
Mark-k5xh
Posts: 4
Registered: ‎04-19-2012
Message 1 of 5 (804 Views)

Filter on Attributes

804 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
jeff
Posts: 338
Registered: ‎05-12-2009
Message 2 of 5 (795 Views)

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

http://www.theswamp.org/index.php?topic=41311.msg464457#msg464457

 

Are you wanting AttributrDefinitions or AttributeReferences?

 

You can also find your answers @ TheSwamp
*Expert Elite*
_gile
Posts: 2,125
Registered: ‎04-29-2006
Message 3 of 5 (789 Views)

Re : Filter on Attributes

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

Hi,

 

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*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 4 of 5 (763 Views)

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

       [CommandMethod("chatts")]
        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);
            try
            {
                //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.UpgradeOpen();
                                                    atref.TextString = newval;
                                                    atref.DowngradeOpen();
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                             }
                        tr.Commit();
                        }

                    }
                }
            catch (System.Exception ex)
            {
                ed.WriteMessage(ex.Message);
            }
        }

 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)
            Try
                '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.UpgradeOpen()
                                                    atref.TextString = newval
                                                    atref.DowngradeOpen()
                                                End If
                                            End If
                                        End If
                                    Next
                                End If
                            End If
                        Next
                        tr.Commit()

                    End Using
                End If
            Catch ex As System.Exception
                ed.WriteMessage(ex.Message)
            End Try
        End Sub

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Member
Mark-k5xh
Posts: 4
Registered: ‎04-19-2012
Message 5 of 5 (732 Views)

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.

 

Mark

 

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.