Очистка словарных записей в файле dwg
Очистка словарей в старых версиях AutoCAD
Достаточно давно на работе я столкнулся с необходимостью очистки файла dwg от словарных записей. Основная работа выполняется в AutoCAD2009x64, и, казалось бы, ничего сложного быть не должно.
Действительно, есть перечень словарей, которые создаются дополнительными модулями, используемыми в конторе; есть ACAD_* словари. А остальные можно пробовать посносить:
- (vl-load-com)
- (vlax-for item (vla-get-dictionaries (vla-get-activedocument (vlax-get-acad-object)))
- (if (or (not (vlax-property-available-p item 'name))
- (not (wcmatch (strcase (vla-get-name item)) "ACAD_*,JOBDICT_*"))
- ) ;_ end of or
- (vl-catch-all-apply
- (function
- (lambda () (vla-delete item))
- ) ;_ end of function
- ) ;_ end of vl-catch-all-apply
- ) ;_ end of if
- ) ;_ end of vlax-for
И эта конструкция прекрасно работала,- до тех пор, пока пользователи не сменили через IMAGEFRAME отображение рамки растровых объектов. Подчеркиваю - работа ведется в AutoCAD2009, где системных переменных FRAME, IMAGEFRAME и т.п. еще не существовало. Эти значения в таких старых версиях AutoCAD хранятся в определенном словаре, который (внимание!) не имеет имени! Следовательно, код надо переделывать (именно для версии 2009):
- (vl-load-com)
- (defun _kpblc-get-ent-name (ent)
- (cond
- ((vlax-property-available-p ent 'effectivename)
- (vla-get-effectivename ent)
- )
- ((vlax-property-available-p ent 'name)
- (vla-get-name ent)
- )
- ) ;_ end of cond
- ) ;_ end of defun
- (vlax-for item (vla-get-dictionaries (vla-get-activedocument (vlax-get-acad-object)))
- (if (not (or (and (not (_kpblc-get-ent-name item))
- (= (cdr (assoc 0 (entget (vlax-vla-object->ename item)))) "RASTERVARIABLES")
- ) ;_ end of and
- (and (_kpblc-get-ent-name item)
- (wcmatch (strcase (_kpblc-get-ent-name item)) "ACAD_*,JOBDICT_*")
- ) ;_ end of and
- ) ;_ end of or
- ) ;_ end of not
- (vl-catch-all-apply
- (function
- (lambda ()
- (vla-delete item)
- ) ;_ end of lambda
- ) ;_ end of function
- ) ;_ end of vl-catch-all-apply
- ) ;_ end of if
- ) ;_ end of vlax-for
Код можно универсализировать, добавив обработку системных переменных *FRAME - к примеру, следующим образом:
- (vl-load-com)
- (defun _kpblc-get-ent-name (ent)
- (cond
- ((vlax-property-available-p ent 'effectivename)
- (vla-get-effectivename ent)
- )
- ((vlax-property-available-p ent 'name)
- (vla-get-name ent)
- )
- ) ;_ end of cond
- ) ;_ end of defun
- (setq sysvar (vl-remove-if-not
- (function cdr)
- (mapcar
- (function
- (lambda (x)
- (cons x (getvar x))
- ) ;_ end of lambda
- ) ;_ end of function
- '("frame" "imageframe" "pdfframe" "dwfframe" "dgnframe" "oleframe")
- ) ;_ end of mapcar
- ) ;_ end of vl-remove-if-not
- ) ;_ end of setq
- (vlax-for item (vla-get-dictionaries (vla-get-activedocument (vlax-get-acad-object)))
- (if (not (or (and (not (_kpblc-get-ent-name item))
- (= (cdr (assoc 0 (entget (vlax-vla-object->ename item)))) "RASTERVARIABLES")
- ) ;_ end of and
- (and (_kpblc-get-ent-name item)
- (wcmatch (strcase (_kpblc-get-ent-name item)) "ACAD_*,JOBDICT_*")
- ) ;_ end of and
- ) ;_ end of or
- ) ;_ end of not
- (vl-catch-all-apply
- (function
- (lambda ()
- (vla-delete item)
- ) ;_ end of lambda
- ) ;_ end of function
- ) ;_ end of vl-catch-all-apply
- ) ;_ end of if
- ) ;_ end of vlax-for
- (foreach item sysvar
- (setvar (car item) (cdr item))
- ) ;_ end of foreach
Самое главное - выполнять контроль результатов очистки файла от мусора: некорректность результата может сказаться в любой, самый неподходящий момент. И в самом неожиданном месте :)
Автор: Алексей Кулик
Обсуждение: http://adn-cis.org/forum/index.php?topic=2946
Опубликовано 26.08.2015