Author Topic: Lauching Autocad from a VB exe? No luck...  (Read 19901 times)

0 Members and 1 Guest are viewing this topic.

havano

  • Guest
Lauching Autocad from a VB exe? No luck...
« on: April 25, 2006, 09:31:20 PM »
Hi all,

Although being a novice at VB(A), I really enjoy using it (most of the time)!

At the moment I'm developing an Autocad application for a customer. For various reasons (ease of use, anti-piracy) I would eventually like to convert the VBA macro to an executable. To that effect I mailed the customer a small test program, compiled with VB6, which essentially consisted of the following:
Code: [Select]
Public AcadObj As AcadApplication
Set AcadObj = CreateObject("AutoCAD.Application")
AcadObj.Visible = True
It worked fine on my system. However, after mailing it to the customer, he reported back the following error message:
Run-time error '429' ActiveX component can't create object

So I mailed him the next version of the test program, its code derived from Joe Sutphin's Autocad 2006 VBA book:
Code: [Select]
Public AcadObj As AcadApplication
Set AcadObj = CreateObject(Class:="AutoCAD.Application")
AcadObj.Visible = True
Now the customer reported another error message:
Run-time error '13' Type mismatch

He also mentioned that there were multiple versions of Autocad on his system: R14, 2006LT and 2006 full version. Don't ask why. So I looked here and elsewhere for a solution and found the following:
Code: [Select]
Public AcadObj As AcadApplication
Set AcadObj = CreateObject("AutoCAD.Application.16.2")
AcadObj.Visible = True
The "16.2" addition should make sure to launch Autocad 2006 full version. However, this attempt put us right back in square 1:
Run-time error '429' ActiveX component can't create object

Meanwhile, in order to verify that the code should work on other systems, I rigged up an ancient PC of mine (PII 300MHz, 128MB memory) with a clean install of XP Home and Autocad 2006 full version. All three versions of my test program launched Autocad flawlessly!

Any ideas why my customer's test-runs keep returning errors, anyone?
« Last Edit: April 25, 2006, 10:44:50 PM by havano »

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Lauching Autocad from a VB exe? No luck...
« Reply #1 on: April 25, 2006, 10:34:40 PM »
This may be an issue attempting a late binding when you have already bound the type library at design time.

Try this:
Code: [Select]
Function GetAcadObject(Optional ByVal AcadVersion As Variant) As Object
 On Error Resume Next
 Set GetAcadObject = GetObject(, "AutoCAD.Application" & AcadVersion)
    If Err <> 0 Then
        Err.Clear
        Set GetAcadObject = CreateObject("AutoCAD.Application" & AcadVersion)
        If Err <> 0 Then
            MsgBox "Could not load or find AutoCAD.", vbExclamation
            End
        End If
    End If
End Function

Now make sure you remove ALL references to the AutoCAD type library when you are done writing your code,  also, whenever you are in need of including an AutoCAD entity as an object in the program, make sure you reference it as an "Object" rather than AcadApplication or AcadLWPolyline or anything Acadxxxxxxx as it will cause issues if the type ibrary required is different than the design time type library.

You also will need to maintain a valid reference to the AcadObject created (or referenced) in order to make the program function properly. For example: If you set AC to the AutoCAD application object, you will need to use AC.property or AC.method rather than simply referencing themethod or property directly.

If you require a specific version of AutoCAD to work with your program, you can call it like so:

Code: [Select]
Set AC = GetAcadObject(".15")

For version independent referencing
Code: [Select]
Set AC = GetAcadObject()
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

havano

  • Guest
Re: Lauching Autocad from a VB exe? No luck...
« Reply #2 on: April 25, 2006, 11:42:05 PM »
Thanks for your speedy reply, Keith!

Your first lines left me somewhat puzzled (being a novice) but I suppose they mean that I'd better not compile my VB code referencing an Autocad type library differing from the one in use by my customer.
OK, I'll keep that in mind. Although I suppose that since the application will be built and  used with Autocad 2006 (by customer's special request) those libraries are identical.

The code snippet you include in your post is very similar to the code in the first version of my test program, except that I skipped the GetObject bit and the inherent error trapping.

Indeed, my application-to-be will be loaded with Autocad entities. So, if the type library issue turns out to be the problem, I will have a lot of re-coding to do when converting the VBA macro into a VB executable.

