Accessing LDATA values from VBA

<?xml encoding=”UTF-8″>By Daniel Du

Issue

A VLISP function can be used to create a dictionary just like:

(vlax-ldata-put “Test” “Helper” “Good”)

And a dictionary named “Test” is created, and a (vlax-ldata-get “Test” “Helper”) retrieves the return value, “Good”. From VBA, how can I get the dictionary data value of “Good”?

Solution

VLISP ldata is attached to a custom object with class name “vlo_VL” and then the object is added to the Named Object Dictionary. However, a custom object is not penetrable by means of the VBA object model alone. You cannot create custom entities/objects with VBA, but you can develop custom entities with ObjectARX and create an ActiveX interface to it so that it can be used within VBA. Unfortunately, there is no direct interface (or Automation server) to a vlo_VL object.

The AutoCAD Visual LISP Automation server (an unsupported interface) can be used to bridge the gap between VBA macro and the LISP environment, though.

If the following has already been entered successfully at the command line:

(vl-load-com)<br>(vlax-ldata-put "Test" "Helper" "Good")

Then, with a little effort a VBA macro can use the LISP server’s generalized object model:

<font face="新宋体"><span><font color="#0000ff"><font>Function</font></font></span><font><font color="#000000"> readEvalHelper(app </font><span><font color="#0000ff">As</font></span><font color="#000000"> </font><span><font color="#0000ff">Object</font></span></font></font><font><font face="新宋体"><font color="#000000">)<br>    </font><span><font color="#008000">' this is a helper function</font></span><br></font><font face="新宋体"><font color="#000000">    vld = app.ActiveDocument<br> <br>    </font><span><font color="#0000ff">Dim</font></span><font color="#000000"> vlf_read </font><span><font color="#0000ff">As</font></span><font color="#000000"> </font><span><font color="#0000ff">Object</font></span><br><font color="#000000">    vlf_read = vld.Functions.Item(</font><span><font color="#a31515">"read"</font></span></font><font face="新宋体"><font color="#000000">)<br> <br>    </font><span><font color="#0000ff">Dim</font></span><font color="#000000"> vl_obj1 </font><span><font color="#0000ff">As</font></span><font color="#000000"> </font><span><font color="#0000ff">Object</font></span><br><font color="#000000">    vl_obj1 = vlf_read.funcall(</font><span><font color="#a31515">"(defun read-eval (arg)(eval (read arg)))"</font></span></font><font face="新宋体"><font color="#000000">)<br> <br>    </font><span><font color="#0000ff">Dim</font></span><font color="#000000"> vlf_eval </font><span><font color="#0000ff">As</font></span><font color="#000000"> </font><span><font color="#0000ff">Object</font></span><br><font color="#000000">    vlf_eval = vld.Functions.Item(</font><span><font color="#a31515">"eval"</font></span></font><font face="新宋体"><font color="#000000">)<br> <br>    </font><span><font color="#0000ff">Dim</font></span><font color="#000000"> vl_obj2 </font><span><font color="#0000ff">As</font></span><font color="#000000"> </font><span><font color="#0000ff">Object</font></span><br></font><font face="新宋体"><font color="#000000">    vl_obj2 = vlf_eval.funcall(vl_obj1)<br> </font><br><span><font color="#0000ff">End</font></span><font color="#000000"> </font><span><font color="#0000ff">Function</font></span><br></font><font face="新宋体"><font color="#000000"> <br> </font><br><span><font color="#0000ff">Public</font></span><font color="#000000"> </font><span><font color="#0000ff">Sub</font></span></font><font face="新宋体"><font color="#000000"> vlsGetLData()<br>    </font><span><font color="#0000ff">Dim</font></span><font color="#000000"> vlApp </font><span><font color="#0000ff">As</font></span><font color="#000000"> </font><span><font color="#0000ff">Object</font></span><br><font color="#000000">    vlApp = CreateObject(</font><span><font color="#a31515">"VL.Application.16"</font></span></font><font face="新宋体"><font color="#000000">)<br> <br>    readEvalHelper(vlApp)<br> <br>    </font><span><font color="#0000ff">Dim</font></span><font color="#000000"> invokeIt </font><span><font color="#0000ff">As</font></span><font color="#000000"> </font><span><font color="#0000ff">Object</font></span><br><font color="#000000">    invokeIt = vlApp.ActiveDocument.Functions.Item(</font><span><font color="#a31515">"read-eval"</font></span></font><font face="新宋体"><font color="#000000">)<br>    invokeIt.funcall(</font><span><font color="#a31515">"(setq lDatum (vlax-ldata-get ""Test"" ""Helper""))"</font></span></font><font face="新宋体"><font color="#000000">)<br> <br>    sym = vlApp.ActiveDocument.Functions.Item(</font><span><font color="#a31515">"read"</font></span><font color="#000000">).funcall(</font><span><font color="#a31515">"lDatum"</font></span></font><font face="新宋体"><font color="#000000">)<br>    GetLispSym = vlApp.ActiveDocument.Functions.Item(</font><span><font color="#a31515">"eval"</font></span></font><font face="新宋体"><font color="#000000">).funcall(sym)<br>    MsgBox(</font><span><font color="#a31515">"Key's data is:"</font></span></font></font><font face="新宋体"><font><font color="#000000"> + Chr(13) + GetLispSym)<br> </font><br><span><font color="#0000ff">End</font></span><font color="#000000"> </font></font><span><font color="#0000ff">Sub</font></span></font>

Comments

2 responses to “Accessing LDATA values from VBA”

  1. Bert Piercey Avatar
    Bert Piercey

    I tried using this and it does not seem to be able to create the object vlApp = CreateObject(“VL.Application.16”).

  2. Joris Claassen Avatar
    Joris Claassen

    CreateObject(“VL.Application.16”) is available when you have a specific version (or range of versions) of AutoCAD.
    To make it easier (not!) the numbering differens for a lot things:
    AutoCAD   version for       first 6      version for 
    program   COM access*   chars of   COM access
    version     to program      dwg file     to VL
      2004             16            AC1018             ?
      2007             17            AC1021             ? 
      2010             18            AC1024           16?   
      2013             19            AC1027             ? 
    *: with either CreateObject or GetObject
    to be checked in

    <

    ul>regedit.exe with:     HKEY_CLASSES_ROOT\AutoCAD.Application.##
    reg.exe:    reg query HKCR  /f “AutoCAD.Application.”      (likewise for VL object:        reg query HKCR  /f “VL.Application.“)

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading