Hi All;
I am using below code to count number of blocks in my drawing, it works well, but there is a problem when i copy/paste a block.
For example, if i found that there are 7 blocks from block (A), then went back to my drawing and copied/pasted one block from this type (A), the result is 8 blocks.
it is good..
but when i delete this copied/pasted one and run the code again, it also gives me 8 blocks.
Important note: Purge command can solve this problem, but from autocad directly.
I tried some codes to purge this copied/pasted block, but there is no success up to now.
Any help please.
Thank for all in advance
<CommandMethod("BOQBlockCounter")> _ Public Sub BOQBlockCounter(ByVal myGrid As DataGridView) Dim myDB As Database = HostApplicationServices.WorkingDatabase Dim curRow As Integer = 0 Using myTrans As Transaction = myDB.TransactionManager.StartTransaction Dim myBT As BlockTable = myDB.BlockTableId.GetObject(OpenMode.ForRead) For Each myBTRid As ObjectId In myBT Dim myBTR As BlockTableRecord = myBTRid.GetObject(OpenMode.ForRead) 'Dim parentName As String = "" 'MsgBox(myBTR.Name & vbTab & myBTR.GetBlockReferenceIds(True, True).Count) If myBTR.Name = "*Model_Space" Or myBTR.Name = "*Paper_Space" Or myBTR.Name = "*Paper_Space0" Then ' Do Nothing Else If myBTR.GetBlockReferenceIds(True, True).Count > 0 Then myGrid.Rows.Add() myGrid.Item(0, curRow).Value = myGrid.Rows.Count myGrid.Item(1, curRow).Value = myBTR.Name myGrid.Item(2, curRow).Value = myBTR.GetBlockReferenceIds(True, True).Count curRow += 1 End If End If Next myTrans.Abort() 'myExcel = Nothing End Using End Sub
The BlockReference list contains also erased references. Usually I check the entities ObjectIds making a call to GetObject(id, true) and checking the IsErased property.
Note the second parameter to True, to allow for reading erased objects.
BlockReference list returned froom BlockTableRecord.GetBlockReferenceIds() DOES NOT include ObjectIds of erased BlockReference, according to the ObjectARX document on this method:
<QUOTE>
This function returns a list of BlockReferences that either directly or indirectly, through block nesting, reference this block. It only returns those block references that are currently active. Use getErasedBlockReferenceIds() to get a list of erased references.
<QUOTE>
Following code shows this:
public class MyCadCommands { private static string _blkName = "MyTestBlock"; // Open a drawing that has a few block "MyTestBlock" inserted // Run this command before and after erase several block references [CommandMethod("BlkCount")] public static void GetBlkCount() { Document dwg = CadApp.DocumentManager.MdiActiveDocument; Editor ed = dwg.Editor; try { ObjectIdCollection activeIds; ObjectIdCollection erasedIds; GetBlockCount( dwg.Database, _blkName, out activeIds, out erasedIds); ed.WriteMessage( "\nActive Block Reference Count: {0}", activeIds.Count); ed.WriteMessage( "\nErased Block Reference Count: {0}", erasedIds.Count); } catch (System.Exception ex) { ed.WriteMessage("\nError: {0}\n{1}", ex.Message, ex.StackTrace); } finally { Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt(); } } private static void GetBlockCount( Database db, string blkName, out ObjectIdCollection activeIds, out ObjectIdCollection erasedIds) { activeIds = null; erasedIds = null; using (Transaction tran=db.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)tran.GetObject( db.BlockTableId, OpenMode.ForRead); if (bt.Has(blkName)) { BlockTableRecord br = (BlockTableRecord) tran.GetObject(bt[blkName], OpenMode.ForRead); activeIds = br.GetBlockReferenceIds(true, true); erasedIds = br.GetErasedBlockReferenceIds(); } tran.Commit(); } } }
Norman Yuan