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

28/04/2016

Подсчет количества объектов словарей

На форуме возник вопрос - как можно быстро посчитать количество объектов AcDgnLS?

Данные об этих элементах хранятся в словаре acad_dgnlinestylecomp. Если мы обрабатываем только текущий документ, то получить указатель на словарь можно и через (namedobjdict). Но обрабатывать только текущий документ, да еще и получать количество записей в этом словаре через ename-представление как-то не очень хочется (прежде всего потому, что это очень медленно). Поэтому воспользуемся ActiveX:

Код - Auto/Visual LISP: [Выделить]
  1. (vl-load-com)
  2.  
  3. (defun checkdgn (doc value / dict)
  4.   (if (not doc)
  5.     (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  6.     ) ;_ end of if
  7.   (if (not value)
  8.     (setq value 100)
  9.     ) ;_ end of if
  10.   (if (and (= (type (setq dict (vl-catch-all-apply
  11.                                  (function (lambda () (vla-item (vla-get-dictionaries doc) "acad_dgnlinestylecomp")))
  12.                                  ) ;_ end of vl-catch-all-apply
  13.                           ) ;_ end of setq
  14.                     ) ;_ end of type
  15.               'vla-object
  16.               ) ;_ end of =
  17.            (> (vla-get-count dict) value)
  18.            ) ;_ end of and
  19.     (alert
  20.       (strcat "Обнаружен словарь DGN, количество записей " (vl-princ-to-string (vla-get-count dict)))
  21.       ) ;_ end of alert
  22.     ) ;_ end of if
  23.   (princ)
  24.   ) ;_ end of defun

Здесь doc - указатель на обрабатываемый документ. Если параметр равен nil, то функция выполняется для текущего документа. value - максимально допустимое значение, при котором AutoCAD еще не выводит никакого сообщения.

Примеры вызова:

Код - Auto/Visual LISP: [Выделить]
  1. (checkdgn nil nil) ; проверка текущего документа, сообщение выводится, если записей больше 100
  2. (checkdgn nil 2000) ; проверка текущего документа, сообщение выводится, если записей больше 2000

Этот код можно расширить, заставив обрабатывать вообще любой словарь:

Код - Auto/Visual LISP: [Выделить]
  1. (vl-load-com)
  2.  
  3. (defun check-dict (doc name / dict)
  4.   ;; doc - Документ (nil - текущий)
  5.   ;; name - имя словаря
  6.   (if (and name
  7.            (= (type (setq dict (vl-catch-all-apply
  8.                                  (function (lambda ()
  9.                                              (vla-item (vla-get-dictionaries
  10.                                                          (cond (doc)
  11.                                                                (t (vla-get-activedocument (vlax-get-acad-object)))
  12.                                                                ) ;_ end of cond
  13.                                                          ) ;_ end of vla-get-Dictionaries
  14.                                                        name
  15.                                                        ) ;_ end of vla-item
  16.                                              ) ;_ end of lambda
  17.                                            ) ;_ end of function
  18.                                  ) ;_ end of vl-catch-all-apply
  19.                           ) ;_ end of setq
  20.                     ) ;_ end of type
  21.               'vla-object
  22.               ) ;_ end of =
  23.            (vlax-property-available-p dict 'count)
  24.            ) ;_ end of and
  25.     (vla-get-count dict)
  26.     ) ;_ end of if
  27.   ) ;_ end of defun

Пример использования будет уже напоминать нечто:

Код - Auto/Visual LISP: [Выделить]
  1. (if (> (check-dict2 nil "ACAD_SCALELIST") 100) (alert "масштабы"))

А можно обработать вообще все словари, у которых есть понятие имени и количества записей (именно так! Некоторые словари могут иметь имя, но при попытке получить у них свойство Count выдается ошибка):

Код - Auto/Visual LISP: [Выделить]
  1. (vl-load-com)
  2.  
  3. (defun check-dict (doc)
  4.   (mapcar (function (lambda (x)
  5.                       (cons (vla-get-name x)
  6.                             (if (vlax-property-available-p x 'count)
  7.                               (vla-get-count x)
  8.                               -1
  9.                               ) ;_ end of if
  10.                             ) ;_ end of cons
  11.                       ) ;_ end of lambda
  12.                     ) ;_ end of function
  13.           (vl-remove-if-not
  14.             (function (lambda (x) (vlax-property-available-p x 'name)))
  15.             ((lambda (/ lst)
  16.                (vlax-for item (vla-get-dictionaries
  17.                                 (cond (doc)
  18.                                       (t (vla-get-activedocument (vlax-get-acad-object)))
  19.                                       ) ;_ end of cond
  20.                                 ) ;_ end of vla-get-dictionaries
  21.                  (setq lst (cons item lst))
  22.                  ) ;_ end of vlax-for
  23.                lst
  24.                ) ;_ end of lambda
  25.              )
  26.             ) ;_ end of vl-remove-if-not
  27.           ) ;_ end of mapcar
  28.   ) ;_ end of defun

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

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

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