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

Filter on Attributes

4 REPLIES 4
Reply
Message 1 of 5
Mark-k5xh
2965 Views, 4 Replies

Filter on Attributes

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

 

 

 

 

 

4 REPLIES 4
Message 2 of 5
jeff
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
Message 3 of 5
_gile
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
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 4 of 5
Hallex
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
Message 5 of 5
Mark-k5xh
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

 

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