Немного об очистке словарных записей в файле 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

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



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


Я не робот.