Один из вариантов выполнения lisp при открытии файла.

Во время Autodesk University Russia мне удалось пообщаться с ciril с dwg.ru. Он предложил весьма занимательный подход к пакетному выполнению лисп-кода. Файлы открываются в AutoCAD в полном объеме и их можно вполне спокойно обрабатывать.

Привожу присланный Кириллом код без исправлений и купюр.

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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
;;;формирует загружаемый файл
;;;открывает, сохраняет и закрывает чертежи из переданного списка
;;;удаляет загружаемый файл
;;;параметры функции:
;;;DwgPath - папка с файлами
;;;ListDwgName - список имен файлов
;;;TestString - строка текста
(defun aiku_createbooster (dwgpath           listdwgname       teststring        /                 lspfilename
                           lspfiledsc        lstsysvar         documentscollection                 dwgfullname
                           applyresultorerror                  resultlist
                           )
  (prin1 '(princ)
         (setq lspfiledsc (open (setq lspfilename (strcat dwgpath (getvar 'loginname) "booster.lsp")) "w"))
         ) ;создает файл в папке с чертежом, записывает в него (princ)
  (close lspfiledsc) ;и закрывает его дескриптор
  (mapcar 'setvar
          (car (setq lstsysvar (append (setq lstsysvar (list '(sdi filedia secureload) '(0 0 0)))
                                       (list (mapcar 'getvar (car lstsysvar)))
                                       ) ;_ end of append
                     ) ;_ end of setq
               ) ;_ end of car
          (cadr lstsysvar)
          ) ;сохраняет системные переменные
  (vl-load-all lspfilename) ;загружает созданный lsp-файл в этот чертеж и последующие чертежи в этой сессии ACAD'a
;;;начало формирования загружаемой функции
;;;для примера функция меняет содержимое всех текстов на переданное значение
  (prin1
    (list 'defun
          'booster
          '(/ consteststring sstext lengthsstext dxfcurent)
          (list 'setq 'consteststring (apply 'quote (list (cons 1 teststring))))
          (quote
            (and (setq sstext (ssget "_X" '((0 . "TEXT"))))
                 (repeat (setq lengthsstext (sslength sstext))
                   (vl-catch-all-apply
                     'entmod
                     (list
                       (subst consteststring
                              (assoc 1 (setq dxfcurent (entget (ssname sstext (setq lengthsstext (1- lengthsstext))))))
                              dxfcurent
                              ) ;_ end of subst
                       ) ;_ end of list
                     ) ;_ end of vl-catch-all-apply
                   ) ;_ end of repeat
                 (setq sstext nil)
                 ) ;_ end of and
            ) ;_ end of quote
          ) ;_ end of list
    (setq lspfiledsc (open lspfilename "w"))
    )     ;записывает сформированную функцию в загружаемый lsp-файл
  (princ '(booster) lspfiledsc) ;и ее имя
  (close lspfiledsc) ;закрывает дескриптор загружаемого lsp-файла
;;;конец формирования загружаемой функции
  (setq documentscollection (vla-get-documents (vlax-get-acad-object)))
;;;открытие в цикле всех файлов, переданных по именам
  (repeat (length listdwgname)
    (if (not
          (vl-catch-all-error-p
            (setq applyresultorerror
                   (vl-catch-all-apply
                     'vla-open
                     (list documentscollection
                           (setq dwgfullname (strcat dwgpath (car listdwgname)))
                           :vlax-false
                           ) ;_ end of list
                     ) ;_ end of vl-catch-all-apply
                  ) ;_ end of setq
            ) ;_ end of vl-catch-all-error-p
          ) ;пытаемся открыть очередной файл
          ;если успешно, то
      (apply
        'or
        (append
          (mapcar
            (function
              (lambda (functionname functionparameter / applyerror)
                (and (vl-catch-all-error-p (setq applyerror (vl-catch-all-apply functionname functionparameter)))
          ;применяем сохранение, закрытие, освобождение, проверяем успешность
                     (princ
                       (strcat "\nThe file " dwgfullname " isn't processed. " (vl-catch-all-error-message applyerror))
                       ) ;_ end of princ
                     ) ;_ end of and
                ) ;_ end of lambda
              ) ;выводим ошибки применения
            '(vla-saveas vla-close vlax-release-object) ;список применяемых функций
            (list (list applyresultorerror dwgfullname)
                  (list applyresultorerror :vlax-false)
                  (list applyresultorerror)
                  ) ;_ end of list
            ) ;список их параметров
          (list (princ (strcat "\nProcessing of the file " dwgfullname " is complete.")))
          ) ;_ end of append
        ) ;выводим сообщение об успешном завершении
          ;если безуспешно открытие файла, то выводим ошибку
      (prompt
        (strcat "\nThe file " dwgfullname " isn't processed. " (vl-catch-all-error-message applyerror))
        ) ;_ end of prompt
      ) ;_ end of if
    (setq listdwgname (cdr listdwgname))
    ) ;_ end of repeat
  (vlax-release-object documentscollection) ;освобождаем коллекцию документов
  (gc)
  (mapcar 'setvar (car lstsysvar) (caddr lstsysvar)) ;восстанавливаем значение системных переменных
  (or (vl-file-delete lspfilename)
      (princ (strcat "\nThe file " lspfilename " isn't remote, make it manually."))
      ) ;_ end of or
  )       ;удаляем загружаемый файл или оповещаем
;;;команда находит все чертежи в папке с чертежом, за исключением чертежа, из которого вызвана, вызывает функцию, формирующую загружаемый файл и открывающую все чертежи в этой папке
(defun c:manipulatefile (/ dwgpath listdwgfile teststring)
  (if (setq listdwgfile (vl-remove (getvar 'dwgname) (vl-directory-files (setq dwgpath (getvar 'dwgprefix)) "*.dwg" 1)))
    (aiku_createbooster
      dwgpath ;папка с файлами
      listdwgfile ;список dwg в папке
      (if (zerop (ascii (setq teststring (getstring "\nInput test string <test string...>: " t))))
        "test string..."
        teststring
        ) ;_ end of if
      )   ;текстовая строка для замены
    (princ (strcat "\nIn the folder " dwgpath " of dwg-files it isn't found..."))
    ) ;_ end of if
  (princ)
  ) ;_ end of defun
(c:manipulatefile)

Все комментарии - Кирилла. Возможно, удастся этот код "присобачить" каким-то образом и к консольному AutoCAD,- не знаю. К сожалению, очень мало времени на проведение экспериментов :(



Комментарии

Есть 1 комментарий к “Один из вариантов выполнения lisp при открытии файла.”
  1. Александр Казимиров пишет:

    Здравствуйте.
    Огромное спасибо Вам и Кириллу за предоставленный здесь код.
    Изучив этот код мне удалось написать одну очень важную для наших инженеров утилиту.
    Еще раз спасибо.

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


Я не робот.