Ну ок, есть у нас какой-то указатель на примитив. Скорее всего, понадобится нам и его ename-, и vla-указатель.
1 2 3 4 5 6 7 8 9 10 11
| (defun _kpblc-is-ent-assoc-array(ent)
;|
* Определяет, является ли переданный примитив указателем на ассоциативный список
* Параметры вызова:
ent ; указатель (ename- или vla-) на обрабатываемый примитив
* Возвращает t, если примитив является ассоциативным массивом
* Примеры вызова:
(_kpblc-is-ent-assoc-array (car (entsel "\nSelect entity : ")))
(_kpblc-is-ent-assoc-array (vlax-ename->vla-object (car (entsel "\nSelect entity : "))))
|;
) |
Первое – приводим ent к хоть какому-то виду. Ну, например, ename. Код элементарен, отдельно его показывать не буду.
Второе, что надо сообразить – что с точки зрения лиспа ассоциативный массив не больше чем блок. Анонимный блок. Следовательно, проверяем – является ли примитив а) блоком; б) анонимным блоком; в) не является вхождением динамического блока (ведь известно, что вхождения дин.блоков практически всегда являются анонимными блоками):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| (defun _kpblc-is-ent-assoc-array (ent / name vla_ename)
;|
* Определяет, является ли переданный примитив указателем на ассоциативный список
* Параметры вызова:
ent ; указатель (ename- или vla-) на обрабатываемый примитив
* Возвращает t, если примитив является ассоциативным массивом
* Примеры вызова:
(_kpblc-is-ent-assoc-array (car (entsel "\nSelect entity : ")))
(_kpblc-is-ent-assoc-array (vlax-ename->vla-object (car (entsel "\nSelect entity : "))))
|;
(and (setq ent (cond ((= (type ent) 'ename) ent)
((= (type ent) 'vla-object) (vlax-vla-object->ename ent))
) ;_ end of cond
) ;_ end of setq
(= (cdr (assoc 0 (entget ent))) "INSERT")
(setq vla_ename (vlax-ename->vla-object ent))
(setq name (if (vlax-property-available-p vla_ename 'effectivename)
(vla-get-effectivename vla_ename)
(vla-get-name vla_ename)
) ;_ end of if
) ;_ end of setq
(wcmatch name "'**" ;; Здесь вместо ' надо ставить обратный апостроф
) ;_ end of and
) ;_ end of defun |
И вот тут начинается самое интересное. С точки зрения вхождения блока различить – простой это анонимный блок или ассоциативный массив – невозможно. Ни через ename, ни через vla. Кто не верит – проверьте, у меня на AutoCAD 2019 и 2020 разницы не было никакой.
Но как-то их ACAD же различает, верно?!
Значит, ползем в сторону описаний блоков – вдруг там что-то есть?
Тут для упрощения кода сделаю предположение, что работа выполняется только в текущем документе. Для нетекущего просто придется делать дополнительные преобразования, которые особого влияния на общую картину не окажут.
Если выполнить строки
1 2
| (setq def (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) name))
(vlax-dump-object def t) |
то разницы с обычным блоком будет ноль.
Ну хорошо, ACAD, не хочешь по плохому, по хорошему будет еще хуже:
1 2
| (setq def (vlax-vla-object->ename (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) name)))
(entget def '("*")) |
И вот тут обнаруживаются забавные вещи:
Это что за группа ‘(102 . “{ACAD_REACTORS”) ? Ну-ка, ну-ка…
1
| (entget (cdr (assoc 330 (member '(102 . "{ACAD_REACTORS") (entget def))))) |
Ух ты! Вспоминаем начальный уровень английского и внимательно смотрим либо на 0, либо на 100 группу: Бла-бла-ASSOCDEPENDENCY, то бишь ассоциативные зависимости. Может, достаточно просто проверять наличие подобных реакторов и, если они есть – то примитив у нас ассоциативный массив?
Несколько десятков проверок так и показали. Следовательно, конечный код будет…