После вставки блока, отредактировать вручную атрибуты.

Автор Тема: После вставки блока, отредактировать вручную атрибуты.  (Прочитано 10350 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн art_rrcАвтор темы

  • ADN Club
  • **
  • Сообщений: 70
  • Карма: 1
  • Skype: art_sapranovich
Собственно суть проблемы описана в заголовке темы. На VBA, после вставки блока, использую такую запись:
Код - Visual Basic [Выбрать]
  1. ThisDrawing.SendCommand "_eattedit _l "

и все работает как надо.
Добавил в код из поста 1 (соседняя тема http://adn-cis.org/forum/index.php?topic=3125.0) после строки:
Код - vb.net [Выбрать]
  1. trans.AddNewlyCreatedDBObject(blockRef, True)
Строку:
Код - vb.net [Выбрать]
  1. dwgDoc.SendStringToExecute("_eattedit _l" & vbCr, True, False, False)
  2. 'dwgDoc.SendStringToExecute("_eattedit" & vbCr & "_l" & vbCr, True, False, False) -можно еще так. Разницы никакой.
  3.  
Но при тестировании в ком. строке получаю "Выбранный блок не имеет редактируемых атрибутов". При вставке блока вручную, все редактируется. Блок в порядке.
Проблему решает добавление строки:
Код - vb.net [Выбрать]
  1. dwgDoc.SendStringToExecute("_ATTSYNC" & vbCr & "_N" & vbCr & blockName & vbCr, False, False, False)
Но! При этом автокад существенно задумывается (при большом кол-ве копий блока) и конечно этот вариант не подходит. Может есть способы обновить атрибуты конкретного блока? Или в идеале вставить блок сразу с рабочими атрибутами (как это делает VBA). Спасибо.

Отмечено как Решение art_rrc 23-10-2015, 14:11:47

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Добавил в код из поста 1 (соседняя тема http://adn-cis.org/forum/index.php?topic=3125.0) после строки:
Код - vb.net: [Выделить]

    trans.AddNewlyCreatedDBObject(blockRef, True)

Строку:
Код - vb.net: [Выделить]

    dwgDoc.SendStringToExecute("_eattedit _l" & vbCr, True, False, False)
    'dwgDoc.SendStringToExecute("_eattedit" & vbCr & "_l" & vbCr, True, False, False) -можно еще так. Разницы никакой.
     
Этот код выполнится только после завершения команды. Поэтому какой примитив будет последним - не знаю.
Но при тестировании в ком. строке получаю "Выбранный блок не имеет редактируемых атрибутов".
А ты добавил атрибуты к вставке блока? Судя по коду - нет. Читай (и далее по ссылке): http://adn-cis.org/forum/index.php?topic=2937
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн art_rrcАвтор темы

  • ADN Club
  • **
  • Сообщений: 70
  • Карма: 1
  • Skype: art_sapranovich
Этот код выполнится только после завершения команды. Поэтому какой примитив будет последним - не знаю.
Этот метод вызывается сразу после вставки блока, так что он и оказывался последним. Пока нареканий не вызывал.
А ты добавил атрибуты к вставке блока? Судя по коду - нет. Читай (и далее по ссылке): http://adn-cis.org/forum/index.php?topic=2937
Ого, как все запутано.. Отдельно геометрия, отдельно атрибуты. Причем эту статью я просматривал, но не придал значения, подумал, что просто значения задаются программно, а меня интересует именно ручной ввод. А тут такое.. Спасибо, что наставили на путь истинный  :)

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Причем эту статью я просматривал, но не придал значения, подумал, что просто значения задаются программно, а меня интересует именно ручной ввод. А тут такое..
Там нет ничего сложного. Проверяются типы AttributeDefinition, и к коллекции атрибутов вставки блока добавляются только неконстантные (т.е. именно так, как делает AutoCAD при вставке блока). 
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн art_rrcАвтор темы

  • ADN Club
  • **
  • Сообщений: 70
  • Карма: 1
  • Skype: art_sapranovich
Большущее спасибо! У меня все получилось, но пришла беда откуда не ждали... После вызова редактора, программа продолжает выполняться как ни в чем не бывало. Хотя я был уверен, что все автокадовские окна модальные. Думал, что вся загвоздка в транзакции (работу которой пока понимаю далеко не идеально), но эксперименты на эту тему результатов не дали. Подскажите пожалуйста, как остановить работу программы на время ввода данных в редакторе блоков. Опять же в VBA таких проблем не встречал, там все строго по порядку. Ох уж эти транзакции...  :-[

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
После вызова редактора, программа продолжает выполняться как ни в чем не бывало.
Уже неоднократно обсуждалось на форуме, что SendStringToExecute выполняется асинхронно, т.е. уже после завершения твоей команды.
В зависимости от версии AutoCAD тебе нужно использовать или Editor.RunCommand или Editor.Command для синхронного запуска команды.
P.S.: Ну и внутри транзакции нечего запускать команды AutoCAD.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн art_rrcАвтор темы

  • ADN Club
  • **
  • Сообщений: 70
  • Карма: 1
  • Skype: art_sapranovich
Спасибо за ответ.
P.S.: Ну и внутри транзакции нечего запускать команды AutoCAD.
Это не рекомендуется или нельзя ни при каких обстоятельствах? А что если мне нужно вставить блок, заполнить атрибуты, отредактировать блок в зависимости от полученных значений... Неужели придется закрывать транзакцию, вызывать редактор, а потом по новой ко всему подключаться, чтоб добраться до блока? Это ведь невероятное разбухание кода получится..

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
А что если мне нужно вставить блок, заполнить атрибуты, отредактировать блок в зависимости от полученных значений... Неужели придется закрывать транзакцию, вызывать редактор, а потом по новой ко всему подключаться, чтоб добраться до блока? Это ведь невероятное разбухание кода получится..
Хочешь проблем? Тогда можешь не разрывать транзакцию. Ты ведь не знаешь какие механизмы эта команда использует внутри себя.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн art_rrcАвтор темы

  • ADN Club
  • **
  • Сообщений: 70
  • Карма: 1
  • Skype: art_sapranovich
Хочешь проблем? Тогда можешь не разрывать транзакцию. Ты ведь не знаешь какие механизмы эта команда использует внутри себя.
Проблем не хочу. :) Я понял, спасибо. В конце концов, не так уж и страшно откопировать часть кода.

Оффлайн art_rrcАвтор темы

  • ADN Club
  • **
  • Сообщений: 70
  • Карма: 1
  • Skype: art_sapranovich
Получается, что нужно закрыть транзакцию, выполнить Editor.Command, а после манипулировать объектами, которые были созданы внутри транзакции. Но вытащить хоть какую-то информацию из "тела" транзакции не получается, видимо dispose очень тщательно все подчищает. Пробовал создать переменную и в нее записать значение, не выходит (см. код), также пытался это сделать через глобальную переменную (которую объявлял вне sub BLK), также безрезультатно. Изначально пробовал непосредственно с BlockReference, но IDE все равно упорно пишет, что пытаешься использовать, прежде чем назначил значение и при выполнении будет Null. Подскажите пожалуйста, как же получить доступ к блоку, после завершения транзакции, в которой он создан? Спасибо.
Демонстрационный код:
 
Извините, вам запрещён просмотр содержимого спойлеров.

Оффлайн German

  • ADN Club
  • **
  • Сообщений: 84
  • Карма: 13
Сохранять можно ObjectId между транзакциями http://adn-cis.org/forum/index.php?topic=570.0

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
art_rrc
Если в двух словах, то ты сначала получаешь ObjectId у вставки блока, который еще не добавлен в базу. ObjectId в этом случае у него нулевой. Только после AppendEntity у него становится не нулевой ObjectId. И еще непонятно зачем ты ObjectId преобразуешь в строку.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн art_rrcАвтор темы

  • ADN Club
  • **
  • Сообщений: 70
  • Карма: 1
  • Skype: art_sapranovich
Сохранять можно ObjectId между транзакциями http://adn-cis.org/forum/index.php?topic=570.0
То что нужно! У меня даже кое что получилось, сейчас пытаюсь грамотно прикрутить в код.
И еще непонятно зачем ты ObjectId преобразуешь в строку.
Для того, чтоб посмотреть в ком строке нуль не нуль? Т.е. посмотреть возвращает что либо или нет.
Только после AppendEntity у него становится не нулевой ObjectId.
Да, но существует он только в пределах транзакции. После dispose никак вытянуть значение не получалось. Поэтому, благодаря Вам и ссылке German'a заменил строку:
Код - vb.net [Выбрать]
  1. ms.AppendEntity(blockRef)
На строку:
Код - vb.net [Выбрать]
  1. blockID = ms.AppendEntity(blockRef)
blockID - объявлен выше старта транзакции. И пока все работает как надо! blockID можно свободно использовать в след. транзакции. Спасибо вам за помощь.
И можно еще маленький вопрос, он слишком незначительный, чтоб создавать тему. Я использую транзакцию, закрываю ее. Выполняю кое-какие манипуляции в коде и после этого снова есть необходимость использовать транзакцию. Я от греха подальше назвал ее другим именем и все. Может быть есть рекомендации по этому поводу? Т.е. можно ли было использовать старое название, или так делать категорически нельзя ,или нежелательно, или если она закрыта, то можно считать будто ее и не было?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Поэтому, благодаря Вам и ссылке German'a заменил строку:
Код - vb.net: [Выделить]

    ms.AppendEntity(blockRef)

На строку:
Код - vb.net: [Выделить]

    blockID = ms.AppendEntity(blockRef)

blockID - объявлен выше старта транзакции. И пока все работает как надо! blockID можно свободно использовать в след. транзакции. Спасибо вам за помощь.
Был второй вариант. У тебя в старом коде поменять местами ms.AppendEntity(blockRef) и blockID = blockRef.ObjectId, т.е. после вызова ms.AppendEntity(blockRef) blockRef.ObjectId возвращает уже ненулевое (правильное) значение.
И можно еще маленький вопрос, он слишком незначительный, чтоб создавать тему. Я использую транзакцию, закрываю ее. Выполняю кое-какие манипуляции в коде и после этого снова есть необходимость использовать транзакцию. Я от греха подальше назвал ее другим именем и все. Может быть есть рекомендации по этому поводу? Т.е. можно ли было использовать старое название, или так делать категорически нельзя ,или нежелательно, или если она закрыта, то можно считать будто ее и не было?
А это только вопрос синтаксиса языка. Если он не будет ругаться на две переменные с одним именем - можешь использовать, если будет ругаться - значит нет. Имя переменной транзакции не имеет никакого значения. Главное, чтобы не нарушала синтаксис языка (в данном случае языка VB.NET, хотя я настоятельно рекомендую перейти на C#).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение