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

ADN Club => AutoCAD .NET API => Тема начата: Вильдар от 05-09-2015, 15:08:22

Название: Удаление листа во внешней базе чертежа
Отправлено: Вильдар от 05-09-2015, 15:08:22
Доброго всем,

Такой код не работает:
Код - C# [Выбрать]
  1. [CommandMethod("Test")]
  2.       public static void Test()
  3.       {        
  4.          using (Database dbTest = new Database(false, true))
  5.          {
  6.             dbTest.ReadDwgFile(@"c:\temp\Test.dwg", FileShare.ReadWrite, false, "");
  7.             Database dbOrig = HostApplicationServices.WorkingDatabase;
  8.             HostApplicationServices.WorkingDatabase = dbTest;
  9.             LayoutManager lm = LayoutManager.Current;
  10.             lm.CopyLayout("Test", "Test1");
  11.             lm.DeleteLayout("Test"); // ошибка - eDelLastLayout
  12.             HostApplicationServices.WorkingDatabase = dbOrig;
  13.             dbTest.SaveAs(@"c:\temp\Test.dwg", DwgVersion.Current);
  14.          }
  15.       }      
В чертеже test.dwg есть один лист "Test". Мне его нужно скопировать и удалить.
Скопированный лист можно удалить, а исходный нет.
Название: Re: Удаление листа во внешней базе чертежа
Отправлено: Александр Ривилис от 05-09-2015, 15:13:16
Попробуй перед:
Код - C# [Выбрать]
  1. lm.DeleteLayout("Test");
вызвать
Код - C# [Выбрать]
  1. lm.CurrentLayout = "Test1";
Но вообще-то LayoutManger корректно работает только с чертежами, открытыми в редакторе AutoCAD,
а не открытыми через Database.ReadDwgFile
Название: Re: Удаление листа во внешней базе чертежа
Отправлено: Александр Ривилис от 05-09-2015, 15:14:34
Мне его нужно скопировать и удалить.
А почему его просто не переименовать? В чем смысл?
Название: Re: Удаление листа во внешней базе чертежа
Отправлено: Вильдар от 05-09-2015, 15:18:52
lm.CurrentLayout = "Test1";
Сработало. Только автокад вылетает )
Название: Re: Удаление листа во внешней базе чертежа
Отправлено: Александр Ривилис от 05-09-2015, 15:19:58
Сработало. Только автокад вылетает )
А как ты смог определить, что "сработало", если AutoCAD "вылетел"?
Название: Re: Удаление листа во внешней базе чертежа
Отправлено: Вильдар от 05-09-2015, 15:23:44
А почему его просто не переименовать? В чем смысл?
Есть шаблон чертежа с шаблоном листа. Копирую файл шаблона, копирую лист шаблона (несколько раз), меняю что-то на скопированных листах, лист шаблона нужно удалить.
Но Вы правы, можно поменять логику, чтобы не нужно было удалять лист. Или через словарь попробовать его удалить.
А как ты смог определить, что "сработало", если AutoCAD "вылетел"?
Файл сохранился при этом как-то, с одним листом Test1.
Название: Re: Удаление листа во внешней базе чертежа
Отправлено: Александр Ривилис от 05-09-2015, 15:48:20
Но Вы правы, можно поменять логику, чтобы не нужно было удалять лист. Или через словарь попробовать его удалить.
LayoutManager.GetLayoutId - получаем ObjectId для Layout, а затем удаляем его. Думаю что сработает.
P.S.: Кстати, после
Код - C# [Выбрать]
  1. HostApplicationServices.WorkingDatabase = dbOrig;
неплохо было бы сделать текущим тот Layout, который был до вызова твоей функции.
Название: Re: Удаление листа во внешней базе чертежа
Отправлено: Вильдар от 05-09-2015, 16:06:03
LayoutManager.GetLayoutId - получаем ObjectId для Layout, а затем удаляем его. Думаю что сработает.
Сорри, а как Layout удалить? Просто Erase, похоже нельзя, файл потом не открывается.
Код - C# [Выбрать]
  1. [CommandMethod("Test")]
  2.       public static void Test()
  3.       {
  4.          using (Database dbTest = new Database(false, true))
  5.          {
  6.             dbTest.ReadDwgFile(@"c:\temp\Test.dwg", FileShare.ReadWrite, false, "");
  7.             Database dbOrig = HostApplicationServices.WorkingDatabase;
  8.             HostApplicationServices.WorkingDatabase = dbTest;
  9.             LayoutManager lm = LayoutManager.Current;
  10.             lm.CopyLayout("Test", "Test1");
  11.             using (var t = dbTest.TransactionManager.StartTransaction ())
  12.             {
  13.                var layoutTest = t.GetObject(lm.GetLayoutId("Test"), OpenMode.ForWrite) as Layout;
  14.                layoutTest.Erase(true);
  15.                t.Commit();
  16.             }            
  17.             HostApplicationServices.WorkingDatabase = dbOrig;
  18.             dbTest.SaveAs(@"c:\temp\Test.dwg", DwgVersion.Current);
  19.          }
  20.       }
