Calling User-Defined VBA Functions From Lisp

Discussion in 'AutoCAD' started by chell, Jan 28, 2004.

  1. chell

    chell Guest

    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...
     
    chell, Jan 28, 2004
    #1
  2. chell

    ECCAD Guest

    Michelle,
    Excellent suggestions. I would appreciate any 'samples' that you would care to pass-on.
    Thanks in advance.!


    Bob Shaw
     
    ECCAD, Jan 28, 2004
    #2
  3. 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...
     
    R. Robert Bell, Jan 28, 2004
    #3
  4. 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.




    function to finish before continueing on to the next Lisp statement. It also does not return a value.
    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.
    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.
    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.
    API or call a user-defined function in, say, a Word document.
     
    Tony Tanzillo, Jan 29, 2004
    #4
  5. chell

    Kenny Guest

    You may find this interesting :

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

    --
    Kenny
    =======
    http://www.afralisp.com
    =====================
    functions can be called from Lisp without the limitations VBArun.
    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.
    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.
    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.
    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.
    to do from LISP. Like access the Windows API or call a user-defined function
    in, say, a Word document.
     
    Kenny, Jan 29, 2004
    #5
  6. chell

    Dave Guest

    Good stuff.

    --
    David Wishengrad
    President & CTO
    MillLister, Inc.
    Software for measuring and stretching multiple 3D solids.
    Http://Construction3D.com
     
    Dave, Jan 30, 2004
    #6
  7. 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
     
    R. Robert Bell, Feb 16, 2004
    #7
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.