ssget и vla-get-ActiveSelectionSet
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > ssget и vla-get-ActiveSelectionSet

ssget и vla-get-ActiveSelectionSet

Ответ
Поиск в этой теме
Непрочитано 03.03.2006, 17:01 #1
ssget и vla-get-ActiveSelectionSet
Apelsinov
 
Проектировщик ВК. LISP-любитель.
 
Москва
Регистрация: 15.12.2003
Сообщений: 1,202

В некоторых программах на лиспе публикуемых в т.ч. на этом форуме (см.например у Fatty
,Лентяя и т.п.) используется следующий оборот для получения обекта текущего выбора:

Код:
[Выделить все]
...
(SSGET)
(setq ass (vla-get-ActiveSelectionSet
     (vla-get-ActiveDocument (vlax-get-acad-object))
   )
)
...
Оно удобно.Но порой такая конструкция приводит к ошибке при повторной попытке доступа:
Код:
[Выделить все]
Automation Error. Calling method Clear of interface
После которой помогает только перезагрузка файла.
Мне не удается зафиксировать условия для появления этой ошибки.

Откуда это? Зачем? Отчего оно появляется, и как этого можно избежать?
(некоторое время назад многоуважаемый г-н Alaspher выразился в том смысле, что вообще затея с подобным оборотом чревата нехорошими последствиями, в плане того, что нефиг смешивать мух с котлетами)

Вопрос практический, хотелось бы иметь аналог ssget, но дающий на выходе LA-OBJECT IAcadSelectionSet а не набор.
Просмотров: 10805
 
Непрочитано 03.03.2006, 18:02
#2
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,439
Отправить сообщение для Елпанов Евгений с помощью Skype™


Наверное тебе нужно, что то типа:
Код:
[Выделить все]
(if (setq sset (ssget))
  (progn
    (setq lst      (mapcar (function vlax-ename->vla-object)
                           (vl-remove-if
                             (function listp)
                             (mapcar (function cadr) (ssnamex sset))
                           ) ;_  vl-remove-if
                   ) ;_  mapcar
          vla_Sets (vla-Add (vla-get-SelectionSets (vla-get-ActiveDocument (vlax-get-acad-object)))
                            "1"
                   ) ;_  vla-Add
    ) ;_  mapcar
    (vla-Additems
      vla_Sets
      (vlax-safearray-fill (vlax-make-safearray '9 (cons 0 (1- (length lst)))) lst)
    ) ;_  setq
  ) ;_  progn
)
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 03.03.2006, 18:41
#3
Apelsinov

Проектировщик ВК. LISP-любитель.
 
Регистрация: 15.12.2003
Москва
Сообщений: 1,202
<phrase 1=


Елпанов Евгений
это конечно все хорошо, и делает то что надо, должно делать. Но нужно мне не это, это костыль через vlax-ename->vla-object, а хотелось бы с ename вообще не работать.
Самое лучшее - вообще написать через vlax методы свой аналог ssget , но лень. потому как кажется мне что это не просто. Да и есть же способ выше, но , к сожалению такие ошибочки дает.
Apelsinov вне форума  
 
Непрочитано 03.03.2006, 19:11
#4
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,439
Отправить сообщение для Елпанов Евгений с помощью Skype™


Да, код работает и прямого пути через ВЛА нет...
Хорошо, если я ошибаюсь
Елпанов Евгений вне форума  
 
Непрочитано 03.03.2006, 20:53
#5
Лентяй

Project Engineer
 
Регистрация: 05.01.2005
Лос Анджелес
Сообщений: 1,392


Цитата:
Сообщение от Елпанов Евгений
Да, код работает и прямого пути через ВЛА нет...
Хорошо, если я ошибаюсь
Вы таки да - ошибаетесь, ибо "у нас есть фсо" (ЛИБ)
ssget->vla-get-ActiveSelectionSet - это просто болезни роста. Идеологически верно - и я последнее время только так и делаю - использовать вот такую последовательность:
Обретатем ass
Код:
[Выделить все]
(setq adoc (vla-get-ActiveDocument (vlax-get-acad-object))
              ass (vla-get ActiveSelectionset))
Очишаем его от старой грязи:
Код:
[Выделить все]
(if (> (vla-get-count ass) 0) (vla-clear ass))
И заполняем новой:
Код:
[Выделить все]
(vla-SelectOnScreen ass)
Если надо, применяем фильтр, например, такойб чтобы выбирать только эллипсы:
Код:
[Выделить все]
(vla-SelectOnScreen ass (vlax-safearray-fill (vlax-make-safearray vlax-vbinteger '(0 . 0)) '(0))
    (vlax-safearray-fill (vlax-make-safearray vlax-vbvariant '(0 . 0)) '("*Ellipse")))
Далее используем ass по своему усмотрению (гусары, молчать!)
Код:
[Выделить все]
(vlax-for obj ass (...))
Лентяй вне форума  
 
Непрочитано 03.03.2006, 21:30 Re: ssget и vla-get-ActiveSelectionSet
#6
Alaspher


 
Регистрация: 11.10.2004
e•burg
Сообщений: 755


Цитата:
Сообщение от Apelsinov
(некоторое время назад многоуважаемый г-н Alaspher выразился в том смысле, что вообще затея с подобным оборотом чревата нехорошими последствиями, в плане того, что нефиг смешивать мух с котлетами)
Угу, котлеты без мух лучче!

Цитата:
Сообщение от Apelsinov
Вопрос практический, хотелось бы иметь аналог ssget, но дающий на выходе LA-OBJECT IAcadSelectionSet а не набор.
В принципе, Лентяй почти всё показал уже. Но немного добавлю и откоментирую.

Цитата:
Сообщение от Лентяй
Обретатем ass
Код:
[Выделить все]
(setq adoc (vla-get-ActiveDocument (vlax-get-acad-object))
              ass (vla-get-ActiveSelectionset adoc))
Не вопрос, смысл такой, но опечатки вкрались.
Цитата:
Сообщение от Лентяй
Очишаем его от старой грязи:
Код:
[Выделить все]
(if (> (vla-get-count ass) 0) (vla-clear ass))
Так нормально, но IF - лишний, чистка чистого - не вредит, а код проще. Кроме того, чистка может быть и не нужна, но это уже от задачи.

Дальше у Лентяя, в принципе всё верно, но я приведу свою функцию, которая, наряду со многим интересным будет опубликована в готовящейся к печати книге: "AutoLISP и Visual LISP в среде AutoCAD"

Функция plbj-filter-select-manual
Код:
[Выделить все]
;;; Помещает выбранные пользователем примитивы в набор, переданный
;;; в качестве первого аргумента. Возвращает nil.
;;; Формат вызова: (pl:obj-filter-select-manual <НАБОР> <ФИЛЬТР>)
;;;      где: <НАБОР>  - VLA-объект
;;;           <ФИЛЬТР> - список фильтров с синтаксисом функции ssget
;;; Пример: (setq sel (vla-get-ActiveSelectionSet
;;;          (vla-get-ActiveDocument (vlax-get-acad-object))))
;;;         (pl:obj-filter-select-manual sel '((8 . "*")))
(defun pl:obj-filter-select-manual (sel filter / i)
  (vla-SelectOnScreen
    sel
    (vlax-safearray-fill
      (vlax-make-safearray
        vlax-vbInteger
        (setq i (cons 1 (length filter)))
      )
      (mapcar (function car) filter)
    )
    (vlax-safearray-fill
      (vlax-make-safearray vlax-vbVariant i)
      (mapcar (function cdr) filter)
    )
  )
)
*Примечание! Функция plbj-filter-select-manual требует обязательной передачи фильтра, в качестве второго аргумента. В том случае, когда ограничений выбора пользователя быть не должно, можно применить такой фильтр, соответствующими которому ока-зываются все примитивы, например: '((8 . "*")).
Alaspher вне форума  
 
Непрочитано 04.03.2006, 00:54 Re: ssget и vla-get-ActiveSelectionSet
#7
fixo

Lisp/VBA/VB.NET Hobbyist
 
Регистрация: 24.03.2005
Славен Град Петров
Сообщений: 367


Цитата:
Сообщение от Apelsinov
В некоторых программах на лиспе публикуемых в т.ч. на этом форуме (см.например у Fatty
,Лентяя и т.п.) используется следующий оборот для получения обекта текущего выбора:

Код:
[Выделить все]
...
(SSGET)
(setq ass (vla-get-ActiveSelectionSet
     (vla-get-ActiveDocument (vlax-get-acad-object))
   )
)
...
Ни разу не было таких проблем, а по завершении хода
стараюсь не забывать:
Код:
[Выделить все]
(vla-clear axss)
(vla-delete axss)
(vlax-release-object axss)
~'J'~
fixo вне форума  
 
Непрочитано 06.03.2006, 09:51 Re: ssget и vla-get-ActiveSelectionSet
#8
Лентяй

Project Engineer
 
Регистрация: 05.01.2005
Лос Анджелес
Сообщений: 1,392


[quote="Fatty"]Ни разу не было таких проблем, а по завершении хода
стараюсь не забывать:
Код:
[Выделить все]
(vla-clear axss)
(vla-delete axss)
(vlax-release-object axss)
Пралльна! Настоящий гуру, как и все хорошие дети, всегда держти свой ass в чистоте
Лентяй вне форума  
 
Автор темы   Непрочитано 06.03.2006, 13:36
#9
Apelsinov

Проектировщик ВК. LISP-любитель.
 
Регистрация: 15.12.2003
Москва
Сообщений: 1,202
<phrase 1=


ВСЕМ больше спасибо! Узнал много нового
Но такой вопрос - может быть есть смысл вообще не спользовать ActiveSelectionSet , а создать свой SelectionSet и загонять туда выбранное, возвращая указатель на него?
Apelsinov вне форума  
 
Непрочитано 06.03.2006, 15:32
#10
Alaspher


 
Регистрация: 11.10.2004
e•burg
Сообщений: 755


Цитата:
Сообщение от Apelsinov
Но такой вопрос - может быть есть смысл вообще не спользовать ActiveSelectionSet , а создать свой SelectionSet и загонять туда выбранное, возвращая указатель на него?
Вариант ничем не хуже, а иногда и интереснее (особенно если надо держать несколько наборов).
Alaspher вне форума  
 
Автор темы   Непрочитано 07.03.2006, 17:12
#11
Apelsinov

Проектировщик ВК. LISP-любитель.
 
Регистрация: 15.12.2003
Москва
Сообщений: 1,202
<phrase 1=


Alaspher
Про plbj-filter-select-manual
Цитата:
Функция plbj-filter-select-manual требует обязательной передачи фильтра, в качестве второго аргумента
А что мешает сделать возможность вводить nil вместо фильтра?
какая-то странная функция, зачем возврат nil, и отлова ошибки нет...


Fatty

Про (vla-clear axss) понятно, но объясните - зачем надо:
Код:
[Выделить все]
(vla-delete axss) 
(vlax-release-object axss)
Apelsinov вне форума  
 
Непрочитано 07.03.2006, 17:36
#12
Alaspher


 
Регистрация: 11.10.2004
e•burg
Сообщений: 755


Цитата:
Сообщение от Apelsinov
А что мешает сделать возможность вводить nil вместо фильтра?
какая-то странная функция, зачем возврат nil, и отлова ошибки нет...
Функция низкого уровня, в них проверок минимум или нет вовсе. Здесь и в книге приведена, как предельно наглядная демонстрация работы механизма выбора через АктивИКС.
Alaspher вне форума  
 
Автор темы   Непрочитано 09.03.2006, 14:28
#13
Apelsinov

Проектировщик ВК. LISP-любитель.
 
Регистрация: 15.12.2003
Москва
Сообщений: 1,202
<phrase 1=


Еще один вопрос в тему:
Как можно применить фильтр стадартно заданный ассоциативным списком (как в ssget) или FilterType и FilterData (как в vla-select) к уже имеющемуся объекту SelectionSet, указатель на который получен свойством PickfirstSelectionSet ?
то бишь, хотелось бы сделать возможность предварительного выбора.
Apelsinov вне форума  
 
Непрочитано 11.03.2006, 00:32
#14
Лентяй

Project Engineer
 
Регистрация: 05.01.2005
Лос Анджелес
Сообщений: 1,392


Насколько я понял, фильтры работают одинаково, что для ass (ActiveSelectionSet), что для pfss (PickFirstSelectionSet).
Лентяй вне форума  
 
Непрочитано 13.03.2006, 08:40
#15
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,411


Для PickFirstSelectionSet (по крайней мере, в документации) нет фильтров.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 13.03.2006, 09:55
#16
Лентяй

Project Engineer
 
Регистрация: 05.01.2005
Лос Анджелес
Сообщений: 1,392


Цитата:
Сообщение от kpblc
Для PickFirstSelectionSet (по крайней мере, в документации) нет фильтров.
Все врут календари!(С) Я вот никаких документов не читамши попробовал - все получилось.
Лентяй вне форума  
 
Автор темы   Непрочитано 13.03.2006, 10:23
#17
Apelsinov

Проектировщик ВК. LISP-любитель.
 
Регистрация: 15.12.2003
Москва
Сообщений: 1,202
<phrase 1=


Лентяй
Нижайше прошу продемонстрировать как отфильтровать, а то я ужо начал выдумывать велосипеды с entget и прочими "прелестями".
Apelsinov вне форума  
 
Непрочитано 13.03.2006, 10:46
#18
Лентяй

Project Engineer
 
Регистрация: 05.01.2005
Лос Анджелес
Сообщений: 1,392


Ну, ты, кум, умеешь уговорить [sm312]!
Что за зверь такой, этот PickFirstSelectioSet, и чем он такой особенный - знать не знал и ведать не ведал, а потому решил обойтись с ним, как и со всяким другим SelectionSet. Накропал код,
Код:
[Выделить все]
(setq adoc (vla-get-ActiveDocument (vlax-get-Acad-object))
      pfss (vla-get-PickFirstSelectionSet adoc))
(vla-SelectOnScreen pfss (vlax-safearray-fill (vlax-make-safearray vlax-vbinteger '(0 . 0)) '(0)) 
    (vlax-safearray-fill (vlax-make-safearray vlax-vbvariant '(0 . 0)) (list "*Insert")))
(vlax-for elt pfss (print (vla-get-name elt)))
Запустил его в рисунке, содержащем блоки, мультитексты, полилинии и стрелки (Leaders), выбрал секрамкой кусок, содержащий фсо(С), причем "засветились", как и положено, только блоки, и получил такой результат:
Код:
[Выделить все]
#<VLA-OBJECT IAcadSelectionSet 09b33054> 
nil 
"SPN011" 
"SPN011" 
"SPN011"
Как видите - все работает
Лентяй вне форума  
 
Автор темы   Непрочитано 13.03.2006, 11:07
#19
Apelsinov

Проектировщик ВК. LISP-любитель.
 
Регистрация: 15.12.2003
Москва
Сообщений: 1,202
<phrase 1=


Лентяй
ФИГУЛИ!!! :cry:

Ты фильтр то применяешь собсно не к надобному vla-get-PickFirstSelectionSet (то бишь к обьектам в входящим в SS, кот. получен с помощью vla-get-PickFirstSelectionSet ), а к вновь добавляемым (а вернее заменяющим) объектам с помощью vla-SelectOnScreen.

то есть надо вот что: есть выделенные обьекты, получаем их SS через vla-get-PickFirstSelectionSet, а теперь, в этом SS надо оставить только те элементы, что соответстыуют фильтру.
Apelsinov вне форума  
 
Непрочитано 13.03.2006, 11:34
#20
Лентяй

Project Engineer
 
Регистрация: 05.01.2005
Лос Анджелес
Сообщений: 1,392


Не понимаю [sm2100], что функция vla-removeItems стала сильно секретной, что-ли? Захепачьте ее по условию, примено так:
Код:
[Выделить все]
(vlax-for elt pfss
  (if (= (vla-get-name elt) "SPN011"); или какое другое условие
    (vla-removeItems pfss
      (vlax-make-variant (vlax-safearray-fill
                       (vlax-make-safearray vlax-vbobject '(0 . 0)) (list elt))))))
и будет вам щасте (наверное).
Лентяй вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > ssget и vla-get-ActiveSelectionSet