Перебор всех объектов

Автор Тема: Перебор всех объектов  (Прочитано 11603 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Перебор всех объектов
« : 10-10-2018, 14:28:44 »
Добрый день!

выполняю перебор всех объектов чертежа. в чертеже есть внешние ссылки.
когда она проверяется и натыкается на эту строчку
Код - C# [Выбрать]
  1. if (myTransaction.GetObject(objId, OpenMode.ForWrite) is MText mt)
выскакивает ошибка
видимо потому что ее нельзя получить внешнюю ссылку для записи. получать два раза как то не хочется: для проверки а потом для изменения
как быть?
Спасибо

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #1 : 10-10-2018, 14:51:56 »
Открывать все подряд объекты на запись - плохая практика. Если есть сомнения, что объект надо будет редактировать, то открывайте на чтение. А прямо перед модификацией вызывайте UpgradeOpen

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #2 : 10-10-2018, 14:53:51 »
ну да логично.
Спасибо.

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #3 : 10-10-2018, 15:01:32 »
а если мне нужно изменить атрибут блока?
правильно я делаю, что блок открываю для чтения, а атрибут для записи?

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #4 : 10-10-2018, 15:02:42 »
да

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #5 : 10-10-2018, 15:10:18 »
Спасибо большое!

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Re: Перебор всех объектов
« Ответ #6 : 10-10-2018, 15:28:36 »
simson43, если я правильно понял, то Ваш код проверяет, методом открытия и приведения объекта, является ли он MText
Попробуйте использовать вот этот код:
Код - C# [Выбрать]
  1. if (objId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(MText))))
он не открывает объект (если я правильно помню) и работает несколько быстрей, да и транзакция не нужна...

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #7 : 10-10-2018, 15:59:57 »
Владимир Шу, cудя по тому что оператор is объявляет переменную mt - я бы предположил, что она где-то дальше используется. Вот если не используется, тогда да - однозначно надо проверять тип объекта по ObjectId.

Отмечено как Решение simson43 10-10-2018, 20:27:50

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Re: Перебор всех объектов
« Ответ #8 : 10-10-2018, 16:12:05 »
avc, конечно используется, иначе какой смысл создавать эту перемененную.
Я просто имел ввиду, что более правильно сначала определить класс объекта, а потом, если он подходит, его открывать...
Код - C# [Выбрать]
  1. if (objId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(MText))))
  2. {
  3.   MText mt = myTransaction.GetObject(objId, OpenMode.ForWrite) as MText;
  4.   //и далее какой-то код
  5.  }

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Перебор всех объектов
« Ответ #9 : 10-10-2018, 18:44:38 »
Открывать все подряд объекты на запись - плохая практика. Если есть сомнения, что объект надо будет редактировать, то открывайте на чтение. А прямо перед модификацией вызывайте UpgradeOpen
Всё так, кроме того, что вместо UpgradeOpen нужно снова вызвать повторно Transaction.GetObject(...), но с OpenMode.ForWrite. UpgradeOpen - это для Open/Close (или OpenCloseTransaction) и может конфликтовать с обычной транзакцией.
« Последнее редактирование: 10-10-2018, 19:45:42 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #10 : 10-10-2018, 18:54:47 »
моджет конфликтовать с обычной транзакцией
Да что вы?! Точно? Я всегда так делаю и в куче примеров видел и у объекта IsWriteEnabled становится true... Неужели я столько лет косячил... шок...

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #11 : 10-10-2018, 19:00:06 »
Полез на блог Kean Walmsley - во всех примерах он берет объекты через транзакции, и потом вызывает UpgradeOpen. Вот от него я и набрался. Вот например тут http://www.keanw.com/2010/01/creating-an-autocad-block-using-net.html
Код - C# [Выбрать]
  1. BlockTable bt =
  2.           (BlockTable)tr.GetObject(
  3.             db.BlockTableId,
  4.             OpenMode.ForRead
  5.           );

и следом

Код - C# [Выбрать]
  1.         bt.UpgradeOpen();
  2.         ObjectId btrId = bt.Add(btr);
  3.         tr.AddNewlyCreatedDBObject(btr, true);

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Перебор всех объектов
« Ответ #12 : 10-10-2018, 19:35:24 »
моджет конфликтовать с обычной транзакцией
Да что вы?! Точно? Я всегда так делаю и в куче примеров видел и у объекта IsWriteEnabled становится true... Неужели я столько лет косячил... шок...
Ты был не один. И я тоже такие примеры приводил с использованием UpgradeOpen. Но один старший товарищ (Art Cooney - один из руководителей разработки AutoCAD) объяснил мне, что я не прав. Это вылезло в одном из обновлений AutoCAD 2018. Тут подробности: https://forums.autodesk.com/t5/net/api-bug-2018-1-causes-crash-using-upgradeopen-on-dependent/m-p/7272262/highlight/true#M54471
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #13 : 10-10-2018, 20:13:15 »
т е или заменить обычную транзакция на openclosetransaction или еще раз получать объект для записи?

а как же вот с оф сайта пример?
https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-NET/files/GUID-CC5CC229-B122-4897-A8DA-5C5ADADB0F38-htm.html?_ga=2.51307242.2126543432.1539105496-1602586928.1535484681

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Перебор всех объектов
« Ответ #14 : 10-10-2018, 20:21:18 »
т е или заменить обычную транзакция на openclosetransaction или еще раз получать объект для записи?
Менять ничего не надо. Просто вместо UpgradeOpen вызываешь снова myTransaction.GetObject, но уже с OpenMode.ForWrite.

а как же вот с оф сайта пример?
https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-NET/files/GUID-CC5CC229-B122-4897-A8DA-5C5ADADB0F38-htm.html?_ga=2.51307242.2126543432.1539105496-1602586928.1535484681
Он ошибочен. И по той ссылке, которую я дал выше, это обсуждается.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение