Обновление атрибутов блоков на всех листах чертежа

Автор Тема: Обновление атрибутов блоков на всех листах чертежа  (Прочитано 15161 раз)

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

Оффлайн ДианкаАвтор темы

  • ADN Club
  • Сообщений: 41
  • Карма: 0
Добрый день(утро) :)
Александр,воспользовалась Вашим вариантом обновления атрибутов блока,но у меня почему то обновляет атрибут только в данном листе %(.
а мне бы хотелось что бы по всем листам обновилось,вроде всё логично....
http://www.caduser.ru/forum/index.php?PAGE_NAME=read&FID=49&TID=24143-тут Ваш код.

хочу уточнить,я вставляю блок в один лист,потом копирую его в другой,т.к. вставка этого же блока из программы мною запрещена,.и потом я запускаю программу обновления,

Вот код на обновление..
Код - C# [Выбрать]
  1.  private void UptAttISO(double AttFontHeight)
  2.         {
  3.             Document doc = acadApp.DocumentManager.MdiActiveDocument;
  4.             Editor ed = doc.Editor;
  5.             Transaction tr = doc.TransactionManager.StartTransaction();
  6.             using (tr)
  7.             {
  8.                 Database curdb = doc.Database;
  9.                 BlockTable bt = (BlockTable)tr.GetObject(curdb.BlockTableId, OpenMode.ForRead);//
  10.                 //BlockTableRecord ps = tr.GetObject(curdb.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;-это мой старый вариант
  11.                 BlockTableRecord ps = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForRead); -эту строку я сегодня поменяла,но не работает.
  12.                 foreach (ObjectId obId in ps)
  13.                 {
  14.                     DBObject dbObj = tr.GetObject(obId, OpenMode.ForRead);
  15.                     BlockReference blkRef = dbObj as BlockReference;
  16.                     if (blkRef != null)
  17.                     {
  18.                         BlockTableRecord blkDef = (BlockTableRecord)tr.GetObject(blkRef.BlockTableRecord, OpenMode.ForRead);
  19.                         if (blkDef.Name.ToUpper() == "SHTAMP") ///мой блок
  20.                             foreach (ObjectId idAtt in blkRef.AttributeCollection)
  21.                             {
  22.                                 Entity ent = (Entity)tr.GetObject(idAtt, OpenMode.ForWrite);
  23.                                 if (ent is AttributeReference)
  24.                                 {
  25.                                     AttributeReference attRef = (AttributeReference)ent;
  26.                                     if (attRef.Tag.ToUpper() == "PRJNAME")
  27.                                     {
  28.                                         attRef.Height = AttFontHeight;
  29.                                         attRef.TextString = txt_PrjName.Text.Trim();
  30.  
  31.                                     }
  32.                                     ///Проверка на стандарт.
  33.                                     //MessageBox.Show("Стандарт   \n" + STD);
  34.                                     if (attRef.Tag.ToUpper() == "SHIFR")
  35.                                     {
  36.                                         attRef.TextString = txt_Shifr.Text.Trim();
  37.                                     }
  38.                                  
  39.                                   }
  40.                               }
  41.                             }
  42.                        }
  43.                 }
  44.                 tr.Commit();
  45.             }
  46.         }

Один вопрос - одна тема. Тему разделил. /* Александр Ривилис */
« Последнее редактирование: 25-11-2014, 11:50:39 от Александр Ривилис »

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
1) При помощи LayoutManager нужно получить коллекцию ObjectId для всех Layout'ов (Листов)
2) По очереди открыть каждый Layout, найти его layout.BlockTableRecordId и использовать его в твоем коде вместо bt[BlockTableRecord.PaperSpace]
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДианкаАвтор темы

  • ADN Club
  • Сообщений: 41
  • Карма: 0
Что-то у меня не то получается  :(
вроде логически понимаю что надо,а как на практике -нет.У меня нет опыта работы что в лиспе,что в .NET



Код - C# [Выбрать]
  1.  
  2. Document doc = acadApp.DocumentManager.MdiActiveDocument;
  3.             Editor ed = doc.Editor;
  4.             Transaction tr = doc.TransactionManager.StartTransaction();
  5.             using (tr)
  6.             {
  7.                 Database curdb = doc.Database;
  8.                 BlockTable bt = (BlockTable)tr.GetObject(curdb.BlockTableId, OpenMode.ForRead);//
  9.                 LayoutManager Lm = LayoutManager.Current;
  10.                 ObjectId lyid = ObjectId.Null;
  11.                 Layout layout = tr.GetObject(Lm.GetLayoutId(Lm.CurrentLayout), OpenMode.ForRead) as Layout;
  12.                 BlockTableRecord olo = (BlockTableRecord)tr.GetObject(layout.BlockTableRecordId, OpenMode.ForWrite);
  13.                 foreach (ObjectId obId in olo)
  14.                 {
  15.                     DBObject dbObj = tr.GetObject(obId, OpenMode.ForRead);
  16.                     BlockReference blkRef = dbObj as BlockReference;
  17.                     if (blkRef != null)
  18.                     {
  19.                         BlockTableRecord blkDef = (BlockTableRecord)tr.GetObject(blkRef.BlockTableRecord, OpenMode.ForRead);
  20.                         if (blkDef.Name.ToUpper() == "SHTAMP") ///мой блок
  21.                             foreach (ObjectId idAtt in blkRef.AttributeCollection)
  22.                             {
  23.                                 Entity ent = (Entity)tr.GetObject(idAtt, OpenMode.ForWrite);
  24.                                 if (ent is AttributeReference)
  25.                                 {
  26.                                     AttributeReference attRef = (AttributeReference)ent;
  27.                                     if (attRef.Tag.ToUpper() == "PRJNAME")
  28.                                     {
  29.                                         attRef.Height = AttFontHeight;
  30.                                         attRef.TextString = txt_PrjName.Text.Trim();
  31.                                     }
  32.                                    
  33.                                             /////////////////////=======//////
  34.                             }
  35.                     tr.Commit();
  36.                 }
  37.             }
« Последнее редактирование: 09-12-2014, 18:06:12 от Дианка »

Оффлайн ДианкаАвтор темы

  • ADN Club
  • Сообщений: 41
  • Карма: 0
немного изменила...
но все равно ошибка
Код - C# [Выбрать]
  1.            BlockTableRecord olo = (BlockTableRecord)tr.GetObject(layout.BlockTableRecordId, OpenMode.ForWrite);
  2.                 foreach (ObjectId obId in olo)
  3.                 {
  4.                     BlockReference blkRef = tr.GetObject(obId, OpenMode.ForRead) as BlockReference; /// НА этой строке ошибка.
  5.                     if (blkRef != null)
  6.                     {
  7.                         BlockTableRecord blkDef = (BlockTableRecord)tr.GetObject(blkRef.BlockTableRecord, OpenMode.ForRead);
  8.                         if (blkDef.Name.ToUpper() == "SHTAMP") ///мой блок
  9.                             foreach (ObjectId idAtt in blkRef.AttributeCollection)
  10.                             {
  11.                                 Entity ent = (Entity)tr.GetObject(idAtt, OpenMode.ForWrite);
  12.                                 if (ent is AttributeReference)
  13.                                 {
  14.                                     AttributeReference attRef = (AttributeReference)ent;
  15.                                     if (attRef.Tag.ToUpper() == "PRJNAME")
  16.                                     { attRef.Height = AttFontHeight;
  17.                                         attRef.TextString = txt_PrjName.Text.Trim();
  18.                                     }
  19. ..................
  20.  
  21.  

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Код совсем не проверял, но идея должна быть понятна:
Код - C# [Выбрать]
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Reflection;
  4. using Autodesk.AutoCAD.Runtime;
  5. using Autodesk.AutoCAD.ApplicationServices;
  6. using Autodesk.AutoCAD.DatabaseServices;
  7. using Autodesk.AutoCAD.Geometry;
  8. using Autodesk.AutoCAD.EditorInput;
  9. using AcRx = Autodesk.AutoCAD.Runtime;
  10. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  11. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  12. using AcGe = Autodesk.AutoCAD.Geometry;
  13. using AcEd = Autodesk.AutoCAD.EditorInput;
  14.  
  15. [assembly: CommandClass(typeof(Rivilis.AttributeUpdater))]
  16.  
  17. namespace Rivilis
  18. {
  19.   public class AttributeUpdater
  20.   {
  21.     [CommandMethod("UpdAttrs")]
  22.     public void UpdAttrs()
  23.     {
  24.       double aHeight = 2.5;
  25.       string aPrjName = "Мой Проект";
  26.       string aDwgName = "Мой Чертеж";
  27.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  28.       AcEd.Editor ed = doc.Editor;
  29.       AcDb.Database db = doc.Database;
  30.       using (AcDb.Transaction tr = doc.TransactionManager.StartTransaction())
  31.       {
  32.         //////////////////////////////////////////////////////////////////////////
  33.         // Проходим по всем листам чертежа. Нам попадется и модель и мы можем
  34.         // обработать ее отдельно
  35.         //////////////////////////////////////////////////////////////////////////
  36.         AcDb.DBDictionary dict =
  37.           tr.GetObject(db.LayoutDictionaryId, AcDb.OpenMode.ForRead) as AcDb.DBDictionary;
  38.         foreach (AcDb.DBDictionaryEntry eDict in dict)
  39.         {
  40.           AcDb.Layout layout = tr.GetObject(eDict.Value, AcDb.OpenMode.ForRead) as AcDb.Layout;
  41.           // Если Пространство Модели нас не интересует - раскоментарь следующую строку
  42.           // if (layout.LayoutName == AcDb.BlockTableRecord.ModelSpace) continue;
  43.           AcDb.BlockTableRecord btrSpace =
  44.             tr.GetObject(layout.BlockTableRecordId, AcDb.OpenMode.ForRead) as AcDb.BlockTableRecord;
  45.           foreach (AcDb.ObjectId id in btrSpace)
  46.           {
  47.             if (id.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(AcDb.BlockReference))))
  48.             {
  49.               AcDb.BlockReference bRef =
  50.                 tr.GetObject(id, AcDb.OpenMode.ForRead) as AcDb.BlockReference;
  51.               AcDb.ObjectId idBtr;
  52.               if (bRef.IsDynamicBlock)  idBtr = bRef.DynamicBlockTableRecord;
  53.                             else        idBtr = bRef.BlockTableRecord;
  54.               AcDb.BlockTableRecord bBtr =
  55.                 tr.GetObject(idBtr, AcDb.OpenMode.ForRead) as AcDb.BlockTableRecord;
  56.               // Если это не наш блок, то нам и делать нечего...
  57.               if (bBtr.Name.ToUpper() != "SHTAMP") continue;
  58.  
  59.               AcDb.AttributeCollection attrs = bRef.AttributeCollection;
  60.               foreach (AcDb.ObjectId idAttr in attrs)
  61.               {
  62.                 AcDb.AttributeReference attr =
  63.                   tr.GetObject(idAttr, AcDb.OpenMode.ForRead) as AcDb.AttributeReference;
  64.                 switch (attr.Tag.ToUpper())
  65.                 {
  66.                   case "PRJNAME":
  67.                     attr.UpgradeOpen();
  68.                     attr.Height = aHeight;
  69.                     attr.TextString = aPrjName;
  70.                     break;
  71.                   case "DWGNAME":
  72.                     attr.UpgradeOpen(); // Этой строки не хватало в первом варианте
  73.                     attr.Height = aHeight;
  74.                     attr.TextString = aDwgName;
  75.                     break;
  76.                 }
  77.               }
  78.             }
  79.           }
  80.         }
  81.         tr.Commit();
  82.       }
  83.     }
  84.   }
  85. }
« Последнее редактирование: 11-12-2014, 00:02:20 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДианкаАвтор темы

  • ADN Club
  • Сообщений: 41
  • Карма: 0
 :o как же красиво!
 Спасибо...распробую.

Оффлайн ДианкаАвтор темы

  • ADN Club
  • Сообщений: 41
  • Карма: 0
в общем получился фатал эррор )я даже не могла включать эту..как её ,пошаговую проверку..
у меня в последнее время ругается на CONTEXT

в итоге я сделала так, достала все Листы, добавила их ID в collection и потом перебором обновляла.(видимо как Вы и советовали,но исполнила иначе)

Код - C# [Выбрать]
  1.                   DBDictionary lays =tr.GetObject(db.LayoutDictionaryId,
  2.                             OpenMode.ForRead) as DBDictionary;
  3.  
  4.                     foreach (DBDictionaryEntry item in lays)
  5.                     {
  6.                         if (item.Key == "Model") continue;
  7.                         {
  8.                             MyData.LayIdColl.Add(GetSpaceId(db, item.Key));
  9.                         }
  10.                     }

Код - C# [Выбрать]
  1. public static ObjectId GetSpaceId(Database db, string layoutName)
  2.         {
  3.             using (Transaction trans = db.TransactionManager.StartTransaction())
  4.             {
  5.                 var layoutDict = (DBDictionary)trans.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);
  6.                 ObjectId layoutId = layoutDict.GetAt(layoutName);
  7.                 var layout = (Layout)trans.GetObject(layoutId, OpenMode.ForRead);
  8.                 return layout.BlockTableRecordId;
  9.  
  10.             }
  11.         }
Код - C# [Выбрать]
  1. foreach (ObjectId obj in MyData.LayIdColl)
  2.                     {
  3.                         UptAttISO(AttFontHeight, obj);
  4.                     }
  5.  
  6.  
  7. //////////
  8.  
  9.  
  10. private void UptAttISO(double AttFontHeight, ObjectId btrId)
  11.  
  12.  

« Последнее редактирование: 10-12-2014, 18:06:35 от Дианка »

Оффлайн ДианкаАвтор темы

  • ADN Club
  • Сообщений: 41
  • Карма: 0
завтра попробую это всё скомпоновать в код покороче...если получится %)

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Не увидел у тебя ни одного вызова trans.Commit(); что означает откат изменений.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Появилась минутка и я проверил свой код. Не хватало сразу после
Код - C# [Выбрать]
  1. case "DWGNAME":
строки
Код - C# [Выбрать]
  1. attr.UpgradeOpen();
Подправил. Код отработал именно так, как указано в постановке задачи.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДианкаАвтор темы

  • ADN Club
  • Сообщений: 41
  • Карма: 0
Доброе утро,ну я естественно не кидала весь код ,у меня в конце там есть коммит,просто что бы суть объяснить, что я натворила %)


Оффлайн ДианкаАвтор темы

  • ADN Club
  • Сообщений: 41
  • Карма: 0
Появилась минутка и я проверил свой код. Не хватало сразу после
Код - C#: [Выделить]
case "DWGNAME":
строки
Код - C#: [Выделить]
attr.UpgradeOpen();
Подправил. Код отработал именно так, как указано в постановке задачи.

странно,я конечно же не копировала -не глядя...я код набирала от руки %) ну что бы хоть кусочек отложился в голове,и соответственно адаптировала под свои данные, т.е. писала не абстрактные таги,а таги свои,и соответственно после каждого кэйс я ставила UpgradeOpen() -по примеру  первой строки -66 линия в Вашем примере...но всё же вылетал фатал.

а почему у меня не работает отладка,(перестала) я пока не разбиралась,видимо проблема в настройках Visual Studio.А так бы я могла сказать на какой строке затык.)


в любом случае спасибо за идею про лэйауты!

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Доброе утро,ну я естественно не кидала весь код ,у меня в конце там есть коммит,просто что бы суть объяснить что я натворила %)
Я имел в виду метод GetSpaceId, который вроде полностью и в котором нет trans.Commit(). И на будущее - не кидайся обрывками кодов. Если даешь код, то только полностью. Тогда хоть можно было понять что в коде не так...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
...я код набирала от руки %)
Это мне напомнило старый еврейский анекдот:
Цитировать
Беседуют два еврея.
 - Не понимаю, почему люди так восхищаются этим Карузо? Косноязычен, гугнив, поёт - ничего не разберёшь!
 - А вы слышали, как поёт Карузо?
 - Да, мне тут кое-что из его репертуара Рабинович напел по телефону.
   ***

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

Оффлайн ДианкаАвтор темы

  • ADN Club
  • Сообщений: 41
  • Карма: 0
Я имел в виду метод GetSpaceId, который вроде полностью и в котором нет trans.Commit(). И на будущее - не кидайся обрывками кодов. Если даешь код, то только полностью. Тогда хоть можно было понять что в коде не так...
а нужно обязателельно закоммитить?? может я туплю,но я где то урывком вроде читала что если using то коммит не обязательно или я не так поняла %) и имеет ли значение что эта функция в цикле учавствует..Я просто боюсь лишний раз строку написать ,дабы не полетело всё это километровое "Добро" )))))

А про анекдот-намёк что я типо коряво набрала ,получается )))
просто когда то,на каких то курсах,учили не тупо копировать код а набирать )))) дабы в голове чуток откладывалось )))