Назначение слоя в цикле

Автор Тема: Назначение слоя в цикле  (Прочитано 3259 раз)

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

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

  • ADN OPEN
  • Сообщений: 27
  • Карма: 2
Назначение слоя в цикле
« : 23-10-2019, 18:11:22 »
  Приветствую всех. Совсем недавно начал изучать C#. Конечно сразу запнулся на трансакциях. Код должен назначить выбранным объектом слой.  Понимаю, что нужно правильно выйти из трансакции. Похожий вопрос был на сайте, но что то без решения((. Помогите новичку, где тут ошибка?




Код - C# [Выбрать]
  1.      public void SelObjOnscr()
  2.     {
  3.         Document acDoc = Application.DocumentManager.MdiActiveDocument;
  4.         Database acCurDb = acDoc.Database;
  5.         PromptSelectionResult acSSPrompt = acDoc.Editor.GetSelection();
  6.         if (acSSPrompt.Status == PromptStatus.OK)
  7.         {
  8.             using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  9.             {
  10.                 {
  11.                     LayerTable acLyrTbl;
  12.                     acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId,
  13.                                                     OpenMode.ForRead) as LayerTable;
  14.                     string sLayerName = "mylayer";
  15.                     if (acLyrTbl.Has(sLayerName) == false)
  16.                     {
  17.                         using (LayerTableRecord acLyrTblRec = new LayerTableRecord())
  18.                         {
  19.                             acLyrTblRec.Name = sLayerName;
  20.                             acLyrTbl.UpgradeOpen();
  21.                             acLyrTbl.Add(acLyrTblRec);
  22.                         }
  23.                     }
  24.                     SelectionSet acSSet = acSSPrompt.Value;
  25.                     foreach (SelectedObject acSSObj in acSSet)
  26.                     {
  27.                         if (acSSObj != null)
  28.                         {
  29.                             Entity acEnt = acTrans.GetObject(acSSObj.ObjectId,
  30.                                                                 OpenMode.ForWrite) as Entity;
  31.                             if (acEnt != null)
  32.                             {
  33.                                 acEnt.Layer = sLayerName;
  34.                             }
  35.                         }
  36.                     }
  37.                 }
  38.                 acTrans.Commit();
  39.             }
  40.         }
  41.     }  
 
« Последнее редактирование: 24-10-2019, 06:55:30 от alihovsky »

Отмечено как Решение alihovsky 24-10-2019, 06:51:40

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 809
  • Карма: 166
    • Мои плагины к Автокаду
Re: Назначение слоя в цикле
« Ответ #1 : 23-10-2019, 18:35:19 »
У вас объекты, только что полученные из чертежа, опять заталкиваются в модель и в транзакцию. Сохранять в БД надо только новые объекты, у которых Id.IsNull Просто уберите AppendEntity и AddNewlyCreatedDBObject.
BTR модели вам не нужен.
И еще. Нет смысла открывать транзакцию пока не выбраны объекты. Вызывайте запрос GetSelection до открытия транзакции.

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

  • ADN OPEN
  • Сообщений: 27
  • Карма: 2
Re: Назначение слоя в цикле
« Ответ #2 : 24-10-2019, 06:53:27 »
Спасибо. Только не совсем понял, почему в строке

acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId,
                                                    OpenMode.ForRead) as LayerTable

"OpenMode.ForRead", а не "OpenMode.ForWrite". "ForRead" копировал из документации, но код срабатывает при обоих вариантах, это фича VS?

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Назначение слоя в цикле
« Ответ #3 : 24-10-2019, 08:37:12 »
alihovsky,
Потому, что потом ты вызываешь acLyrTbl.UpgradeOpen(); для перевода в состояние OpenMode.ForWrite
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 27
  • Карма: 2
Re: Назначение слоя в цикле
« Ответ #4 : 24-10-2019, 09:04:19 »
Потому, что потом ты вызываешь acLyrTbl.UpgradeOpen(); для перевода в состояние OpenMode.ForWrite

Вроде дошло) , спасибо

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 809
  • Карма: 166
    • Мои плагины к Автокаду
Re: Назначение слоя в цикле
« Ответ #5 : 24-10-2019, 10:32:43 »
И не так давно обсуждалось, что UpgradeOpen не всегда корректно работает с транзакциями. Нынче модно вместо него вызывать еще раз GetObject, но уже для записи. Результат такого вызова можно никуда не сохранять - состояние объекта и так изменится.
Код - C# [Выбрать]
  1.        {
  2.         acLyrTblRec.Name = sLayerName;
  3.         acTrans.GetObject(acCurDb.LayerTableId,  OpenMode.ForWrite);
  4.         acLyrTbl.Add(acLyrTblRec);
  5.        }