Название: Re: Удаление листа во внешней базе чертежа
Отправлено: Вильдар от 05-09-2015, 16:25:24
Немного изврат,
Код - C# [Выбрать]
  1. private static void ConvertLayoutNames(Database dbTest, string name1, string name2)
  2.       {
  3.          Database dbOrig = HostApplicationServices.WorkingDatabase;        
  4.          HostApplicationServices.WorkingDatabase = dbTest;
  5.          LayoutManager lm = LayoutManager.Current;
  6.          string tempName1 = name1 + name1;
  7.          lm.RenameLayout(name1, tempName1);
  8.          lm.RenameLayout(name2, name1);
  9.          lm.RenameLayout(tempName1, name2);
  10.          HostApplicationServices.WorkingDatabase = dbOrig;
  11.       }
После этого можно удалять "оригинальный" лист )
Название: Re: Удаление листа во внешней базе чертежа
Отправлено: Александр Ривилис от 05-09-2015, 16:28:55
Вот так у меня работает (AutoCAD 2015) и не вылетает:
Код - C# [Выбрать]
  1. [CommandMethod("Test")]
  2. public static void Test()
  3. {
  4.   using (Database dbTest = new Database(false, false))
  5.   {
  6.     LayoutManager lm = LayoutManager.Current;
  7.     Database dbOrig = HostApplicationServices.WorkingDatabase;
  8.     string layOrig = lm.CurrentLayout;
  9.     dbTest.ReadDwgFile(@"c:\temp\Test.dwg", FileShare.ReadWrite, false, "");
  10.     HostApplicationServices.WorkingDatabase = dbTest;
  11.     lm.CopyLayout("Test", "Test1");
  12.     lm.CurrentLayout = "Test1";
  13.     lm.DeleteLayout("Test");
  14.     HostApplicationServices.WorkingDatabase = dbOrig;
  15.     dbTest.SaveAs(@"c:\temp\Test.dwg", DwgVersion.Current);
  16.     lm.CurrentLayout = layOrig;
  17.   }
  18. }
Название: Re: Удаление листа во внешней базе чертежа
Отправлено: Вильдар от 05-09-2015, 16:34:14
Вау, супер. Спасибо Вам Александр Наумович!
Название: Re: Удаление листа во внешней базе чертежа
Отправлено: Andrey-Adamenko от 10-02-2021, 11:39:23
Здравствуйте, Александр Ривилис!

Немного изменил метод, но у меня вылетает после сохранения файла.
То есть файл сохраняется и открывается без ошибок, но выполнение команды завершается "вылетом" AutoCAD.

Код - C# [Выбрать]
  1. [CommandMethod("RemoveLayout")]
  2. public static void Test()
  3. {
  4.         using (Database dbTest = new Database(false, false))
  5.         {
  6.                 LayoutManager lm = LayoutManager.Current;
  7.                 Database dbOrig = HostApplicationServices.WorkingDatabase;
  8.                 string layOrig = lm.CurrentLayout;
  9.                 dbTest.ReadDwgFile(@"D:\CAD\Чертежи\TestFile.dwg", FileShare.ReadWrite, false, "");
  10.                 HostApplicationServices.WorkingDatabase = dbTest;
  11.                 //lm.CopyLayout("Test", "Test1");
  12.                 lm.CurrentLayout = "Model";
  13.                 lm.DeleteLayout("1");
  14.                 lm.DeleteLayout("2");
  15.                 HostApplicationServices.WorkingDatabase = dbOrig;
  16.                 dbTest.SaveAs(@"D:\CAD\Чертежи\TestFile_2.dwg", DwgVersion.Current);
  17.                 lm.CurrentLayout = layOrig;
  18.         }
  19. }
  20.  

У меня AutoCAD 2014  :-[
Название: Re: Удаление листа во внешней базе чертежа
Отправлено: Александр Ривилис от 10-02-2021, 17:43:18
Andrey-Adamenko,
Вероятнее всего это баг в конкретной версии AutoCAD. Возможно есть обновление для этой версии. Проверь.
Название: Re: Удаление листа во внешней базе чертежа
Отправлено: Привалов Дмитрий от 10-02-2021, 18:17:10
выполнение команды завершается "вылетом" AutoCAD
А ты случайно не удаляешь все листы из чертежа?
lm.DeleteLayout("1");
lm.DeleteLayout("2");
Один лист должен присутствовать всегда.