It's been a hectic week, between one thing and another, and I don’t expect it to get better anytime soon: apart from anything else, my wife is due to give birth any day to our second child. We're both excited - and admittedly a little anxious - about it, and our 2 year-old seems to be feeding of that, which means none of us have ended getting much sleep of late. All good preparation, I suppose. :-)
So I decided the path of least resistance for getting a blog entry out today was to look through some of the responses DevTech have sent out to ADN members recently, to find something that might be of interest to a wider audience. A lot of what we do ends up being very specific to individual situations, but we also get requests for code samples that prove to be of general interest (these latter topics are generally turned into DevNotes (technical solutions) and get posted to the ADN website). Over the busy months ahead I'm sure I'll end up feeding many of these through this blog.
One response that caught my eye was this helpful little code sample, written by Varadan (a.k.a. Krishnan Varadarajan), a member of the DevTech team in India.
It asks the user to select block references, and then goes through them, looking for any contained attributes, which it then dumps to the AutoCAD console:
using Autodesk.AutoCAD;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
namespace MyApplication
{
public class DumpAttributes
{
[CommandMethod("LISTATT")]
public void ListAttributes()
{
Editor ed =
Application.DocumentManager.MdiActiveDocument.Editor;
Database db =
HostApplicationServices.WorkingDatabase;
Transaction tr =
db.TransactionManager.StartTransaction();
// Start the transaction
try
{
// Build a filter list so that only
// block references are selected
TypedValue[] filList = new TypedValue[1] {
new TypedValue((int)DxfCode.Start, "INSERT")
};
SelectionFilter filter =
new SelectionFilter(filList);
PromptSelectionOptions opts =
new PromptSelectionOptions();
opts.MessageForAdding = "Select block references: ";
PromptSelectionResult res =
ed.GetSelection(opts, filter);
// Do nothing if selection is unsuccessful
if (res.Status != PromptStatus.OK)
return;
SelectionSet selSet = res.Value;
ObjectId[] idArray = selSet.GetObjectIds();
foreach (ObjectId blkId in idArray)
{
BlockReference blkRef =
(BlockReference)tr.GetObject(blkId,
OpenMode.ForRead);
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
blkRef.BlockTableRecord,
OpenMode.ForRead
);
ed.WriteMessage(
"\nBlock: " + btr.Name
);
btr.Dispose();
AttributeCollection attCol =
blkRef.AttributeCollection;
foreach (ObjectId attId in attCol)
{
AttributeReference attRef =
(AttributeReference)tr.GetObject(attId,
OpenMode.ForRead);
string str =
("\n Attribute Tag: "
+ attRef.Tag
+ "\n Attribute String: "
+ attRef.TextString
);
ed.WriteMessage(str);
}
}
tr.Commit();
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
ed.WriteMessage(("Exception: " + ex.Message));
}
finally
{
tr.Dispose();
}
}
}
}
Here's what happened when I ran it against the "Blocks and Tables - Imperial.dwg" sample drawing that ships with AutoCAD. On running the LISTATT command and selecting the title block on the right of the page, here's what was dumped out:
Command: LISTATT
Select block references: 1 found
Select block references:
Block: ARCHBDR-D
Attribute Tag: NAME
Attribute String: CORY B.
Attribute Tag: NAME
Attribute String: BOB M.
Attribute Tag: DATE
Attribute String:
Attribute Tag: X"=X'-X"
Attribute String: 1/4" =1'
Attribute Tag: 0
Attribute String: 1
Attribute Tag: 0
Attribute String: 1
Attribute Tag: PROJECT
Attribute String: ADDA
Attribute Tag: TITLE
Attribute String: FLOOR PLANS
Attribute Tag: X
Attribute String:
Attribute Tag: X
Attribute String:
Attribute Tag: X
Attribute String:
Attribute Tag: X/XX/XX
Attribute String:
Attribute Tag: X/XX/XX
Attribute String:
Attribute Tag: X/XX/XX
Attribute String:
Attribute Tag: COMMENT
Attribute String:
Attribute Tag: COMMENT
Attribute String:
Attribute Tag: COMMENT
Attribute String:
Command: