Не могу разобраться с *error*
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Не могу разобраться с *error*

Не могу разобраться с *error*

Ответ
Поиск в этой теме
Непрочитано 19.09.2007, 12:13 #1
Не могу разобраться с *error*
Makswell
 
Инженер-строитель
 
Киров
Регистрация: 15.08.2007
Сообщений: 2,204

Никак не могу разобраться...
Я так понял функция *error* должна срабатывать при нажатии ESC. Но почему-то ,например, здесь:
Код:
[Выделить все]
(defun test (/ *error* pt1)
  (defun *error* (msg)
    (princ "\nбыла нажата ESC\n")
  )
  (setvar "cmdecho" 0)
  (princ "\nнажми ESC...")
  (vl-cmdf "_.line")
)
этого не просходит.
Хотя, например, здесь:
Код:
[Выделить все]
(defun test (/ *error* pt1)
  (defun *error* (msg)
    (princ "\nнажата ESC\n")
  )
    (setq pt1 (getpoint "\nУкажи точку или нажми ESC..."))
)
всё работает.
Т.е. получается *error* не срабатывает при прерывании команды автокада.
Вопрос: как контролировать нажатие ESC, если выполняется команда?

PS Если вопрос тупой, то заранее извиняюсь...
Просмотров: 6913
 
Непрочитано 19.09.2007, 12:21
#2
Кулик Алексей aka kpblc
Moderator

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


Функция *error* срабатывает при генерации ошибки, а не при прерывании выполнения стандартной команды AutoCAD'a.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 19.09.2007, 12:42
#3
Makswell

Инженер-строитель
 
Регистрация: 15.08.2007
Киров
Сообщений: 2,204


Так как же контролировать нажатие ESC, если выполняется команда?

Знаю, что это можно сделать через реакторы, но может есть решение попроще?

Может использовать проверку cmdactive?
Makswell вне форума  
 
Непрочитано 19.09.2007, 12:55
#4
Кулик Алексей aka kpblc
Moderator

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


Так а какая задача полностью? На http://www.arcada.com.ua/forum/viewtopic.php?t=1088 было немного обсуждения по поводу программного завершения команд.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 19.09.2007, 13:09
#5
Alaspher


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


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

Например, если прервать такие конструкции - ошибка будет:
Код:
[Выделить все]
(defun test (/ *error* pt1)
    (defun *error* (msg) (princ "\nбыла нажата ESC\n"))
    (setvar "cmdecho" 0)
    (princ "\nнажми ESC...")
    (vl-cmdf "_.line" (getpoint) (getpoint) (getpoint) "")
)

(defun test (/ *error* pt1)
    (defun *error* (msg) (princ "\nбыла нажата ESC\n"))
    (setvar "cmdecho" 0)
    (princ "\nнажми ESC...")
    (vl-cmdf "_.line")
    (while (not (zerop (getvar "cmdactive"))) (command pause))
)
А вот так не будет:
Код:
[Выделить все]
(defun test (/ *error* pt1)
    (defun *error* (msg) (princ "\nбыла нажата ESC\n"))
    (setvar "cmdecho" 0)
    (princ "\nнажми ESC...")
    (vl-cmdf "_.line")
    (while (not (zerop (getvar "cmdactive"))) (vl-cmdf pause))
)

(defun test (/ *error* pt1)
    (defun *error* (msg) (princ "\nбыла нажата ESC\n"))
    (setvar "cmdecho" 0)
    (princ "\nнажми ESC...")
    (command "_.line")
)
В первом случае, потому что vl-cmdf может штатно прерываться ESC'ом, а во втором потому, что собственно выполнение автолисп функции (test) уже закончено в момент работы команды line.
Alaspher вне форума  
 
Автор темы   Непрочитано 19.09.2007, 16:02
#6
Makswell

Инженер-строитель
 
Регистрация: 15.08.2007
Киров
Сообщений: 2,204


Разобрался. Или думаю, что разобрался...
Просто не было должного понимания работы *error*. У Полещука целая страница про это написана, но сколько не перечитывал - нихрена не понял, а здесь всё разжевали в двух строках. Спасибо всем!

