TheSwamp
Code Red => VB(A) => Topic started 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
(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
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
-
Here's a solution:
http://www.theswamp.org/index.php?topic=1497.0
-
This should also work.
(setq USERS1 (getfiled "Select Image File" (getvar "dwgprefix") "tif" 8))
Imgname = ThisDrawing.GetVariable("USERS1")
-
Hey Matt
Been there done that; it didn't work
It is not passing the variable from ACAD to VBA
Mark
-
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
-
What version of AutoCAD?
Hint ... vl.application.## ...
/guess
-
MP
R16.2
So, you are saying:
Dim vlax As New vlax
Set New vlax to vl.application. 16.2 ?
Mark
-
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.
-
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.
-
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?
-
What MP said++
-
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:
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:
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.
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
-
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
-
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?
-
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)
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
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.
-
Hi Some!
Is this a function that will work without That VLAX Class module?
Mark
-
CM,
To answer your question;
The post started like this
This should also work.
(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
-
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
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
-
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
-
Hey Some
So, the code (setting the reference) that I posted just above you last post; along with your function should work together?
Mark
-
This is really ugly and I am not sure that I would use this approach but can anyone tell me how to get this
(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
-
Try this one
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'~
-
ML,
I was going to comment, but I won't bother - you're obviously not learning.
-
The post started like this
This should also work.
(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.....
(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.
-
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?
-
You're asking for trouble there Jeff :wink:
-
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
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
-
Hey Glenn,
I saw your comment but I chose to ignore it. I don't have time for that kind of negativity. Sorry!
-
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.
^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:
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
-
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