Hello,
When I try to delete a block I get this error:
---------------------------
AutoCAD Error Aborting
---------------------------
INTERNAL ERROR: !dbobji.cpp@8638: eNotOpenForWrite
---------------------------
What is happenening? I have my tables opened for Write.
Here is the code Im using:
<CommandMethod("CleanHouse")> Sub CleanHouse() Dim OldBlocks() As String = {"MyOldBlock1","OldBlock2"} Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Dim ed As Editor = doc.Editor 'get object id's of all block in the active drawing Dim objIdColl As ObjectIdCollection = BlockReferenceInModelSpace(ed) 'lock document Dim docLock As DocumentLock = doc.LockDocument 'start transaction Dim tx As Transaction = db.TransactionManager.StartTransaction 'iterate object id For Each objId As ObjectId In objIdColl 'get the obeject Dim ent As Entity = tx.GetObject(objId, OpenMode.ForWrite) If (TypeOf ent Is BlockReference) Then 'casting block reference Dim br As BlockReference = CType(ent, BlockReference) '~ Loop Thru the Defined Borders For x = LBound(OldBlocks) To UBound(OldBlocks) '~ Check if the block is in the block table Dim acBlkTbl As BlockTable acBlkTbl = tx.GetObject(db.BlockTableId, OpenMode.ForWrite) If acBlkTbl.Has(OldBlocks(x)) Then 'Loop thru all the blocks For Each blk In acBlkTbl ''now check the block name here If (br.Name = OldBlocks(x)) Then br.Erase(True) tx.Commit() End If Next End If Next x End If Next objId End Sub
Solved! Go to Solution.
Solved by owenwengerd. Go to Solution.
The line tx.Commit() closes all objects open in the transaction.
Thanks, that worked.
I moved the commit before the end function and modified the IF to include an Else for tx.dispose().
One question though, if a block is nested why doesnt it get deleted?
Tony
Nested block references would not be in model space, they would be in the containing block. If you want to erase all instances of a block, you should simply get the list of block references from the block table record, then open each instance and erase it regardless of who owns it. You're likely to get more responses if you post your followup as a new thread.
While you got your code working by moving Transaction.Commit() to correct place, your code logic is rather odd.
Why do you need outer for (...) loop to loop through a set of block references? in your code the outer for (...) loop does nothing but wasting computing power. Also, you should open BlockTable once before you loop through OldBlocks array.
It seems that your intention is to remove an array of old block definitions from drawing. Unless you are absolutely sure, before this code runs, there is no block references based on the old block definitions in drawing, your code runs ok would only based on good luck. You need to first to see if a block definition is really purge-able/delete-able before you call br.Erase(), or the code would raise exception.
That is, when loop through the OldBlocks, for each block definition, you need to see if there is block reference based on this block definition by calling GetBlockreferenceIds(). If the block definition is a dynamic block, you also need to find out if there is anonymous block is derived from this block definition, by calling GetAnonymousBlockIds().
If you just want to try to delete a block definition and when that if the block definition is not erase-able, you want to skip it, then you can use try...catch...
try
{
br.Erase(true);
}
catch
{
//print on command line or messagebox, if necessary;
}
//the code coninue on next block definition
Norman Yuan
Can't find what you're looking for? Ask the community or share your knowledge.