Насчет конкретной задачи.
Был макрос - поворот с копированием:
Код:
[Выделить все]
^C^C(defun c:M-Command () (ssget) (vl-cmdf "_.copy" "_pr" "" pause "@" "_.rotate" "_pr" "" "@" ));M-Command;
Здесь набор сначала копировался сам на себя, а потом поворачивался. Так вот, я вдруг заметил, что если вместо того, чтобы ввести угол, юзер вдруг нажимал ESC, то поворота не происходило, а копия набора оставалась и объекты нещадно множились, причем незаметно для юзера. Этот макрос оказался не просто плохим, но даже очень вредным!

С учетом вышеприведенных советов вместо макроса получился уже лисп, в котором все это дело отлавливается:
Код:
[Выделить все]
(defun C:M_CopyRotate (/ *error*)
  (defun *error* (msg)
    (vl-cmdf "_.undo" "_e")
    (vl-cmdf "_.undo" 1)
    (princ "\nВыполнение программы прервано пользователем!")
  )
  (setvar "cmdecho" 0)
  (vl-cmdf "_.undo" "_be")
  (ssget)
  (vl-cmdf "_.copy" "_pr" "" (getpoint "\nБазовая точка: ") "@" "_.rotate" "_pr" "" "@")
  (while (= (getvar "cmdactive") 1) (command pause))
  (vl-cmdf "_.undo" "_e")
)
PS Про конкретную задачу я написал, чтобы просто показать, как не надо писать макросы и как вместо этого писать программы. Может кому и пригодится.
Makswell вне форума  
 
Непрочитано 19.09.2007, 16:33
#7
Кулик Алексей aka kpblc
Moderator

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


"Вредность" не уменьшилась. У тебя набор не обнуляется, а их может быть создано не более 128 штук в течение одной сессии одного файла.
Код:
[Выделить все]
(defun C:M_CopyRotate (/ *error* selset _cmdecho)
  (defun *error* (msg)
    (setvar "cmdecho" _cmdecho)
    (vl-cmdf "_.undo" "_e")
    (vl-cmdf "_.undo" 1)
    (princ "\nВыполнение программы прервано пользователем!")
  )

(setq _cmdecho (getvar "cmdecho"))
  (setvar "cmdecho" 0)
  (vl-cmdf "_.undo" "_be")
(setq selset  (ssget))
  (vl-cmdf "_.copy" "_pr" "" (getpoint "\nБазовая точка: ") "@" "_.rotate" "_pr" "" "@")
  (while (= (getvar "cmdactive") 1) (command pause))
  (vl-cmdf "_.undo" "_e")
  (setvar "cmdecho" _cmdecho)
  (princ)
)
Кроме того, есть експрессовская команда mocoro, чем она не угодила?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 19.09.2007, 21:17
#8
Евгений А.

Армспорт
 
Регистрация: 18.07.2006
Ейск
Сообщений: 355


2006: макрос
Код:
[Выделить все]
^P(vl-cmdf "_rotate" (ssget) "" pause "_c");
_____
Не устраивает?
Евгений А. вне форума  
 
Автор темы   Непрочитано 20.09.2007, 08:38
#9
Makswell

Инженер-строитель
 
Регистрация: 15.08.2007
Киров
Сообщений: 2,204


Цитата:
Сообщение от Евгений А.
2006: макрос
Код:
[Выделить все]
^P(vl-cmdf "_rotate" (ssget) "" pause "_c");
Не работает, у меня Автокад 2004...

to kpblc
Спасибо за поправки.
Про (ssget) я не знал. Кстати, сразу возник вопрос: а что будет, если наборов будет больше 128?
Набрал (repeat 129 (ssget)), но чё-то задолбался выделять, думаю, зачем мучаться, если есть знающие люди...
Makswell вне форума  
 
Непрочитано 20.09.2007, 08:48
#10
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от Makswell
Про (ssget) я не знал. Кстати, сразу возник вопрос: а что будет, если наборов будет больше 128?
Набрал (repeat 129 (ssget)), но чё-то задолбался выделять, думаю, зачем мучаться, если есть знающие люди...
В 129 раз вернет nil вместо набора. Поэтому после использования набора следует его "обниливать" (т.е. присваивать nil).
Александр Ривилис вне форума  
 
Непрочитано 20.09.2007, 08:49
#11
Кулик Алексей aka kpblc
Moderator

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


Ну можно было добиться аналогичного эффекта, сделав:
Код:
[Выделить все]
(repeat 129 (ssget "_X"))
После превышения ограничения в 128 штук ни один набор больше создать будет невозможно. Я один раз словил, с тех пор стараюсь поаккуратнее
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 20.09.2007, 09:27
#12
Alaspher


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


Цитата:
Сообщение от Makswell
Набрал (repeat 129 (ssget)), но чё-то задолбался выделять, думаю, зачем мучаться, если есть знающие люди...
В таком варианте - ничего плохого быть не должно, поскольку созданный набор не сохраняется. А вот так:
Код:
[Выделить все]
(progn (setq test nil) (repeat 129 (setq test (cons (ssget "_X") test))))
ошибку (не nil) можно лицезреть.

Лиспик, я-п переделал как-то так:
Код:
[Выделить все]
(defun c:m_copyrotate (/ selset _cmdecho point good)
    (if (and (setq selset (vl-catch-all-apply (function ssget)))
             (not (vl-catch-all-error-p selset))
             (setq point (vl-catch-all-apply
                             (function getpoint)
                             '("\nБазовая точка <Выход>: ")
                         )
             )
             (not (vl-catch-all-error-p point))
        )
        (progn (setq _cmdecho (getvar "cmdecho"))
               (setvar "cmdecho" 0)
               (vl-cmdf "_.undo" "_be" "_.copy" "_pr" "" point "@" "_.rotate" "_pr" "" "@")
               (princ "\nУгол поворота: ")
               (setq good (while (not (zerop (getvar "cmdactive"))) (vl-cmdf pause)))
               (vl-cmdf "_.undo" "_e")
               (if (not good)
                   (progn (vl-cmdf "_.undo" 1)
                          (princ "\nВыполнение программы прервано пользователем!")
                   )
               )
               (setvar "cmdecho" _cmdecho)
        )
    )
    (princ)
)
И от переопределения *error* можно избавиться и от нештатных прерываний защититься.
Alaspher вне форума  
 
Непрочитано 02.10.2011, 16:16
#13
AMATOP


 
Регистрация: 02.10.2011
Сообщений: 10