In fact, I hope that the cause of my problem is less discouraging. As mentioned, I found out that the version specification in the CreateObject argument is ".16.2" for Autocad 2006. Could it be that this specification is the same for Autocad 2006 LT and Autocad 2006 full version, which might cause a conflict on my customers system? If so, a simple solution would be to use only the GetObject statement and if this causes an error, display a Messagebox urging the user to (exclusively) launch Autocad 2006 full version, and suspend further execution until he has done so. Maybe something like this:
Code: [Select]
Private Sub cmdLookForOpenAutocad2006FullVersion() 'commandbutton
Dim strMsg As String
strMsg = "Please launch Autocad 2006 full version" & vbCr
strMsg = strMsg & "(first close any other Autocad version)"
On Error Resume Next
Set AcadObj = GetObject(, "AutoCAD.Application.16.2")
If Err Then MsgBox (strMsg): Exit Sub 'Acad 2006 full version not open
'if not error, continue with the sub
« Last Edit: April 26, 2006, 04:28:13 AM by havano »

Bryco

  • Water Moccasin
  • Posts: 1882
Re: Lauching Autocad from a VB exe? No luck...
« Reply #3 on: April 26, 2006, 01:50:49 AM »
havano, I don't use vb (Only vba) so I don't have your problem with getting autocad but I do have the same type of problem getting  Excel. Once you
Dim Excel As Excel.Application
You are commited to setting the correct version of Excel on every machine that will run this code.
You do this by setting the correct reference in Tools-> References in the vbaide (where you code)
This is very tricky to do, but there is another way, late binding.
Late binding doesn't need any references and will look for the default version of excel on the computer.
But you now  must dim everything as object, see below.
    Dim Excel As Object         
    Dim ExcelSheet As Object
    Dim ExcelWorkbook As Object
    Dim strSaveName As String
    Dim i As Integer, j As Integer, k As Integer
   
    On Error Resume Next
    Set Excel = GetObject(, "Excel.Application")
    If Err <> 0 Then
        Set Excel = CreateObject("Excel.Application")
    End If
    On Error GoTo 0
    Set ExcelWorkbook = Excel.Workbooks.Open(strXLpath)


Although  ExcelWorkbook  is dimmed as an object you still use it as a workbook and it has the properties of a workbook.

havano

  • Guest
Re: Lauching Autocad from a VB exe? No luck...
« Reply #4 on: April 26, 2006, 02:13:26 AM »
Ah, now I understand the meaning of Late Binding much better. At least I think I do. Thanks Bryco!

Still, I think I will stick to early binding for this project: The customer insisted on Autocad 2006 (and 2006 alone) for compatibility, and who am I to argue?

One of the "competing" Autocad versions on my customer's systems is Autocad 2006 LT. Trying to access a Lite version from VB will result in an error anyway, no matter which type library.

So for now I'll concentrate on how to successfully launch or access Autocad 2006 Full Version from VB in a multi-Acad-version environment. Any suggestions on that are (also) highly appreciated.
« Last Edit: April 26, 2006, 05:18:49 AM by havano »

havano

  • Guest
Re: Lauching Autocad from a VB exe? No luck...
« Reply #5 on: April 26, 2006, 05:39:14 AM »
OK. I am pretty confident that this code will work for my customers situation, but if anyone detects a snag please tell, I am reluctant to burden my customer (and our relationship) with yet another failing test. For example, will this code detect and trap errors due to Autocad LT interfering?

For convenience, I put the whole test program inside one form with three command buttons: Start Autocad, Draw Textstring and Exit. The code for keeping the form in the foreground is omitted in this snippet.

Option Explicit
Public AcadObj As AcadApplication
'----------
Private Sub StartAutocad_Click()
'look for Autocad 2006 (full version)
On Error Resume Next
Set AcadObj = GetObject(, "AutoCAD.Application.16.2")
If Err <> 0 Then
    Err.Clear
    Set AcadObj = CreateObject("AutoCAD.Application.16.2")
    If Err <> 0 Then ErrorMessage1: Exit Sub 'Get and Create failed
