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

Need help getting an existing table using vb in .net

5 REPLIES 5
SOLVED
Reply
Message 1 of 6
cncah
703 Views, 5 Replies

Need help getting an existing table using vb in .net

Hello, I've hit a wall trying to access an existing table by layer name in vb.net. I've seen in the help documents how to play around with tables when creating a new one, but I can't find an example online that gets me access to one without user input. I have only one table in the drawing and it is on layer "BOMTable". I figured this would be enough to filter through the entities in the drawing and get me access to the table. I'm still learning the Autocad API, and I'm willing to go through the motions with trial and error to get certain cell contents via the help documents. But I just need to know how to iterate through all entities in a drawing, then if that entity is on layer "BOMTable", assign my acTable variable to that entity. I'll stumble on from there. Any help would be GREATLY appreciated. Thank You.

5 REPLIES 5
Message 2 of 6
cncah
in reply to: cncah

I got it.

 

Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument

Dim acDB As Database = acDoc.Database

Dim acBlkTbl As BlockTable
Dim acBlkTblRec As BlockTableRecord

Dim acTable As Table = Nothing

Using acTrans As Transaction = acDB.TransactionManager.StartTransaction

   acBlkTbl = acTrans.GetObject(acDB.BlockTableId,
               OpenMode.ForRead)
            acBlkTblRec =
               acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), _
               OpenMode.ForWrite)

For Each acObjId As ObjectId In acBlkTblRec

     Dim ent As Entity = acTrans.GetObject(acObjId, OpenMode.ForRead)

     If TypeOf ent Is Table And CStr(ent.Layer) = "BOMTable" Then

        acTable = ent

        Exit For

     End If

Next

End Using

 

Message 3 of 6
khoa.ho
in reply to: cncah

It is better to have a generic method to get entities from a give type (table, line...), then use it to retrieve any information you want. Here is the code:

 

C#

public class Test
{
    [CommandMethod("GetEntitiesByType")]
    public static void GetEntitiesByType()
    {
        var doc = Application.DocumentManager.MdiActiveDocument;
        var db = doc.Database;
        IEnumerable<Table> list = GetAllEntitiesInModelSpace<Table>(db);
        foreach (Table table in list)
        {
            string layer = table.Layer;

        }
    }

    public static IEnumerable<T> GetAllEntitiesInModelSpace<T>(Database db, OpenMode openMode = OpenMode.ForRead, bool openErased = false)
    {
        using (Transaction trans = db.TransactionManager.StartTransaction())
        {
            var blockTable = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
            var model = (BlockTableRecord)trans.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead);
            var list = new List<T>();
            foreach (ObjectId id in model)
            {
                var entity = trans.GetObject(id, openMode, openErased) as Entity;
                if ((entity != null) && (entity is T))
                {
                    object obj2 = entity;
                    list.Add((T)obj2);
                }
            }
            return list;
        }
    }
}

 

VB.NET

Public Class Test
    <CommandMethod("GetEntitiesByType")> _
    Public Shared Sub GetEntitiesByType()
        Dim doc = Application.DocumentManager.MdiActiveDocument
        Dim db = doc.Database
        Dim list As IEnumerable(Of Table) = GetAllEntitiesInModelSpace(Of Table)(db)
        For Each table As Table In list

            Dim layer As String = table.Layer
        Next
    End Sub

    Public Shared Function GetAllEntitiesInModelSpace(Of T)(db As Database, Optional openMode__1 As OpenMode = OpenMode.ForRead, Optional openErased As Boolean = False) As IEnumerable(Of T)
        Using trans As Transaction = db.TransactionManager.StartTransaction()
            Dim blockTable = DirectCast(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
            Dim model = DirectCast(trans.GetObject(blockTable(BlockTableRecord.ModelSpace), OpenMode.ForRead), BlockTableRecord)
            Dim list = New List(Of T)()
            For Each id As ObjectId In model
                Dim entity = TryCast(trans.GetObject(id, openMode__1, openErased), Entity)
                If (entity IsNot Nothing) AndAlso (TypeOf entity Is T) Then
                    Dim obj2 As Object = entity
                    list.Add(DirectCast(obj2, T))
                End If
            Next
            Return list
        End Using
    End Function
End Class

 

We can use all LINQ for IEnumerable type classes to have shorter code, but it will make it difficult to understand than longer code.

 

Message 4 of 6
cncah
in reply to: khoa.ho

Thank You!

Message 5 of 6
kdub_nz
in reply to: khoa.ho

khoa.ho,

Why do you include optional parameters to  GetAllEntitiesInModelSpace ??  

 

 

I can understand perhaps using openErased  but not not openMode .

 


// Called Kerry in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect.

class keyThumper<T> : Lazy<T>;      another  Swamper

Message 6 of 6
khoa.ho
in reply to: kdub_nz

I use optional parameters in GetAllEntitiesInModelSpace to get more options of the entity type to read or write. Here is the modified version which is better for faster performance, and presents both OpenMode.ForRead and .ForWrite

 

Instead of using Transaction.GetObject for every objects in model space during the loop, which costs memory and time, we can check class of an ObjectId for a given type.

 

C#

[CommandMethod("ReadEntities")]
public static void ReadEntities()
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Editor editor = doc.Editor;
    Database db = doc.Database;
    using (Transaction trans = db.TransactionManager.StartTransaction())
    {
        // Get all lines in model space for read
        IEnumerable<Line> list = GetAllEntitiesInModelSpace<Line>(db);
        foreach (Line line in list)
        {
            // Display line info
            editor.WriteMessage(line.StartPoint.ToString() + "," + line.EndPoint.ToString());
        }
    }
}

[CommandMethod("WriteEntities")]
public static void WriteEntities()
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Editor editor = doc.Editor;
    Database db = doc.Database;
    using (Transaction trans = db.TransactionManager.StartTransaction())
    {
        // Get all circles in model space for write
        IEnumerable<Circle> list = GetAllEntitiesInModelSpace<Circle>(db, OpenMode.ForWrite);
        foreach (Circle circle in list)
        {
            // Change circle radius by multiply 2
            circle.Radius *= 2;
            // Downgrade this entity to read before transaction commit
            circle.DowngradeOpen();
        }
        trans.Commit();
    }
}

public static IEnumerable<T> GetAllEntitiesInModelSpace<T>(Database db, OpenMode openMode = OpenMode.ForRead, bool openErased = false) where T : DBObject
{
    var list = new List<T>();
    using (Transaction trans = db.TransactionManager.TopTransaction ?? db.TransactionManager.StartTransaction())
    {
        var blockTable = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
        var model = (BlockTableRecord)trans.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead);
        foreach (ObjectId id in model)
        {
            if (id.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(T))))
            {
                DBObject entity = trans.GetObject(id, openMode, openErased);
                list.Add((T)entity);
            }
        }
    }
    return list;
}

 

VB.NET

<CommandMethod("ReadEntities")> _
Public Shared Sub ReadEntities()
    Dim doc As Document = Application.DocumentManager.MdiActiveDocument
    Dim editor As Editor = doc.Editor
    Dim db As Database = doc.Database
    Using trans As Transaction = db.TransactionManager.StartTransaction()
        ' Get all lines in model space for read
        Dim list As IEnumerable(Of Line) = GetAllEntitiesInModelSpace(Of Line)(db)
        For Each line As Line In list
            ' Display line info
            editor.WriteMessage(line.StartPoint.ToString() + "," + line.EndPoint.ToString())
        Next
    End Using
End Sub

<CommandMethod("WriteEntities")> _
Public Shared Sub WriteEntities()
    Dim doc As Document = Application.DocumentManager.MdiActiveDocument
    Dim editor As Editor = doc.Editor
    Dim db As Database = doc.Database
    Using trans As Transaction = db.TransactionManager.StartTransaction()
        ' Get all circles in model space for write
        Dim list As IEnumerable(Of Circle) = GetAllEntitiesInModelSpace(Of Circle)(db, OpenMode.ForWrite)
        For Each circle As Circle In list
            ' Change circle radius by multiply 2
            circle.Radius *= 2
            ' Downgrade this entity to read before transaction commit
            circle.DowngradeOpen()
        Next
        trans.Commit()
    End Using
End Sub

Public Shared Function GetAllEntitiesInModelSpace(Of T As DBObject)(db As Database, Optional openMode1 As OpenMode = OpenMode.ForRead, Optional openErased As Boolean = False) As IEnumerable(Of T)
    Dim list = New List(Of T)()
    Using trans As Transaction = If(db.TransactionManager.TopTransaction, db.TransactionManager.StartTransaction())
        Dim blockTable = DirectCast(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
        Dim model = DirectCast(trans.GetObject(blockTable(BlockTableRecord.ModelSpace), OpenMode.ForRead), BlockTableRecord)
        For Each id As ObjectId In model
            If id.ObjectClass.IsDerivedFrom(RXClass.GetClass(GetType(T))) Then
                Dim entity As DBObject = trans.GetObject(id, openMode1, openErased)
                list.Add(DirectCast(entity, T))
            End If
        Next
    End Using
    Return list
End Function

 

Khoa

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