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