Calling User-Defined VBA Functions From Lisp

Chell

Usenet Archive
Joined
Dec 18, 2003
Messages
5
Reaction score
0
Hello Everyone;

I thought I would pass on the following idea of how user-defined VBA functions can be called from Lisp without the limitations VBArun.

The biggest problems with VBArun is that it does not accept function arguements and Lisp does not wait for the VBA function to finish before continueing on to the next Lisp statement. It also does not return a value.

The secret is to use the EVAL method (not Lisp function) of the AutoCad Application object. This method evaluates a string as though it was a line of VBA code. For example, the call (vla-eval AcadObj "ThisDocument.MyFunc ( 3 4)") would run the indicated function with the arguements of 3 and 4. By this means, any user-defined function with arguements that can be reduced to strings can be called from Lisp. The Eval method will not return control to your Lisp rountine until after MyFunc finishes. This is the behavior you would expect from a sub-routine.

There are still a couple of problems to work around before nirvana is reached: passing complex arguements (objects) and getting a value in return. My solution is to create an Xrecord and then pass the handle to the VBA function. Values can be returned from VBA in the same manner.

So why bother?

One reason would be for menus. Say you wanted to invoke a function that would find the length of a line and increase it by X%. And each line of the menu would specify a different percentage. In Lisp you would do it by creating a function where the percentage was passed in as an arguement. In VBA and without EVAL you would have to create seperate function for each possible percentage.

Stil why bother? Because VBA can do somethings that are hard or impossible to do from LISP. Like access the Windows API or call a user-defined function in, say, a Word document.

Hoping this helps....
Michelle

PS: I do have some sample code I could pass on...
 
Michelle,
Excellent suggestions. I would appreciate any 'samples' that you would care to pass-on.
Thanks in advance.!

Bob Shaw
 
Thanks for the post. This is a very interesting approach!

--
R. Robert Bell, MCSE
www.AcadX.com

| Hello Everyone;
|
| I thought I would pass on the following idea of how user-defined VBA functions can be called from Lisp without the limitations VBArun. | | The biggest problems with VBArun is that it does not accept function arguements and Lisp does not wait for the VBA function to finish before continueing on to the next Lisp statement. It also does not return a value. | | The secret is to use the EVAL method (not Lisp function) of the AutoCad Application object. This method evaluates a string as though it was a line of VBA code. For example, the call (vla-eval AcadObj "ThisDocument.MyFunc ( 3 4)") would run the indicated function with the arguements of 3 and 4. By this means, any user-defined function with arguements that can be reduced to strings can be called from Lisp. The Eval method will not return control to your Lisp rountine until after MyFunc finishes. This is the behavior you would expect from a sub-routine. | | There are still a couple of problems to work around before nirvana is reached: passing complex arguements (objects) and getting a value in return. My solution is to create an Xrecord and then pass the handle to the VBA function. Values can be returned from VBA in the same manner. | | So why bother? | | One reason would be for menus. Say you wanted to invoke a function that would find the length of a line and increase it by X%. And each line of the menu would specify a different percentage. In Lisp you would do it by creating a function where the percentage was passed in as an arguement. In VBA and without EVAL you would have to create seperate function for each possible percentage. | | Stil why bother? Because VBA can do somethings that are hard or impossible to do from LISP. Like access the Windows API or call a user-defined function in, say, a Word document. | | Hoping this helps.... | Michelle | | PS: I do have some sample code I could pass on...
 
The vla-runmacro method of the AcadApplication object
is the preferred way to execute a VBA macro in the document context (document context = executes synchonously and LISP waits for it to complete). The Eval method is a variant of it that also returns a result.

chell said:
Hello Everyone;

I thought I would pass on the following idea of how user-defined VBA functions can be called from Lisp without the limitations VBArun.

The biggest problems with VBArun is that it does not accept function arguements and Lisp does not wait for the VBA
function to finish before continueing on to the next Lisp statement. It also does not return a value.
The secret is to use the EVAL method (not Lisp function) of the AutoCad Application object. This method evaluates a
string as though it was a line of VBA code. For example, the call (vla-eval AcadObj "ThisDocument.MyFunc ( 3 4)") would run the indicated function with the arguements of 3 and 4. By this means, any user-defined function with arguements that can be reduced to strings can be called from Lisp. The Eval method will not return control to your Lisp rountine until after MyFunc finishes. This is the behavior you would expect from a sub-routine.
There are still a couple of problems to work around before nirvana is reached: passing complex arguements (objects)
and getting a value in return. My solution is to create an Xrecord and then pass the handle to the VBA function. Values can be returned from VBA in the same manner.
So why bother?

One reason would be for menus. Say you wanted to invoke a function that would find the length of a line and increase
it by X%. And each line of the menu would specify a different percentage. In Lisp you would do it by creating a function where the percentage was passed in as an arguement. In VBA and without EVAL you would have to create seperate function for each possible percentage.
Stil why bother? Because VBA can do somethings that are hard or impossible to do from LISP. Like access the Windows
API or call a user-defined function in, say, a Word document.
 
You may find this interesting :

http://www.afralisp.com/vl/vl-vba1.htm

chell said:
Hello Everyone;

I thought I would pass on the following idea of how user-defined VBA
functions can be called from Lisp without the limitations VBArun.
The biggest problems with VBArun is that it does not accept function
arguements and Lisp does not wait for the VBA function to finish before continueing on to the next Lisp statement. It also does not return a value.
The secret is to use the EVAL method (not Lisp function) of the AutoCad
Application object. This method evaluates a string as though it was a line of VBA code. For example, the call (vla-eval AcadObj "ThisDocument.MyFunc ( 3 4)") would run the indicated function with the arguements of 3 and 4. By this means, any user-defined function with arguements that can be reduced to strings can be called from Lisp. The Eval method will not return control to your Lisp rountine until after MyFunc finishes. This is the behavior you would expect from a sub-routine.
There are still a couple of problems to work around before nirvana is
reached: passing complex arguements (objects) and getting a value in return. My solution is to create an Xrecord and then pass the handle to the VBA function. Values can be returned from VBA in the same manner.
So why bother?

One reason would be for menus. Say you wanted to invoke a function that
would find the length of a line and increase it by X%. And each line of the menu would specify a different percentage. In Lisp you would do it by creating a function where the percentage was passed in as an arguement. In VBA and without EVAL you would have to create seperate function for each possible percentage.
Stil why bother? Because VBA can do somethings that are hard or impossible
to do from LISP. Like access the Windows API or call a user-defined function in, say, a Word document.
 
Michelle,

Design a function in VBA that uses the Utility's Get... methods to receive data from LISP passed via the command pipeline. Another alternative is to stuff the data into a dictionary or the registry and then read it from there.

--
R. Robert Bell, MCSE
www.AcadX.com

Hello Everyone;

My thanks to all who replied to my post. I finally found some time to think about the issues that some of them raised.

My first stop was to look at the solution done by AfraLisp. They used the Eval method also but used the USER system varibles to pass parameters back and forth. This is vastly simplifies the code involved (Good) but does suffer from the fact that USER is a global varible that could be in use by others.

I also checked out the VLA-RunMacro function again. Lisp does wait for the function to finish but I still couldn't pass arguements to VBA using it.

My code is also attached.

Thanks once more,
Michelle
 

Latest threads

Back
Top