Convert vba codes to vb.net

Convert vba codes to vb.net

bahman.jf.68
Advocate Advocate
2,896 Views
14 Replies
Message 1 of 15

Convert vba codes to vb.net

bahman.jf.68
Advocate
Advocate

Hello everyone,

I have some modules in vba and I intend to migrate from vba to vb.net , I haven't had much experience with .Net programming, and also I extremely need to perform a project with vb.net which I have written it with vba already.

 

Now, my question is that is it possible to put vba codes in vb.net as it is and then compiling to DLL ??

Or I should translate line by line ?

0 Likes
2,897 Views
14 Replies
Replies (14)
Message 2 of 15

ntclmain
Advocate
Advocate

You can utilize the COM Interoperability (.NET)

https://help.autodesk.com/view/OARX/2023/ENU/?guid=GUID-BFFF308E-CC10-4C56-A81E-C15FB300EB70

Com interop code is nearly the same as VBA, except:

- No "ThisDrawing" is declared by default. You should call it through .NET API active document

 

Imports Autodesk.AutoCAD.ApplicationServices.DocumentExtension
............
ThisDrawing = TryCast(Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.GetAcadDocument, IAcadDocument)

 

 - "Set" keyword is not valid

-  You should imports some libraries so that your keyword, function in VBA can work in VB.NET

 

Imports System
Imports System.Math
Imports System.Text
Imports System.Linq
Imports System.Array
Imports System.IO
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports System.Management
Imports System.Security.Permissions
Imports System.Security
Imports System.Reflection
Imports System.ComponentModel
Imports System.Runtime.CompilerServices

Imports Autodesk.AutoCAD.Interop 
Imports Autodesk.AutoCAD.Interop.Common
Imports Autodesk.AutoCAD.Interop.Common.AcSelect

Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput

Imports Autodesk.AutoCAD.ApplicationServices.DocumentExtension
Imports Autodesk.AutoCAD.ApplicationServices.DatabaseExtension
Imports Autodesk.AutoCAD.ApplicationServices.DocumentCollectionExtension
Imports Autodesk.AutoCAD.ApplicationServices.TabbedDialogExtension

 

Here is my favorite import list, some are  not necessary in your case.

 *
You can find more information here:

https://www.keanw.com/2010/05/more-translated-autocad-vba-to-vbnet-migration-devtvs.html

https://www.keanw.com/visual_basic/

Message 3 of 15

bahman.jf.68
Advocate
Advocate

Thanks a lot for replying,

Could you please give a simple example to run vba code through .net ? 

0 Likes
Message 4 of 15

norman.yuan
Mentor
Mentor

@bahman.jf.68 wrote:

Thanks a lot for replying,

Could you please give a simple example to run vba code through .net ? 


@bahman.jf.68 , you might misunderstand what @ntclmain has said: you CANNOT "run vba code through .net". You must use a .NET IDE (e.g. Visual Studio 20xx) to start a .NET Framework class library project and write the .NET code, which can be "very closed" line-by-line vba translation, if you do know both VBA and VB.NET well. However, since AutoCAD .NET API is quite different from AutoCAD COM API (which is used by AutoCAD VBA), closedly line-by-line translation may or may not work as expected in the .NET project; and even it works, it is not a best approach of doing it, in most cases.

 

So, if you do have mission-critical VBA code that needs to be migrated/converted to AutoCAD .NET API code, re-writing is a better term to describe what you need to do, which means you need to know/learn AutoCAD .NET API well enough. As long as you fully understand what the VBA code does to AutoCAD, I'd suggest to forget VBA code, and do the .NET API code with C# rather than VB.NET.

 

Norman Yuan

Drive CAD With Code

EESignature

Message 5 of 15

bahman.jf.68
Advocate
Advocate

Great, thank you both, I could translate a simple vba program to .net with Com Interop so easily.



 Now, I want to add a form to this DLL so that user enter the values into the textboxs like vba's userform. 
Is it as easy as creating vba's userforms ? 

I'd appreciate it if you could help me with it.

0 Likes
Message 6 of 15

norman.yuan
Mentor
Mentor

When doing AutoCAD .NET API, you can do UI much easier than in VBA: you can use either Windows Forms, or WPF to build UI with richer user experience. @_gile has a very helpful tutorial here

 

Again, translating VBA code in .NET API with COM interop is not a good practice, unless the task is very simple, needed urgently, or temporary. The biggest issue of this practice is the solution is tied to AutoCAD version because of the reference to the COM interop, while pure .NET API solutions would work for multiple AutoCAD versions (since Acad2013) in most cases. In Acad .NET API solution, if the case warrants to use COM API, the good practice would be to use late binding when it is possible.

Norman Yuan

Drive CAD With Code

EESignature

Message 7 of 15

bahman.jf.68
Advocate
Advocate

You're right, 
I checked it out on the another version of Autocad, it didn't workd. As you mentioned I should work with C# and pure .NET API.

Many thanks for your sincerely helping.

0 Likes
Message 8 of 15

ntclmain
Advocate
Advocate

Dear @norman.yuan

Could you please explain more about the bold line?

"Again, translating VBA code in .NET API with COM interop is not a good practice, unless the task is very simple, needed urgently, or temporary. The biggest issue of this practice is the solution is tied to AutoCAD version because of the reference to the COM interop, while pure .NET API solutions would work for multiple AutoCAD versions (since Acad2013) in most cases. In Acad .NET API solution, if the case warrants to use COM API, the good practice would be to use late binding when it is possible."

*
For me, I have converted 2 VBA projects to Com interop.  The target AutoCAD is 2015 to 2023 64 bit.  I didn't involve in big errors regarding specific AutoCAD version tie, except:

-  A call to AcadDocument.Application  caused fatal error in 2021 version

-  If multi AutoCAD/ AutoCAD based-products instances of the same version are opening, then the GetObject() function will only return the first active instance, not the instance that fired the macro;

I don't have .NET experiences with 32 bit AutoCAD and 64 bit AutoCAD below 2015 versions.

*

Is there anything I've missed?
Thanks in advance.

Message 9 of 15

bahman.jf.68
Advocate
Advocate

This is a simple code which I've translated with COM interop (VS 2015, .Net wizard 2017 and ObjectARX 2017) and it only works with Autocad 2017 :

 

 

Imports System
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.ApplicationServices.DocumentExtension
Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common
Imports Autodesk.AutoCAD.Interop.Common.AcSelect
Imports Autodesk.AutoCAD.ApplicationServices.DatabaseExtension
Imports Autodesk.AutoCAD.ApplicationServices.DocumentCollectionExtension
Imports Autodesk.AutoCAD.ApplicationServices.TabbedDialogExtension

<Assembly: CommandClass(GetType(AutoCAD_VB_plug_in1.MyCommands))>
Namespace AutoCAD_VB_plug_in1
    Public Class MyCommands

        <CommandMethod("MyCommand", CommandFlags.Modal)>
        Public Sub MyCommand()

            Dim circleObj As AcadCircle
            Dim ThisDrawing As Object
            Dim centerPoint(0 To 2) As Double
            Dim radius As Double

            ThisDrawing = TryCast(Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.GetAcadDocument, IAcadDocument)
            radius = 5.0#
            ' Create the Circle
            centerPoint = ThisDrawing.Utility.GetPoint(, "insertion: ")
            circleObj = ThisDrawing.ModelSpace.AddCircle(centerPoint, radius)
        End Sub
    End Class
End Namespace

 

As I said it works on Autocad 2017 fine, but it gives this error with Autocad 2018 :
Screenshot (129).png

 

0 Likes
Message 10 of 15

hippe013
Advisor
Advisor

The code you posted last doesn't have a need for interop. As others have said, if you want to use the COM api and have it be used with multiple versions then you may need to look into late binding. 

 

Otherwise here is your code using just the managed .NET API - Simple Circle Command

 

