Подсчет количества объектов словарей
На форуме возник вопрос - как можно быстро посчитать количество объектов AcDgnLS?
Данные об этих элементах хранятся в словаре acad_dgnlinestylecomp. Если мы обрабатываем только текущий документ, то получить указатель на словарь можно и через (namedobjdict). Но обрабатывать только текущий документ, да еще и получать количество записей в этом словаре через ename-представление как-то не очень хочется (прежде всего потому, что это очень медленно). Поэтому воспользуемся ActiveX:
- (vl-load-com)
- (defun checkdgn (doc value / dict)
- (if (not doc)
- (setq doc (vla-get-activedocument (vlax-get-acad-object)))
- ) ;_ end of if
- (if (not value)
- (setq value 100)
- ) ;_ end of if
- (if (and (= (type (setq dict (vl-catch-all-apply
- (function (lambda () (vla-item (vla-get-dictionaries doc) "acad_dgnlinestylecomp")))
- ) ;_ end of vl-catch-all-apply
- ) ;_ end of setq
- ) ;_ end of type
- 'vla-object
- ) ;_ end of =
- (> (vla-get-count dict) value)
- ) ;_ end of and
- (alert
- (strcat "Обнаружен словарь DGN, количество записей " (vl-princ-to-string (vla-get-count dict)))
- ) ;_ end of alert
- ) ;_ end of if
- (princ)
- ) ;_ end of defun
Здесь doc - указатель на обрабатываемый документ. Если параметр равен nil, то функция выполняется для текущего документа. value - максимально допустимое значение, при котором AutoCAD еще не выводит никакого сообщения.
Примеры вызова:
- (checkdgn nil nil) ; проверка текущего документа, сообщение выводится, если записей больше 100
- (checkdgn nil 2000) ; проверка текущего документа, сообщение выводится, если записей больше 2000
Этот код можно расширить, заставив обрабатывать вообще любой словарь:
- (vl-load-com)
- (defun check-dict (doc name / dict)
- ;; doc - Документ (nil - текущий)
- ;; name - имя словаря
- (if (and name
- (= (type (setq dict (vl-catch-all-apply
- (function (lambda ()
- (vla-item (vla-get-dictionaries
- (cond (doc)
- (t (vla-get-activedocument (vlax-get-acad-object)))
- ) ;_ end of cond
- ) ;_ end of vla-get-Dictionaries
- name
- ) ;_ end of vla-item
- ) ;_ end of lambda
- ) ;_ end of function
- ) ;_ end of vl-catch-all-apply
- ) ;_ end of setq
- ) ;_ end of type
- 'vla-object
- ) ;_ end of =
- (vlax-property-available-p dict 'count)
- ) ;_ end of and
- (vla-get-count dict)
- ) ;_ end of if
- ) ;_ end of defun
Пример использования будет уже напоминать нечто:
- (if (> (check-dict2 nil "ACAD_SCALELIST") 100) (alert "масштабы"))
А можно обработать вообще все словари, у которых есть понятие имени и количества записей (именно так! Некоторые словари могут иметь имя, но при попытке получить у них свойство Count выдается ошибка):
- (vl-load-com)
- (defun check-dict (doc)
- (mapcar (function (lambda (x)
- (cons (vla-get-name x)
- (if (vlax-property-available-p x 'count)
- (vla-get-count x)
- -1
- ) ;_ end of if
- ) ;_ end of cons
- ) ;_ end of lambda
- ) ;_ end of function
- (vl-remove-if-not
- (function (lambda (x) (vlax-property-available-p x 'name)))
- ((lambda (/ lst)
- (vlax-for item (vla-get-dictionaries
- (cond (doc)
- (t (vla-get-activedocument (vlax-get-acad-object)))
- ) ;_ end of cond
- ) ;_ end of vla-get-dictionaries
- (setq lst (cons item lst))
- ) ;_ end of vlax-for
- lst
- ) ;_ end of lambda
- )
- ) ;_ end of vl-remove-if-not
- ) ;_ end of mapcar
- ) ;_ end of defun
Автор: Алексей Кулик
Обсуждение: http://adn-cis.org/forum/index.php?topic=
Опубликовано 28.04.2016