.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Error When Deleteing Block - eNotOpenForWrite

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
TTIII
905 Views, 4 Replies

Error When Deleteing Block - eNotOpenForWrite

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

 

4 REPLIES 4
Message 2 of 5
owenwengerd
in reply to: TTIII

The line tx.Commit() closes all objects open in the transaction.

--
Owen Wengerd
ManuSoft
Message 3 of 5
TTIII
in reply to: owenwengerd

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

 

Message 4 of 5
owenwengerd
in reply to: TTIII

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.

--
Owen Wengerd
ManuSoft
Message 5 of 5
norman.yuan
in reply to: TTIII

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

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost