TheSwamp

Code Red => VB(A) => Topic started by: ML on December 14, 2007, 02:48:24 PM

Title: Getting a variable in VBA from ACAD
Post by: ML on December 14, 2007, 02:48:24 PM
Hi,

I am trying something here; in theory this should work but I think that I am doing something wrong

Using LISP (in a menu macro) I set my variable

Code: [Select]
(setq imgname (getfiled "Select Image File" (getvar "dwgprefix") "tif" 8))

Now, in VBA I want to use it.
Is this possible?  If so, how would I write the syntax?
Here was my attempt

Code: [Select]
Imgname = ThisDrawing.GetVariable("!Imgname")

In ACAD, if I simply do !Imgname at the command line, it is returning the proper file name that I assigned to the variable

but with VBA no luck


Thanks!

Mark

Title: Re: Getting a variable in VBA from ACAD
Post by: deegeecees on December 14, 2007, 02:53:51 PM
Here's a solution:

http://www.theswamp.org/index.php?topic=1497.0
Title: Re: Getting a variable in VBA from ACAD
Post by: Guest on December 14, 2007, 02:55:36 PM
This should also work.

Code: [Select]
(setq USERS1 (getfiled "Select Image File" (getvar "dwgprefix") "tif" 8))

Code: [Select]
Imgname = ThisDrawing.GetVariable("USERS1")
Title: Re: Getting a variable in VBA from ACAD
Post by: ML on December 14, 2007, 04:15:41 PM

Hey Matt

Been there done that; it didn't work

It is not passing the variable from ACAD to VBA

Mark
Title: Re: Getting a variable in VBA from ACAD
Post by: ML on December 14, 2007, 04:33:20 PM

Dec..

That is cool but I am getting an user defined type not defined.

I tried setting a reference to The Visual Lisp Active X Module but that didn't help

What am I missing?

Mark
Title: Re: Getting a variable in VBA from ACAD
Post by: MP on December 14, 2007, 04:40:52 PM
What version of AutoCAD?

Hint ... vl.application.## ...

/guess
Title: Re: Getting a variable in VBA from ACAD
Post by: ML on December 14, 2007, 04:43:22 PM

MP

R16.2

So, you are saying:

Dim vlax As New vlax

Set New vlax to vl.application. 16.2    ?

Mark
Title: Re: Getting a variable in VBA from ACAD
Post by: MP on December 14, 2007, 05:00:43 PM
Not quite.

In the vlax.cls definition (which I don't have) there's a reference to vl.application. Ensure it references "vl.application.16".

PS: May not be the problem, I'm shooting blind from your description.
Title: Re: Getting a variable in VBA from ACAD
Post by: Glenn R on December 14, 2007, 06:05:23 PM
Now, in VBA I want to use it.
Is this possible? 

No.

The AutoLISP interpreter inside AutoCAD and VBA were never designed to communicate. In later versions of AutoLISP (read VisualLISP) you can access ActiveX components on the system, but you still can't pass variables in between the two environments (easily). You can do what 'Matt W' suggested and 'park' you resultant variable(s) in the 'USERX' system envornment varaible(s) inside AutoCAD, but they can't house complex types.

You could go down the ugly (IMO) VLAX Class route, which was developed a few years ago, by hooking into the AutoCAD VisualLisp ActiveX process and automating it, but I would seriously suggest against it.

Title: Re: Getting a variable in VBA from ACAD
Post by: MP on December 14, 2007, 06:28:49 PM
You could go down the ugly (IMO) VLAX Class route, which was developed a few years ago, by hooking into the AutoCAD VisualLisp ActiveX process and automating it, but I would seriously suggest against it.

Have to agree. I'd revisit the solution -- what is it that is "mandating" the vb <-> lisp exchange?
Title: Re: Getting a variable in VBA from ACAD
Post by: Glenn R on December 14, 2007, 06:59:00 PM
What MP said++
Title: Re: Getting a variable in VBA from ACAD
Post by: ML on December 14, 2007, 07:37:52 PM

Hey guys

Already there;

I got the whole long VLAX Class Module

I don't like it too much; it seems like a lot just to pass a lousy variable to VBA.

With The VLAX Class Module inserted into your project, you can do this:
Code: [Select]
Sub VBAToLisp()

Dim Obj As VLAX
Dim strText As String

Set Obj = New VLAX

strText = "Hello!"

Obj.SetLispSymbol "Test", strText

Debug.Print strText

then in ACAD, type !Test

It should return Hello!

If so, then the variable Test was just passed from VBA to ACAD or LISP which is very cool

---------------

On the flip side; I am trying to read in a variable but no luck so far
Here is what I have:

Code: [Select]
Dim Obj As VLAX
Dim strText As String

strText = "M"   'M was set to Mark in ACAD (setq M "Mark")

Set Obj = New VLAX

Obj.GetLispSymbol , strText 
Debug.Print strText

Have a look at this:

I am actually more interested in getting this method to work but still no luck.

Code: [Select]
Sub VBAToLisp()

Dim VL As Object
Dim strText As String

Set VL = CreateObject("VL.Application.16")

strText = "Hello!"

VL.SetLispSymbol "Test", strText
Debug.Print strText


End Sub

I do not have the methods of The VL.Application Object, so I don't even know if The GetLispSymbol and SetLispSymbol methods are even available in VLISP. The error is saying that object doesn't support this method, so I guess that is my answer.

Anyone? Any Ideas?

Thanks
Mark

Title: Re: Getting a variable in VBA from ACAD
Post by: ML on December 14, 2007, 07:41:05 PM

Also I believe you will need to set a reference to The Visual LISP Active X Module Library.
Then you will have access to The VLISP objects

Mark
Title: Re: Getting a variable in VBA from ACAD
Post by: CmdrDuh on December 14, 2007, 08:44:53 PM
I would try to stick with just VBA if it were me.  You could declare a Global variable, and store info there.  From what I read so far, why couldn't you do the whole thing in VBA?  Prompt for select object, filtering for images, and pull the info from the selection set.  Or are you just experimenting?
Title: Re: Getting a variable in VBA from ACAD
Post by: SomeCallMeDave on December 14, 2007, 09:28:30 PM
Here is one that I cobbled together several years ago using the VLAX as a guide.

You will have to adjust the .GetInterfaceObject to suit your version of ACAD (this one works in 2004)

Code: [Select]
Public Function vbGetLispList(pVarName As String) As Variant

Dim VLisp As Object
Dim VLispFunc As Object
Dim varTemp As Variant
Dim varRetVal As Variant
Dim varType As Variant

Dim obj1 As Object
Dim obj2 As Object

Dim strHnd As String
Dim strVer As String

Dim lngCount As Long
Dim i As Long
Dim j As Long

On Error GoTo vbGetLispVarError

If Me.Application.Version = "16.0" Then
  Set VLisp = ThisDrawing.Application.GetInterfaceObject("VL.Application.16")
Else
  Set VLisp = ThisDrawing.Application.GetInterfaceObject("VL.Application.1")
End If

Set VLispFunc = VLisp.ActiveDocument.Functions
Set obj1 = VLispFunc.Item("read").funcall("pSCMDtemp")
  varRetVal = VLispFunc.Item("set").funcall(obj1, pVarName)
Set obj1 = VLispFunc.Item("read").funcall("(type (eval (read pSCMDtemp)))")
Set obj2 = VLispFunc.Item("eval").funcall(obj1)
varType = VLispFunc.Item("vl-princ-to-string").funcall(obj2)

Select Case varType
  Case "LIST"
    Set obj1 = VLispFunc.Item("read").funcall(pVarName)
    Set obj2 = VLispFunc.Item("eval").funcall(obj1)
    varRetVal = VLispFunc.Item("vl-princ-to-string").funcall(obj2)
  Case "SYM", "INT", "STR", "REAL"
    Set obj1 = VLispFunc.Item("read").funcall(pVarName)
    varRetVal = VLispFunc.Item("eval").funcall(obj1)
  Case Else
    varRetVal = "nil"
End Select

vbGetLispList = varRetVal

'clean up the newly created LISP symbols
Set obj1 = VLispFunc.Item("read").funcall("(setq pSCMDtemp nil)")
  varRetVal = VLispFunc.Item("eval").funcall(obj1)


 
'release the objects or Autocad gets squirrely
Set obj2 = Nothing
Set obj1 = Nothing
Set VLispFunc = Nothing
Set VLisp = Nothing

Exit Function

vbGetLispVarError:
  Set obj2 = Nothing
  Set obj1 = Nothing
  Set VLispFunc = Nothing
  Set VLisp = Nothing
  Debug.Print Err.Number
  'MsgBox "Error occurred " & Err.Description

End Function

This is a simple test function that does what I think you are trying to do

Code: [Select]
Public Sub test2()
  Dim varTest As Variant
     

  varTest = vbGetLispList("temp2")
  MsgBox varTest
 
End Sub

At the ACAD command line, set temp2 with (setq temp2 (''string of your choice"))

Maybe this will help.
Title: Re: Getting a variable in VBA from ACAD
Post by: ML on December 17, 2007, 10:25:27 AM

Hi Some!

Is this a function that will work without That VLAX Class module?

Mark
Title: Re: Getting a variable in VBA from ACAD
Post by: ML on December 17, 2007, 10:30:41 AM

CM,

To answer your question;
The post started like this

Quote
This should also work.

Code: [Select]
(setq USERS1 (getfiled "Select Image File" (getvar "dwgprefix") "tif" 8))

Imgname = ThisDrawing.GetVariable("USERS1")


Instead of having to use The really long FileOpenDialog in ACAD - VBA just to browse (using Windows) and grab a lousy file; I thought that I would just use the getfiled method in LISP instead. That is when this problem occurred. With LISP, I can set my variable in CAD; however, that variable will not carry over to VBA; hence this.

God, in Excel, THe FileOpenDialog is built into VBA and it is like 4 lines.

Mark

Mark
Title: Re: Getting a variable in VBA from ACAD
Post by: ML on December 17, 2007, 10:33:36 AM

Does anyone think that they could get this method working, without VLAX? I think it is much cleaner.
I have done some research on The Net and it does look like we can effectively set a reference to The VLISP object, the question is, how do we use the VLISP methods in VBA?

Mark

Code: [Select]
Sub VBAToLisp()

Dim VL As Object
Dim strText As String

Set VL = CreateObject("VL.Application.16")

strText = "Hello!"

VL.SetLispSymbol "Test", strText
Debug.Print strText

End Sub
Title: Re: Getting a variable in VBA from ACAD
Post by: SomeCallMeDave on December 17, 2007, 11:23:59 AM

Hi Some!

Is this a function that will work without That VLAX Class module?

Mark

Mark,
Yes, it will work without the VLAX class, but will require a reference to be set to the visual LISP activeX module
Title: Re: Getting a variable in VBA from ACAD
Post by: ML on December 17, 2007, 12:40:07 PM

Hey Some

So, the code (setting the reference) that I posted just above you last post; along with your function should work together?

Mark

Title: Re: Getting a variable in VBA from ACAD
Post by: ML on December 17, 2007, 12:41:53 PM

This is really ugly and I am not sure that I would use this approach but can anyone tell me how to get this
Code: [Select]
(setq imgname (getfiled "Select Image File" (getvar "dwgprefix") "tif" 8))

To The ACAD Command Line?

Thisdrawing.SendCommand  (setq imgname (getfiled "Select Image File" (getvar "dwgprefix") "tif" 8))

Thanks
Mark
Title: Re: Getting a variable in VBA from ACAD
Post by: Fatty on December 17, 2007, 04:29:53 PM
Try this one

Code: [Select]
Sub Try()
Dim fname As String
ThisDrawing.SetVariable "USERS1", ""
     ThisDrawing.SendCommand "(setvar " & Chr(34) & "USERS1" & Chr(34) & _
                             " (setq imgname (getfiled " & Chr(34) & _
                             "Select Image File " & Chr(34) & Chr(34) & _
                             "C:\\ " & Chr(34) & Chr(32) & Chr(34) & "jpg" & Chr(34) & " 16)))" & vbCr
     If ThisDrawing.GetVariable("USERS1") <> vbNullString Then
     [color=red]fname[/color] = ThisDrawing.GetVariable("USERS1")
     MsgBox "You choosen: " & vbCr & fname
     End If
End Sub

~'J'~
Title: Re: Getting a variable in VBA from ACAD
Post by: Glenn R on December 17, 2007, 06:12:11 PM
ML,

I was going to comment, but I won't bother - you're obviously not learning.
Title: Re: Getting a variable in VBA from ACAD
Post by: Jeff_M on December 17, 2007, 07:35:07 PM
The post started like this
Quote
This should also work.
Code: [Select]
(setq USERS1 (getfiled "Select Image File" (getvar "dwgprefix") "tif" 8))

Imgname = ThisDrawing.GetVariable("USERS1")

If Matt would've typed what he meant :-) , you may not have needed to go this far.....
Code: [Select]
(setvar "USERS1" (getfiled "Select Image File" (getvar "dwgprefix") "tif" 8))
I should add, however, that I concur with what Michael, Glenn, & David have all tried to say.....stick with a VBA solution.
Title: Re: Getting a variable in VBA from ACAD
Post by: Jeff_M on December 17, 2007, 07:55:22 PM
Another thought, Mark, since you seem to know how to get this in Excel, why not link to Excel's ActiveX and use it's FIleDialog?
Title: Re: Getting a variable in VBA from ACAD
Post by: Glenn R on December 17, 2007, 08:05:16 PM
You're asking for trouble there Jeff  :wink:
Title: Re: Getting a variable in VBA from ACAD
Post by: ML on December 17, 2007, 08:18:28 PM

Hey Guys,

I think I got it!
Please try it out; it seems to be working very well for me.
Here are 2 short examples and the nec. functions
With this, you should be able to assign (LISP) variables to ACAD from VBA and vice versa.

Mark

Code: [Select]
Dim VL As Object
Sub Lisp2VBA()
 A = GetLispSym("M") 'In ACAD, at the command line, set your variable ie (setq M "Test")
 Debug.Print "Variable = " & A
'MsgBox A
End Sub

Sub VBA2Lisp()
'Dim Value As Double
 Dim Value As String
 Value = "Test" '(120#)
 PutLispSym "B", Value 'In ACAD, type !B. The variable (B) should return Test
End Sub

Function GetLispSym(symbolName As String) As Variant
 Dim sym As Object
 Set VL = CreateObject("VL.Application.16")
 Set sym = VL.ActiveDocument.Functions.Item("read").funcall(symbolName)
 GetLispSym = VL.ActiveDocument.Functions.Item("eval").funcall(sym)
End Function

Function PutLispSym(symbolName As String, Value As Variant)
 Dim sym As Object
 Set VL = CreateObject("VL.Application.16")
 Set sym = VL.ActiveDocument.Functions.Item("read").funcall(symbolName)
 VL.ActiveDocument.Functions.Item("set").funcall sym, Value
End Function




Title: Re: Getting a variable in VBA from ACAD
Post by: ML on December 18, 2007, 11:07:35 AM

Hey Glenn,

I saw your comment but I chose to ignore it. I don't have time for that kind of negativity. Sorry!

Title: Re: Getting a variable in VBA from ACAD
Post by: ML on December 18, 2007, 11:25:29 AM

Anyhow, back to better things:
I was finally able to acheive what I had set out to do:

I have a menu macro in ACAD

This mixes up VBA and LISP a bit
So, with The VBA Expression, I set PaperSpace as current, then with the getfiled method in LISP, I set my variable imgname to the name of the tif file; then run my Sub in VBA.

Code: [Select]
^c^cvbastmt;ThisDrawing.ActiveSpace = acPaperSpace;(setq imgname (getfiled "Select Image File" (getvar "dwgprefix") "tif" 8));^c^c-vbarun;"K:/Type/in your path/Projectname.dvb!Module.Macro";

Then, this is an abbreviated version of my Sub:
Code: [Select]
Sub Name ()
Dim RastImg As AcadRasterImage
Dim Imgpth As String
Dim Imgname As String
Dim InsertPnt(0 To 2) As Double, scalefactor As Double, RotAngle As Double

Imgpth = ThisDrawing.Path & "\"
Imgname = GetLispSym("Imgname") 'Here, calling the below (GetLispSym) function, I am retreiving the variable (filename) from ACAD and successfully assigning it to the Set RastImg line and so on and so on.

InsertPnt(0) = -8#: InsertPnt(1) = 0#: InsertPnt(2) = 0#
scalefactor = 1
RotAngle = 0

On Error GoTo Errorhandler
Set RastImg = ThisDrawing.PaperSpace.AddRaster(Imgpth & Imgname, InsertPnt, scalefactor, RotAngle)

Function GetLispSym(symbolName As String) As Variant
  Dim VL As Object
  Dim sym As Object
  Set VL = CreateObject("VL.Application.16")
  Set sym = VL.ActiveDocument.Functions.Item("read").funcall(symbolName)
  GetLispSym = VL.ActiveDocument.Functions.Item("eval").funcall(sym)
End Function


Title: Re: Getting a variable in VBA from ACAD
Post by: ML on December 18, 2007, 11:33:29 AM

SomeCall

I pretty much did the same as you :)
I kind of muffled through The VLAX Class as well, saw your function and an old post that helped me to narrow it down to pretty much just want I need. Trust me, I do not know VLISP at all and very little LISP.

I do like that you test for the version and that is a good idea to Set the objects to nothing at the end.

Thanks for the help!

Mark