Изменить файл не открывая AutoCAD

Автор Тема: Изменить файл не открывая AutoCAD  (Прочитано 7029 раз)

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

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

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

  • ADN OPEN
  • Сообщений: 15
  • Карма: 1
Всем доброго времени суток.
Мне достался файл с множеством динамических блоков с двумя линейными параметрами и 4-мя атрибутами.
Вобщем, блоки несложные, но что с ними не знаю:
при непрограммном (руками) изменении какого -либо динамического параметра AutoCAD тормозит ужасно и часто fatal error выскакивает даже если всего 50 блоков изменяешь.

Моя задача, грубо говоря, поменять все блоки с длиной  равной 500 на длину равную 400.
Мысль сделать это программно не открывая AutoCAD.
Это возможно?
Сам код, думаю, я смогу написать, но как получить документ?
то есть что написать вместо строчки:
Код - C# [Выбрать]
  1. Document doc = AcadApp.DocumentManager.MdiActiveDocument;
???

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #1 : 21-09-2017, 15:12:11 »
Мысль сделать это программно не открывая AutoCAD.
Это как? Вообще не запуская AutoCAD? Тогда или accoreconsole.exe (это бесплатно) или RealDWG (это платно и стоит очень прилично).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #2 : 21-09-2017, 15:17:50 »
Или имеется в виду не загружая чертеж в редактор AutoCAD? Тогда можно через Database.ReadDwgFile(...)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 15
  • Карма: 1
Re: Изменить файл не открывая AutoCAD
« Ответ #3 : 21-09-2017, 15:23:08 »
Да, AutoCAD на компьютере установлен, если Вы об этом, но не нужно его запускать.
А Database.ReadDwgFile(...) - это
Код - C# [Выбрать]
  1. Document doc = Database.ReadDwgFile(filePath);
где filePath - путь к файлу?


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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #4 : 21-09-2017, 15:45:30 »
Да, AutoCAD на компьютере установлен, если Вы об этом, но не нужно его запускать.
Без запуска AutoCAD у тебя ничего не получится.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Serg34 22-09-2017, 10:51:10

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #5 : 21-09-2017, 15:54:47 »
А Database.ReadDwgFile(...) - это
Код - C# [Выбрать]

    Document doc = Database.ReadDwgFile(filePath);

где filePath - путь к файлу?

Это бред. Пример использования Database.ReadDwgFile: http://adn-cis.org/izmenenie-putej-k-vneshnim-ssyilkam-iz-absolyutnyix-v-otnositelnyie.html
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 15
  • Карма: 1
Re: Изменить файл не открывая AutoCAD
« Ответ #6 : 21-09-2017, 16:21:57 »
Спасибо, дома попробую!

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

  • ADN OPEN
  • Сообщений: 15
  • Карма: 1
Re: Изменить файл не открывая AutoCAD
« Ответ #7 : 22-09-2017, 11:05:33 »
Все работает, но тут следующая проблема:
при изменении длины блока штриховка не меняет габарита и вылезает за габариты блока

При открытом файле все нормально проходит, хотя код, вроде, такой же за одним исключением:
Для закрытого файла я убрал строчку: ed.Regen();
Код могу привести, но он у меня по разным классам разнесен.
Может, без моего кода сможете подсказать в чем может быть дело?

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #8 : 22-09-2017, 11:24:52 »
1. Не все, что можно сделать с файлом в редакторе AutoCAD можно сделать без редактора (т.е. имея Document)
2. Попробуйте переключить рабочую базу на ту, что редактируете, а по окончании редактирования верните назад. Иногда такое помогает.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 15
  • Карма: 1
Re: Изменить файл не открывая AutoCAD
« Ответ #9 : 22-09-2017, 11:47:02 »
Не совсем пойму.
Вот код (на всякий случай поясню, это метод-итератор, который принимает метод-обработчик в качестве аргумента и при выполнении условий применяет этот метод-обработчик к блоку):
Код - C# [Выбрать]
  1. private static void AccessGlobalFromFile(
  2.         GlobalBlocksAccessor action, // метод обработки блока
  3.         string blockName = "",
  4.         string autoCADFilePath = "",
  5.         bool manyblocks = true,
  6.         bool dynamicOnly = false,
  7.         bool attributesAndParametrsMust = false)
  8. {
  9.         Document doc = Application.DocumentManager.MdiActiveDocument;
  10.         if (doc == null) return;
  11.  
  12.         Editor ed = doc.Editor;
  13.         using (Database db = new Database(false, true))
  14.         {
  15.                 db.ReadDwgFile(autoCADFilePath, FileOpenMode.OpenForReadAndWriteNoShare, false, "");
  16.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  17.                 {
  18.                         BlockTable blocktable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); // получаем таблицу блоков и проходим по всем записям таблицы блоков
  19.                         foreach (ObjectId btrId in blocktable)
  20.                         {
  21.                                 BlockTableRecord blockTableRecord = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);// получаем запись таблицы блоков и смотрим анонимная ли она
  22.                                 if (!dynamicOnly || blockTableRecord.IsDynamicBlock)
  23.                                         if (string.IsNullOrWhiteSpace(blockName) || blockTableRecord.Name == blockName)
  24.                                         {
  25.                                                 ObjectIdCollection anonymousIds = blockTableRecord.GetAnonymousBlockIds();// получаем все анонимные блоки динамического блока
  26.                                                 foreach (ObjectId anonymousBtrId in anonymousIds)
  27.                                                 {
  28.                                                         BlockTableRecord anonymousBtr = (BlockTableRecord)tr.GetObject(anonymousBtrId, OpenMode.ForRead);// получаем анонимный блок
  29.                                                         ObjectIdCollection blocksCollection = anonymousBtr.GetBlockReferenceIds(true, true);// получаем все вставки этого блока
  30.  
  31.                                                         var attributeRefCollection = new List<AttributeReference>();
  32.                                                         DynamicBlockReferencePropertyCollection parametrsRefCollection = null;
  33.                                                         BlockReference blockReference = null;
  34.  
  35.                                                         if (attributesAndParametrsMust)
  36.                                                         {
  37.                                                                 foreach (ObjectId entId in blocksCollection)
  38.                                                                 {
  39.                                                                         if (tr.GetObject(entId, OpenMode.ForRead) is Entity ent)
  40.                                                                         {
  41.                                                                                 blockReference = ent as BlockReference;
  42.                                                                                 if (blockReference != null)
  43.                                                                                 {
  44.                                                                                         BlockTableRecord bd = (BlockTableRecord)tr.GetObject(blockReference.BlockTableRecord, OpenMode.ForRead);
  45.                                                                                         foreach (ObjectId arId in blockReference.AttributeCollection)// ... to see whether it's a block with the name we're after
  46.                                                                                         {
  47.                                                                                                 DBObject obj = tr.GetObject(arId, OpenMode.ForRead);
  48.                                                                                                 if (obj is AttributeReference ar)
  49.                                                                                                         attributeRefCollection.Add(ar);
  50.                                                                                         }
  51.                                                                                         parametrsRefCollection = blockReference.DynamicBlockReferencePropertyCollection;
  52.                                                                                         if (!manyblocks) break; // получили атрибуты и параметры. Если нужен только один блок, то выходим из перечисления вставок блока
  53.                                                                                 }
  54.                                                                         }
  55.                                                                 }
  56.                                                         }
  57.                                                         action(blockTableRecord, blocksCollection, blockReference, attributeRefCollection, parametrsRefCollection); // непосредственно обработка блока при помощи передаваемого метода
  58.                                                         if (!manyblocks) break;// получили все параметры. Если нужен только один блок, то выходим из перечисления типов блоков
  59.                                                 }
  60.                                         }
  61.                         }
  62.                         tr.Commit();
  63.                 }
  64.                 if (manyblocks) db.SaveAs(db.OriginalFileName, true, db.OriginalFileVersion, db.SecurityParameters);
  65.         }
  66. }

Где тут рабочая база?
И в какой строчке нужно менять базу?

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #10 : 22-09-2017, 11:53:24 »
Где тут рабочая база?
HostApplicationServices.WorkingDatabase - это рабочая база. Сразу после создания db переключаешься на неё, а перед удалением базы (после сохранения) переключаешься обратно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 15
  • Карма: 1
Re: Изменить файл не открывая AutoCAD
« Ответ #11 : 22-09-2017, 12:04:05 »
Можно пример?

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #12 : 22-09-2017, 12:12:59 »
Со смартфона тяжело. Посмотри это: http://adn-cis.org/forum/index.php?topic=831.msg3438#msg3438
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 15
  • Карма: 1
Re: Изменить файл не открывая AutoCAD
« Ответ #13 : 22-09-2017, 12:24:11 »
Спасибо большое.
По примеру сделал так:
Код - C# [Выбрать]
  1. private static void AccessGlobalFromFile(...)
  2. {
  3.         Document doc = Application.DocumentManager.MdiActiveDocument;
  4.         if (doc == null) return;
  5.  
  6.         Editor ed = doc.Editor;
  7.         using (Database db = new Database(false, true))
  8.         {
  9.                 db.ReadDwgFile(autoCADFilePath, FileOpenMode.OpenForReadAndWriteNoShare, false, "");
  10.                 Database prevDb = HostApplicationServices.WorkingDatabase;
  11.                 HostApplicationServices.WorkingDatabase = db;
  12.  
  13.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  14.                 {
  15.                         ...
  16.                         tr.Commit();
  17.                 }
  18.                 HostApplicationServices.WorkingDatabase = prevDb;
  19.                 db.SaveAs(db.OriginalFileName, true, db.OriginalFileVersion, db.SecurityParameters);
  20.         }
  21. }
Эффект тот же(
Попробую еще с открытым файлом - может, если программно блоки редактировать, то не будет fatal error

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #14 : 22-09-2017, 22:18:18 »
Ну возможно еще в коде обновления что-то не то. Например, я обратил внимание, что BlockTable открыт для чтения, а изменение параметров динамического блока приводит к созданию нового анонимного блока, BlockTableRecord которого должен записаться в BlockTable.
Короче говоря поиграйся с заменой OpenMode.ForRead на OpenMode.ForWrite в разных местах у себя. А может стоит заменить обычную транзакцию на эмуляцию транзакции.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Изменить файл не открывая AutoCAD
« Ответ #15 : 22-09-2017, 23:21:46 »
Задачка явно выше уровнем, чем знания автора...

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

  • ADN OPEN
  • Сообщений: 15
  • Карма: 1
Re: Изменить файл не открывая AutoCAD
« Ответ #16 : 25-09-2017, 14:03:39 »
поиграйся с заменой OpenMode.ForRead на OpenMode.ForWrite
Мне это всегда казалось странным, что я для чтения открываю и редактирую, но запись до этого всегда проходила корректно.
Но в моем случае замена на ForWrite все равно не помогла(((

заменить обычную транзакцию на эмуляцию транзакции
Опять же прошу пример если можно.

Задачка явно выше уровнем, чем знания автора...
Так форум для этого и существует. Разве нет?


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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 15
  • Карма: 1
Re: Изменить файл не открывая AutoCAD
« Ответ #18 : 26-09-2017, 11:44:35 »
Проблему решил установкой AutoCAD 2018 - с ним все непрограммно сделал (36часов машина работала, но задачу выполнила).
Но в любом случае спасибо Вам за помощь :)