<CommandMethod("MyCommand")>
        Public Sub MyCommand()

            'Get your Document, Editor, and Database
            Dim aDoc As Document = Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = aDoc.Editor
            Dim db As Database = aDoc.Database

            'Prompt for Point
            Dim opt As New PromptPointOptions(vbCrLf & "Select Center Point: ")
            Dim res As PromptPointResult = ed.GetPoint(opt)
            If res.Status <> PromptStatus.OK Then
                Exit Sub
            End If

            'Create your Circle
            Dim circle As New Circle(res.Value, Vector3d.ZAxis, 5.0)

            'Create a Transaction
            Using tr As Transaction = db.TransactionManager.StartTransaction
                'Get the block table and the block table record for the modelspace
                Dim blkTbl As BlockTable = tr.GetObject(db.BlockTableId, OpenMode.ForRead)
                Dim blkTblRec As BlockTableRecord = tr.GetObject(blkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite)

                'Append the new circle entity
                blkTblRec.AppendEntity(circle)

                'Let the transaction know about it
                tr.AddNewlyCreatedDBObject(circle, True)

                'Commit your transaction. This is often forgotten.
                tr.Commit()
            End Using
        End Sub

 

0 Likes
Message 11 of 15

ntclmain
Advocate
Advocate

@bahman.jf.68 

I've create a new project with Visual studio 2019, with references to AutoCAD 2022 interop libraries, Net framework version 4.8 
I copied your code & build a .dll file

ntclmain_0-1661444943861.png

The .dll file (Project_Test_No01.dll) works fine with AutoCAD 2022 and 2016 version.

*
I've attached my test project.  You can find the compiled .dll in:  ...AutoCAD_VB\Project_Test_No01\bin\Debug  folder

Remember to unblock the .dll file before testing in AutoCAD 2017 & 2018

*

In this case:

It seems that 2022 interop version provides backward compatible ability

while  2017 interop version is not forward compatible with 2018 (same .NET framework version 4.6)

Message 12 of 15

bahman.jf.68
Advocate
Advocate

I loaded the DLL which you have created, as you said it works fine on Autocad 2015 to 2022. I tried to create my own DLL with vs 2019 and Autocad 2022 (Net Framework 4.8) but it only works  with Autocad 2022 and returns the same error on the other versions like 2020 : 

Screenshot (132).png

I'm puzzeld as my project is exactly the same as your project in terms of Autocad, ObjectARX and Visual studio versions, I also compiled your project again and it works with older versions but mine not. (I attached my project)

0 Likes
Message 13 of 15

ntclmain
Advocate
Advocate

@bahman.jf.68 
Your description is true.
I also received that error message in 2016 version after correcting reference path (for my PC ) & rebuild your project
*
After changing some reference file settings (as images below), I saved & rebuilt your project, the macro worked again in 2016 version.

ntclmain_0-1661618994301.pngntclmain_1-1661619012109.png

*
I attached the edited project below.

Message 14 of 15

bahman.jf.68
Advocate
Advocate

Great, thanks mate, my problem has been resolved.
I have three questions :
- Do I have to compile it for 32 bit apart from this DLL ?
- Is any difference between COM interop and Pure .Net in terms of speed of running codes in Autocad and compatibility of all systems ?
- As a vba programmer it's hard to me for learning and creating DLL with Transactions and .Net pure codes, therefore could I trust COM interop method forever or at least for a while?

0 Likes
Message 15 of 15

ntclmain
Advocate
Advocate

1. Do I have to compile it for 32 bit apart from this DLL ?

Yes, if you use COM interop, you need to compile the 2 separate .dll files for using in 32 bit and 64 bit AutoCAD

https://forums.autodesk.com/t5/net/32-bit-c-net-plugin-for-64-bit-autocad/td-p/4539709

2. Is any difference between COM interop and Pure .Net in terms of speed of running codes in Autocad and compatibility of all systems ?

About the speed .NET API (pure .Net) is much faster than COM interop. 

Also VBA speed in 64 bit version is much slower than COM interop.

https://forums.autodesk.com/t5/net/code-excecution-time-comparison-net-api-net-com-interop-and-vba/m...
3. As a VBA programmer it's hard to me for learning and creating DLL with Transactions and .Net pure codes, therefore could I trust COM interop method forever or at least for a while?

Look at 2, you will have motivation to use .NET API

However, when coming from VBA,  .NET interop may be a reasonable option when you have little time. I found that the code works fine (at least for  64 bit AutoCAD version), the speed is nearly the same as VBA in 32 bit AutoCAD version.

After familiar with Visual studio environment, VB.Net language ... you will find it easier to move up to .NET API;

 

 

0 Likes