Неожидаемая передача в атрибут

Автор Тема: Неожидаемая передача в атрибут  (Прочитано 3322 раз)

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Здравствуйте!
Тестирую код в отладчике, вроде все идет по сценарию команды, но в атрибут блока записывает 1 вместо числа элементов коллекции. Смысл команды в подсчете блоков содержащих определенные символы, и записи их количества в атрибут. А. Ривилис советовал сделать такую команду на событиях-я пытаюсь, но пока я разбираюсь, а функционал уже нужен. Где-то я допускаю ошибку и скорее всего некрупную, но не вижу где. Прошу ткнуть меня в нее.

Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.Runtime;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using System.Collections;
  6.  
  7. namespace ITAT_Autocad
  8. {
  9.      public class AutoCAD_Template
  10.      {
  11.  
  12.           [CommandMethod("077")]
  13.           public void UpdateBlockWithAnAttribute()
  14.           {
  15.                //--------------------------------------------------------------------Mandatory variables
  16.                Document acDoc = Application.DocumentManager.MdiActiveDocument;
  17.                Database acCurDb = acDoc.Database;
  18.                Transaction acTrans = acCurDb.TransactionManager.StartTransaction();
  19.                //--------------------------------------------------------------------Mandatory variables
  20.                using (acTrans)
  21.                {
  22.                     BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead, false, true) as BlockTable;
  23.  
  24.                     ArrayList allTitles = new ArrayList() { };
  25.                     if (acBlkTbl.Has("MainTitle"))
  26.                     {
  27.                          foreach (ObjectId btrId in acBlkTbl)
  28.                          {
  29.                               BlockTableRecord btr = acTrans.GetObject(btrId, OpenMode.ForRead) as BlockTableRecord;
  30.  
  31.                               foreach (ObjectId blockRefId in btr.GetBlockReferenceIds(true, true))
  32.                               {
  33.                                    
  34.                                    BlockReference br = acTrans.GetObject(blockRefId, OpenMode.ForWrite) as BlockReference;
  35.  
  36.                                    if (br.Name.Contains("Title"))
  37.                                    {
  38.                                         allTitles.Add(br.Name.Contains("Title"));
  39.                                    }
  40.  
  41.                                    int nTitles = allTitles.Count;
  42.  
  43.                                    foreach (ObjectId attRefId in br.AttributeCollection)
  44.                                    {
  45.                                         AttributeReference ar = acTrans.GetObject(attRefId, OpenMode.ForWrite) as AttributeReference;
  46.                                         if (ar != null && ar.Tag == "Pages")
  47.                                         {
  48.                                              ar.TextString = nTitles.ToString();
  49.                                         }
  50.                                    }
  51.                               }
  52.                          }
  53.                     }
  54.                     else acDoc.Editor.WriteMessage("\n Block does not exist");
  55.  
  56.                     acTrans.Commit();
  57.                }
  58.           }
  59.  
  60.      }
  61.  
  62. }
  63.  


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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Неожидаемая передача в атрибут
« Ответ #1 : 12-06-2018, 21:14:47 »
В коде очень много лишнего, много глупостей, но явной ошибки я не увидел. Выложи dwg-файл на котором экспериментируешь.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Re: Неожидаемая передача в атрибут
« Ответ #2 : 12-06-2018, 22:57:19 »
Выкладываю.
очень много лишнего, много глупостей
, а каких? Там всего около 45 строк активного кода как их переписать?

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Re: Неожидаемая передача в атрибут
« Ответ #3 : 12-06-2018, 23:07:15 »
А существует ли способ, чтобы напрямую обратится к BlockTableRecord с определенным именем не проходя весь путь через итерации по BlockTable и BlockTableRecord ? Если я правильно понимаю то имя BlockTableRecord = имя блока.

