Author Topic: Getting started in VB.NET  (Read 11058 times)

0 Members and 1 Guest are viewing this topic.

DaveW

  • Guest
Getting started in VB.NET
« on: March 19, 2007, 06:27:47 PM »
I have been looking at the labs for 2 days and have a few things working, but I must say the lack of practical examples in the ACAD help is really making this difficult. I am not a programmer by trade and there is still a whole world in VB6 I still do not understand. I have been able to code quite a bit by using other source code as an example and modifying it as needed.

After an hour or so I finally had it working in design time by loading the dll in the bin folder and setting the 2 dlls res in the ACAD dir to false. About an hour or so later I had the active document. After that it has been a stand still. I have tried a bunch of example code snippets and can never seem to get where I want.

In vb6 if I wanted to parse through every entity in modelspace I would:

Dim ent as acadentity
Dim thisdrawing as acaddocument

Set thsidrawing as acadactivedocument

for each ent in thissdrawing.modlespace

If ent.objectname = "AcDb3dSolid then

msgbox "I have a solid"

next

In vb.net I have gotten modelspace though the db, blah blah, from example code, but how to iterate through and look for what I want, I have no idea. I have even passed out the ids of the objects selected to a message box, but still cannot find a objectfromobjectid or objectfromhandleid method.

This is just one of about100 typical things that I would expect to have available in the help file.
Instead, it points you to the password protected ADN site of which I refuse to enroll in due to the nature of the licence agreement. The cost is not an issue at all.

Is anyone here game for creating a library of functions and methods for public use?
I am thinking about taking a day or two and creating 50 or so typical VB6 pieces of code that do things like set an object color, layer, linetype, etc., add layers, get the coords of pline, work with multiple documents and on and on and then sending it off to a programming company, each as its own project not to load down too much in each area, and have them convert it to vb.net.

What do you guys think?

sinc

  • Guest
Re: Getting started in VB.NET
« Reply #1 on: March 19, 2007, 06:45:34 PM »
Have you looked at the Transaction class yet?  Database access in .NET is basically controlled there.

I've mostly been working in C#.NET so far, and with Civil-3D, but you can try checking out what I've done here.  VB.NET and C#.NET are close enough that just looking at this code might give you lots of ideas, even if you don't have Civil-3D and can't actually run any of my code.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Getting started in VB.NET
« Reply #2 on: March 19, 2007, 06:50:58 PM »
Here is what was posted by Kerry to help me out.  It's C#, but I think it can help you.
Code: [Select]
// Posted by Kerry Brown
[CommandMethod("PrintMSpacev02")]
public static void MyPrintMspace_1()
        {
            Database db = HostApplicationServices.WorkingDatabase;
            Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;           
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)(trans.GetObject(db.BlockTableId, OpenMode.ForRead));
                foreach (ObjectId ObjId in
                    (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead))
                {
                    Entity Ent = (Entity)trans.GetObject(ObjId, OpenMode.ForRead, true);
                    ed.WriteMessage("\n  Layer: " + Ent.Layer);
                }               
            }
        }
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Getting started in VB.NET
« Reply #3 on: March 19, 2007, 08:06:24 PM »
This may be indicative ..
Code: [Select]
[CommandMethod("test103")]
static public void test()
{
    Database db = HostApplicationServices.WorkingDatabase;
    Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;
    using (Transaction trans = db.TransactionManager.StartTransaction())
    {
        BlockTable bt = (BlockTable)(trans.GetObject(db.BlockTableId, OpenMode.ForRead));
        foreach (ObjectId ObjId in
            (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead))
        {
            Entity Ent = (Entity)trans.GetObject(ObjId, OpenMode.ForRead, true);
            ed.WriteMessage(string.Format(
                "\n  Layer: {0} \tObjectType: {1} \tHandle: {2}",
                 Ent.Layer,
                 Ent.GetType().Name,
                 Ent.Handle  ));
        }
    }

}

added:
and the piccy for example output ..
« Last Edit: March 19, 2007, 08:36:10 PM by Kerry Brown »
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.

Fatty

  • Guest
Re: Getting started in VB.NET
« Reply #4 on: March 19, 2007, 08:15:13 PM »
Here is what was posted by Kerry to help me out.  It's C#, but I think it can help you.
I think so and thanks to KWB :)
Here is VB.NET version translated from
example above
Code: [Select]
Imports System
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.DatabaseServices
Imports acApp = Autodesk.AutoCAD.ApplicationServices.Application

Namespace Properties

    Public Class EntProps

        <CommandMethod("ShowLays", CommandFlags.Modal Or CommandFlags.Session)> _
        Public Shared Sub PrintLayers()
            Dim db As Database = HostApplicationServices.WorkingDatabase
            Dim ed As Editor = acApp.DocumentManager.MdiActiveDocument.Editor
            Using trans As Transaction = db.TransactionManager.StartTransaction()

                Dim bt As BlockTable = CType(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                Dim btr As BlockTableRecord = (CType(trans.GetObject(db.CurrentSpaceId, OpenMode.ForRead), BlockTableRecord))
                For Each ObjId As ObjectId In btr
                    Dim Ent As Entity = CType(trans.GetObject(ObjId, OpenMode.ForRead, True), Entity)
                    ed.WriteMessage(vbCrLf & "   Layer: " & Ent.Layer)
                Next
            End Using
        End Sub

    End Class

End Namespace

~'J'~

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Getting started in VB.NET
« Reply #5 on: March 19, 2007, 08:25:46 PM »
and from the more explicit example
Code: [Select]
Public Class kdubTest103
    '
    ' TODO: Add constructor logic here
    '
    Public Sub New()
    End Sub
    <CommandMethod("test103")> _
    Public Shared Sub test()
        Dim db As Database = HostApplicationServices.WorkingDatabase
        Dim ed As Editor = AcadApp.DocumentManager.MdiActiveDocument.Editor
        Using trans As Transaction = db.TransactionManager.StartTransaction()
            Dim bt As BlockTable = DirectCast((trans.GetObject(db.BlockTableId, OpenMode.ForRead)), BlockTable)
            For Each ObjId As ObjectId In DirectCast(trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForRead), BlockTableRecord)
                Dim Ent As Entity = DirectCast(trans.GetObject(ObjId, OpenMode.ForRead, True), Entity)
                ed.WriteMessage(String.Format("" & Chr(10) & "  Layer: {0} " & Chr(9) & "ObjectType: {1} " & Chr(9) & "Handle: {2}", Ent.Layer, Ent.[GetType]().Name, Ent.Handle))
            Next
        End Using

    End Sub

End Class

added:
I get the burps when I use VB. This was translated using SharpDevelop 2.1 .. There are a few things that are not conventional to ACAD .. DirectCast for example

perhaps someone should tart-up the code.
« Last Edit: March 19, 2007, 08:39:55 PM by Kerry Brown »
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.

Glenn R

  • Guest
Re: Getting started in VB.NET
« Reply #6 on: March 19, 2007, 08:34:35 PM »
Kerry - VB...shame on you  :evil:

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Getting started in VB.NET
« Reply #7 on: March 19, 2007, 08:37:42 PM »
Sorry Glenn
I'm just a masochist I guess ..

[*slinks away*]
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.

Fatty

  • Guest
Re: Getting started in VB.NET
« Reply #8 on: March 19, 2007, 08:46:19 PM »
Here is another example from masochist too :)
Select then rotate entity

Code: [Select]
Imports System
Imports System.Collections
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.DatabaseServices
Imports graph = Autodesk.AutoCAD.GraphicsInterface
Imports acApp = Autodesk.AutoCAD.ApplicationServices.Application
'//<--->
Public Class EntityRot
        <CommandMethod("ROE", CommandFlags.Modal Or
CommandFlags.Session)> _
        Public Sub RotEnt()
            Dim ed As Editor = acApp.DocumentManager.MdiActiveDocument.Editor
            Dim db As Database =

