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

Commit BlockTableRecord with erased objects

1 REPLY 1
Reply
Message 1 of 2
di98feja
349 Views, 1 Reply

Commit BlockTableRecord with erased objects

Hello good people, I am in need of your wisdom.

I have a BlockTableRecord that is referenced several times in a drawing. I wish to update the contents of this BlockTableRecord and therefore I Erase all objects in it and append new ones.
But when I commit the transaction I get one System.NullReferenceException for each erased object?

Here is some code recreating the exception:

using AcDb = Autodesk.AutoCAD.DatabaseServices;

AcDb.Database db = AcDb.HostApplicationServices.WorkingDatabase;
AcDb.ObjectId myBlockReferenceId = AcDb.ObjectId.Null;
using (AcDb.Transaction trans = db.TransactionManager.StartTransaction())
{
try
{
AcDb.BlockTable bt = (AcDb.BlockTable)trans.GetObject(db.BlockTableId, AcDb.OpenMode.ForWrite);
AcDb.BlockTableRecord modelspace = (AcDb.BlockTableRecord)trans.GetObject(bt[AcDb.BlockTableRecord.ModelSpace], AcDb.OpenMode.ForWrite);
AcDb.BlockTableRecord myBlock = new AcDb.BlockTableRecord();
myBlock.Name = "MyTestBlock";
bt.Add(myBlock);
trans.AddNewlyCreatedDBObject(myBlock, true);

AcDb.MText myText = new AcDb.MText();
myBlock.AppendEntity(myText);
trans.AddNewlyCreatedDBObject(myText, true);

AcDb.BlockReference myBlockReference = new AcDb.BlockReference(new Autodesk.AutoCAD.Geometry.Point3d(), myBlock.ObjectId);
modelspace.AppendEntity(myBlockReference);
trans.AddNewlyCreatedDBObject(myBlockReference, true);

myBlockReferenceId = myBlockReference.ObjectId;

trans.Commit();
}
catch (Autodesk.AutoCAD.Runtime.Exception)
{
trans.Abort();
}
}

using (AcDb.Transaction trans = AcDb.HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
{
try
{
AcDb.BlockReference myBlockReference = trans.GetObject(myBlockReferenceId, AcDb.OpenMode.ForRead) as AcDb.BlockReference;
AcDb.BlockTableRecord myBlock = trans.GetObject(myBlockReference.BlockTableRecord, AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord;
foreach (AcDb.ObjectId objId in myBlock)
{
AcDb.DBObject myObj = trans.GetObject(objId, AcDb.OpenMode.ForWrite);
myObj.Erase(true);
}
trans.Commit();
}
catch (Autodesk.AutoCAD.Runtime.Exception)
{
trans.Abort();
}
}

}

Am I doing something the wrong way or should I not bother with this exception?

Could it be related to what is discussed in this thread:
http://discussion.autodesk.com/thread.jspa?messageID=4915935

Thanks
/Jan-Eric
1 REPLY 1
Message 2 of 2
Anonymous
in reply to: di98feja

The code you posted seems to work fine (when run from a registered command handler).

One possible cause is that the block you're adding already exists, and your use of try/catch is supressing the exception thrown.

Don't use try/catch to do nothing but abort a transaction, because that will happen anyways if the call to Commit() is never reached when an exception is thrown. The problem with what you're doing with try/catch is that it catches any exception that gets thrown; aborts the transaction; and then execution continues as if nothing went wrong, which shouldn't happen. Your should allow any thrown exception that you did not expect to stop your program dead in its tracks.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

wrote in message news:5830154@discussion.autodesk.com...
Hello good people, I am in need of your wisdom.

I have a BlockTableRecord that is referenced several times in a drawing. I wish to update the contents of this BlockTableRecord and therefore I Erase all objects in it and append new ones.
But when I commit the transaction I get one System.NullReferenceException for each erased object?

Here is some code recreating the exception:

using AcDb = Autodesk.AutoCAD.DatabaseServices;

AcDb.Database db = AcDb.HostApplicationServices.WorkingDatabase;
AcDb.ObjectId myBlockReferenceId = AcDb.ObjectId.Null;
using (AcDb.Transaction trans = db.TransactionManager.StartTransaction())
{
try
{
AcDb.BlockTable bt = (AcDb.BlockTable)trans.GetObject(db.BlockTableId, AcDb.OpenMode.ForWrite);
AcDb.BlockTableRecord modelspace = (AcDb.BlockTableRecord)trans.GetObject(bt[AcDb.BlockTableRecord.ModelSpace], AcDb.OpenMode.ForWrite);
AcDb.BlockTableRecord myBlock = new AcDb.BlockTableRecord();
myBlock.Name = "MyTestBlock";
bt.Add(myBlock);
trans.AddNewlyCreatedDBObject(myBlock, true);

AcDb.MText myText = new AcDb.MText();
myBlock.AppendEntity(myText);
trans.AddNewlyCreatedDBObject(myText, true);

AcDb.BlockReference myBlockReference = new AcDb.BlockReference(new Autodesk.AutoCAD.Geometry.Point3d(), myBlock.ObjectId);
modelspace.AppendEntity(myBlockReference);
trans.AddNewlyCreatedDBObject(myBlockReference, true);

myBlockReferenceId = myBlockReference.ObjectId;

trans.Commit();
}
catch (Autodesk.AutoCAD.Runtime.Exception)
{
trans.Abort();
}
}

using (AcDb.Transaction trans = AcDb.HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
{
try
{
AcDb.BlockReference myBlockReference = trans.GetObject(myBlockReferenceId, AcDb.OpenMode.ForRead) as AcDb.BlockReference;
AcDb.BlockTableRecord myBlock = trans.GetObject(myBlockReference.BlockTableRecord, AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord;
foreach (AcDb.ObjectId objId in myBlock)
{
AcDb.DBObject myObj = trans.GetObject(objId, AcDb.OpenMode.ForWrite);
myObj.Erase(true);
}
trans.Commit();
}
catch (Autodesk.AutoCAD.Runtime.Exception)
{
trans.Abort();
}
}

}

Am I doing something the wrong way or should I not bother with this exception?

Could it be related to what is discussed in this thread:
http://discussion.autodesk.com/thread.jspa?messageID=4915935

Thanks
/Jan-Eric

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