Author Topic: eNullObjectId  (Read 3904 times)

0 Members and 1 Guest are viewing this topic.

GumbyCAD

  • Newt
  • Posts: 84
eNullObjectId
« on: May 23, 2014, 01:49:46 AM »
Hi Team,

I have a scenario in which I step thru all objects in either ModelSpace / Paparespace.

When I get to a curtain block the fails as the Block return back "eNullObjectId" when I try to do the following:

Code - Visual Basic: [Select]
  1.         Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
  2.  
  3.         For Each btrId As ObjectId In bt
  4.  
  5.             Dim btr As BlockTableRecord = DirectCast(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord)
  6.  
  7.             If btr.IsLayout Then
  8.  
  9.                 Dim lo As Layout = DirectCast(tr.GetObject(btr.LayoutId, OpenMode.ForRead), Layout)
  10.                 Dim ms As BlockTableRecord = DirectCast(tr.GetObject(lo.BlockTableRecordId, OpenMode.ForRead), BlockTableRecord)
  11.  
  12.                 For Each objId As ObjectId In ms
  13.  
  14.                     Dim ent As Entity
  15.                     Dim blk As BlockReference
  16.  
  17.                     Try
  18.  
  19.                         If objId.IsNull Or objId.IsErased Then
  20.                             Continue For
  21.                         End If
  22.  
  23.                         ent = DirectCast(tr.GetObject(objId, OpenMode.ForRead), Entity)
  24.  
  25.                         If Not ent.[GetType]().ToString().Contains("BlockReference") Then
  26.                             Continue For
  27.                         End If
  28.  
  29.                         blk = DirectCast(ent, BlockReference)
  30.                         If blk.IsDisposed Or blk.IsErased Then
  31.                             Continue For
  32.                         End If
  33.  
  34.                         dim BLName as string = blk.Name   '<---- This is where it fails on a particular Block
  35.  

I fixed it by auditing the drawing and Audit deleted 1 Block and repaired another.

Audit Log Below:

Quote
Auditing Tables


Auditing Entities Pass 1

Pass 1 68800   objects audited
Auditing Entities Pass 2

Pass 2 68200   objects auditedAcDbBlockReference(3A7AF)  BTR Id invalid
AcDbBlockReference(3A7AF)         could not be repaired.  It will be Erased.
AcDbBlockReference(3A7CD)  BTR Id invalid
AcDbBlockReference(3A7CD)         could not be repaired.  It will be Erased.
Pass 2 68800   objects audited
Auditing Blocks


 7338    Blocks audited

Total errors found 2 fixed 2

Erased 2 objects
I was wondering if anyone had a way for checking / trapping for this?

As per usual I thank you guys in advance.

Stephan

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: eNullObjectId
« Reply #1 on: May 23, 2014, 02:00:29 AM »
I don't know how to do it in VB.net but instead of DirectCast is there something similar to 'as' in C#??

e.g. in C# you would get an object from the transaction using something like:

Polyline poly = tr.GetObject(objectId, OpenMode.ForWrite) as Polyline;


The direct cast way in C# would be:
Polyline poly = (Polyline)tr.GetObject(objectId, OpenMode.ForWrite);

The diffference is, 'as' returns null on error whereas the other would cause an exception so with 'as' all you need to do is check if the returned object is null:

if(poly == null){
      continue; // skip it, it isn't any good anyway.
}

hope that makes sense
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

GumbyCAD

  • Newt
  • Posts: 84
Re: eNullObjectId
« Reply #2 on: May 23, 2014, 03:06:40 AM »
Perfect Response.   Fixed it exactly.

An explaination from VB.net Point of view.

is DirectCast and TryCast.
TryCast will return "Nothing" is the conversion is not possible.
Were it appears DirectCast will Create the Empty object based on definintion of what you are casting to.

Code - Visual Basic: [Select]
  1.                         blk = TryCast(ent, BlockReference)
  2.                         If blk Is Nothing Then
  3.                             'Abort Code goes here.....
  4.                        End If
  5.  

http://www.codeproject.com/Articles/38070/Difference-Between-DirectCast-and-TryCast

Stephan

GumbyCAD

  • Newt
  • Posts: 84
Re: eNullObjectId
« Reply #3 on: May 23, 2014, 03:07:14 AM »
Thanks Today was not a waist of time... Learned something new.   :ugly:

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: eNullObjectId
« Reply #4 on: May 23, 2014, 03:35:16 AM »
I like the strongly typed way that we deal with objects in c, it requires a bit of extra work on the front end but saves from these odd issues in the end.
Code - C#: [Select]
  1. blk = (BlockReference)ent;
would have thrown an error to notify you that something had gone awry.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: eNullObjectId
« Reply #5 on: May 23, 2014, 04:04:41 AM »
Hi,

It's cheaper (and more concise) to check the ObjectId.ObjectClass before openning the entity than checking the opened entity type with as (or TryCast)

Code - C#: [Select]
  1. if (objId.ObjectClass != RXClass.GetClass(typeof(BlockReference)))
  2.     continue;
  3. blk = (BlockReference)tr.GetObject(objId, OpenMode.ForRead);
Code - vb.net: [Select]
  1. If objId.ObjectClass <> RXClass.GetClass(GetType(MLeaderStyle)) Then
  2.     Continue For
  3. blk = DirectCast(tr.GetObject(objId, OpenMode.ForRead), BlockReference)
Speaking English as a French Frog

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: eNullObjectId
« Reply #6 on: May 23, 2014, 05:26:15 AM »
and if you have a lot of check to make for the sane object type just set a variable to re-use

Code - C#: [Select]
  1. var myBlockClass = RXClass.GetClass(typeof(BlockReference))
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.