Отмечено как Решение Atomohod 13-06-2018, 20:38:19

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Неожидаемая передача в атрибут
« Ответ #4 : 12-06-2018, 23:36:40 »
Сравни со своим кодом и проверь результаты.

Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.Runtime;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5.  
  6. // This line is not mandatory, but improves loading performances
  7. [assembly: CommandClass(typeof(Rivilis.CalcPages))]
  8.  
  9. namespace Rivilis
  10. {
  11.   public class CalcPages
  12.   {
  13.  
  14.     [CommandMethod("CalcPages")]
  15.     public void MyCommand() // This method can have any name
  16.     {
  17.       Document doc = Application.DocumentManager.MdiActiveDocument;
  18.       if (doc == null) return;
  19.       Editor ed = doc.Editor;
  20.       Database db = doc.Database;
  21.       ObjectIdCollection idsAttPages = new ObjectIdCollection();
  22.       int nPages = 0;
  23.       using (Transaction tr = doc.TransactionManager.StartTransaction())
  24.       {
  25.         BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  26.         if (bt.Has("MainTitle"))
  27.         {
  28.           foreach (ObjectId idBtr in bt)
  29.           {
  30.             BlockTableRecord btr = tr.GetObject(idBtr, OpenMode.ForRead) as BlockTableRecord;
  31.             if (btr.Name.Contains("Title"))
  32.             {
  33.               ObjectIdCollection idsBr = btr.GetBlockReferenceIds(false, true);
  34.               nPages += idsBr.Count;
  35.               foreach (ObjectId idBr in idsBr)
  36.               {
  37.                 BlockReference br = tr.GetObject(idBr, OpenMode.ForRead) as BlockReference;
  38.                 AttributeCollection idsAtt = br.AttributeCollection;
  39.                 foreach (ObjectId idAtt in idsAtt)
  40.                 {
  41.                   AttributeReference att = tr.GetObject(idAtt, OpenMode.ForRead) as AttributeReference;
  42.                   if (att.Tag == "Pages") idsAttPages.Add(idAtt);
  43.                 }
  44.               }
  45.             }
  46.           }
  47.         }
  48.         /////////////////////////////////////////////////////////////////////////////////////
  49.         // Вписывать количество страниц можно только после того, как мы их ВСЕ подсчитали!!!
  50.         /////////////////////////////////////////////////////////////////////////////////////
  51.         if (idsAttPages.Count > 0)
  52.         {
  53.           foreach (ObjectId idAtt in idsAttPages)
  54.           {
  55.             AttributeReference att = tr.GetObject(idAtt, OpenMode.ForWrite) as AttributeReference;
  56.             att.TextString = nPages.ToString();
  57.           }
  58.         }
  59.         tr.Commit();
  60.       }
  61.     }
  62.   }
  63. }
  64.  
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Неожидаемая передача в атрибут
« Ответ #5 : 12-06-2018, 23:55:21 »
А существует ли способ, чтобы напрямую обратится к BlockTableRecord с определенным именем не проходя весь путь через итерации по BlockTable и BlockTableRecord ?
Чтобы получить что? Если ты знаешь имя блока, то можешь из BlockTable (имя переменной пусть будет bt) получить ObjectId для BlockTableRecord с этим именем используя оператор bt["Имя блока"]
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Re: Неожидаемая передача в атрибут
« Ответ #6 : 13-06-2018, 00:14:26 »
ОК, попробую, по результатам напишу.

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Re: Неожидаемая передача в атрибут
« Ответ #7 : 13-06-2018, 19:42:05 »
Все работает, спасибо. То есть моя ошибка в том, что я смешал в одном блоке кода два раздельных действия-подсчет количества и запись в атрибут? А первоначально должен был получить количество и только потом передать в атрибут и это не одновременные процессы, верно?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Неожидаемая передача в атрибут
« Ответ #8 : 13-06-2018, 20:56:41 »
То есть моя ошибка в том, что я смешал в одном блоке кода два раздельных действия-подсчет количества и запись в атрибут?
Да. Но в твоём коде еще масса нелогичных вещей. Например, что это такое:
Код - C# [Выбрать]
  1. allTitles.Add(br.Name.Contains("Title"));
???
Или зачем открывать BlockReference ForWrite, если модифицируешь не его, а AttributeReference.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение