Lisp из-под VBA
В теме Interop в AutoCAD всплыл старый-старый vba-шный код, позволявший из-под VBA работать с LISP-выражениями, переменными и т.п.
Я не мог удержаться и специально проверил упомянутый код. Класс потребовал переделки, и вот что получилось в результате:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | Option Explicit ' VLAX.CLS v1.4 (Last updated 8/27/2001) ' Copyright 1999-2001 by Frank Oquendo ' ' Permission to use, copy, modify, and distribute this software ' for any purpose and without fee is hereby granted, provided ' that the above copyright notice appears in all copies and ' that both that copyright notice and the limited warranty and ' restricted rights notice below appear in all supporting ' documentation. ' ' FRANK OQUENDO (THE AUTHOR) PROVIDES THIS PROGRAM "AS IS" AND WITH ' ALL FAULTS. THE AUTHOR SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY ' OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. THE AUTHOR ' DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE ' UNINTERRUPTED OR ERROR FREE. ' ' Use, duplication, or disclosure by the U.S. Government is subject to ' restrictions set forth in FAR 52.227-19 (Commercial Computer ' Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) ' (Rights in Technical Data and Computer Software), as applicable. ' ' VLAX.cls allows developers to evaluate AutoLISP expressions from ' Visual Basic or VBA ' ' Notes: ' All code for this class module is publicly available througout various posts ' at news://discussion.autodesk.com/autodesk.autocad.customization.vba. I do not ' claim copyright or authorship on code presented in these posts, only on this ' compilation of that code. In addition, a great big "Thank you!" to Cyrille Fauvel ' demonstrating the use of the VisualLISP ActiveX Module. ' ' Dependencies: ' Use of this class module requires the following application: ' 1. VisualLISP Private VL As Object Private VLF As Object Private Sub Class_Initialize() Set VL = ThisDrawing.Application.GetInterfaceObject("VL.Application.16") Set VLF = VL.ActiveDocument.Functions End Sub Private Sub Class_Terminate() Set VLF = Nothing Set VL = Nothing End Sub Public Function EvalLispExpression(lispStatement As String) Dim sym As Object, RET As Object, retVal Set sym = VLF.Item("read").funcall(lispStatement) retVal = VLF.Item("eval").funcall(sym) EvalLispExpression = retVal End Function Public Sub SetLispSymbol(symbolName As String, value) Dim sym As Object, RET, symValue symValue = value Set sym = VLF.Item("read").funcall(symbolName) RET = VLF.Item("set").funcall(sym, symValue) EvalLispExpression "(defun translate-variant (data) (cond ((= (type data) 'list) (mapcar 'translate-variant data)) ((= (type data) 'variant) (translate-variant (vlax-variant-value data))) ((= (type data) 'safearray) (mapcar 'translate-variant (vlax-safearray->list data))) (t data)))" EvalLispExpression "(setq " & symbolName & "(translate-variant " & symbolName & "))" EvalLispExpression "(setq translate-variant nil)" End Sub Public Function GetLispSymbol(symbolName As String) Dim sym As Object Set sym = VLF.Item("read").funcall(symbolName) GetLispSymbol = VLF.Item("eval").funcall(sym) End Function Public Function GetLispList(symbolName As String) As Variant Dim sym As Object, list As Object Dim Count, elements(), i As Long Set sym = VLF.Item("read").funcall(symbolName) Set list = VLF.Item("eval").funcall(sym) Count = VLF.Item("length").funcall(list) ReDim elements(0 To Count - 1) As Variant For i = 0 To Count - 1 elements(i) = VLF.Item("nth").funcall(i, list) Next GetLispList = elements End Function Public Sub NullifySymbol(ParamArray symbolName()) Dim i As Integer For i = LBound(symbolName) To UBound(symbolName) EvalLispExpression "(setq " & CStr(symbolName(i)) & " nil)" Next End Sub |
Мне думается, что код может быть интересен тем, кто обращается к AutoCAD (и AutoLISP) из-под сторонних приложений (Excel / Word / ...). Некоторые вещи проще всего делать из-под lisp'а, чем пытаться реализовать из на СОМ.
Код vlax.cls можно брать тут.
Краткий пример вызова (просто шпаргалка для себя):
1 2 3 4 5 6 7 8 9 10 | Option Explicit Public Sub test() Dim obj As Vlax Set obj = New Vlax MsgBox obj.GetLispSymbol("aa") obj.NullifySymbol "aa" MsgBox obj.GetLispSymbol("aa") End Sub |