Получить доступ к атрибуту через ObjectId

Автор Тема: Получить доступ к атрибуту через ObjectId  (Прочитано 2200 раз)

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Здравствуйте!
Ситуация- я знаю ObjectId  и Handle нужного мне BlockReference. Можно ли по ObjectId или Handle конкретного BlockReference получить доступ к его атрибуту (знаю имя тэга) без итерации foreach?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Да, конечно можно. Как обычно пользуешься Transaction.GetObject для открытия. Если у атрибута знаешь только тег, то потребуется итерация по атрибутам блока.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Код - C# [Выбрать]
  1. [CommandMethod("ListBlockReferences")]
  2.                public static void SetCurrentPageNumber( )
  3.                {
  4.                     //--------------------------------------------------------------------Mandatory variables
  5.                     Document acDoc = Application.DocumentManager.MdiActiveDocument;
  6.                     Database acCurDb = acDoc.Database;
  7.                     Editor ed = acDoc.Editor;
  8.                     Transaction acTrans = acCurDb.TransactionManager.StartTransaction( );
  9.                     //--------------------------------------------------------------------Mandatory variables
  10.                     int curPageNumber = 1;
  11.                     List<long> listOfHandles = new List<long>( );
  12.                     ObjectIdCollection attIdWithPage = new ObjectIdCollection( );
  13.                     using (acTrans)
  14.                     {
  15.                          BlockTable bt = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead, false, true) as BlockTable;
  16.                          foreach (ObjectId btrId in bt)
  17.                          {
  18.                               BlockTableRecord btr = acTrans.GetObject(btrId, OpenMode.ForRead, false, true) as BlockTableRecord;
  19.                               if (btr.Name.StartsWith("Regular"))
  20.                               {
  21.                                    ObjectIdCollection brIdCollection = btr.GetBlockReferenceIds(false, true);
  22.                                    curPageNumber = curPageNumber + brIdCollection.Count;
  23.                                    foreach (ObjectId brId in brIdCollection)
  24.                                    {
  25.                                         BlockReference br = acTrans.GetObject(brId, OpenMode.ForRead) as BlockReference;
  26.                                         {
  27.                                              AttributeCollection brAttCollection = br.AttributeCollection;
  28.                                              foreach (ObjectId attId in brAttCollection)
  29.                                              {
  30.                                                   AttributeReference attribute = acTrans.GetObject(attId, OpenMode.ForRead) as AttributeReference;
  31.                                                   if (attribute.Tag == "Page")
  32.                                                   {
  33.                                                        attIdWithPage.Add(attId);
  34.                                                        listOfHandles.Add(br.Handle.Value);
  35.                                                   }
  36.                                              }
  37.                                         }
  38.                                    }
  39.                               }
  40.                          }
  41.  
  42.  
  43.                          long brHandle = listOfHandles.Max( );
  44.                          Handle yyy = new Handle(brHandle);
  45.                          
  46.                          ObjectId idTitle = acCurDb.GetObjectId(false,yyy, 0);
  47.                          if (idTitle!=null)
  48.                          {
  49.                               BlockReference br = acTrans.GetObject(idTitle, OpenMode.ForRead) as BlockReference;
  50.                               {
  51.                                    AttributeCollection brAttCollection = br.AttributeCollection;
  52.                                    foreach (ObjectId attId in brAttCollection)
  53.                                    {
  54.                                         AttributeReference attribute = acTrans.GetObject(attId, OpenMode.ForWrite) as AttributeReference;
  55.                                         if (attribute.Tag == "Page")
  56.                                         {
  57.                                              attribute.TextString = curPageNumber.ToString( );
  58.                                         }
  59.                                    }
  60.                               }
  61.                          }
  62.  
  63.                          acTrans.Commit( );
  64.                     }
  65.  
  66.                     Application.DocumentManager.MdiActiveDocument.Editor.Regen( );
  67.                }

Вроде все заработало. Александр Ривилис, большое спасибо. Прокомментируйте, пожалуйста, код на корректность написания(избыточность, плохой стиль и т.п.).


Оффлайн Вильдар

  • ADN Club
  • ****
  • Сообщений: 405
  • Карма: 77
  • Skype: vildar82
Atomohod,
1. Везде используется оператор as, но нигде нет проверки на null.
Тогда, лучше явно приводить тип - (BlockTable).
А еще лучше комбинировать. Потому что, если BlockTable не откроется, то продолжать бессмысленно. Его приводить через ().
А вот, BlockReference может и не открыться, из-за ошибок в чертеже. Его лучше через as с проверкой на null.
2. При открытии объекта GetObject не везде передаются все аргументы (открытие удаленных и на заблокированных слоях).
А еще лучше, метод открытия объектов GetObject - вынести в библиотечный метод, где все это будет учтено один раз.

Мне так видится 8)