acApp.DocumentManager.MdiActiveDocument.Database
            Dim tr As Transaction = db.TransactionManager.StartTransaction()
            Try
                '// select object
                Dim selOpts As New PromptSelectionOptions()
                Dim res As PromptSelectionResult

                selOpts.SingleOnly = True
                selOpts.MessageForAdding = "    Select an entity"
                res = ed.GetSelection(selOpts)
                If res.Status <> PromptStatus.OK Then Return

                Dim id As ObjectId = res.Value.GetObjectIds(0)
                Dim ent As Entity = tr.GetObject(id, OpenMode.ForWrite, False)
                '// get point
                Dim orig As Point3d
                Dim ptRes As PromptPointResult
                ptRes = ed.GetPoint("   Specify base point")
                If ptRes.Status <> PromptStatus.OK Then Return
                orig = ptRes.Value
                '// get angle
                Dim ang As Double
                Dim angOPts As PromptAngleOptions = New PromptAngleOptions("

Specify rotation angle or pick a second point: ")
                '// add another options to prompt
                angOPts.AllowNone = False
                angOPts.AllowZero = False
                angOPts.UseBasePoint = True
                angOPts.BasePoint = orig
                '// get result
                Dim angRes As PromptDoubleResult = ed.GetAngle(angOPts)
                If angRes.Status <> PromptStatus.OK Then Return
                ang = angRes.Value
                '// rotate entity by using transformation matrix
                Dim v3d As Vector3d =

ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Zaxis
                Dim m3d As Matrix3d = Matrix3d.Rotation(ang, v3d, orig)
                ent.TransformBy(m3d)

                tr.Commit()
            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                tr.Abort()
                MsgBox(ex.Message)
            Finally
                tr.Dispose()
            End Try

        End Sub

    End Class


~'J'~

Paul Richardson

  • Guest
Re: Getting started in VB.NET
« Reply #9 on: March 19, 2007, 11:18:54 PM »
Sample to iterate a SymbolTable. Thanks to T.T. for the original idea - although I added the SymbolTableEnumerator. It's in c++ but just ignore all the funny symbols and you have c# - then add a few more funny symbols and you have VB...~) : Update - removed 'doc' from 'HasName' arguments in Tests...oops)

Code: [Select]
static void
Tests()
{
Document ^ doc = GetActiveDoc();
Database ^ db = doc->Database;
Editor ^ ed = doc->Editor;
String ^ recordName = "foo";

ed->WriteMessage
(HasName(db->BlockTableId, recordName).ToString() + "\n");

ed->WriteMessage
(HasName(db->LayerTableId, recordName).ToString() + "\n");

}

static bool
HasName(ObjectId ^ symbolTableId, String ^ recName)
{
Document ^ doc = GetActiveDoc();
Database ^ db = doc->Database;
Editor ^ ed = doc->Editor;

SymbolTableRecord ^ str;

Transaction ^ tr =
db->TransactionManager->StartTransaction();
try
{
SymbolTable ^ st =
(SymbolTable^)tr->GetObject(*symbolTableId, OpenMode::ForRead);

SymbolTableEnumerator ^ ste = st->GetEnumerator();

while (ste->MoveNext())
{
str = (SymbolTableRecord^)ste->Current.GetObject(OpenMode::ForRead);

if (str->Name == recName)
return true;

}
}

finally
{
delete tr;
}

return false;
}

static Document ^
GetActiveDoc()
{
Document ^ doc =
Application::DocumentManager->MdiActiveDocument;
return doc;
}

EDIT: Tony Tanzillo recommends against using SymbolTableEnumerator as I have here. Use For Each instead! Teach me to modify his code...:)
« Last Edit: June 13, 2007, 09:57:46 AM by Paul Richardson »

DaveW

  • Guest
Re: Getting started in VB.NET
« Reply #10 on: March 20, 2007, 10:04:21 AM »
Thanks guys. Great stuff. I see I had the ID's, but

Code: [Select]
                For Each ObjId As ObjectId In btr
                    Dim Ent As Entity = CType(trans.GetObject(ObjId, OpenMode.ForRead, True), Entity)

was the way to go. I would have never figured that out!

There is one small step. Once I have something to share for beginners like me I will post some too.

Needlessto say I will never catch you guys.

Thanks again,

Dave

Fatty

  • Guest
Re: Getting started in VB.NET
« Reply #11 on: March 20, 2007, 10:22:57 AM »
Sample to iterate a SymbolTable. Thanks to T.T. for the original idea - although I added the SymbolTableEnumerator. It's in c++ but just ignore all the funny symbols and you have c# - then add a few more funny symbols and you have VB...~) : Update - removed 'doc' from 'HasName' arguments in Tests...oops)


Dear Paul,
I couldn't to convert your example on VB.NET,
because of my browser not found SymbolTable name
Can you upload here a VB.NET (or on C#),version?
Thanks in advance,
Regards,

Oleg :|

~'J'~

Paul Richardson

  • Guest
Re: Getting started in VB.NET
« Reply #12 on: March 20, 2007, 10:42:18 AM »
Sample to iterate a SymbolTable. Thanks to T.T. for the original idea - although I added the SymbolTableEnumerator. It's in c++ but just ignore all the funny symbols and you have c# - then add a few more funny symbols and you have VB...~) : Update - removed 'doc' from 'HasName' arguments in Tests...oops)


Dear Paul,
I couldn't to convert your example on VB.NET,
because of my browser not found SymbolTable name
Can you upload here a VB.NET (or on C#),version?
Thanks in advance,
Regards,

Oleg :|

~'J'~


Here is the link to Tony's original post in c#... Not sure why you don't have a SymbolTable datatype - I assume you've referenced 'acdbmgd.dll' - What version of AutoCAD are you using?
http://discussion.autodesk.com/thread.jspa?messageID=5437715

Fatty

  • Guest
Re: Getting started in VB.NET
« Reply #13 on: March 20, 2007, 01:05:15 PM »
Quote

Here is the link to Tony's original post in c#... Not sure why you don't have a SymbolTable datatype - I assume you've referenced 'acdbmgd.dll' - What version of AutoCAD are you using?
http://discussion.autodesk.com/thread.jspa?messageID=5437715


Here is complete code
Well, the debugger have not found any error
there, but this is not working for now... :(

Code: [Select]
Imports System
Imports System.Collections
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.DatabaseServices
Imports graph = Autodesk.AutoCAD.GraphicsInterface
Imports Autodesk.AutoCAD.ApplicationServices
Imports acApp = Autodesk.AutoCAD.ApplicationServices.Application

Namespace WorkSpace

    Public Class InfoDoc
        '//not working for now
        <CommandMethod("DwgCont", CommandFlags.Modal Or CommandFlags.Session)> _
        Public Sub Tests()

            Dim doc As Document = GetActiveDoc()
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            Dim recordName As String = "foo"

            ed.WriteMessage _
   (HasName(doc.Database.BlockTableId, recordName).ToString() & vbNewLine)

            ed.WriteMessage _
   (HasName(doc.Database.LayerTableId, recordName).ToString() & vbNewLine)
        End Sub

        Public Function HasName(ByVal symbolTableId As ObjectId, ByVal recName As String) As Boolean

            Dim doc As Document = GetActiveDoc()
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor

            Dim str As SymbolTableRecord

            Dim tr As Transaction = _
            db.TransactionManager.StartTransaction()
            Try
                Dim st As SymbolTable = CType(tr.GetObject(symbolTableId, OpenMode.ForRead, False), SymbolTable)

                Dim ste As SymbolTableEnumerator = st.GetEnumerator()

                While ste.MoveNext()
                    str = CType(ste.Current.GetObject(OpenMode.ForRead, False), SymbolTableRecord)

                    If str.Name = recName Then
                        Return True
                    End If

                End While
            Finally
                tr.Dispose()
            End Try

            Return False
        End Function

        Public Function GetActiveDoc() As Document
            Dim doc As Autodesk.AutoCAD.ApplicationServices.Document = _
            Application.DocumentManager.MdiActiveDocument()
            Return doc
        End Function
    End Class

End Namespace

~'J'~

Paul Richardson

  • Guest
Re: Getting started in VB.NET
« Reply #14 on: March 21, 2007, 02:08:12 AM »
Quote

Here is the link to Tony's original post in c#... Not sure why you don't have a SymbolTable datatype - I assume you've referenced 'acdbmgd.dll' - What version of AutoCAD are you using?
http://discussion.autodesk.com/thread.jspa?messageID=5437715


Here is complete code
Well, the debugger have not found any error
there, but this is not working for now... :(

Code: [Select]
Imports System
Imports System.Collections
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.DatabaseServices
Imports graph = Autodesk.AutoCAD.GraphicsInterface
Imports Autodesk.AutoCAD.ApplicationServices
Imports acApp = Autodesk.AutoCAD.ApplicationServices.Application

Namespace WorkSpace

    Public Class InfoDoc
        '//not working for now
        <CommandMethod("DwgCont", CommandFlags.Modal Or CommandFlags.Session)> _
        Public Sub Tests()

            Dim doc As Document = GetActiveDoc()
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            Dim recordName As String = "foo"

            ed.WriteMessage _
   (HasName(doc.Database.BlockTableId, recordName).ToString() & vbNewLine)

            ed.WriteMessage _
   (HasName(doc.Database.LayerTableId, recordName).ToString() & vbNewLine)
        End Sub

        Public Function HasName(ByVal symbolTableId As ObjectId, ByVal recName As String) As Boolean

            Dim doc As Document = GetActiveDoc()
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor

            Dim str As SymbolTableRecord

            Dim tr As Transaction = _
            db.TransactionManager.StartTransaction()
            Try
                Dim st As SymbolTable = CType(tr.GetObject(symbolTableId, OpenMode.ForRead, False), SymbolTable)

                Dim ste As SymbolTableEnumerator = st.GetEnumerator()

                While ste.MoveNext()
                    str = CType(ste.Current.GetObject(OpenMode.ForRead, False), SymbolTableRecord)

                    If str.Name = recName Then
                        Return True
                    End If

                End While
            Finally
                tr.Dispose()
            End Try

            Return False
        End Function

        Public Function GetActiveDoc() As Document
            Dim doc As Autodesk.AutoCAD.ApplicationServices.Document = _
            Application.DocumentManager.MdiActiveDocument()
            Return doc
        End Function
    End Class

End Namespace

~'J'~

How about "And" instead of "Or"
CommandFlags.Session And CommandFlags.Modal

Fatty

  • Guest
Re: Getting started in VB.NET
« Reply #15 on: March 21, 2007, 04:31:49 AM »
That would a trick! Thanks a ton Paul!  :-)
It works like a charm now
Regards,

Oleg

~'J'~

Paul Richardson

  • Guest
Re: Getting started in VB.NET
« Reply #16 on: March 21, 2007, 08:34:38 AM »
That would a trick! Thanks a ton Paul!  :-)
It works like a charm now
Regards,

Oleg

~'J'~

Cool! In C#/VB you can wrap the Transaction in Using block instead of the try catch. Might want to try it...

Update:
I see you've used 'using' in your posts...
« Last Edit: March 21, 2007, 12:22:21 PM by Paul Richardson »

fly_902

  • Guest
Re: Getting started in VB.NET
« Reply #17 on: March 24, 2007, 04:13:36 AM »
 :-)
Thank you Fatty
Help me solve about this Problem