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

Размещено в AutoCAD, VBA, Код LISP, Новости · Метки: , ,



Поделитесь своим мнением


Я не робот.