Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Badim от 09-08-2017, 12:49:12

Название: Задача: Прочитать атрибуты в динамическом блоке
Отправлено: Badim от 09-08-2017, 12:49:12
Добрый день, простая задача но никак не получается
Надо из динамического блока прочитать атрибут и его значение

Код - C# [Выбрать]
  1. [CommandMethod("ListAtributes")]
  2.             public void ListAttributes2()
  3.             {
  4.                 String SourceAtribut = "ФРАЗРАБ";
  5.                 ListAttributes("Штамп", ref  SourceAtribut);
  6.  
  7.             }

Первое значение Штамп - название динамического блока
Второе значение Название атрибута, а потом в нем вернется Значение атрибута

Код - C# [Выбрать]
  1. public void ListAttributes(String blockName, ref String SourceAtribut)
  2.  
  3.             {
  4.                 Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  5.                 Database db = HostApplicationServices.WorkingDatabase;
  6.                 Transaction tr = db.TransactionManager.StartTransaction();
  7.  
  8.                 // Start the transaction
  9.                 try
  10.                 {
  11.                    // открываем таблицу блоков на чтение
  12.                     BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  13.  
  14.                     ObjectId btrId = bt[blockName]; // ID - Главного блока
  15.  
  16.                     BlockTableRecord acBlkTblRec = tr.GetObject(btrId, OpenMode.ForRead) as BlockTableRecord;
  17.                     foreach (ObjectId entId in acBlkTblRec)
  18.                     {
  19.                         Entity ent = tr.GetObject(entId, OpenMode.ForRead) as Entity;
  20.  
  21.                         if (ent != null)
  22.                         {
  23.                             BlockReference br = ent as BlockReference;
  24.  
  25.                             if (br != null)
  26.                             {
  27.                                 // Check each of the attributes...
  28.  
  29.                                 foreach (ObjectId arId in br.AttributeCollection)
  30.                                 {
  31.                                     DBObject obj = tr.GetObject(arId, OpenMode.ForRead);
  32.  
  33.                                     AttributeReference ar = obj as AttributeReference;
  34.  
  35.                                     if (ar != null)
  36.                                     {
  37.                              
  38.                                     if (SourceAtribut == ar.Tag)
  39.                                     {
  40.                                         SourceAtribut = ar.TextString;
  41.                                         return;
  42.                                     }
  43.                                  
  44.                                 }
  45.                                     }
  46.                                 }
  47.                             }
  48.                            
  49.                             tr.Commit();
  50.                         }
  51.                     }
  52.                 }
  53.                 catch (Autodesk.AutoCAD.Runtime.Exception ex)
  54.                 {
  55.                     ed.WriteMessage(("Exception: " + ex.Message));
  56.                 }
  57.                 finally
  58.                 {
  59.                     tr.Dispose();
  60.                 }
  61.             }

Выскакивает ошибка при получении - BlockReference
Название: Re: Задача: Прочитать атрибуты в динамическом блоке
Отправлено: trir от 09-08-2017, 12:59:37
потому что это не BlockReference
Название: Re: Задача: Прочитать атрибуты в динамическом блоке
Отправлено: Badim от 09-08-2017, 13:37:17
потому что это не BlockReference
согласен

подскажите пожалуйста, где я ошибаюсь?
Название: Re: Задача: Прочитать атрибуты в динамическом блоке
Отправлено: trir от 09-08-2017, 13:44:59
Нужно открыть ModelSpace и перебрать все Entity - и смотреть их тип, например через wEnt.ObjectId.ObjectClass.DxfName
http://adndevblog.typepad.com/autocad/2012/05/identifying-block-name-from-the-block-reference.html
Название: Re: Задача: Прочитать атрибуты в динамическом блоке
Отправлено: Александр Ривилис от 09-08-2017, 14:22:37
Badim

Начни с этого: Как найти все вставки динамического блока (http://adn-cis.org/kak-najti-vse-vstavki-dinamicheskogo-bloka.html)

Название: Re: Задача: Прочитать атрибуты в динамическом блоке
Отправлено: Badim от 08-09-2017, 13:52:21
Продолжим
добрался до атрибутов, считал значения, но столкнулся с новой бедой
пытаюсь прочитать значение поля а получаю только кучу решоток (######)

так как поле является ссылкой, но значение поля указано и на чертеже отображается


Вопрос: как прочитать значение поля?

Код - C# [Выбрать]
  1.             public void GettingAttributes2()
  2.            
  3.             {
  4.                 // Get the current database and start a transaction
  5.                 Database acCurDb;
  6.                 acCurDb = Application.DocumentManager.MdiActiveDocument.Database;
  7.                 Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  8.  
  9.                 using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  10.                 {
  11.                     // Open the Block table for read
  12.                     BlockTable acBlkTbl;
  13.                     acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
  14.  
  15.                     ObjectId blkRecId = ObjectId.Null;
  16.                         blkRecId = acBlkTbl["Штамп"];
  17.                    
  18.                    if (blkRecId != ObjectId.Null)
  19.                     {
  20.                         BlockTableRecord acBlkTblRec;
  21.                         acBlkTblRec = acTrans.GetObject(blkRecId, OpenMode.ForRead) as BlockTableRecord;
  22.  
  23.                         // Verify block table record has attribute definitions associated with it
  24.                         if (acBlkTblRec.HasAttributeDefinitions)
  25.                             {
  26.                                 // GET attributes from the block table record
  27.                                 foreach (ObjectId objID in acBlkTblRec)
  28.                                 {
  29.                                     DBObject dbObj = acTrans.GetObject(objID, OpenMode.ForRead) as DBObject;
  30.  
  31.                                     if (dbObj is AttributeDefinition)
  32.                                     {
  33.                                         AttributeDefinition acAtt = dbObj as AttributeDefinition;
  34.  
  35.                                         if (!acAtt.Constant)
  36.                                         {
  37.                                                
  38.                                              string acAttTag = acAtt.Tag;
  39.  
  40.                                             if (acAtt.Tag == "ФРАЗРАБ")
  41.                                         {
  42.                                          
  43. // Здесь и получаем одни решеточки
  44.                                              ed.WriteMessage("\nАтрибут \"{0}\" значение {1} \n", acAtt.Tag, acAtt.TextString);
  45.                                         }
  46.  
  47.                                        
  48.                                        
  49.                                     }
  50.                                     }
  51.                                 }
  52.                                
  53.                             }
  54.           }
  55.  
  56.                    acTrans.Commit();
  57.  
  58.                     // Dispose of the transaction
  59.                 }
  60.             }
  61.  
(https://s26.postimg.org/wsdog63jp/image.jpg) (https://postimg.org/image/wsdog63jp/)
Название: Re: Задача: Прочитать атрибуты в динамическом блоке
Отправлено: Александр Ривилис от 08-09-2017, 15:17:37
Ты смотришь в определении блока (BlockTableRecord) определение атрибута (AttributeDefinition). А должен найти вставку блока (BlockReference) и относящийся к нему атрибут (AttributeReference) и из него брать значение.
Название: Re: Задача: Прочитать атрибуты в динамическом блоке
Отправлено: Badim от 12-09-2017, 09:04:36
корявенько, но получилось

Код - C# [Выбрать]
  1.  public void selectDynamicBlockReferences2()
  2.             {
  3.                 Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  4.                 Database db = Application.DocumentManager.MdiActiveDocument.Database;
  5.                 using (Transaction trans = db.TransactionManager.StartTransaction())
  6.                 {
  7.                     // получаем таблицу блоков
  8.                     BlockTable bt =
  9.                       (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
  10.                     ObjectId btrId = ObjectId.Null;
  11.                     btrId = bt["Штамп"];
  12.  
  13.                         // получаем запись таблицы блоков и смотри анонимная ли она
  14.                         BlockTableRecord btr = (BlockTableRecord)trans.GetObject(btrId, OpenMode.ForRead);
  15.                         if (btr.IsDynamicBlock)
  16.                         {
  17.                             // получаем все анонимные блоки динамического блока
  18.                             ObjectIdCollection anonymousIds = btr.GetAnonymousBlockIds();
  19.                             // получаем все прямые вставки динамического блока
  20.                             ObjectIdCollection dynBlockRefs = btr.GetBlockReferenceIds(true, true);
  21.                             foreach (ObjectId anonymousBtrId in anonymousIds)
  22.                             {
  23.                                 // получаем анонимный блок
  24.                                 BlockTableRecord anonymousBtr = (BlockTableRecord)trans.GetObject(anonymousBtrId, OpenMode.ForRead);
  25.                                 // получаем все вставки этого блока
  26.                                 ObjectIdCollection blockRefIds = anonymousBtr.GetBlockReferenceIds(true, true);
  27.                                 foreach (ObjectId id in blockRefIds)
  28.                                 {
  29.                                     dynBlockRefs.Add(id);
  30.                                
  31.                                     BlockReference blkRef = (BlockReference)trans.GetObject(id, OpenMode.ForRead);
  32.  
  33.                                     BlockTableRecord btr2 = (BlockTableRecord)trans.GetObject(blkRef.BlockTableRecord, OpenMode.ForRead);
  34.  
  35.                                     ed.WriteMessage("\nBlock: " + btr2.Name);
  36.                                     btr2.Dispose();
  37.  
  38.                                     AttributeCollection attCol = blkRef.AttributeCollection;
  39.  
  40.                                     foreach (ObjectId attId in attCol)
  41.                                     {
  42.                                         AttributeReference attRef = (AttributeReference)trans.GetObject(attId, OpenMode.ForRead);
  43.  
  44.                                     string str = ("\n  Attribute Tag: " + attRef.Tag + "\n    Attribute String: " + attRef.TextString);
  45.                                         ed.WriteMessage(str);
  46.                                     }
  47.                                 }
  48.                             }
  49.                             // Что-нибудь делаем с созданным нами набором
  50.                             ed.WriteMessage("\nДинамическому блоку \"{0}\" соответствуют {1} анонимных блоков и {2} вставок блока\n",
  51.                                 btr.Name, anonymousIds.Count, dynBlockRefs.Count);
  52.                         }
  53.                 }
  54.             }
  55.  

вопрос,
никак не нашел объяснения путнего между Анонимным блоком и Вхождением блока

(в целях ликвидации безграмотности, среди отдельно взятого индивидума, объясните пожалуйста)

как это понимаю я:
в чертеже, в Таблице блоков хранятся все Именованные блоки, которые создал пользователь
Когда блок вставляем на лист или модель  - получаем Вхождение блока и сразу Анонимный блок (*U)
Когда блок вставили на лист 10 раз  - получили 10 Вхождений и 10 Анонимных блоков (*U1, *U2, ... ,*U10)

Еще, если блок ставить несколько раз(вхождения) то данные фрагмент кода, не видит другие копии
Название: Re: Задача: Прочитать атрибуты в динамическом блоке
Отправлено: Александр Ривилис от 12-09-2017, 10:13:29
Не просто корявенько, а очень корявенько. Где trans.Commit()? Зачем btr2.Dispose();?
как это понимаю я:
в чертеже, в Таблице блоков хранятся все Именованные блоки, которые создал пользователь
Когда блок вставляем на лист или модель  - получаем Вхождение блока и сразу Анонимный блок (*U)
Когда блок вставили на лист 10 раз  - получили 10 Вхождений и 10 Анонимных блоков (*U1, *U2, ... ,*U10)

Еще, если блок ставить несколько раз(вхождения) то данные фрагмент кода, не видит другие копии
1. В таблице блоков хранятся как именованные блоки созданные пользователем или попавшие туда другим образом (например, вставили из другого чертежа), так и неименованные - это и варианты динамического блока и размерные блоки и т.д. и т.п.
2. При вставке динамического блока получается анонимный если мы изменили параметры динамического блока (например, параметр видимости).
3. Не при каждой вставке динамического блока появлется новый анонимный. На один и тот же анонимный могут ссылаться несколько вставок блока если их параметры совпадают.
Название: Re: Задача: Прочитать атрибуты в динамическом блоке
Отправлено: Александр Ривилис от 12-09-2017, 10:19:36
Еще, если блок ставить несколько раз(вхождения) то данные фрагмент кода, не видит другие копии
Потому что ты обрабатываешь только вставки анонимного блока, но не обрабатываешь вставки основного (динамического) блока.
Т.е. в коде должно быть как-то так:
Код - C# [Выбрать]
  1. foreach (ObjectId id in blockRefIds)
  2. {
  3.   dynBlockRefs.Add(id);
  4. }
  5. foreach (ObjectId id in dynBlockRefs)
  6. {
  7.   // Здесь печатаешь атрибуты блока
  8. }
  9.