how can a block be completely purged from a drawing

how can a block be completely purged from a drawing

Anonymous
Not applicable
999 Views
6 Replies
Message 1 of 7

how can a block be completely purged from a drawing

Anonymous
Not applicable
If the user erases and purges blocks from a drawing the blocks still exist in the database to a certain extent. If the user saves, closes and opens the drawing then the purged blocks are no longer in the database. How can I programatically clear the drawing of purged blocks to the same extent that manually saving, closing and opening the drawing does?

Thanks

Fred
0 Likes
1,000 Views
6 Replies
Replies (6)
Message 2 of 7

Anonymous
Not applicable
Possibly cycle through the block table collection and if the block table record's IsErased property = true the remove the block table record from the block table collection.

Sorry if the answer is vague but I do not have AutoCAD or Visual Studio here.
0 Likes
Message 3 of 7

Anonymous
Not applicable
Here's a couple of examples that I found by doing a s e a r c h .


http://discussion.autodesk.com/forums/thread.jspa?messageID=5997910蕖
http://discussion.autodesk.com/forums/thread.jspa?messageID=5473990蛆



Bill
0 Likes
Message 4 of 7

Anonymous
Not applicable
Thanks. I thought that I tried a search but obviously not.
0 Likes
Message 5 of 7

Anonymous
Not applicable
I am still having trouble with a "purged" block that is not completely purged.

I can create, populate and insert the block no problem.

I can create and purge a block, save, close and open the drawing and then create and populate the block no problem.

However, if I create a block, purge it and create it again (with the same name) and try to populate the block with entities I get an eWasErased error.

It seems that with the same drawing session the "IsErased" property of the block has survived the purge and creation of a new block definition with the same name. The drawing has to be saved, closed and opened to completely purge the block.

How can I completely purge a block definition without having to close the drawing?

(This the first time I have posted code, how exactly do I preserve formatting? The {code} does not seem sufficient.)

{code}

Public Sub Create(ByVal iBlockName As String)

'create an empty block definition

Dim pTransMan As DatabaseServices.TransactionManager
Dim pTrans As DatabaseServices.Transaction
Dim pDwg As Document
Dim pDB As Database
Dim pBT As BlockTable
Dim pBTR As BlockTableRecord

pDwg = Application.DocumentManager.MdiActiveDocument
pDB = pDwg.Database
pTransMan = pDwg.TransactionManager
pTrans = pTransMan.StartTransaction

'open the blocktable
pBT = pTrans.GetObject(pDB.BlockTableId, OpenMode.ForWrite)

'add a blocktablerecord for the block definition
pBTR = New BlockTableRecord
pBTR.Name = iBlockName
pBT.Add(pBTR)

'add the blocktablerecord to the transaction
pTrans.AddNewlyCreatedDBObject(pBTR, True)

'commit the transaction
pTrans.Commit()

'dispose of the transaction objects
pTrans.Dispose()
pTransMan.Dispose()

End Sub


Public Sub Populate( _
ByVal iBlockName As String, _
ByVal iEntities As Collection _
)

'add entities to an existing block definition

Dim pTransMan As DatabaseServices.TransactionManager
Dim pTrans As DatabaseServices.Transaction
Dim pDwg As Document
Dim pBT As BlockTable
Dim pBTR As BlockTableRecord

pDwg = Application.DocumentManager.MdiActiveDocument
pTransMan = pDwg.TransactionManager
pTrans = pTransMan.StartTransaction

'open the blocktable
pBT = pTrans.GetObject(pDwg.Database.BlockTableId, OpenMode.ForWrite)

Try
'get the blocktablerecord for the block

'********************************************************
'this is where I get the error
' Autodesk.AutoCAD.Runtime.Exception: eWasErased

pBTR = pBT(iBlockName).GetObject(OpenMode.ForWrite)
'********************************************************

'process the entities
Dim pEntity As Entity
For Each pEntity In iEntities
'append the entity to the block table record
pBTR.AppendEntity(pEntity)
'add the entity to the transaction
pTrans.AddNewlyCreatedDBObject(pEntity, True)
Next

Catch ex As Autodesk.AutoCAD.Runtime.Exception
'the blockdef was created, purged, and created again
'the IsErased flag is still set to TRUE
pDwg.Editor.WriteMessage(vbCr & ex.ToString)
End Try

'commit the transaction
pTrans.Commit()

'dispose of the transaction objects
pTrans.Dispose()
pTransMan.Dispose()

End Sub

Public Sub Purge(ByVal iBlockName As String)

'purge the block definition if there are no block references

Dim pTransMan As DatabaseServices.TransactionManager
Dim pTrans As DatabaseServices.Transaction
Dim pDwg As Document
Dim pDB As Database
Dim pBT As BlockTable
Dim pBTR As BlockTableRecord

pDwg = Application.DocumentManager.MdiActiveDocument
pDB = pDwg.Database
pTransMan = pDwg.TransactionManager
pTrans = pTransMan.StartTransaction

Try

'assume the blockrefs have already been erased from the drawing
' so the block definition can be purged
pBT = pTrans.GetObject(pDB.BlockTableId, OpenMode.ForRead)
'use ... True, True to get all block definitions
pBTR = pTrans.GetObject(pBT(iBlockName), OpenMode.ForWrite, True, True)
Dim pObjectIDCollection As ObjectIdCollection = New ObjectIdCollection()
pObjectIDCollection.Add(pBTR.ObjectId)
pDB.Purge(pObjectIDCollection)
pBTR.Erase(True)
pTrans.Commit()

Catch ex As Autodesk.AutoCAD.Runtime.Exception
pDwg.Editor.WriteMessage(vbCr & ex.ToString)
End Try

'dispose of the transaction objects
pTrans.Dispose()
pTransMan.Dispose()

End Sub
0 Likes
Message 6 of 7

Anonymous
Not applicable
For about 4 years I have been completely baffled at how Autodesk could allow
its .NET API designers to put this booby-trap in place, and leave it there
to this day.

The 'booby trap' I'm referring to is the SymbolTable's default indexer and
Has() method, both of which treat erased entries in the table with
indifference.

When a symbol table contains multiple entries with the same name, all except
one of which are erased, Has() returns true regardless of whether the first
entry it finds is erased or not, and the default indexer returns the first
entry it finds, erased or not.

Or to put it more simply, this was a major screw-up.

The way it should have been done, is to have both Has() and the default
indexer ignore erased entries, unless they are invoked on the copy of the
SymbolTable that's returned by the IncludingErased property.

I honestly don't know what to tell you, other than to download the code I
use (http://www.caddzone.com/DBUtils.cs).

Beware that the versions of the methods in that file that use P/Invoke do
not work on both 32 and 64 bit platforms because the EntryPoint sigs are not
the same.


--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD
Supporting AutoCAD 2000 through 2010

http://www.acadxtabs.com

Email: string.Format("{0}@{1}.com", "tonyt", "caddzone");

wrote in message
news:[email protected]...
I am still having trouble with a "purged" block that is not completely
purged.

I can create, populate and insert the block no problem.

I can create and purge a block, save, close and open the drawing and then
create and populate the block no problem.

However, if I create a block, purge it and create it again (with the same
name) and try to populate the block with entities I get an eWasErased error.

It seems that with the same drawing session the "IsErased" property of the
block has survived the purge and creation of a new block definition with the
same name. The drawing has to be saved, closed and opened to completely
purge the block.

How can I completely purge a block definition without having to close the
drawing?

(This the first time I have posted code, how exactly do I preserve
formatting? The {code} does not seem sufficient.)

{code}

Public Sub Create(ByVal iBlockName As String)

'create an empty block definition

Dim pTransMan As DatabaseServices.TransactionManager
Dim pTrans As DatabaseServices.Transaction
Dim pDwg As Document
Dim pDB As Database
Dim pBT As BlockTable
Dim pBTR As BlockTableRecord

pDwg = Application.DocumentManager.MdiActiveDocument
pDB = pDwg.Database
pTransMan = pDwg.TransactionManager
pTrans = pTransMan.StartTransaction

'open the blocktable
pBT = pTrans.GetObject(pDB.BlockTableId, OpenMode.ForWrite)

'add a blocktablerecord for the block definition
pBTR = New BlockTableRecord
pBTR.Name = iBlockName
pBT.Add(pBTR)

'add the blocktablerecord to the transaction
pTrans.AddNewlyCreatedDBObject(pBTR, True)

'commit the transaction
pTrans.Commit()

'dispose of the transaction objects
pTrans.Dispose()
pTransMan.Dispose()

End Sub


Public Sub Populate( _
ByVal iBlockName As String, _
ByVal iEntities As Collection _
)

'add entities to an existing block definition

Dim pTransMan As DatabaseServices.TransactionManager
Dim pTrans As DatabaseServices.Transaction
Dim pDwg As Document
Dim pBT As BlockTable
Dim pBTR As BlockTableRecord

pDwg = Application.DocumentManager.MdiActiveDocument
pTransMan = pDwg.TransactionManager
pTrans = pTransMan.StartTransaction

'open the blocktable
pBT = pTrans.GetObject(pDwg.Database.BlockTableId,
OpenMode.ForWrite)

Try
'get the blocktablerecord for the block

'********************************************************
'this is where I get the error
' Autodesk.AutoCAD.Runtime.Exception: eWasErased

pBTR = pBT(iBlockName).GetObject(OpenMode.ForWrite)
'********************************************************

'process the entities
Dim pEntity As Entity
For Each pEntity In iEntities
'append the entity to the block table record
pBTR.AppendEntity(pEntity)
'add the entity to the transaction
pTrans.AddNewlyCreatedDBObject(pEntity, True)
Next

Catch ex As Autodesk.AutoCAD.Runtime.Exception
'the blockdef was created, purged, and created again
'the IsErased flag is still set to TRUE
pDwg.Editor.WriteMessage(vbCr & ex.ToString)
End Try

'commit the transaction
pTrans.Commit()

'dispose of the transaction objects
pTrans.Dispose()
pTransMan.Dispose()

End Sub

Public Sub Purge(ByVal iBlockName As String)

'purge the block definition if there are no block references

Dim pTransMan As DatabaseServices.TransactionManager
Dim pTrans As DatabaseServices.Transaction
Dim pDwg As Document
Dim pDB As Database
Dim pBT As BlockTable
Dim pBTR As BlockTableRecord

pDwg = Application.DocumentManager.MdiActiveDocument
pDB = pDwg.Database
pTransMan = pDwg.TransactionManager
pTrans = pTransMan.StartTransaction

Try

'assume the blockrefs have already been erased from the drawing
' so the block definition can be purged
pBT = pTrans.GetObject(pDB.BlockTableId, OpenMode.ForRead)
'use ... True, True to get all block definitions
pBTR = pTrans.GetObject(pBT(iBlockName), OpenMode.ForWrite,
True, True)
Dim pObjectIDCollection As ObjectIdCollection = New
ObjectIdCollection()
pObjectIDCollection.Add(pBTR.ObjectId)
pDB.Purge(pObjectIDCollection)
pBTR.Erase(True)
pTrans.Commit()

Catch ex As Autodesk.AutoCAD.Runtime.Exception
pDwg.Editor.WriteMessage(vbCr & ex.ToString)
End Try

'dispose of the transaction objects
pTrans.Dispose()
pTransMan.Dispose()

End Sub
0 Likes
Message 7 of 7

Anonymous
Not applicable
Thanks very much Tony. Your code gets me around the "booby trap". I thought that I was losing it there for a while.

Fred
0 Likes