End If
'Get or Create Acad 2006 (full version?) was successful
Err.Clear: On Error GoTo 0
AcadObj.Visible = True
End Sub
'----------
Private Sub DrawTextstring_Click()
On Error Resume Next
Dim textObj As AcadText
Dim text As String
Dim insPt(0 To 2) As Double
Dim height As Double
' Define the text object
text = ". Test successful ."
insPt(0) = 2: insPt(1) = 2: insPt(2) = 0
height = 0.5
' Create the text object in model space
Set textObj = AcadObj.ActiveDocument.ModelSpace.AddText(text, insPt, height)
AcadObj.ZoomExtents
If Err <> 0 Then ErrorMessage2 'Autocad 2006 LT may have spoiled the fun...
End Sub
'----------
Private Sub Exit_Click()
On Error Resume Next 'just in case button was clicked without Acad loaded
AcadObj.Quit
Unload Me
End Sub
'----------
Private Sub ErrorMessage1()
Err.Clear: On Error GoTo 0
Dim strMsg As String
strMsg = "Can't find or start Autocad 2006 full version." & vbCr
strMsg = strMsg & "Please close all other versions and" & vbCr
strMsg = strMsg & "launch Autocad 2006 full version yourself."
MsgBox (strMsg)
End Sub
'----------
Private Sub ErrorMessage2()
Err.Clear: On Error GoTo 0
Dim strMsg As String
strMsg = "If Autocad 2006 full version has been opened" & vbCr
strMsg = strMsg & "but no text was drawn just now, then" & vbCr
strMsg = strMsg & "maybe Autocad 2006 LT is interfering."
MsgBox (strMsg)
End Sub
« Last Edit: April 26, 2006, 08:12:54 AM by havano »

Dnereb

  • Guest
Re: Lauching Autocad from a VB exe? No luck...
« Reply #6 on: April 26, 2006, 07:54:48 AM »
Use Late Binding for these reasons... your client might upgrade to a newer version of acad within a few years.
this code will flunk before it is run because it uses a reference to an acad object and the interpreter will haltpre - scanning your code.

Option Explicit
Public AcadObj As Object
'----------
Private Sub StartAutocad_Click()
'look for Autocad 2006 (full version)
On Error Resume Next
Set AcadObj = GetObject(, "AutoCAD.Application.16.2")
If Err <> 0 Then
    Err.Clear
    Set AcadObj = CreateObject("AutoCAD.Application.16.2")
    If Err <> 0 Then ErrorMessage: Exit Sub 'Get and Create failed
End If
'Get or Create Acad 2006 (full version?) was successful
Err.Clear: On Error GoTo 0
AcadObj.Visible = True
End Sub
'----------
Private Sub DrawTextstring_Click()
On Error Resume Next
Dim textObj As Object  'this is a direct reference to the acad object as well
Dim text As String
Dim insPt(0 To 2) As Double
Dim height As Double
' Define the text object
text = ". Test successful ."
insPt(0) = 2: insPt(1) = 2: insPt(2) = 0
height = 0.5
' Create the text object in model space
Set textObj = AcadObj.ActiveDocument.ModelSpace.AddText(text, insPt, height)
AcadObj.ZoomExtents
If Err <> 0 Then ErrorMessage 'Autocad 2006 LT may have spoiled the fun...
End Sub
'----------
Private Sub Exit_Click()
On Error Resume Next 'just in case button was clicked without Acad loaded
AcadObj.Quit
Unload Me
End Sub
'----------
Private Sub ErrorMessage()
Err.Clear: On Error GoTo 0
Dim strMsg As String
strMsg = "Can't find or start Autocad 2006 full version." & vbCr
strMsg = strMsg & "Please close all other versions and" & vbCr
strMsg = strMsg & "launch Autocad 2006 full version yourself."
MsgBox (strMsg)
End Sub


The key to using late binding is earlly bind while developing being aware to change acad constants into their values and alter all assigning to acad objects into "as Object"
and removeing the reference. his will ensure future use at the cost of some speed loss

havano

  • Guest
Re: Lauching Autocad from a VB exe? No luck...
« Reply #7 on: April 26, 2006, 08:24:57 AM »
Hi Berend, thanks for your comments and above all, your rewriting my code into a late-binding version.
I'll try it later, if all else fails. Btw you forgot to erase the Acadverson argument, which would frustrate the getobject and createobject part.

But please forgive me my slightly different view on the matter:  Being self-employed, my future income might largely or even solely consist of maintenance fees...
Catch my drift?  :kewl:

