ADN Open CIS
Сообщество программистов Autodesk в СНГ

26/08/2015

Очистка словарных записей в файле dwg

Очистка словарей в старых версиях AutoCAD

Достаточно давно на работе я столкнулся с необходимостью очистки файла dwg от словарных записей. Основная работа выполняется в AutoCAD2009x64, и, казалось бы, ничего сложного быть не должно.

Действительно, есть перечень словарей, которые создаются дополнительными модулями, используемыми в конторе; есть ACAD_* словари. А остальные можно пробовать посносить:

Код - Auto/Visual LISP: [Выделить]
  1. (vl-load-com)
  2.  
  3. (vlax-for item (vla-get-dictionaries (vla-get-activedocument (vlax-get-acad-object)))
  4.   (if (or (not (vlax-property-available-p item 'name))
  5.           (not (wcmatch (strcase (vla-get-name item)) "ACAD_*,JOBDICT_*"))
  6.           ) ;_ end of or
  7.     (vl-catch-all-apply
  8.       (function
  9.         (lambda () (vla-delete item))
  10.         ) ;_ end of function
  11.       ) ;_ end of vl-catch-all-apply
  12.     ) ;_ end of if
  13.   ) ;_ end of vlax-for

И эта конструкция прекрасно работала,- до тех пор, пока пользователи не сменили через IMAGEFRAME отображение рамки растровых объектов. Подчеркиваю - работа ведется в AutoCAD2009, где системных переменных FRAME, IMAGEFRAME и т.п. еще не существовало. Эти значения в таких старых версиях AutoCAD хранятся в определенном словаре, который (внимание!) не имеет имени! Следовательно, код надо переделывать (именно для версии 2009):

Код - Auto/Visual LISP: [Выделить]
  1. (vl-load-com)
  2.  
  3. (defun _kpblc-get-ent-name (ent)
  4.   (cond
  5.     ((vlax-property-available-p ent 'effectivename)
  6.      (vla-get-effectivename ent)
  7.      )
  8.     ((vlax-property-available-p ent 'name)
  9.      (vla-get-name ent)
  10.      )
  11.     ) ;_ end of cond
  12.   ) ;_ end of defun
  13.  
  14. (vlax-for item (vla-get-dictionaries (vla-get-activedocument (vlax-get-acad-object)))
  15.   (if (not (or (and (not (_kpblc-get-ent-name item))
  16.                     (= (cdr (assoc 0 (entget (vlax-vla-object->ename item)))) "RASTERVARIABLES")
  17.                     ) ;_ end of and
  18.                (and (_kpblc-get-ent-name item)
  19.                     (wcmatch (strcase (_kpblc-get-ent-name item)) "ACAD_*,JOBDICT_*")
  20.                     ) ;_ end of and
  21.                ) ;_ end of or
  22.            ) ;_ end of not
  23.     (vl-catch-all-apply
  24.       (function
  25.         (lambda ()
  26.           (vla-delete item)
  27.           ) ;_ end of lambda
  28.         ) ;_ end of function
  29.       ) ;_ end of vl-catch-all-apply
  30.     ) ;_ end of if
  31.   ) ;_ end of vlax-for

Код можно универсализировать, добавив обработку системных переменных *FRAME - к примеру, следующим образом:

Код - Auto/Visual LISP: [Выделить]
  1. (vl-load-com)
  2.  
  3. (defun _kpblc-get-ent-name (ent)
  4.   (cond
  5.     ((vlax-property-available-p ent 'effectivename)
  6.      (vla-get-effectivename ent)
  7.      )
  8.     ((vlax-property-available-p ent 'name)
  9.      (vla-get-name ent)
  10.      )
  11.     ) ;_ end of cond
  12.   ) ;_ end of defun
  13.  
  14. (setq sysvar (vl-remove-if-not
  15.                (function cdr)
  16.                (mapcar
  17.                  (function
  18.                    (lambda (x)
  19.                      (cons x (getvar x))
  20.                      ) ;_ end of lambda
  21.                    ) ;_ end of function
  22.                  '("frame" "imageframe" "pdfframe" "dwfframe" "dgnframe" "oleframe")
  23.                  ) ;_ end of mapcar
  24.                ) ;_ end of vl-remove-if-not
  25.       ) ;_ end of setq
  26.  
  27.  
  28. (vlax-for item (vla-get-dictionaries (vla-get-activedocument (vlax-get-acad-object)))
  29.   (if (not (or (and (not (_kpblc-get-ent-name item))
  30.                     (= (cdr (assoc 0 (entget (vlax-vla-object->ename item)))) "RASTERVARIABLES")
  31.                     ) ;_ end of and
  32.                (and (_kpblc-get-ent-name item)
  33.                     (wcmatch (strcase (_kpblc-get-ent-name item)) "ACAD_*,JOBDICT_*")
  34.                     ) ;_ end of and
  35.                ) ;_ end of or
  36.            ) ;_ end of not
  37.     (vl-catch-all-apply
  38.       (function
  39.         (lambda ()
  40.           (vla-delete item)
  41.           ) ;_ end of lambda
  42.         ) ;_ end of function
  43.       ) ;_ end of vl-catch-all-apply
  44.     ) ;_ end of if
  45.   ) ;_ end of vlax-for
  46.  
  47. (foreach item sysvar
  48.   (setvar (car item) (cdr item))
  49.   ) ;_ end of foreach

Самое главное - выполнять контроль результатов очистки файла от мусора: некорректность результата может сказаться в любой, самый неподходящий момент. И в самом неожиданном месте :)

Автор: Алексей Кулик

Обсуждение: http://adn-cis.org/forum/index.php?topic=2946

Опубликовано 26.08.2015