|
||
| Правила | Регистрация | Пользователи | Сообщения за день | | Поиск | | Справка по форуму | Файлообменник | |
|
![]() |
Поиск в этой теме |
![]() |
#1 | |
Как автоматически обновлять поля блока?
Programming, automation, CADs, GISs. "Теплоком"
Россия, Санкт-Петербург
Регистрация: 02.02.2007
Сообщений: 306
|
||
Просмотров: 11804
|
|
||||
Программист-энтузиаст Регистрация: 17.07.2009
Воронеж
Сообщений: 575
|
Только вот вопрос? Если Ваш ректор будет срабатывать на изменение блока и попытается изменить содержимое полей, которые в свою очередь являются элементами блока, то это приведет к новому срабатыванию реактора, так как блок поменялся и так до бесконечности, а точнее сразу все прервется какой-нибудь фатальной ошибкой? Или нет?
|
|||
![]() |
|
||||
Programming, automation, CADs, GISs. "Теплоком" Регистрация: 02.02.2007
Россия, Санкт-Петербург
Сообщений: 306
|
Проблема цикличного вызова реактора "из себя" решается просто введением флага активности реактора.
>Александр Ривилис Благодарю за подсказку. Такое решение кажется вполне подходящим. Попробую. Вот только чем поля обновлять? В LISP-е не нашел такой функции. (command), опять же, нельзя - в реакторах не работает
__________________
На LISPе можно мыслить! Последний раз редактировалось Ax3, 29.07.2010 в 17:01. |
|||
![]() |
|
||||
Moderator
LISP, C# (ACAD 200[9,12,13,14]) Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,411
|
vla-update не сработает?
__________________
Моя библиотека lisp-функций --- Обращение ко мне - на "ты". Все, что сказано - личное мнение. |
|||
![]() |
|
||||
Programming, automation, CADs, GISs. "Теплоком" Регистрация: 02.02.2007
Россия, Санкт-Петербург
Сообщений: 306
|
Парни, я решил проблему! Ключом оказалась функция (vla-sendcommand). Она сама дожидается освобождения ("простоя") автокада и симулирует ввод команд.
Таким образом получил следующее. 1. "Вешаю" реактор на свой блок: Код:
Код:
Спасибо за подсказки! P.S. Поправка. Рекуррентные вызовы-то на самом деле, конечно, не исключаются, но само тело callback-функции при установленном флаге активности не выполняется. А вот исключить совсем рекуррентные вызовы можно теоретически "отцеплянием" реактора от блока в теле самого реактора (то есть на время выполнения реактора). По завершении работы реактора "прицеплять" его обратно. В Delphi подобный замут делал - работало, в LISP-е не пробовал еще... P.P.S. Еще поправка. (vla-sendcommand), конечно, ничего не дожидается, видимо, она просто кладет указанные команды в некую очередь (пользовательских?) команд, которая как раз во время выполнения LISP-функций не обрабатывается кадом. P.P.P.S. А, и еще важный момент. Надо позаботиться об удалении блока. То есть по идее при создании блока на него надо вешать два объектных реактора (vlr-object-reactor) - реактор на событие модификации (:vlr-modified либо :vlr-objectClosed) и реактор на событие "перед-удалением" (:vlr-goodbye). В реакторе "перед-удалением" надо отцеплять оба реактора от блока, иначе после удаления кад ругается "Automation error: object was erased". Но это так, к слову. {} По ходу, я рано обрадовался. Глянул тему Supermax-а http://forum.dwg.ru/showthread.php?t...command&page=2 и решил попробовать изменить lookup-ы своего блока из окна Properties. И акад вылетел с треском! Что делать?.. (риторический, наверно, вопрос :-)) {2010.08.02} Посмотрев еще раз тему supermax-а, решил все-таки вынести само обновление полей во внешнее приложение, использующее связь с кадом по технологии COM. Код callback-функции реактора преобразился примерно так: Код:
Код:
Работает пока без сбоев, никаких "тупо подождать пару секунд" нет, единственное узкое место - работа с винчестером для запуска внешней программы. С точки зрения программиста - через одно место, но зато надежно, при редактировании свойств (в т.ч. лукапов) блока из окна properties все отрабатывает без ошибок. Интересно, можно ли это считать решением?
__________________
На LISPе можно мыслить! Последний раз редактировалось Ax3, 30.07.2010 в 19:00. |
|||
![]() |
|
||||
КИП и А Регистрация: 28.04.2010
Киев
Сообщений: 101
![]() |
Цитата:
Извините за глупые вопросы. У меня возник вопрос по автобновлениям. тут А вот сам вопрос #2065 Последний раз редактировалось Eddicordo, 17.08.2010 в 11:36. |
|||
![]() |
|
||||
Programming, automation, CADs, GISs. "Теплоком" Регистрация: 02.02.2007
Россия, Санкт-Петербург
Сообщений: 306
|
>>Eddicordo
Дружище, извини, давно не заглядывал в тему. Да, конечно, через денек-другой сделаю и выложу. На самом деле работа с реакторами оказалась несколько сложнее, чем я полагал вначале :-)
__________________
На LISPе можно мыслить! |
|||
![]() |
|
||||
Programming, automation, CADs, GISs. "Теплоком" Регистрация: 02.02.2007
Россия, Санкт-Петербург
Сообщений: 306
|
{2010.09.01 15.30}
Выложил в заголовке. Инструкции и описание - внутри, файл !readme! P.S. С днем знаний! :-) {2010.09.01 17.36} P.P.S. Есть еще усложненный код, который сравнивает значения атрибутов до и после обновления и меняет цвет атрибута, текст которого изменился (то есть показывает пользователю, какие атрибуты он заполнил, а какие - нет). Если надо - могу выложить. {2010.09.01 18.30} P.P.P.S. Друзья, у кого есть возможность - протестируйте, пожалуйста! Буду очень благодарен за нахождение новых багов :-) {2010.09.06 09:06} Пришла светлая мысль перенести весь LISP-код обновления полей обратно в LISP-программу. Это исключает конфликты кода обновления с кадом из-за его занятости. Во внешнем приложении оставил только вызов программы обновления полей плюс добавил обработку COM-ошибок, т.к. иногда не удавалось заставить кад отработать sendcommand с первого раза. Версия 1.01 выложена в заголовке. Для изучения COM-поведения када использовалась вот эта программка: ACAD_COM_test(c)Danilov_AS_aka_`Hawk`_2010.09.03.rar
__________________
На LISPе можно мыслить! Последний раз редактировалось Ax3, 06.09.2010 в 09:13. |
|||
![]() |
|
||||
КИП и А Регистрация: 28.04.2010
Киев
Сообщений: 101
![]() |
Можешь выложить что то по проще. И без привязки к определенному полю дин блока.
А то запустить некую постороннюю программу добавить доп меню. Очень сложно для пользования обычными пользователями. Или я не правильно ее использовал........ все по инструкции. За пример можно взять самый простой дин блок в котором линия с атрибутом в котором поле с длиной линии. |
|||
![]() |
|
||||
Programming, automation, CADs, GISs. "Теплоком" Регистрация: 02.02.2007
Россия, Санкт-Петербург
Сообщений: 306
|
в readme написано:
Цитата:
Поясни, плз, что значит "без привязки к определенному полю дин.блока?" Блок, приложенный в качестве примера, обновляется целиком независимо от того, какое поле или динамическое свойство было отредактировано
__________________
На LISPе можно мыслить! |
|||
![]() |
|
||||
КИП и А Регистрация: 28.04.2010
Киев
Сообщений: 101
![]() |
Ax3
Извени что долго не отвечал. Выполняю все как написано. Цитата:
Оп заметил что у тебя поля в атрибуте забиты как то по иному.(Выбор Лукапа) Может из за этого? Тогда встречный вопрос. Как забить в атрибут поле с выбором Лукапа? Я обычно указываю какой лукап. Вот файл Вариант №1.dwg http://forum.dwg.ru/showpost.php?p=639362&postcount=106 Да и это получается что каждый раз как мне надо работать в AutoCad с дин блоками нужно будет всегда запускать файл ACAD_apps_u.setup.exe День спустя. Странно проделываю все что было сказано и уже не работает выдает ошибку Код:
Последний раз редактировалось Eddicordo, 27.10.2010 в 17:33. |
|||
![]() |
|
||||
Programming, automation, CADs, GISs. "Теплоком" Регистрация: 02.02.2007
Россия, Санкт-Петербург
Сообщений: 306
|
>>Eddicordo
1. Немного изменил сборку. Распаковываешь архив, запускаешь 0_ainst_universal_script_v1.09(c)Danilov_AS_aka_`Hawk`_2009.12.15.exe. Если все нормально отработает, то: - Папка blk_autoupd появится в %Program Files%\ACAD_addons\ - blk_autoupd.lsp будет добавлен в Startup Suite - при первом (после установки данной программы) запуске автокада появится сообщение об обновлении панели `blk_autoupd` 2. Вместо тестового блока вставил твой, только атрибуты в нем сделал предустановленными. Ну а дальше понятно - на появившейся в каде панельке интсрументов `blk_autoupd` жмем серую кнопку, вставится блок, щелкаем в нем лукапы - срабатывает автообновление. После закрытия-открытия чертежа автообновление не работает. Для восстановления автообновления нажать красную кнопку. Если надо вставить в значение атрибута не свойства объекта, а значения лукапов, то в block editor'е в диалоговом окне вставки поля в левом списке выбрать не "Объект", а "BlockPlaceHolder" (по-русски, кажись, "Местозаполнитель блока"). Отпишись, плз, как проверишь, - работает ли. Удачи. Кстати, любопытно - что это за блок? В смысле как он используется и для чего?
__________________
На LISPе можно мыслить! Последний раз редактировалось Ax3, 29.10.2010 в 20:08. |
|||
![]() |
|
||||
КИП и А Регистрация: 28.04.2010
Киев
Сообщений: 101
![]() |
ОО вроде работает отлично с моим блоком "Кабель".
Есть очень большой минус. Обновляется только блок с именем "Кабель". А если на чертеже много блоков с полями и разными именами. Они не обновляются. Я так понял нужно дописывать ИМЕНА всех используемых блоков. Куда дописывать? Цитата:
Да и это мне понятно что для обновления нужно клацнуть. А другие могут и не понять что если хочешь автообновление то при каждом заходе на чертеж нужно по клацать там, там и еще там. Да и перед компом 3 раза присесть и сказать волшебное слово. ![]() Цитата:
Естественно блок сырой и набросан по быстрому что бы идея была понятна. Используется он очень просто. Каждый прибор соединяется кабелем и куда то подключается (клеммная коробка, щит и т.д.). Вот на "Схеме соединений внешних проводок" КИП и А нужно показывать каким именно кабелем ты подключаешь прибор и куда ведешь его. Вот еще одно не удобство. При изменении одного из Лукапов и автообновлении, его выделение блока снимается. В моем случае с блоком "Кабель" для настройки блока нужно поиграться с 4 Лукапами. То есть 4 раза выделять блок заново приходится. Что не есть хорошо. Обновление должно происходить с тем блоком который я выделил. И не выходить из выделения пока я сам этого не захочу стандартным методом. Выходя с этого более реально сделать автообновление полей в блоках по всему чертежу, а не конкретных которых я прописал где то. Тобиш обновление происходит только с выделенным блоком. А не автообновление всех блоков на чертеже. Что и не будет влечь за собой нагрузку на ПК и тормоза. Последний раз редактировалось Eddicordo, 01.11.2010 в 14:05. |
|||
![]() |
|
||||
Programming, automation, CADs, GISs. "Теплоком" Регистрация: 02.02.2007
Россия, Санкт-Петербург
Сообщений: 306
|
Cорри. В нашей нелегкой жизни так часто бывают запарки и геморрои.
Версия 2.1. Реактор обновления теперь сохраняется в чертеже. Красная кнопка больше не нужна. Однако если открыть чертеж на компе, где не установлена программа blk_autoupd, при изменении лукапа блока кад будет ругаться на то, что "; error: no function definition: BU__UPD-FIELDS_FUNC". В принципе это не страшно, просто так - к сведению. blk_autoupd_v2.1(c)Danilov_AS_aka_`Hawk`_2010.11.30.rar Пока на большее не созрел, извиняй, дружище. P.S. По поводу снятия выделения. Технически - на самом деле выделение не снимается. Просто есть у Автокада какой-то глюк с прорисовкой pickfirst selection set (я использую функцию sssetfirst), выражающийся в том, что пропадают ручки редактирования у объектов, включенных в pickfirst selection set. Впрочем, как бы там ни было, эта проблема пока не решена. P.P.S. По поводу других блоков. Как лучше реализовать? Мне в голову пришли такие способы: 1. Для каждого блока - своя кнопка в панели инструментов для его вставки в чертеж. 2. Одна кнопка (назовем ее "Повесить реактор на блок", например), которая просит указать блок и включает автообновление полей указанного блока. 3. Тупо, без разбора вешать реакторы на все блоки при их вставке в чертеж (или прописать список блоков, на которые вешать автообновление, и делать это при вставке в чертеж блоков, перечисленных в этом списке) {Добавлено _2010.12.04_22.39.22} Или вот еще мысль. 4. При создании все блоки, к которым предполагается прикреплять автообновление полей, помечаются каким-нибудь скрытым атрибутом. Тогда можно прописать реактор на команду вставки блока, который будет анализировать вставленный в чертеж блок на предмет этого самого скрытого атрибута и при его обнаружении будет прикреплять реактор автообновления полей к вставленному экземпляру блока. Но этот вариант будет слегка тормозить работу Автокада и вообще он замороченный. Мне кажется, что оптимально будет сделать панель инструментов с кнопками для вставки всех нужных блоков. Ну и в главное меню в раздел "Вставка" можно добавить пункт "Блоки кабелей"-><список блоков>.
__________________
На LISPе можно мыслить! Последний раз редактировалось Ax3, 04.12.2010 в 22:46. |
|||
![]() |
|
||||
КИП, АСУ ТП, слаботочка Регистрация: 02.09.2010
Москва-Тюмень
Сообщений: 422
|
Доброе время автору темы и всем-всем-всем!
Тоже решил сегодня разобраться с реакторами. И мне это удалось. Благодаря автору и еще некоторым программистам с этого форума. Вот этот код можно закинуть в .lsp файл, сохранить и загрузить как приложение: Код:
Просто такая легко модифицируемая форма проще воспринимается, чем готовое внешнее приложение, управляющее акадом, по крайней мере такими начинающими лисперами-любителями как я. Автору респект и увжуха ![]() Возник такой вопрос - можно ли как-нить так переделать код, чтобы измененный нами блок остался выделенным? Работа реактора и callback функции убивает грипсы - выделение блока исчезает. Пробовал внутри vla-sendcommand выделить при помощи sssetfirst, но не получилось. Нашел ответ: (vl-cmdf "_.regen") только на слабых компах ощутимые тормоза начинаются ))) Последний раз редактировалось Frigate, 14.01.2011 в 06:54. |
|||
![]() |
|
||||
Инженер LISP Регистрация: 11.05.2005
Минск
Сообщений: 6,996
|
Зыбыл добавить описание функции adv-convertdatatype-selset-to-vlalist
__________________
Как использовать код на Лиспе читаем здесь |
|||
![]() |
|
||||
КИП, АСУ ТП, слаботочка Регистрация: 02.09.2010
Москва-Тюмень
Сообщений: 422
|
![]() Код:
Код:
точно ))) Сейчас откорректирую пост. №20 В принципе, эта функция является "чкстно стыренной" у тебя же ![]() Интересно узнать, как у других сработает код, с каким вариантом строки "(vl-cmdf ...)" Совместно с реакторами на удаление объекта работать не получается. ПОможет ли здесь удаление первого реактора и запись его пар во второй объект реактора? И как удалить реактотр? Именно удалить, а не остановить (vlr-remove), которая все равно не работает. Последний раз редактировалось Frigate, 14.01.2011 в 07:29. |
|||
![]() |
|
||||
Programming, automation, CADs, GISs. "Теплоком" Регистрация: 02.02.2007
Россия, Санкт-Петербург
Сообщений: 306
|
>>Frigate
По поводу внешнего приложения. Я в самом начале так же, как и ты, решил, что (vla-sendcommand) поможет. Но попытка изменения свойств блока из окна properties приводила к Fatal Error (см. пост #7), поэтому я и решил вынести обновление блока во внешнее приложение. Однако мой опыт работы в этом направлении показал, что работа с реакторами чрезвычайно... (прошу прощения за выражение) геморройна. То есть автообновление полей несложных блоков, пожалуй, имеет смысл, а со сложными динамическими блоками это всё работает как-то через ж... Впрочем, помучившись изрядно, я добился-таки стабильной работы своего блока с автообновлением, но второй раз что-то уже нет желания повторять такое :-) По поводу (vl-cmdf "_UPDATEFIELD" obj_to_upd "" "") и проблем с одной/двумя кавычками - ха, спасибо, друг, подтвердил мои проблемы, описанные в теме http://forum.dwg.ru/showthread.php?p=606042#post606042. Я этот момент поборол так: Код:
__________________
На LISPе можно мыслить! Последний раз редактировалось Ax3, 19.01.2011 в 12:44. |
|||
![]() |
|
||||
Регистрация: 11.10.2010
Сообщений: 979
|
Я не очень понимаю, а в updatefield подставляется указатель на вхождение блока, что ли (просто не сталкивался с такой задачей)? Если да, то почему б не попробовать так:
Код:
--- P.S. Спасибо Админу, классную кнопочку сделал!
__________________
(/= RegDate StartReadDate) |
|||
![]() |
|
||||
КИП, АСУ ТП, слаботочка Регистрация: 02.09.2010
Москва-Тюмень
Сообщений: 422
|
точно )))
а я не вникал в суть этой переменной раньше... ее изменение в "0" (если потом не восстановить, в том числе предусмотреть это и в обработике ошибок) может сильно осложнить жизнь юзерам автокада - ничего нельзя привычным способом отредактировать ![]() вот так вот поменял функцию callback: Код:
пока вроде работает Лиспер, что-то я не понимаю, как твою функцию применить в callback функции... Ведь реактор кинет в callback функцию (у мня пока другого не получалось) только ОДИН указатель на блок, и обновлять надо именно этот блок. К тому же в твоем коде именно комендный метод, который и применен у меня, именно такой вариант убирает выделение блока после редактирования его динсвойств. Что заметил: эти две строки Код:
Ну, как я уже писал, в таком случае можно вообще обойтись регенерацией, не затрагивая обновление полей - и выделение не пропадает и все нормуль, только слабые компы подвисают ))) Есть ли возможность сделать регенерацию для отдельного объекта (у нас - блока)? ТОлько не _update - это поля не обновляет Прошу прощения, выделил в коде красным две строки, которые все равно не работают, а иногда и вызывают сбой... Я о выделении через ssetfirst. Их лучше убрать. Итак вывод: обновление полей автоматом после изменения динсвойства блока возможно. Но оно неприменимо для динблоков, с динсвойствами которых часто и много работают, т.к. при обновлении полей исчезает выделение блока, вернуть выделение у меня не получилось. Нуа ГУРУ ЛИСПа пока тоже не отвечают, возможно этой проблемой никто и не занимался, зная проблемность реакторов. Единственный вариант, когда возможно обновить поля и сохранить выделение - это использовать вместо _updatefiekd регенерацию _regen. Но - слабые компы такого издевательства не выдержат. Так что это нельзя назвать универсальным инструментом, так как у пользователя не обязательно будет навороченный комп. Последний раз редактировалось Frigate, 20.01.2011 в 06:49. |
|||
![]() |
![]() |
|
|
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Некорректно обновляются поля блока | NEDIS | AutoCAD | 50 | 19.02.2013 15:47 |
Поля атрибутов вложенного блока не отображают своих значений | hwd | AutoCAD | 7 | 23.12.2009 08:40 |
Подскажите, пожалуйста, как сделать описание (description) для блока? | Ламер | AutoCAD | 5 | 27.08.2009 14:33 |
Мониторы LCD CRT | Разное | 94 | 17.06.2008 10:51 | |
Как в чертеже автоматически прописать полный путь? | Соня | AutoCAD | 5 | 14.09.2004 16:33 |