Groet!

Btw you forgot to erase the Acadverson property, which would frustrate GetObject and CreateObject because thereby the version-dependency would sneak back in.
« Last Edit: April 26, 2006, 08:54:58 AM by havano »

Dnereb

  • Guest
Re: Lauching Autocad from a VB exe? No luck...
« Reply #8 on: April 26, 2006, 08:46:12 AM »
Yes I understand your way of doing business
but i do not think it will be the best way to continue screwing your customers.
(having a small business besides my daytime job)

havano

  • Guest
Re: Lauching Autocad from a VB exe? No luck...
« Reply #9 on: April 26, 2006, 09:04:59 AM »
I had a hunch you would react like that. Sorry if I upset you.

I used to have your morals. That was about the time I had your monthly paycheck.

Would it help if I told you that I allowed the customer to "screw" me on this one, only hoping to get even some day? Believe me, I stil manage to keep close to the straight & narrow. The last thing I want or deserve is being looked down upon.

Enough about ethics, let's return to the subject.
« Last Edit: April 26, 2006, 09:20:40 AM by havano »

Mark

  • Custom Title
  • Seagull
  • Posts: 28753
Re: Lauching Autocad from a VB exe? No luck...
« Reply #10 on: April 26, 2006, 09:28:28 AM »
Enough about ethics, let's return to the subject.

Yes, please.  :-)
TheSwamp.org  (serving the CAD community since 2003)

Dnereb

  • Guest
Re: Lauching Autocad from a VB exe? No luck...
« Reply #11 on: April 26, 2006, 09:49:22 AM »
No apologies needed, i'm not easely upset, nor do i look down upon you.

apart from maintence stuff you still need to late bind. because the pre compiler or interpreter will flunk as soon as it detects the object reference is missing.
your code specifily wants to create an instance of version 16.2 so it wont work with 17.x nor 16.3
anyways. so you still can cash in on acad upgrades

havano

  • Guest
Re: Lauching Autocad from a VB exe? No luck...
« Reply #12 on: April 26, 2006, 10:28:00 AM »
Not easily upset? I envy you, 'cause I am!

My code has an escape hatch. When coded with late binding, maybe the StartAutocad commandbutton will fail because of the version property, but once the user has launched Autocad manually, the DrawTextstring commandbutton (and other controls-in-the-making) should work fine.

My hesitation to indulge in late binding frenzies is not so much shrewdness as it is being just plain lazy.

Added later, to compensate for a post I deleted:
From what I read about late binding in the VB documentation, my program will become very slow, and I will have to do without the "cute little code completion helpers" while writing it. I think I will first develop the whole application on my machine using early binding, then demonstrate it to my client using my machine and then, as the last step, solve the problems I encounter while porting it to their environment. Maybe It would be a good idea to invoke the help of this community in that stage.
« Last Edit: April 27, 2006, 02:53:14 AM by havano »

Dnereb

  • Guest
Re: Lauching Autocad from a VB exe? No luck...
« Reply #13 on: April 26, 2006, 11:20:40 AM »
this line will lock your macro.
Public AcadObj As AcadApplication
because it refers to the specific Acad object you are referencing now.
as it is public and in a vba module it wil be proccessed as soon as code in this module wil run.
only You can judge if thes could happen in your situation
I understand your lazyness, I have the same flaw.
But if you want a nice error advising to contact you with an adress and such. $$$$$ :wink:
it would help.

Have a nice day... (leaving the office)

off topic:
And don't envy my elephant skin I've got it due to many head bangings in the past.


Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Lauching Autocad from a VB exe? No luck...
« Reply #14 on: April 26, 2006, 02:16:03 PM »
Pretty close, except for the Poland France thingy ...

You can still have the cute little code helpers if you reference the library at design time, (early bind) then remove the binding (and all referenced bound objects) before building the executable. One thing to remember which we have not discussed is marshalling. Anytime you create an executable (something.exe) it will by necessity have to invoke marshalling to communicate with AutoCAD. In that instance, speed degradation will become a significant factor. You can prevent that by compiling to an ActiveX dll and calling your dll with VisualLisp or VBA. Then, late binding will be nearly negated as the dll will operate just as if it had been written right in the VBA IDE.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie