.NET
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic to the Top
- Bookmark
- Subscribe
- Printer Friendly Page
Filter on Attributes
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
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
Re: Filter on Attributes
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
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.msg4
Are you wanting AttributrDefinitions or AttributeReferences?
Re : Filter on Attributes
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
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 Handling > Selection Set Filter Lists and related topics.
Just think array of TypedValue instead of dotted pair list.
Re: Filter on Attributes
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
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.D ocumentManager.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.D ocumentManager.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
Re: Filter on Attributes
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
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

