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

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

Какой-то глюк в LAYOUT - как отловить его программно?

Ответ
Поиск в этой теме
Непрочитано 15.12.2017, 09:14 #1
Какой-то глюк в LAYOUT - как отловить его программно?
===AAA===
 
г. Норильск
Регистрация: 15.08.2005
Сообщений: 451

Всем добрый день.

АutoCAD-2016 (русский)

При отладке программы столкнулся со странной ситуацией - она
стала вылетать после выполнения вполне банального

(command "_-layout" "_ren" ...параметры...)

Стал разбираться - оказалось, дело в какой-то "хитрой ошибке"
dwg-файла, суть которой проявляется в том, что после переименования
вкладки Листа она как бы "блокируется", т.е. никаких действий с нею
больше сделать нельзя. Вот лог ввода команд, показывающий, как
это выглядит.

Код:
[Выделить все]
 Команда:   <Переход на: Модель>
Восстановление кэшированных видовых экранов.
=== вводим команду ===
Команда: РЛИСТ
Задайте параметр для листа [Копировать/Удалить/Новый/Шаблон/Переименовать/Сохранить/усТановить/?] <установить>: ?
=== вводим знак ? ===
Активные листы:
Лист: Вып1         Имя блока компоновки: *Paper_Space.
Лист: Принтер      Имя блока компоновки: *Paper_Space4.
=== снова вводим команду ===
Команда: РЛИСТ
Задайте параметр для листа [Копировать/Удалить/Новый/Шаблон/Переименовать/Сохранить/усТановить/?] <установить>: П
=== вводим П ===
Какой лист переименовать <Вып1>:
Новое имя листа: 777
Лист "Вып1" переименован в "777".
=== всё замечательно, переименовалось, снова вводим команду ===
Команда: РЛИСТ
Задайте параметр для листа [Копировать/Удалить/Новый/Шаблон/Переименовать/Сохранить/усТановить/?] <установить>: ?
=== вводим знак ? ===
Активные листы:
Лист: 777          Имя блока компоновки: *Paper_Space.
Лист: Принтер      Имя блока компоновки: *Paper_Space4.
=== снова вводим команду ===
Команда: РЛИСТ
Задайте параметр для листа [Копировать/Удалить/Новый/Шаблон/Переименовать/Сохранить/усТановить/?] <установить>: П
Какой лист переименовать <777>:
=== нажимаем Enter ===
Лист "777" не существует.
Опаньки!

Причём "зрительно" я вижу вкладки "Модель" "Принтер" и "777",
но ничего с этой 777 сделать уже не получается, даже удалить.

Пока обнаружил только один такой файл, но вопрос хочется
решить "в общем виде", ведь рано или поздно такое обязательно
повторится и на других файлах.

а) Кто-нибудь с таким сталкивался?
б) Есть ли идеи, как программно обработать эту ситуацию, выдав
пользователю внятное сообщение о проблеме с конкретным файлом?
__________________
Счастливо, Алексей!
Просмотров: 2642
 
Непрочитано 15.12.2017, 09:23
#2
Кулик Алексей aka kpblc
Moderator

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


Ты бы код, что ли, показал
Код:
[Выделить все]
 (defun tt (old-name new-name / adoc err layout)
  (if (= (type
           (setq layout (vl-catch-all-apply
                          (function
                            (lambda ()
                              (vla-item (vla-get-layouts (setq adoc (vla-get-activedocument (vlax-get-acad-object)))) old-name)
                              ) ;_ end of lambda
                            ) ;_ end of function
                          ) ;_ end of vl-catch-all-apply
                 ) ;_ end of setq
           ) ;_ end of type
         'vla-object
         ) ;_ end of =
    (if (vl-catch-all-error-p
          (setq err (vl-catch-all-apply (function (lambda () (vla-put-name layout new-name)))))
          ) ;_ end of vl-catch-all-error-p
      (princ (strcat "\nError : " (vl-catch-all-error-message err)))
      ) ;_ end of if
    ) ;_ end of if
  ) ;_ end of defun
У меня (ACAD2016x64Eng) сработало корректно

----- добавлено через ~2 мин. -----
Пример вызова:
Код:
[Выделить все]
 (tt "layout1" "newLayout")
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 15.12.2017, 09:44
#3
===AAA===


 
Регистрация: 15.08.2005
г. Норильск
Сообщений: 451


Код простой до безобразия. :-)

Вот фрагмент:

Код:
[Выделить все]
 
(setq laylst (layoutlist))
(setq namlay (car laylst))
(princ "\nСейчас переименую!")(princ namlay)(getint)
          (command "_-layout" "_ren" namlay "ОА-ВЫПУСК")
(princ "\nПереименовал!")(getint)
Вот после этого (или в Автокаде с клавиатуры - без разницы)
в совершенно конкретном единичном чертеже происходит глюк.

(tt )

попробую чуть позже, сейчас надо убегать по срочному делу.

----- добавлено через ~3 мин. -----
Да, вкладка ЛАЙОУТ только одна, проверка на это дело
производится до вызова этой части. Если вкладок несколько,
этот фрагмент кода обходится.
__________________
Счастливо, Алексей!
===AAA=== вне форума  
 
Непрочитано 15.12.2017, 09:50
#4
Кулик Алексей aka kpblc
Moderator

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


Кстати, замени у себя command на command-s
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 15.12.2017, 10:39
#5
===AAA===


 
Регистрация: 15.08.2005
г. Норильск
Сообщений: 451


Прибежал - попробовал.

То же самое.

Команда:
Команда: (tt "Вып1" "888")
nil
Команда: (tt "888" "777")
nil

Первый вызов без проблем, второй - не меняет и диагностику не выводит.
Вкладка "888" блокируется, удалять её Автокад отказывается.

>>>Кстати, замени у себя command на command-s

Меняю мало-помалу. В обработчике ошибок (а там у меня тоже были
command) уже заменил, т.к. действительно они не отрабатывали,
и выдавали лишние сообщения, а command-s - отрабатывают.
В других местах меняю по мере обнаружения проблем, т.к. не ясно
себе представляю, чем одна отличается от другой, хотя мануал
вроде бы и прочитал.
__________________
Счастливо, Алексей!
===AAA=== вне форума  
 
Непрочитано 15.12.2017, 10:47
#6
Кулик Алексей aka kpblc
Moderator

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


Если я правильно понимаю, то command-s выполняется в тот момент, когда ты ее вызываешь в коде. command и vl-cmdf ставятся "в очередь", которая обрабатывается уже после того, как сработал лисп. Могу ошибаться, естественно.
P.S. Специально несколько раз прогнал - переименование листа выполняется корректно. Удаление выполняется корректно. Даже если лист еще ни разу не активировался. Может, у тебя с ACAD'ом что-то "не то" и какое-то дополнение влезает? Я-то тестировал на "чистом"
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 15.12.2017, 11:39
#7
===AAA===


 
Регистрация: 15.08.2005
г. Норильск
Сообщений: 451


Может быть...

У меня (ACAD2016x64Rus)

Но всё это безобразие происходит в одном-единственном файле.
В него вставлена какая-то 3D-модель (кто и в чём её делал - неведомо).
В других файлах всё штатно - что (tt ...), что команды классического
автолиспа.

В принципе, ситуацию можно отловить, выставив чего-нибудь в глобальную
переменную перед вызовом (command-s "_-layout" "_ren" ...) и сбросив
сразу же после, а если "вылетело и не сбросилось" - обработать в *error*
по наличию этой переменной да и обнулить её там же.

Но - подумалось мне - вдруг есть более другие штатные средства.
Например, некая системная переменная (хранящаяся в чертеже),
которая управляет поведением Лайоутов.
__________________
Счастливо, Алексей!
===AAA=== вне форума  
 
Непрочитано 15.12.2017, 11:57
#8
Кулик Алексей aka kpblc
Moderator

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


Цитата:
Сообщение от ===AAA=== Посмотреть сообщение
Но всё это безобразие происходит в одном-единственном файле.
Следовательно, проблема в файле. _.audit, _.purge, _.-wblock - рецепты-то стандартные.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 15.12.2017, 12:14
#9
===AAA===


 
Регистрация: 15.08.2005
г. Норильск
Сообщений: 451


О!

Ещё один момент обнаружил.

Дай, думаю, посмотрю, что у него внутри "глазами".
Сохранил в DXF. И что же?

Лайоут, который всем показывал, что он "переименовался",
отображаясь новым именем в ответе на (setq laylst (layoutlist))
и на названии вкладки, в реальности оставался под старым
именем (исходное было "ВЫП1"), на которое он радостно
отзывался при вызове команды _layout и позволял делать
с собой что угодно, включая удаление.

А вот (tt ) после первого переименования его не видит всё
равно - ни по "старому" (скрытому), ни "новому" (отображаемому)
имени.

Во как!

----- добавлено через ~9 мин. -----
Да, "_аудит" помогает (найдено и исправлено 14 ошибок), после
чего моя программа радостно шурует дальше.

В принципе - решение есть:

до проблемного места выставляем в глобальную переменную
признак "опасности", который снимаем после его прохождения,
если вылетели - обрабатываем его в *error*, где выводим
пользователю сообщение о необходимости запустить
аудит файла.

Как-то так...

Всем спасибо за участие!
__________________
Счастливо, Алексей!
===AAA=== вне форума  
 
Непрочитано 15.12.2017, 17:38
#10
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,665


как вариант, без проверки на дубль

Код:
[Выделить все]
 
(defun Layout_rename (old_name new_name / )
  (setq acad_Object (vlax-get-acad-object)
        document_Object (vla-get-ActiveDocument acad_Object)
       	layouts_Collection (vla-get-layouts document_Object)
  )
  (vlax-for layout_item layouts_Collection
    (if (and (/= 0 (vla-get-TabOrder layout_item))
	     (= (vla-get-name layout_item) old_name)
	)
          (setq error_occured (vl-catch-all-apply 'vla-put-name (list layout_item new_name)))
    )
  )
  (if error_occured
    (progn
    	(princ (strcat "\nCan't Rename \"" old_name "\" to \"" new_name "\""))
    	(princ)
    )
  )  
)  

Последний раз редактировалось koMon, 15.12.2017 в 17:53.
koMon вне форума  
 
Автор темы   Непрочитано 18.12.2017, 10:34
#11
===AAA===


 
Регистрация: 15.08.2005
г. Норильск
Сообщений: 451


Всем привет!

Да, этот вариант на "кривом файле" работает:

Команда: (load "r2")
Layout_rename
Команда: (Layout_rename "Вып1" "777")
nil
Команда: (Layout_rename "777" "888")
Can't Rename "777" to "888"

Т.е. на сообщение об ошибке мы выходим, но счастья это не принесло,
т.к. после первого переименования (формально выполненного успешно),
далее по ходу программы следует команда

(setvar "ctab" namlay)

которая тоже будет давать ошибку. В приведённом выше примере
это выглядит так:

Команда: (setvar "ctab" "777")
Настройка переменной AutoCAD отвергнута: "ctab" "777"
__________________
Счастливо, Алексей!
===AAA=== вне форума  
 
Непрочитано 18.12.2017, 10:38
#12
Кулик Алексей aka kpblc
Moderator

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


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Следовательно, проблема в файле. _.audit, _.purge, _.-wblock - рецепты-то стандартные.
Сделано?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 18.12.2017, 11:42
#13
===AAA===


 
Регистрация: 15.08.2005
г. Норильск
Сообщений: 451


Да сделано конечно, я же писал об этом выше...

Проблема-то ведь не в том, как победить конкретный файл
(она уже решена), а в том, как сделать универсальный
lisp-код, который будет корректно обрабатывать эту
ситуацию, ежели она встретится в дальнейшем на другом
файле.

----- добавлено через ~1 мин. -----
Я специально сейчас тестирую этот участок кода на бережно
сохранённой "кривой копии" файла. :-)))
__________________
Счастливо, Алексей!
===AAA=== вне форума  
 
Непрочитано 18.12.2017, 12:20
#14
Кулик Алексей aka kpblc
Moderator

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


ИМХО намного проще при открытии файла выполнять его проверку.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 19.12.2017, 16:26
#15
===AAA===


 
Регистрация: 15.08.2005
г. Норильск
Сообщений: 451


Теоретически да, но не хотелось терять время (секунды, конечно)
на профилактической проверке Аудитом каждого файла.
Да и "неспортивно" оно как-то...

Но всё оказалось ещё интереснее.

После первого же переименования Лайоута файл становился "кривым
окончательно", и ему не помогал даже Аудит. Т.е. программа, сама того
не ведая и не желая вносила в файл критичные изменения, что плохо
от слова "совсем".

Пришлось по ходу ставить метку "групповой отмены при аварии" и
передавать это дело (т.е. и вывод человеческого сообщения о проблеме
пользователю и откат в начальное состояние) на давным-давно
переопределённую *error*. Ну, было в ней до этого 150 строчек кода,
добавил ещё 20.

В общем - поразвлекался малость. :-)))

Зато теперь всё работает как надо.
__________________
Счастливо, Алексей!
===AAA=== вне форума  
 
Непрочитано 19.12.2017, 17:53
#16
Кулик Алексей aka kpblc
Moderator

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


Цитата:
Сообщение от ===AAA=== Посмотреть сообщение
Ну, было в ней до этого 150 строчек кода,
Скока-скока??? Блин, че-то у тебя не то в *error*, похоже, творится.
P.S. Я вообще не переопределю *error* уже лет 5, наверное. И горя не знаЮ vl-catch-* зачем выдумали, как думаешь?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 19.12.2017, 18:24
#17
===AAA===


 
Регистрация: 15.08.2005
г. Норильск
Сообщений: 451


Она у меня универсальная на три довольно специфических вида деятельности.
В основном идёт восстановление системных переменных, отработка глобальных
переменных "в зависимости от", записи логов в файлы и прочая и прочая.

Как была написана лет 15 назад - так её и не трогал с тех пор. :-)
__________________
Счастливо, Алексей!
===AAA=== вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Какой-то глюк в LAYOUT - как отловить его программно?

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LISP. Копирование, сортировка, переименование листов (layout) VVA Готовые программы 96 08.12.2023 14:11
Какой нормативный документ действующий по эвакуационным путям и выходам? kolja Поиск литературы, чертежей, моделей и прочих материалов 4 13.08.2010 10:19
Как применить настройки к Layout (AutoCAD MDT) DonVik Программирование 5 06.08.2009 16:50
Печать (несколько layout за один раз) Малюк AutoCAD 2 25.07.2008 10:38
Программно задать размер листа в Layout Ax3 Программирование 6 02.03.2008 11:28