(изменено: Денис Перепецкий, 30 апреля 2014г. 12:38:03)

Тема: Сохранить файл с несколькими Листами в отдельные файлы

Опишу задачу подробнее.
Есть некий файл со скомпонованными листами. Нужно пересохранить этот файл в отдельные файлы с одним Листом в каждом файле. Т.е. если был файл "Плита_01.dwg" с листами с названиями

"Лист01"
"Лист02"
"Лист03"

то на выходе мы должны иметь 3 файла

Плита_01_[Лист01]_.dwg
Плита_01_[Лист02]_.dwg
Плита_01_[Лист03]_.dwg

с соответствующими листами.
Есть код

        [CommandMethod("dpSaveLayoutsToSeparateFiles2")]
        public void dpSaveLayouts2()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            Document doc = Application.DocumentManager.MdiActiveDocument;
            HostApplicationServices hs = HostApplicationServices.Current;
            Database db = Application.DocumentManager.MdiActiveDocument.Database;

            //системная переменная, проверяем сохранен ли файл или нет
            object DWGTITLED = Application.GetSystemVariable("DWGTITLED");

            //если не сохранен выходим
            if (System.Convert.ToInt16(DWGTITLED) == 0)
            {
                Application.ShowAlertDialog("Перед использованием процедуры сохранить");
                return;
            }

            //получаем полный путь к DWG файлу
            string dwgFullPath = hs.FindFile(doc.Name, doc.Database, FindFileHint.Default);
            //получаем имя DWG файла
            string dwgName = Path.GetFileName(dwgFullPath);
            //получаем имя DWG файла без расширения
            string dwgNameWoExt = Path.GetFileNameWithoutExtension(dwgFullPath);
            //получаем путь к DWG файлу
            string dwgPath = Path.GetDirectoryName(dwgFullPath);
            //путь для сохранения новых DWG файлов
            string dwgNewFullPath = "";
            //получаем путь к TEMP
            string tempPath = System.IO.Path.GetTempPath();

            //блокируем документ
            using (DocumentLock doclock = doc.LockDocument())
            {
                //пошла транзакция
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    {
                        //получаем коллекцию Layout
                        DBDictionary acLayouts = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
                        //получаем количество вкладок
                        int layoutsCount = acLayouts.Count;
                        LayoutManager acLayoutMgr;
                        acLayoutMgr = LayoutManager.Current;
                        //перебираем все вкладки
                        foreach (DBDictionaryEntry item in acLayouts)
                        {
                            //имя лейаута
                            String layoutName = item.Key;
                            //получаем Лейаут
                            Layout acLayout = tr.GetObject(item.Value, OpenMode.ForRead) as Layout;

                            //если не модель то идем дальше
                            if (acLayout.LayoutName.ToUpper() != "MODEL" && acLayout.LayoutName.ToUpper() != "МОДЕЛЬ")
                            {
                                //acLayoutMgr.CurrentLayout = acLayout.LayoutName;
                                //активируем вкладку
                                acLayoutMgr.CurrentLayout = acLayout.LayoutName;
                                //получаем систменую переменную отображеня вывода в консоль
                                Object CMDECHO = Application.GetSystemVariable("CMDECHO");
                                //запрещаем вывод в консоль
                                Application.SetSystemVariable("CMDECHO", 0);
                                //создаем путь к нашему новому файлу
                                dwgNewFullPath = dwgPath + "\\" + dwgNameWoExt + "_[" + acLayout.LayoutName + "]_.dwg";
                                //сохраняем файл и экранируем слеши
                                db.SaveAs(dwgNewFullPath.Replace("\\", "\\\\"), DwgVersion.AC1021);

                                ///////////////////////////////////////////////////////////////////////////////////
                                Database db2 = new Database(false, true);
                                db2.ReadDwgFile(dwgNewFullPath, FileOpenMode.OpenForReadAndWriteNoShare, false, "");
                                using(Transaction tr2 = db2.TransactionManager.StartTransaction())
                                {
                                    db2.Save();
                                    tr2.Commit();
                                }
                                ///////////////////////////////////////////////////////////////////////////////////

                                //восстанавливаем систменую переменную отображеня вывода в консоль
                                Application.SetSystemVariable("CMDECHO", CMDECHO);
                                //dpDelLayoutsFromDWG(dwgTempPath, dwgNewFullPath);
                                ed.WriteMessage("Сохранено: " + dwgNewFullPath + "\n");
                            }
                        }
                    }
                    tr.Commit();
                }
            }
        }

[S]ошибка в этой строке db2.Save();

Autodesk.AutoCAD.Runtime.Exception: eFileInternalErr
   at Autodesk.AutoCAD.DatabaseServices.Database.Save()

[/S]
чтобы не было ошибки надо так

db2.SaveAs(dwgNewFullPath.Replace("\\", "\\\\"), DwgVersion.Current);

Re: Сохранить файл с несколькими Листами в отдельные файлы

См. пометку "Внимание!" здесь.

Re: Сохранить файл с несколькими Листами в отдельные файлы

Здравствуйте хочу возобновить данную тему так как понадобился данный код.
Со всеми описаниями получился код такой (библиотеки все подключены acdbmgd, accoremgd, acmgd):

using System;
using System.IO;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;

namespace ClassLibrary2
{
        public class Class1
    {
        [CommandMethod("dpSaveLayoutsToSeparateFiles2")]
        public void dpSaveLayouts2()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            Document doc = Application.DocumentManager.MdiActiveDocument;
            HostApplicationServices hs = HostApplicationServices.Current;
            Database db = Application.DocumentManager.MdiActiveDocument.Database;

            //системная переменная, проверяем сохранен ли файл или нет 
            object DWGTITLED = Application.GetSystemVariable("DWGTITLED");

            //если не сохранен выходим 
            if (System.Convert.ToInt16(DWGTITLED) == 0)
            {
                Application.ShowAlertDialog("Перед использованием процедуры сохранить");
                return;
            }

            //получаем полный путь к DWG файлу 
            string dwgFullPath = hs.FindFile(doc.Name, doc.Database, FindFileHint.Default);
            //получаем имя DWG файла 
            string dwgName = Path.GetFileName(dwgFullPath);
            //получаем имя DWG файла без расширения 
            string dwgNameWoExt = Path.GetFileNameWithoutExtension(dwgFullPath);
            //получаем путь к DWG файлу 
            string dwgPath = Path.GetDirectoryName(dwgFullPath);
            //путь для сохранения новых DWG файлов 
            string dwgNewFullPath = "";
            //получаем путь к TEMP 
            string tempPath = System.IO.Path.GetTempPath();

            //блокируем документ 
            using (DocumentLock doclock = doc.LockDocument())
            {
                //пошла транзакция 
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    {
                        //получаем коллекцию Layout 
                        DBDictionary acLayouts = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
                        //получаем количество вкладок 
                        int layoutsCount = acLayouts.Count;
                        LayoutManager acLayoutMgr;
                        acLayoutMgr = LayoutManager.Current;
                        //перебираем все вкладки 
                        foreach (DBDictionaryEntry item in acLayouts)
                        {
                            //имя лейаута 
                            String layoutName = item.Key;
                            //получаем Лейаут 
                            Layout acLayout = tr.GetObject(item.Value, OpenMode.ForRead) as Layout;

                            //если не модель то идем дальше 
                            if (acLayout.LayoutName.ToUpper() != "MODEL" && acLayout.LayoutName.ToUpper() != "МОДЕЛЬ")
                            {
                                //acLayoutMgr.CurrentLayout = acLayout.LayoutName; 
                                //активируем вкладку 
                                acLayoutMgr.CurrentLayout = acLayout.LayoutName;
                                //получаем систменую переменную отображеня вывода в консоль 
                                Object CMDECHO = Application.GetSystemVariable("CMDECHO");
                                //запрещаем вывод в консоль 
                                Application.SetSystemVariable("CMDECHO", 0);
                                //создаем путь к нашему новому файлу 
                                dwgNewFullPath = dwgPath + "\\" + dwgNameWoExt + "_[" + acLayout.LayoutName + "]_.dwg";
                                //сохраняем файл и экранируем слеши 
                                db.SaveAs(dwgNewFullPath.Replace("\\", "\\\\"), DwgVersion.AC1021);

                                //////////////////­//////////////////////////////////////////////////­/////////////// 
                                Database db2 = new Database(false, true);
                                db2.ReadDwgFile(dwgNewFullPath, FileOpenMode.OpenForReadAndWriteNoShare, false, "");
                                using (Transaction tr2 = db2.TransactionManager.StartTransaction())
                                {
                                    db2.SaveAs(dwgNewFullPath.Replace("\\", "\\\\"), DwgVersion.Current);
                                    tr2.Commit();
                                }
                                //////////////////­//////////////////////////////////////////////////­/////////////// 

                                //восстанавливаем систменую переменную отображеня вывода в консоль 
                                Application.SetSystemVariable("CMDECHO", CMDECHO);
                                //dpDelLayoutsFrom­DWG(dwgTempPath, dwgNewFullPath); 
                                ed.WriteMessage("Сохранено: " + dwgNewFullPath + "\n");
                            }
                        }
                    }
                    tr.Commit();
                }
            }
        }
    }
}

При запуске на 2016 автокаде выдает сообщение :

Приложение не поддерживает оперативную (JIT)
отладку. Подробная информацию приводится в конце данного сообщения.

************** Текст исключения **************
Autodesk.AutoCAD.Runtime.Exception: eFileSharingViolation
   в Autodesk.AutoCAD.DatabaseServices.Database.SaveAs(String fileName, DwgVersion version)
   в ClassLibrary2.Class1.dpSaveLayouts2() в C:\Users\levanyukms\Documents\Visual Studio 2015\Projects\ClassLibrary2\ClassLibrary2\Class1.cs:строка 85
   в Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   в Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   в Autodesk.AutoCAD.Runtime.PerDocumentCommandClass.Invoke(MethodInfo mi, Boolean bLispFunction)
   в Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()

Re: Сохранить файл с несколькими Листами в отдельные файлы

Так как я не владею языком программирования, как исправить данные недочеты?