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

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

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

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

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

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


Код:
[Выделить все]
(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,787


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

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


А, я подумал, что у тебя пробелмы с открытием. Тогда используй функцию *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,787


В конце концов, в "Библиотеке функций" есть обработчик ошибок. Весьма и весьма.
__________________
Моя библиотека 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,787


Во-первых, как ты определяешь, что файл не закрывается? Ты его можешь, например, переименовать после того, как программа завершила работу?
Во-вторых, поставь точки останова и пройдись по коду пошагово (если честно, там тьма мест, где можно сделать по-другому; но у меня сейчас на это нет времени). Таким образом выловишь ошибочное место.
__________________
Моя библиотека 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,787


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

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,990
<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,787


Я полагаю, что дескриптор файла еще какое-то время (определяемое, кстати, не 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,787


Ну, я сказал на основании собственного опыта работы с 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