Message 1 of 13
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
How to get a collection of all block table records in a file?
Solved! Go to Solution.
How to get a collection of all block table records in a file?
Solved! Go to Solution.
Solved - by using this method:
TransactionManager.GetAllObjects
Edit: Not a solution. The method above gets all opened DBObjects in a transaction.
The object you need to open in order to get all BlockTableRecords, is, not surprisingly, BlockTable. You do:
using (var tran=[db].TransactionManager.StartTransaction())
{
var tbl=(BlockTable)tran.GetObject([db].BlockTableId, OpenMode4.ForRead);
IEnumerable<BlockTableRecord> allRecords=
tbl.Cast<ObjectId>().Select(id=>(BlockTableRecord)tran.GetObject(id, OpenMode.ForRead);
// work with the records as needed
... ...
tran.Commit();
}
public static class MyExtensions
{
public static IEnumerable<T> GetObjects<T>(this IEnumerable<ObjectId> ids,
Transaction tr,
OpenMode mode = OpenMode.ForRead)
where T : DBObject
{
if(ids == null)
throw new ArgumentNullException(nameof(ids));
if(tr == null)
throw new ArgumentNullException(nameof(tr));
RXClass rxclass = RXObject.GetClass(typeof(T));
foreach(ObjectId id in ids)
{
if(id.ObjectClass.IsDerivedFrom(rxclass))
{
yield return Unsafe.As<T>(tr.GetObject(id, mode));
}
}
}
}
public static class Example
{
[CommandMethod("LISTBLOCKNAMES")]
public static void ListBlockNames()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
using(var trans = doc.TransactionManager.StartTransaction())
{
var blockTable = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
var ids = blockTable.Cast<ObjectId>();
var blockTableRecords = ids.GetObjects<BlockTableRecord>(trans);
foreach(BlockTableRecord btr in blockTableRecords)
{
/// btr is only usable up to the call to Commit() below.
ed.WriteMessage($"\n{btr.Name}");
}
trans.Commit();
}
}
}
ed.WriteMessage($"\n{btr.Name}");
I'm checking the docs and I don't see that block table records have 'Name' property...
@OrmArTHe a écrit :
ed.WriteMessage($"\n{btr.Name}");I'm checking the docs and I don't see that block table records have 'Name' property...
BlockTableRecord derives from SymbolTableRecord which has a Name property.
Could you please explain this line:
var blockTableRecords = ids.GetObjects<BlockTableRecord>(trans);
I can't seem to find GetObjects method in the docs...
Got it. But GetObject method returns ObjectId... How do I convert it to BlockTableRecord so I can access its Name property?
Here's a method wich return a collection of all the the block table record names.
private static IEnumerable<string> GetBlockNames(Database db)
{
using (var tr = new OpenCloseTransaction())
{
var blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId id in blockTable)
{
var btr = (BlockTableRecord)tr.GetObject(id, OpenMode.ForRead);
yield return btr.Name;
}
tr.Commit();
}
}
Here's a testing command:
[CommandMethod("TEST")]
public static void Test()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
foreach (string name in GetBlockNames(db))
{
ed.WriteMessage($"\n{name}");
}
}
This is not directly related to this topic, but I just want to thank @ActivistInvestor and @_gile for your contributions. Even if a topic is not something I'm directly needing help on, I almost always learn something from your posts. Thank you both!
The GetObjects method is in the code that I posted, it is not built into the api. Did you try the code or are you simply looking at it?
Generally, I try to understand it before trying it, but yes, I was too hasty and I missed your 'MyExtensions' Class... Sorry about that... I appreciate your help, your solution if really robust...