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

ObjectClass is not a member of ObjectID (AutoCAD 2008)

21 REPLIES 21
Reply
Message 1 of 22
SRSDS
869 Views, 21 Replies

ObjectClass is not a member of ObjectID (AutoCAD 2008)

Hi,

I need to make my application compatible with 2008 and have one error saying that ObjectClass is not a member of SubEntId (As ObjectID) in my InsertBlock routine. Can anyone suggest a solution here?

 

    Public Sub InsertBlock(ByVal blockname As String, ByVal trans As Transaction)
        Dim db As Database = Application.DocumentManager.MdiActiveDocument.Database
        ' Test if block exists in the block table
        Dim bt As BlockTable = DirectCast(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
        Dim id As ObjectId = bt(blockname)
        Dim btr As BlockTableRecord = trans.GetObject(id, OpenMode.ForRead, False, True)
        Dim br As New BlockReference(New Point3d(0, 0, 0), id)
        Dim MS As BlockTableRecord = DirectCast(trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
        MS.AppendEntity(br)
        trans.AddNewlyCreatedDBObject(br, True)
        If btr.HasAttributeDefinitions Then
            Dim AtDef As AttributeDefinition, AttRef As AttributeReference
            For Each SubEntId As ObjectId In btr
                If SubEntId.ObjectClass.Name = "AcDbAttributeDefinition" Then
                    AtDef = trans.GetObject(SubEntId, OpenMode.ForRead, False, True)
                    AttRef = New AttributeReference
                    AttRef.SetAttributeFromBlock(AtDef, br.BlockTransform)
                    br.AttributeCollection.AppendAttribute(AttRef)
                    trans.AddNewlyCreatedDBObject(AttRef, True)
                    AtDef.Dispose()
                    AttRef.Dispose()
                End If
            Next
        End If
        BlockRefID = br.ObjectId
    End Sub

 

21 REPLIES 21
Message 2 of 22
norman.yuan
in reply to: SRSDS

ObjectId.ObjectClass property was only made available since AutoCAD 2009.

 

Message 3 of 22
Alfred.NESWADBA
in reply to: SRSDS

Hi,

 

if gettype(trans.getobject(SubEntId,OpenMode.ForRead, False, False).Equals(gettype(DatabaseServices.AttributeReference)) then

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 4 of 22
SRSDS
in reply to: Alfred.NESWADBA

Alfred,

Adding that now says that "trans.getobject" is not defined.

A bit strange bit intellisense doesn't register what "trans" is within the gettype() function.

Message 5 of 22
Alfred.NESWADBA
in reply to: SRSDS

Hi,

 

in your sample-code the variable "trans" was the transaction you used, I just used it again.

 

But just because I reread your post, you are searching for a DatabaseServices.AttributeDefinition and not for an DatabaseServices.AttributeReference, so please correct that in my line.

But the rest should work.

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 6 of 22
Alfred.NESWADBA
in reply to: SRSDS

Oh, oh, oh, one bracket missing! It should be:

 

if gettype(trans.getobject(SubEntId,OpenMode.ForRead, False, False)).Equals(gettype(DatabaseServices.AttributeDefinition)) then

 

(I know I should have tried it, sorry!)

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 7 of 22
SRSDS
in reply to: Alfred.NESWADBA

Hi,

I'm not sure what's happened to  the trans variable. It doesn't register within the gettype function for some reason.

Screenshot attached.

Message 8 of 22
Alfred.NESWADBA
in reply to: SRSDS

Hi,

 

have you seen my previous message with "missing brackets"?

At leat the GetObject is used the same way as you had it one line after the if, so it has to work.

 

The lines can also be tried in that way (simplier then:

 

Dim tDbObj as DatabaseServices.DBObject = trans.GetObject(SubEntId,OpenMode.ForRead,False,False)

if tDbObj.Gettype.Equals(Gettype(DatabaseServices.AttributeDefinition)) then

    'now you can use your attribute-defintion

    AtDef = ctype(tDbObj, DatabaseServices.AttributeDefinition)

 

Hoping not to have additional typos!

 


- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 9 of 22
SRSDS
in reply to: SRSDS

I've added the ).

 

Still no dice.  I may just be throwing in a useless and confusing bit of information but this version uses .NET 3.0

 

 

Message 10 of 22
Alfred.NESWADBA
in reply to: SRSDS

our posts crossed again! 😉

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 11 of 22
Hallex
in reply to: SRSDS

Try to add bracket after IF:

if (gettype(trans.getobject(SubEntId,OpenMode.ForRead, False, False))).Equals(gettype(DatabaseServices.AttributeDefinition)) then

...

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 12 of 22
_gile
in reply to: Hallex

Hi,

 

what about using as (C#) or TryCast (VB) ?

 

C#

AttributeDefinition attDef = trans.getObject(SubEntId,OpenMode.ForRead, False, False) as AttributeDefinition;
if (attDef != null)
{ }

 VB (not certain about syntax)

Dim attDef As AttributeDefinition = TryCast(trans.getobject(SubEntId,OpenMode.ForRead, False, False),  AttributeDefinition)
If attDef IsNot Nothing Then


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 13 of 22


@Alfred.NESWADBA wrote:

Hi,

 

have you seen my previous message with "missing brackets"?

At leat the GetObject is used the same way as you had it one line after the if, so it has to work.

 

The lines can also be tried in that way (simplier then:

 

Dim tDbObj as DatabaseServices.DBObject = trans.GetObject(SubEntId,OpenMode.ForRead,False,False)

if tDbObj.Gettype.Equals(Gettype(DatabaseServices.AttributeDefinition)) then

    'now you can use your attribute-defintion

    AtDef = ctype(tDbObj, DatabaseServices.AttributeDefinition)

 

Hoping not to have additional typos!

 


- alfred -


I would recommend that *you* should probably hit the books and become more familar with the correct way to do typecasting and type discovery..  Consider googling TryCast().

 

It might also help if you didn't post example code that calls GetType() on the result of Transaction.GetObject(), which  discards the result of GetObject(), even though it is perfectly obvious from the OP's original code that he needs to use the object after successfully casting it to an AttributeDefinition.  

 

 

Message 14 of 22
DiningPhilosopher
in reply to: SRSDS


@SRSDS wrote:

I've added the ).

 

Still no dice.  I may just be throwing in a useless and confusing bit of information but this version uses .NET 3.0

 


Hi. The solution to your problem is quite simple, if you first disregard what you've been trying to follow up to this point.

 

The TryCast() method will attempt to cast the object to the destination type, and return the object cast to that type, if it is of the requested type. Othewise, it will return Nothing.

 

See gile's response for an intelligent example.

Message 15 of 22

Hi,

 

>> I would recommend that *you* should probably hit the books and become more familar

>> It might also help if you didn't post example code that calls GetType() on the result of Transaction.GetObject(),

I normally don't include any error handling mechanism to make a sample as short and understandable as possible.

So I assumed that SubEntId is valid (and is proofed to be valid) and so <Transaction>.GetObject always returns something based on DatabaseServices.DbObject.

And in that case when I know it's a valid result with a valid type for the following function I'm on a better way to use CType then to use TryCast because of time differences, TryCast is a quite slower than CType is it does not include any testing mechanism in it.

 

At least back to OP:

yes, you might include the line

if (SubEntID.isValid) andalso (Not SubEntID.IsErased) then

or you use the method mentioned by Gile's or DiningPhilosopher's TryCast.

 

Again sorry for my bracket mistakes!

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 16 of 22


@Alfred.NESWADBA wrote:

Hi,

 

I normally don't include any error handling mechanism to make a sample as short and understandable as possible.

So I assumed that SubEntId is valid (and is proofed to be valid) and so <Transaction>.GetObject always returns something based on DatabaseServices.DbObject.

And in that case when I know it's a valid result with a valid type for the following function I'm on a better way to use CType then to use TryCast because of time differences, TryCast is a quite slower than CType is it does not include any testing mechanism in it.

 

At least back to OP:

yes, you might include the line

if (SubEntID.isValid) andalso (Not SubEntID.IsErased) then

or you use the method mentioned by Gile's or DiningPhilosopher's TryCast.

 

Again sorry for my bracket mistakes!

 

- alfred -


It doesn't really have anything to do with error handling.  

 

It would be inaccurate to compare TryCast() to CType() because TryCast() is also doing what your other code does (e.g., calling GetType(), and then Equals()), only TryCast() is doing it more correctly, where you code is not.

 

TryCast() tests if a given object is an instance of a type, or any derived type, whereas your use of Equals() only tells if the object's runtime type is a specific type but not a derived type. While it may be that there will never be an object derived from AttributeDefinition, that doesn't make the use of Equals() to do type discovery any more correct.

 

So why am I objecting to your example?  because it should be obvious that the OP is just starting out and is looking for guidance on how to do generic type discovery and casting correctly, rather than incorrectly.

 

There's no need for IsErased or IsValid here, since there is no way that either of those can be true.

 

Message 17 of 22

Hi,

 

>> It would be inaccurate to compare TryCast() to CType()

Point of view? TryCast tests first and if ok it casts, CType casts without test (resulting in exception if fails), at least both functions do casting (so they can be compared ... my personal oppinion).

 

>> [...]because TryCast() is also doing what your other code does (e.g., calling GetType(), and then Equals()),

So with your words now my code is not as wrong as you wrote? 😉

 

>> While it may be that there will never be an object derived from AttributeDefinition

There may be ... yes may be, but here the code searches for an object of type AttributeDefinition and not of "may be anything else". Is my english that bad that I overread something and it was any other objecttype searched for?

Or do you mean that the OP has created a dervived class based on AttributeReference and in that case GetType().Equals does not work? Well ok, but in that case I don't think that this is the case here and again, we want to make simple samples and not split any letter of code into whens and whys (what we are doing at the moment, I know).

 

>> TryCast() tests if a given object is an instance of a type, or any derived type, whereas your use of Equals()

You are absolutly right, yes .... but the job here works perfect, So you mentioned one additional option that TryCast can handle, but it's not needed here. Against that you now wrote:

>> [...] for guidance on how to do generic type discovery and casting correctly,

 

As started, I guess it's a point of view what to prefere, Gile's code (and your suggestion) is working in similar ways and both results are correct (I see mine code running faster in case of a big data amount).

 

>> There's no need for IsErased or IsValid here, since there is no way that either of those can be true.

If someone did first a _PURGE and so erased the Blockdefinition then the ObjectID of an erased Entity within a BlockTableRecords might be marked as erased. (Well the OP might have checked that before, I haven't seen that code)

 

I have biggest respect of you and your work, but I don't know why a simple (working) code is that criticised.

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 18 of 22
jeff
in reply to: Alfred.NESWADBA

Hi SRSDS,
In VB if you know for sure what the object is DiredtCast is the fastest, but casting is not the point.

In case you did not pick up on what gile and DinningPhilospher were pointing out, they were trying to show you how to avoid extra calls to GetObject.

I am repeating what gile and DiningPhilosopher have already pointed out but you have an Objectid and your intrested in the type of DbObject it points to in memory. From your original example it looks like that if it is the type your intrested in then you would like to use the object.

They mentioned TryCast because it is a clean way to test and to get the object.

The reason you are having problems getting the first example to work is there are 2 different GetTypes.
The GetType operator and the GetType method of the type Type.

The operator GetType takes a argument that is the Type name, and the GetType method is used with a object variable.

To get it to compile and look at it a little closer

                Dim AttRef As AttributeReference
                For Each SubEntId As ObjectId In btr
                    If trans.GetObject(SubEntId, OpenMode.ForRead, False, False).GetType().Equals(GetType(AttributeReference)) Then
                        AttRef = trans.GetObject(SubEntId, OpenMode.ForRead, False, True)
                    End If
                Next

I think the main point others were trying to make is notice how the result of GetObject is thrown away in testing for the type.

 

Perhaps he meant something along the lines of

                Dim AttRef As AttributeReference
                For Each SubEntId As ObjectId In btr
                    Dim dbo As DBObject = trans.GetObject(SubEntId, OpenMode.ForRead, False, True)
                    If dbo.GetType().Equals(GetType(AttributeReference)) Then
                        AttRef = dbo
                    End If
                Next

 

That still does another check, but not as costly as calling GetObject 2 times for every object you want to know the type from its ObjectId.

 

Or even

                Dim AttRef As AttributeReference
                For Each SubEntId As ObjectId In btr
                    Dim dbo As DBObject = trans.GetObject(SubEntId, OpenMode.ForRead, False, True)
                    If TypeOf dbo Is AttributeReference Then
                        AttRef = dbo
                    End If
                Next

 Now knock it all out at once.

                Dim AttRef As AttributeReference
                For Each SubEntId As ObjectId In btr
                    AttRef = TryCast(trans.GetObject(SubEntId, OpenMode.ForRead, False, True), AttributeReference)
                    If Not AttRef Is Nothing Then
                        ''''''
                    End If
                Next

 That was the point I think they were trying to make and were not trying to argue if TryCast is faster than CType which is still not as fast as DirectCast but TryCast it is much cleaner a quicker if you do not know the type. In a situation where you would use Ctype there is no need for any of this because already know type your dealing with.

 

No matter how you look it, it is still VB so it sucks but the TryCast is a little less sucky.

 

Since the post is this long I might as well finish it with a idiotic story to bring home the point.

There are 2 parcel companies(UPS and FedEx are examples) called Ctype ans TryCast delivery.(I still do not understand how Ctype got involved but going with it.) Now Ctype is faster than TryCast but TryCast is still fast.(DirectCast is still the fastest). So one day living in America you and 2 buddies need packages from Europe and you tell the Ctype guy I think i have this package in Europe could you go check and get it? So he flies to Europe comes back and is like "great news your package was there". Then you stand there for a moment waiting for the package and you ask "well can i have it?" and he is like "I do not have it I just checked for you." Now your standing there in a awkward moment staring at the guy thinking there is no way this tard flew all the way to Europe to check for a package I needed and flew all the way back to tell me it was there. Then he tells you if the package is not there and I try to get we have to start handling exceptions, and about that time running a little behind is the Trycast guy who your buddies used and tell one buddy your package was not there so I have nothing and the other it was and here is your package. This is really getting stupid.

You can also find your answers @ TheSwamp
Message 19 of 22
jeff
in reply to: Alfred.NESWADBA


@Alfred.NESWADBA wrote:

 Well ok, but in that case I don't think that this is the case here and again, we want to make simple samples and not split any letter of code into whens and whys (what we are doing at the moment, I know).

 

I have biggest respect of you and your work, but I don't know why a simple (working) code is that criticised.

 

- alfred -


First off Alred I have read many of your post and I am sure many would agree with me when I say they have been very helpful and thanks.

 

I got to call you out on that comment and hopefully you understand it is only because I have respect for you and know your a smart guy.

 

That is one the biggest problems it seems that the when the whens and whys are never covered it only leads to assumptions and lack of understanding. I do not think anyone could disagree that Tony understands the fundamentals and how important they are and is trying to pass that on to beginners.

I can not count the hours I wasted googling for subjects skimming through webages quickly just to get enough info(don't forget time for looking at porn) just to end up with unconnected concepts and not gaining any real new knowledge, and you have helped many to gain knowledge and seemed like somrthing you would not say, but maybe I mis-understood it.

 

You can also find your answers @ TheSwamp
Message 20 of 22

Hi sorry don't have time to go point-by-point with you.

 

Here are some facts:

 

First you posted code that discarded the result of the call to GetObject().

 

Then you posted revised code that used it, and did a comparision using GetType() and Equals().

 

And then you erroneously suggested that CType() is faster than TryCast(), while completely ignoring the fact that CType() cannot be used without also calling GetType() and Equals() or (more correctly) IsAssignableFrom() first.

 

I trust most here got the jist of my comments, so I'm not going to waste time debating that with you.

 

 

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