Здравствуйте!
К сожалению, коротко не выйдет. Поскольку обдумав суть вопроса и внимательно прочитав всю ветку, пришел к выводу, что нужно описывать и условия задачи, которая мотивировала меня напрячься в отношение *error*.
Итак, цитирую Полещука:
Цитата:
Получает в сбойных ситуациях от системы AutoCAD строку с некоторым сообщением и обрабатывает ее (обычно выводит разъясняющее сообщение)
(*error* <сообщение>)
Аргумент - текстовая строка.
Не могу понять как ею пользоваться! Где и как вставлять в код, не зная когда эта сбойная ситуация настанет? И что за (msg) постоянно присутствующее в случае переопределения этой функции? Если не в тяжесть, помогите тупику выйти из тупика!
Теперь о самой задаче (в принципе факультативная информация).
Есть куча 3d solid-ов. Хочу отсеять все НЕ "Box"-ы:
Код:
[Выделить все]
 (if dutyob
  (setq dutyob (entnext dutyob))
  (setq dutyob (entnext))
)
(vl-load-com)
(setq zna4enie (vlax-get-property (vlax-ename->vla-object dutyob) 'SolidType))
; дальше не важно
И все бы хорошо, но вот , скажем в случае обращения к остатку "Box"-а после его обработки стандартной "Slice" упираюсь в:
Цитата:
; error: Automation Error. Description was not provided.
Читал Полещука далее. Загорелся vl-exit-with-value, но на "ура" тоже не выходит. Такие дела...
Спасибо, что дочитали до конца.
AMATOP вне форума  
 
Непрочитано 02.10.2011, 17:40
#14
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от AMATOP Посмотреть сообщение
Загорелся vl-exit-with-value
Забудьте про эту функцию, пока, загоритесь лучше vl-catch-all-apply
gomer вне форума  
 
Непрочитано 02.10.2011, 19:06
#15
Кулик Алексей aka kpblc
Moderator

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


Как один из вариантов: http://autolisp.ru/2009/09/13/error-catch/
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 02.10.2011, 19:14
#16
Лиспер


 
Регистрация: 11.10.2010
Сообщений: 979


Добавлю: можно предварительно проверять наличие свойства (vlax-property-available-p)
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 03.10.2011, 12:55
#17
AMATOP


 
Регистрация: 02.10.2011
Сообщений: 10


Огромнейшее спасибо Всем откликнувшимся! С утра попробовал "изменить тактику захвата противника", но пока все в песок! - Наверняка какая то синтаксическая галиматья. Поэтому, пока не выкладываю этот опус (стыдно если честно). Думаю вечером отпишусь. Еще раз спасибо Всем за поддержку!
Лиспер, очень признателен за замечание! Думаю с него вечером и начну.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Увы!Вот что (правильно сказать) не получилось:
Код:
[Выделить все]
 (vl-load-com)
(setq object (car (entsel)))
(vlax-property-available-p (vlax-ename->vla-object object) 'Solidtype)
И указываю подопытный объект - срезанный slice-ом BOX.
Консоль выдает:
Цитата:
<Entity name: 7ffffb05d30>
T
_$
Заметьте - true!!!
А теперь все то же самое, только с помощью:
Код:
[Выделить все]
 (vl-load-com)
(setq object (car (entsel)))
(vlax-get-property (vlax-ename->vla-object object) 'Solidtype)
Ну и было бы странно, если бы произошло чудо:
Цитата:
<Entity name: 7ffffb05d30>
; error: Automation Error. Description was not provided.
_$
Может я чего то не учитываю?!

Последний раз редактировалось AMATOP, 03.10.2011 в 22:44. Причина: Пришел вечер
AMATOP вне форума  
 
Непрочитано 11.11.2011, 00:09
#18
AMATOP


 
Регистрация: 02.10.2011
Сообщений: 10


Вынужден опять надоедать почтеннейшему обществу.
Все о той же ошибке. Ведь то что ее обработать можно - сомнений нет. Факты:
Код:
[Выделить все]
 (vl-load-com)
(vlax-dump-object (vlax-ename->vla-object (car (entsel))))
и в консоли:
...
; SolidType (RO) = Ошибка
...
Каким образом не происходит остановка выполнения кода?
__________________
Все люди думают по-разному!
А тупят одинаково :rolleyes:

Последний раз редактировалось AMATOP, 11.11.2011 в 00:26.
AMATOP вне форума  
 
Непрочитано 11.11.2011, 00:21
#19
Лиспер


 
Регистрация: 11.10.2010
Сообщений: 979


Как я понимаю, SolidType "срабатывает" только для фигур, созданных изначально средстваи AutoCAD: box, torus, cylinder etc. После выполнения любой операции над твердым телом это свойство "уничтожается".
А что код не останавливается - ну, значит, так дамп написан...
---
Добавлено:
Для выполнения задачи "Есть куча 3d solid-ов. Хочу отсеять все НЕ "Box"-ы" я б, наверное, использовал нечто типа:
Код:
[Выделить все]
(defun test (/ ss)
  (if (= (type (setq ss (vl-catch-all-apply
                          (function
                            (lambda ()
                              (ssget '((0 . "3DSOLID")))
                              ) ;_ end of lambda
                            ) ;_ end of function
                          ) ;_ end of vl-catch-all-apply
                     ) ;_ end of setq
               ) ;_ end of type
         'pickset
         ) ;_ end of =
    (vl-remove-if
      (function
        (lambda (x / tmp)
          (setq x (vlax-ename->vla-object x))
          (or (not (vlax-property-available-p x 'solidtype))
              (vl-catch-all-error-p (setq tmp (vl-catch-all-apply (function (lambda () (vla-get-solidtype x))))))
              (not (member (strcase tmp) '("BOX" "ЯЩИК")))
              ) ;_ end of or
          ) ;_ end of lambda
        ) ;_ end of function
      (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
      ) ;_ end of vl-remove-if
    ) ;_ end of if
  ) ;_ end of defun
В результате получишь список ename-представлений солидов, "которые точно боксы".
__________________
(/= RegDate StartReadDate)

Последний раз редактировалось Лиспер, 11.11.2011 в 00:29.
Лиспер вне форума  
 
Непрочитано 11.11.2011, 00:31
#20
AMATOP


 
Регистрация: 02.10.2011
Сообщений: 10


Спасибо, сейчас же буду разбираться.
__________________
Все люди думают по-разному!
А тупят одинаково :rolleyes:
AMATOP вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Не могу разобраться с *error*