Немного об очистке словарных записей в файле dwg
Очистка словарей в старых версиях AutoCAD
Достаточно давно на работе я столкнулся с необходимостью очистки файла dwg от словарных записей. Основная работа выполняется в AutoCAD2009x64, и, казалось бы, ничего сложного быть не должно.
Действительно, есть перечень словарей, которые создаются дополнительными модулями, используемыми в конторе; есть ACAD_* словари. А остальные можно пробовать посносить:
1 2 3 4 5 6 7 8 9 10 11 12 13 | (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):
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 | (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 - к примеру, следующим образом:
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 | (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 |
Самое главное - выполнять контроль результатов очистки файла от мусора: некорректность результата может сказаться в любой, самый неподходящий момент. И в самом неожиданном месте