vb.net - delete object by ObjectId - get layerinformation

vb.net - delete object by ObjectId - get layerinformation

jan_tappenbeck
Collaborator Collaborator
3,373 Views
4 Replies
Message 1 of 5

vb.net - delete object by ObjectId - get layerinformation

jan_tappenbeck
Collaborator
Collaborator

hi!

 

i want to delete entities by ObjectId.

 

question 1

how is it possible to delete entities by the ObjectId?

 

question 2

how is it possible to get the layername of this entities by question 1?

 

regards Jan

0 Likes
3,374 Views
4 Replies
Replies (4)
Message 2 of 5

_gile
Consultant
Consultant

Hi,

 

An ObjectId is mainly an identifier for database resident objects.

The ObjectId type itself exposes only few members so you cannot directly erase an ObjectId, even less get its layer name (only entities have a Layer property, not other database resident objects as SymbolTable, SymbolTableRecord, DBDictionary).

 

Anyway, you can check if the ObjectId refers to an Entity (using ObjectId.ObjectClass), then open it as Entity, and get its layer and/or erase it.

 

See the topics in this section of the AutoCAD .NET Developer's Guide.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 5

_gile
Consultant
Consultant

Here's a little example using different ways to open an object from its ObjectId.

 

C#

        [CommandMethod("TEST")]
        public void Test()
        {
            var ed = AcAp.DocumentManager.MdiActiveDocument.Editor;
            var per = ed.GetEntity("\nSelect object: ");
            if (per.Status == PromptStatus.OK)
                if(TryGetLayer(per.ObjectId, out string layerName))
                {
                    try
                    {
                        Erase(per.ObjectId);
                        ed.WriteMessage($"\nErased an entity on layer: {layerName}");
                    }
                    catch(System.Exception ex)
                    {
                        ed.WriteMessage($"\nError: {ex.Message}");
                    }
                }
        }

        /// <summary>
        /// Tries to get the entiy layer.
        /// Does not care if a transaction is active and uses an OpenCloseTransaction to open the entity.
        /// </summary>
        /// <param name="id">Entity idenfier.</param>
        /// <param name="layerName">Layer name (ouput)</param>
        /// <returns>true if the objectId is bound to an Entity, false otherwise.</returns>
        public bool TryGetLayer(ObjectId id, out string layerName)
        {
            if (id.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Entity))))
                using (var tr = id.Database.TransactionManager.StartOpenCloseTransaction())
                {
                    layerName = ((Entity)tr.GetObject(id, OpenMode.ForRead)).Layer;
                    return true;
                }
            layerName = null;
            return false;
        }

        /// <summary>
        /// Erases the DBObject.
        /// Opens the object using the active transaction if any, the Open() method otherwise.
        /// </summary>
        /// <param name="id">DBObject identifier</param>
        public void Erase(ObjectId id)
        {
            if (id.Database.TransactionManager.TopTransaction != null)
                id.GetObject(OpenMode.ForWrite).Erase();
            else
#pragma warning disable CS0618
                using (var obj = id.Open(OpenMode.ForWrite))
                    obj.Erase();
#pragma warning restore CS0618
        }

VB

        <CommandMethod("Test")>
        Public Sub Test()
            Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
            Dim per As PromptEntityResult = ed.GetEntity(vbLf + "Select object: ")
            If per.Status = PromptStatus.OK Then
                Dim layerName As String = Nothing
                If TryGetLayer(per.ObjectId, layerName) Then
                    Try
                        Delete(per.ObjectId)
                        ed.WriteMessage(vbLf + $"Erased an entity on layer: {layerName}")
                    Catch ex As System.Exception
                        ed.WriteMessage(vbLf + $"Error: {ex.Message}")
                    End Try
                End If
            End If
        End Sub

        ''' <summary>
        ''' Tries to get the entiy layer.
        ''' Does not care if a transaction is active and uses an OpenCloseTransaction to open the entity.
        ''' </summary>
        ''' <param name="id">Entity identifier.</param>
        ''' <param name="layer">Layer name (output).</param>
        ''' <returns>True if the objectId is bound to an Entity, False otherwise.</returns>
        Public Function TryGetLayer(ByVal id As ObjectId, ByRef layer As String) As Boolean
            If id.ObjectClass.IsDerivedFrom(RXObject.GetClass(GetType(Entity))) Then
                Using tr As OpenCloseTransaction = id.Database.TransactionManager.StartOpenCloseTransaction()
                    layer = DirectCast(tr.GetObject(id, OpenMode.ForRead), Entity).Layer
                    Return True
                End Using
            End If
            Return False
        End Function

        ''' <summary>
        ''' Erases the DBObject.
        ''' Opens the object using the active transaction if any, the Open() method otherwise.
        ''' </summary>
        ''' <param name="id">DBObject identifier</param>
        Public Sub Delete(ByVal id As ObjectId)
            If id.Database.TransactionManager.TopTransaction IsNot Nothing Then
                id.GetObject(OpenMode.ForWrite).Erase()
            Else
#Disable Warning BC40000 ' disable the 'Obsolete' warning
                Using obj = id.Open(OpenMode.ForWrite)
                    obj.Erase()
                End Using
#Enable Warning BC40000
            End If
        End Sub


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 4 of 5

ActivistInvestor
Mentor
Mentor

@jan_tappenbeck wrote:

hi!

 

i want to delete entities by ObjectId.

 

question 1

how is it possible to delete entities by the ObjectId?

 

question 2

how is it possible to get the layername of this entities by question 1?

 

regards Jan


Here's yet another way:

 

   ObjectId myObjectId = .......

// Get the entity's Layer name:
string layerName = ((dynamic)myObjectId).Layer;
// Erase the entity:
((dynamic)myObjectId).Erase();

 

Message 5 of 5

_gile
Consultant
Consultant

Yes, using the DLR is another option.

 

With VB, you have to set the 'Option Strict' to off so that you can use late binding.

 

' Get the ObjectId as Object:
Dim myObject As Object = myObjectId

' Get the layer name:
Dim layerName As String = myObject.Layer

' Erase the entity:
myObject.Erase()


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes