Создание нового листа по шаблону

Автор Тема: Создание нового листа по шаблону  (Прочитано 5371 раз)

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

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

  • ADN Club
  • Сообщений: 16
  • Карма: 0
  • Skype: myckola_kolomoets
Имеется функция разбивки выделенного фрагмента на листы. Создание новых листов на основе шаблона делает следующая функция:

Код - C# [Выбрать]
  1. private ObjectId CopyLayout(String fileName, ref String layName, ref String paperName, ref ObjectId newViewPortId, int paperNo)
  2.         {
  3.             Database templateDb = new Database(false, true);
  4.             templateDb.ReadDwgFile(fileName, FileOpenMode.OpenForReadAndAllShare, true, "");
  5.             int pageWidth = 0;
  6.             Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  7.             Editor ed = doc.Editor;
  8.             Database db = doc.Database;
  9.  
  10.             Layout newLayout;
  11.             LayoutManager layManager = LayoutManager.Current;
  12.  
  13.             using (Transaction trx = db.TransactionManager.StartTransaction())
  14.             {
  15.                 using (Transaction templateTrx = templateDb.TransactionManager.StartTransaction())
  16.                 {
  17.                     DBDictionary layoutDictionary = trx.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
  18.                     while (layoutDictionary.Contains(paperName + paperNo.ToString()))
  19.                     {
  20.                         ed.WriteMessage("\nЭтот чертеж уже содержит лист с именем {0}. ", paperName + paperNo.ToString());
  21.                         PromptStringOptions strOpt = new PromptStringOptions("Укажите имя листа: ");
  22.                         PromptResult strRes = ed.GetString(strOpt);
  23.                         if (strRes.Status != PromptStatus.OK)
  24.                         {
  25.                             MessageBox.Show("Ввод данных отменен");
  26.                             return new ObjectId();
  27.                         }
  28.                         paperName = strRes.StringResult;
  29.                     }
  30.  
  31.                     DBDictionary templateLayoutDictionary = templateTrx.GetObject(templateDb.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
  32.                     if (!(templateLayoutDictionary.Contains(layName)))
  33.                     {
  34.                         ed.WriteMessage("\nTemplate does not contain a Layout with that name.");
  35.                         return new ObjectId();
  36.                     }
  37.  
  38.                     ObjectId newLayoutId = layManager.CreateLayout(paperName+paperNo.ToString());
  39.                     newLayout = trx.GetObject(newLayoutId, OpenMode.ForWrite) as Layout;
  40.                     newLayout.LayoutName = paperName + paperNo.ToString();
  41.  
  42.                     Layout templateLayout = templateLayoutDictionary.GetAt(layName).GetObject(OpenMode.ForWrite) as Layout;
  43.                     newLayout.CopyFrom(templateLayout);
  44.  
  45.                     BlockTableRecord templateLayoutBtr = templateTrx.GetObject(templateLayout.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;
  46.  
  47.                     ObjectIdCollection objIdColl = new ObjectIdCollection();
  48.                     foreach (ObjectId id in templateLayoutBtr)
  49.                         objIdColl.Add(id);
  50.                     BlockTable extBt = templateDb.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable;
  51.                     IdMapping map = new IdMapping();
  52.                     db.WblockCloneObjects(objIdColl, newLayout.BlockTableRecordId, map, DuplicateRecordCloning.Replace, false);
  53.  
  54.                     newViewPortId = newLayout.Initialize();
  55.  
  56.                     templateTrx.Commit();
  57.                     trx.Commit();
  58.                 }
  59.             }
  60.             return newLayout.Id;
  61.             //return newViewPortId;
  62.         }

Метод работает, но "через раз", периодически валит AutoCAD фатальной ошибкой, причем явной закономерности найти так и не удалось - часто просто пробую несколько раз ее выполнить, получается со второй или третьей попытки, при тех же начальных условиях.
В чем может быть причина? Подозрение у меня на WblockCloneObjects, не совсем понятно, как он работает.

И второй вопрос тут же в тему - создаю видовой экран на листе после создания листа. Все работает нормально, если после работы программы физически перейти на этот лист. Если этого не сделать, после повторного открытия чертежа видовой экран "исчезает". Выкрутился добавлением команды
Код - C# [Выбрать]
  1. newLayout.Initialize();
, теперь программа "перелистывает" листы при работе. Не критично, но при очень многостраничных документах (рекорд - 192 листа  :-[) замедление работы сильно ощутимо.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Создание нового листа по шаблону
« Ответ #1 : 02-08-2013, 16:47:16 »
Мне кажется, что нужно начать с изучения готовых примеров. Например, Create a copy of a layout from a drawing template
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей (IdeaSoft)

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Создание нового листа по шаблону
« Ответ #2 : 04-12-2018, 17:05:55 »
Я выкинул из кода содержимое внутри блоков using
Получается, так что trx.Commit(); вызывается во внутреннем блоке using

Код - C# [Выбрать]
  1. using (Transaction trx = db.TransactionManager.StartTransaction())
  2. {
  3. using (Transaction templateTrx = templateDb.TransactionManager.StartTransaction())
  4. {
  5.  
  6. // Опустим содержимое кода
  7.  
  8. templateTrx.Commit();
  9. trx.Commit();
  10. }
  11. }

Наверное нужно так сделать

Код - C# [Выбрать]
  1. using (Transaction trx = db.TransactionManager.StartTransaction())
  2. {
  3. using (Transaction templateTrx = templateDb.TransactionManager.StartTransaction())
  4. {
  5.  
  6. // Опустим содержимое кода
  7.  
  8. templateTrx.Commit();
  9. }
  10. trx.Commit();
  11. }



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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Создание нового листа по шаблону
« Ответ #3 : 04-12-2018, 17:09:19 »
Получается, так что trx.Commit(); вызывается во внутреннем блоке using
В данном случае никакой разницы нет. Точнее она совершенно несущественна.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Создание нового листа по шаблону
« Ответ #4 : 05-12-2018, 13:14:03 »
Наверное нужно так сделать
Можно их вообще в один блок объединить:
Код - C# [Выбрать]
  1. using (Transaction trx = db.TransactionManager.StartTransaction())
  2. using (Transaction templateTrx = templateDb.TransactionManager.StartTransaction())
  3. {
  4.  
  5. // Опустим содержимое кода
  6.  
  7. templateTrx.Commit();
  8. trx.Commit();
  9. }