Как задать свои значения атрибутов для каждой вставки блока

Автор Тема: Как задать свои значения атрибутов для каждой вставки блока  (Прочитано 7345 раз)

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Здравствуйте!

Кто-нибудь может помочь с примером кода установки атрибута в блоке? Проблема вот в чем:
Вставляю программно блок с атрибутами в пространство модели. Все в порядке, далее повторяю то же самое для второй позиции и последующих. Всего около 500 штук. Добавление вставок блока в цикле через запуск метода InsertSpaceTag. Проблема в том что не получается установить значения атрибутов для каждой вставки - все они создаются со значениями первой позиции, а все позиции содержат свои уникальные данные. Подскажите- что не так?
Код - C# [Выбрать]
  1. public void InsertSpaceTag(string spaceDesignation, string buildingNumber, string idOneC, Point3d insertionPoint)
  2.         {
  3.             Document doc = Application.DocumentManager.MdiActiveDocument;
  4.             Database db = doc.Database;
  5.  
  6.             //Point3d insertionPoint=insertionPoint;// = doc.Editor.GetPoint("Set point").Value;
  7.  
  8.             using (Transaction acTrans = db.TransactionManager.StartTransaction())
  9.             {
  10.                 // Open the Block table for read
  11.                 BlockTable acBlkTbl = acTrans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  12.  
  13.                 ObjectId blkRecId = ObjectId.Null;
  14.  
  15.                 if (!acBlkTbl.Has("SpaceTag"))
  16.                 {
  17.                     using (BlockTableRecord acBlkTblRec = new BlockTableRecord())
  18.                     {
  19.                         acBlkTblRec.Name = "SpaceTag";
  20.  
  21.                         // Set the insertion point for the block
  22.                         acBlkTblRec.Origin = new Point3d(0, 0, 0);
  23.  
  24.                         // Add a circle to the block
  25.                         using (Circle acCirc = new Circle())
  26.                         {
  27.                             acCirc.Center = new Point3d(0, 0, 0);
  28.                             acCirc.Radius = 4.5;
  29.  
  30.                             acBlkTblRec.AppendEntity(acCirc);
  31.  
  32.                             acBlkTbl.UpgradeOpen();
  33.                             acBlkTbl.Add(acBlkTblRec);
  34.                             acTrans.AddNewlyCreatedDBObject(acBlkTblRec, true);
  35.  
  36.                             // Add an attribute definition to the block
  37.                             using (AttributeDefinition posNumber = new AttributeDefinition())
  38.                             {
  39.                                 posNumber.Position = new Point3d(0, 0, 0);
  40.                                 posNumber.Prompt = "Position Number";
  41.                                 posNumber.Tag = "PosNumber";
  42.                                 posNumber.TextString = "1";
  43.                                 posNumber.Height = acCirc.Radius * 0.7;
  44.                                 posNumber.Justify = AttachmentPoint.MiddleCenter;
  45.                                 acBlkTblRec.AppendEntity(posNumber);
  46.                             }
  47.  
  48.                             using (AttributeDefinition designation = new AttributeDefinition())
  49.                             {
  50.                                 designation.Position = new Point3d(0, -5, 0);
  51.                                 designation.Prompt = "Designation";
  52.                                 designation.Tag = "Designation";
  53.                                 designation.TextString = spaceDesignation;
  54.                                 designation.Invisible = true;
  55.                                 designation.Height = 5;
  56.                                 designation.Justify = AttachmentPoint.MiddleCenter;
  57.                                 acBlkTblRec.AppendEntity(designation);
  58.                             }
  59.  
  60.                             using (AttributeDefinition spaceNumber = new AttributeDefinition())
  61.                             {
  62.                                 spaceNumber.Position = new Point3d(0, -10, 0);
  63.                                 spaceNumber.Prompt = "Space number";
  64.                                 spaceNumber.Tag = "SpaceNumber";
  65.                                 spaceNumber.TextString = buildingNumber;
  66.                                 spaceNumber.Invisible = true;
  67.                                 spaceNumber.Height = 5;
  68.                                 spaceNumber.Justify = AttachmentPoint.MiddleCenter;
  69.                                 acBlkTblRec.AppendEntity(spaceNumber);
  70.                             }
  71.  
  72.                             using (AttributeDefinition mainWatertightCompartment = new AttributeDefinition())
  73.                             {
  74.                                 mainWatertightCompartment.Position = new Point3d(0, -15, 0);
  75.                                 mainWatertightCompartment.Prompt = "Main watertight compartment";
  76.                                 mainWatertightCompartment.Tag = "MWC";
  77.                                 mainWatertightCompartment.TextString = "01";
  78.                                 mainWatertightCompartment.Invisible = true;
  79.                                 mainWatertightCompartment.Height = 5;
  80.                                 mainWatertightCompartment.Justify = AttachmentPoint.MiddleCenter;
  81.                                 acBlkTblRec.AppendEntity(mainWatertightCompartment);
  82.                             }
  83.  
  84.                             using (AttributeDefinition gastightContour = new AttributeDefinition())
  85.                             {
  86.                                 gastightContour.Position = new Point3d(0, -20, 0);
  87.                                 gastightContour.Prompt = "Gastight contour";
  88.                                 gastightContour.Tag = "GastightContour";
  89.                                 gastightContour.TextString = "015";
  90.                                 gastightContour.Invisible = true;
  91.                                 gastightContour.Height = 5;
  92.                                 gastightContour.Justify = AttachmentPoint.MiddleCenter;
  93.                                 acBlkTblRec.AppendEntity(gastightContour);
  94.                             }
  95.  
  96.                             using (AttributeDefinition fireRatingClass = new AttributeDefinition())
  97.                             {
  98.                                 fireRatingClass.Position = new Point3d(0, -25, 0);
  99.                                 fireRatingClass.Prompt = "Fire rating class";
  100.                                 fireRatingClass.Tag = "FireRatingClass";
  101.                                 fireRatingClass.TextString = "1";
  102.                                 fireRatingClass.Invisible = true;
  103.                                 fireRatingClass.Height = 5;
  104.                                 fireRatingClass.Justify = AttachmentPoint.MiddleCenter;
  105.                                 acBlkTblRec.AppendEntity(fireRatingClass);
  106.                             }
  107.  
  108.                             using (AttributeDefinition OneCId = new AttributeDefinition())
  109.                             {
  110.                                 OneCId.Position = new Point3d(0, -25, 0);
  111.                                 OneCId.Prompt = "One C Id";
  112.                                 OneCId.Tag = "OneCId";
  113.                                 OneCId.TextString = idOneC;
  114.                                 OneCId.Invisible = true;
  115.                                 OneCId.Height = 5;
  116.                                 OneCId.Justify = AttachmentPoint.MiddleCenter;
  117.                                 acBlkTblRec.AppendEntity(OneCId);
  118.                             }
  119.  
  120.                             blkRecId = acBlkTblRec.Id;
  121.                         }
  122.                     }
  123.                 }
  124.                 else
  125.                 {
  126.                     blkRecId = acBlkTbl["SpaceTag"];
  127.                 }
  128.  
  129.                 // Insert the block into the current space
  130.                 if (blkRecId != ObjectId.Null)
  131.                 {
  132.                     BlockTableRecord acBlkTblRec = acTrans.GetObject(blkRecId, OpenMode.ForRead) as BlockTableRecord;
  133.  
  134.                     // Create and insert the new block reference
  135.                     using (BlockReference acBlkRef = new BlockReference(insertionPoint, blkRecId))
  136.                     {
  137.                         BlockTableRecord acCurSpaceBlkTblRec = acTrans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
  138.  
  139.                         acCurSpaceBlkTblRec.AppendEntity(acBlkRef);
  140.                         acTrans.AddNewlyCreatedDBObject(acBlkRef, true);
  141.  
  142.                         // Verify block table record has attribute definitions associated with it
  143.                         if (acBlkTblRec.HasAttributeDefinitions)
  144.                         {
  145.                             foreach (ObjectId objID in acBlkTblRec)
  146.                             {
  147.                                 DBObject dbObj = acTrans.GetObject(objID, OpenMode.ForRead);
  148.  
  149.                                 if (dbObj is AttributeDefinition)
  150.                                 {
  151.                                     AttributeDefinition acAtt = dbObj as AttributeDefinition;
  152.  
  153.                                     if (!acAtt.Constant)
  154.                                     {
  155.                                         using (AttributeReference acAttRef = new AttributeReference())
  156.                                         {
  157.                                             acAttRef.SetAttributeFromBlock(acAtt, acBlkRef.BlockTransform);
  158.                                             acAttRef.Position = acAtt.Position.TransformBy(acBlkRef.BlockTransform);
  159.                                             if ( acAttRef.Tag== "OneCId")
  160.                                             {
  161.                                                 acAttRef.TextString = idOneC;
  162.                                             }
  163.                                             if (acAttRef.Tag == "SpaceNumber")
  164.                                             {
  165.                                                 acAttRef.TextString = buildingNumber;
  166.                                             }
  167.                                             if (acAttRef.Tag == "Designation")
  168.                                             {
  169.                                                 acAttRef.TextString = spaceDesignation;
  170.                                             }
  171.                                             if (acAttRef.Tag == "PosNumber")
  172.                                             {
  173.                                                 acAttRef.TextString = idOneC;
  174.                                             }
  175.  
  176.                                             else acAttRef.TextString = acAtt.TextString;
  177.                                             acBlkRef.AttributeCollection.AppendAttribute(acAttRef);
  178.                                             acTrans.AddNewlyCreatedDBObject(acAttRef, true);
  179.                                         }
  180.                                     }
  181.                                 }
  182.                             }
  183.                         }
  184.                     }
  185.                 }
  186.  
  187.                 acTrans.Commit();
  188.             }
  189.         }

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Подскажите- что не так?
Запусти под отладчиком и посмотри. На первый взгляд всё в порядке если ты передаёшь при каждом вызове разные параметры.
Впрочем я не увидел acTrans.AddNewlyCreatedDBObject для определений атрибутов.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 546
  • Карма: 119
Проблема в том что не получается установить значения атрибутов для каждой вставки - все они создаются со значениями первой позиции, а все позиции содержат свои уникальные данные. Подскажите- что не так?


Код - C# [Выбрать]
  1. if (acAttRef.Tag == "PosNumber")
  2. {
  3.    acAttRef.TextString = idOneC;
  4. }
  5. else acAttRef.TextString = acAtt.TextString;
  6.  

В конце условия получается, что если атрибут не  "PosNumber", тогда значение взять из AttributeDefinition.

Поменяй "if"  на "else if" между "if ( acAttRef.Tag== "OneCId")" и else.

Отмечено как Решение Atomohod 21-01-2020, 21:52:54

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Atomohod,
Привалов Дмитрий,
Точно. Не заметил сразу где подвох в этом нагромождении using'оф, if'ов и т.д.
Atomohod,
Всю конструкцию с if'ами нужно заменить на такую:
Код - C# [Выбрать]
  1. switch (acAttRef.Tag)
  2. {
  3.   case "OneCId":
  4.     acAttRef.TextString = idOneC;
  5.     break;
  6.   case "SpaceNumber":
  7.     acAttRef.TextString = buildingNumber;
  8.     break;
  9.   case "Designation":
  10.     acAttRef.TextString = spaceDesignation;
  11.     break;
  12.   case "PosNumber":
  13.     acAttRef.TextString = idOneC;
  14.     break;
  15.   default:
  16.     acAttRef.TextString = acAtt.TextString;
  17.     break;
  18. }

Тогда логика работы будет прозрачнее.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Atomohod, нерационально использовать using для объектов и транзакцию одновременно.
Когда ты выполняешь AddNewlyCreatedDBObject для объекта, транзакция начинает управлять закрытием этого объекта и закроет все такие объекты по завершению транзакции. Отдельная конструкция using для них становится лишней. Единственный вариант, когда это может потребоваться - это если объект должен быть обязательно принудительно закрыт раньше, чем закончится транзакция. Но в таком случае лучше тогда разделять транзакцию на несколько, чтобы не запутаться потом.

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
нерационально использовать using для объектов и транзакцию одновременно.
А к чему это приводит - расход памяти, увеличение времени обработки?
если объект должен быть обязательно принудительно закрыт раньше, чем закончится транзакция
Что за случаи? Где можно встретить?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А к чему это приводит - расход памяти, увеличение времени обработки?
К смешиванию различных методов открытия/закрытия объектов, что чревато ошибками и аварийным завершением AutoCAD.
Что за случаи? Где можно встретить?
Множество различных случаев, не описанных нигде. Но встречающихся в жизни и неоднократно решенных на этом форуме.
Вот например: https://adn-cis.org/forum/index.php?topic=9642.0
« Последнее редактирование: 22-01-2020, 15:50:18 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
А к чему это приводит - расход памяти, увеличение времени обработки?
В лёгких случаях - к некрасивому форматированию кода из-за лишних отступов и усложнение чтения этого кода. В более серьёзных - как Александр Наумович сказал:
чревато ошибками и аварийным завершением AutoCAD
Что за случаи? Где можно встретить?
Вот пример: https://adn-cis.org/forum/index.php?topic=7829.msg26408#msg26408
Правда, там это касается OpenCloseTransaction. Но суть от этого не меняется.