Реклама i
Стань нашим партнером - зарабатывай с нами!
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Как написать обработчик ошибки?

Как написать обработчик ошибки?

Ответ
Поиск в этой теме
Непрочитано 11.04.2016, 09:58 #1
Как написать обработчик ошибки?
Сет
 
Регистрация: 19.11.2014
Сообщений: 2,435

Лисп-программа обращается к файлу. В случае ошибки файл остается открытым и я теряю к нему доступ. Как можно отловить ошибку с тем чтобы закрыть файл?
Код:
[Выделить все]
 (setq file (open "file.txt" "r"))
; что-то делаю, где может возникнуть ошибка
(close file) ; до сюда программа не доходит
Просмотров: 2672
 
Непрочитано 11.04.2016, 10:10
#2
Krieger

инженер (КМ)
 
Регистрация: 30.10.2004
Красноярск
Сообщений: 3,826


Код:
[Выделить все]
(if (setq file (open "file.txt" "r"))
(progn
 ; что-то делаю, где может возникнуть ошибка
(close file) ; до сюда программа не доходит
);progn
);if
__________________
Делай хорошо, плохо само получится.
Krieger вне форума  
 
Автор темы   Непрочитано 11.04.2016, 10:16
#3
Сет


 
Регистрация: 19.11.2014
Сообщений: 2,435


Не понял, как это сработает? Если возникнет ошибка с строке "что-то делаю", то до (close file) программа уже не дойдет и файл останется открытым.
Сет вне форума  
 
Непрочитано 11.04.2016, 10:22
1 | #4
Кулик Алексей aka kpblc
Moderator

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


http://autolisp.ru/2009/09/13/error-catch/
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 11.04.2016, 10:23
1 | #5
Krieger

инженер (КМ)
 
Регистрация: 30.10.2004
Красноярск
Сообщений: 3,826


А, я подумал, что у тебя пробелмы с открытием. Тогда используй функцию *error*, которая будет выполняться при ошибке. В ней и пропишешь закрытие файла. Типа:
Код:
[Выделить все]
 (defun *error* (msg) (close file))
__________________
Делай хорошо, плохо само получится.
Krieger вне форума  
 
Непрочитано 11.04.2016, 10:25
#6
Кулик Алексей aka kpblc
Moderator

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


В конце концов, в "Библиотеке функций" есть обработчик ошибок. Весьма и весьма.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 11.04.2016, 11:04
#7
Сет


 
Регистрация: 19.11.2014
Сообщений: 2,435


Проверил отлов ошибки в тестовой простой функции - работает:
Код:
[Выделить все]
 (defun c:testerror (/ *error* file)
  (defun *error* (msg)
    (princ "закрываю файл")
    (close file)
  )  
  (setq file (open "D:\\MyAutoCAD\\temp.txt" "r"))  
  (/ 1 0)
  (close file)
)
Проверил работу в своей функции - не работает. Причину не понимаю, выкладываю весь код функции. Я специально изменил одну строку (комментарий "здесь ошибка"), сделав там ошибку. Управление функции *error*передается, так как сообщение "моя ошибка" выводится, но файл file не закрывается. Почему?
Код:
[Выделить все]
 (defun cs_make_specification_string (block / *error*				     
  file
  mode
  element_type
  pos
  prokat_type				     
  oboznachenie
  naimenovanie				     
  marka
  steel_gost
  steel_marka
  element_length
  num
  weight
  note
  offset
  width				     
  i				     
  attributes
  attribute
  tag
  naimenovanie_full
  mtext
  mtext_point1
  mtext_point2
  mtext_height
  text_compression
  naimenovanie_full_compessed)
  (defun *error* (msg)
    (princ "моя ошибка")
    (close file)
  ) ; defun
  (setq file (open "D:\\MyAutoCAD\\temp.txt" "r"))
  (setq mode (read-line file))
    (progn
      (setq element_type (read-line file))
      (setq pos (read-line file))
      (setq prokat_type (read-line file))
      (setq oboznachenie (read-line file))
      (setq naimenovanie (read-line file))
      (setq marka (read-line file))
      (setq steel_gost (read-line file))
      (setq steel_marka (read-line file))
      (setq element_length (read-line file))
      (setq num (read-line file))
      (setq weight (read-line file))
      (setq note (read-line file))
      (setq offset (read-line file))
      (setq width (read-line file))
      (setq attributes (vlax-variant-value (vla-GetAttributes block)))
      (setq i 0)
      (while (< i 15)	    
        ;(setq attribute (vlax-safearray-get-element attributes i)) - правильный вариант   
       (setq attribute (vlax-safearray-get-element attributes -1)) ; здесь ошибка
        (setq tag (vla-get-TagString attribute))
        (cond
          ((= tag "ПОЗ")         (vla-put-TextString attribute pos))
          ((= tag "ОБОЗНАЧЕНИЕ") (vla-put-TextString attribute oboznachenie))
          ((= tag "КОЛ")         (vla-put-TextString attribute num))
          ((= tag "МАССА")       (vla-put-TextString attribute weight))
          ((= tag "ПРИМЕЧАНИЕ")  (vla-put-TextString attribute note))
          ((= tag "ТИП")         (vla-put-TextString attribute element_type))	  
          ((= tag "ЭЛЕМЕНТ")     (vla-put-TextString attribute naimenovanie))	  
          ((= tag "МАРКА")       (vla-put-TextString attribute marka))		  
          ((= tag "СТАЛЬ")       (vla-put-TextString attribute steel_gost))		  
          ((= tag "МАРКА_СТАЛИ") (vla-put-TextString attribute steel_marka))	  
          ((= tag "ДЛИНА")       (vla-put-TextString attribute element_length))	  
          ((= tag "ТИП_ПРОКАТА") (vla-put-TextString attribute prokat_type)) 	  
          ((= tag "ШИРИНА")      (vla-put-TextString attribute width)) 	   
          ((= tag "НАИМЕНОВАНИЕ")
          (cond
            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; строка спецификации Прокат ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
            ((= element_type "Прокат")
              (setq naimenovanie_full (strcat "\\A1;" naimenovanie " {\\H0.88x;\\S" marka " " oboznachenie "/" steel_marka " " steel_gost ";}" " L=" element_length)) 
              (vla-put-TextString attribute naimenovanie_full)
	      (if (= mode "ADD") (vla-Move attribute (vlax-3D-point '(0 0 0)) (vlax-3D-point (list 0 (atoi offset) 0))))
	      (setq mtext (vla-AddMText model_space (vlax-3D-point '(0 0 0)) 6350 naimenovanie_full))
	      (vla-GetBoundingBox mtext 'mtext_point1 'mtext_point2)
	      (setq mtext_height (- (vlax-safearray-get-element mtext_point2 1) (vlax-safearray-get-element mtext_point1 1)))
	      (if (> mtext_height 700)
	        (progn		    
                  (setq text_compression 1.00)
                  (while (> mtext_height 700)
                    (setq text_compression (- text_compression 0.02))
                    (setq naimenovanie_full_compessed (strcat "{\\W" (rtos text_compression 2 2) ";" naimenovanie_full "}"))
                    (vla-put-TextString mtext naimenovanie_full_compessed)
                    (vla-GetBoundingBox mtext 'mtext_point1 'mtext_point2)
                    (setq mtext_height (- (vlax-safearray-get-element mtext_point2 1) (vlax-safearray-get-element mtext_point1 1)))
                  ) ; while
		  (vla-put-TextString attribute naimenovanie_full_compessed)
		) ; progn
              ) ; if
	      (vla-Delete mtext)
	    ) ; прокат
            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; строка спецификации Арматура ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
            ((= element_type "Арматура")
              (setq naimenovanie_full (strcat "%%c" marka " " steel_marka " L=" element_length)) 
              (vla-put-TextString attribute naimenovanie_full)
            ) ; арматура
            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; строка спецификации Дерево ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
            ((= element_type "Дерево")
              (setq naimenovanie_full (strcat naimenovanie " " marka "x" width " L=" element_length)) 
              (vla-put-TextString attribute naimenovanie_full)
            ) ; дерево
	  ) ; cond
	) ; tag наименование
      ) ; cond
      (setq i (1+ i))
    ) ; while
  ) ; progn
  (close file)
) ; defun
Сет вне форума  
 
Непрочитано 11.04.2016, 11:44
#8
Кулик Алексей aka kpblc
Moderator

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


Во-первых, как ты определяешь, что файл не закрывается? Ты его можешь, например, переименовать после того, как программа завершила работу?
Во-вторых, поставь точки останова и пройдись по коду пошагово (если честно, там тьма мест, где можно сделать по-другому; но у меня сейчас на это нет времени). Таким образом выловишь ошибочное место.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 11.04.2016, 11:57
#9
Сет


 
Регистрация: 19.11.2014
Сообщений: 2,435


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Во-первых, как ты определяешь, что файл не закрывается? Ты его можешь, например, переименовать после того, как программа завершила работу?
Внешнее приложение не может получить доступ к этому файлу для перезаписи. Система выдает сообщение, что файл используется.

Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Во-вторых, поставь точки останова и пройдись по коду пошагово (если честно, там тьма мест, где можно сделать по-другому; но у меня сейчас на это нет времени). Таким образом выловишь ошибочное место.
Я не очень хорошо умею пользоваться редактором VLisp, пошагово не знаю как. Но тут и не вижу такой необходимости. Код без сознательно устроенной ошибки работает. Ошибка - отрицательный индекс массива safearray. Что мне даст пошаговая проходка? Я точно знаю где будет ошибка и точно знаю, что к моменту возникновения ошибки в локальной переменной file хранится дескриптор открытого файла. Но почему команда (close file) в обработчике *error* не закрывает файл? В сам обработчик программа точно заходит, потому что выводит сообщение "моя ошибка".
Сет вне форума  
 
Непрочитано 11.04.2016, 12:25
1 | #10
Кулик Алексей aka kpblc
Moderator

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


Ну закрывай файл сразу как закончил из него читать. Дальше-то он тебе не нужен.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 11.04.2016, 12:27
1 | #11
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,991
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Сет, Ты из файла считываешь строчек 15 один раз. Перенеси (close file) после 49 строки. Дальше-то он тебе не нужен.

Код:
[Выделить все]
...
(setq offset (read-line file)) 
(setq width (read-line file)) 
(close file) ;_<<<<<<<<<<<< Добавить
...
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 11.04.2016, 12:30
#12
Сет


 
Регистрация: 19.11.2014
Сообщений: 2,435


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Ну закрывай файл сразу как закончил из него читать. Дальше-то он тебе не нужен.
Цитата:
Сообщение от VVA Посмотреть сообщение
Ты из файла считываешь строчек 15 один раз. Перенеси (close file) после 49 строки.
Ну да, это очевидно. Я тут затупил. Нет смысла держать открытым файл все время.

Но глобальный вопрос остается. Почему обработчик *error* не закрывает файл?
Сет вне форума  
 
Непрочитано 11.04.2016, 12:41
#13
Кулик Алексей aka kpblc
Moderator

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


Я полагаю, что дескриптор файла еще какое-то время (определяемое, кстати, не AutoCAD'ом) считается "занятым". Можешь после обработки данных вывести (princ) - только для обновления статуса AutoCAD
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 11.04.2016, 12:45
#14
Сет


 
Регистрация: 19.11.2014
Сообщений: 2,435


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Я полагаю, что дескриптор файла еще какое-то время (определяемое, кстати, не AutoCAD'ом) считается "занятым".
Что это значит? После (close file) файл еще некоторое время будет недоступен? При выполнении кода без ошибок это не так - внешнее приложение сразу получает доступ к файлу.
Сет вне форума  
 
Непрочитано 11.04.2016, 13:34
#15
Кулик Алексей aka kpblc
Moderator

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


Ну, я сказал на основании собственного опыта работы с VB6 - там не всегда освобождалось сразу.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Как написать обработчик ошибки?

Размещение рекламы


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибки Autocad MEP, Autocad Architecture, Autodesk Design Review VitalyAF Вертикальные решения на базе AutoCAD 60 11.10.2023 19:49
Какой язык перспективен для инженера-конструктора с условием The_Mercy_Seat Программирование 705 17.03.2021 14:19
AutoCAD 2013 Rus SP2 СПДС при проверке _audit находит и исправляет ошибки но, повторная проверка опять указывает на тоже zoro ПО от CSoft 10 06.08.2013 00:33
Ошибки в сортаментах (покушение на основы) IBZ Разное 18 02.09.2008 13:03