[Rtm.CommandMethod("Test")]
public static void Test()
{
Db.Database db = new Db.Database();
db.ReadDwgFile(@"D:\TestFile.dwg", Db.FileOpenMode.OpenForReadAndWriteNoShare, false, null);
string targetLayName = "2";
Db.Handle targetLayHandle = new Db.Handle();
using (Db.Transaction operateDwgTrans = db.TransactionManager.StartTransaction())
{
Db.DBDictionary spaces = operateDwgTrans.GetObject(db.LayoutDictionaryId, Db.OpenMode.ForWrite) as Db.DBDictionary;
foreach (Db.DBDictionaryEntry curSpace in spaces)
{
Db.ObjectId curSpaceId = curSpace.Value;
Db.Layout acadLayout = operateDwgTrans.GetObject(curSpaceId, Db.OpenMode.ForWrite) as Db.Layout;
if (acadLayout.LayoutName == targetLayName)
{
targetLayHandle = acadLayout.Handle;
}
}
}
try
{
DeleteLayouts(db, targetLayHandle);
}
catch (System.Exception ex)
{
Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog($"Message: {ex.Message}; Trace: {ex.StackTrace}!\n");
}
try
{
db.SaveAs(@"D:\TestFileNew.dwg", Db.DwgVersion.Current);
}
catch (System.Exception ex)
{
Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog($"Message: {ex.Message};\n Trace: {ex.StackTrace}!\n");
}
//db.Dispose();
}
/// <summary>
/// Удаляем лишние листы
/// </summary>
/// <param name="db">база данных из которой удаляем листы</param>
/// <param name="layoutHandle">лист который не нужно удалять</param>
private static void DeleteLayouts(Db.Database db, Db.Handle layoutHandle)
{
Db.Database oldDb = Db.HostApplicationServices.WorkingDatabase;
Db.HostApplicationServices.WorkingDatabase = db;
//Перед удалением Layout нужно переключиться на тот, который не удаляем
Db.LayoutManager layoutManager = Db.LayoutManager.Current;
Db.ObjectId layoutId = Db.ObjectId.Null;
string targetLayName = "";
if (db.TryGetObjectId(layoutHandle, out layoutId))
{
if (!layoutId.IsNull)
{
if (layoutId.ObjectClass == Rtm.RXObject.GetClass(typeof(Db.Layout)))
{
using (Db.Transaction operateDwgTrans = db.TransactionManager.StartTransaction())
{
Db.Layout lay = operateDwgTrans.GetObject(layoutId, Db.OpenMode.ForRead) as Db.Layout;
targetLayName = lay.LayoutName;
}
layoutManager.CurrentLayout = targetLayName;
//и удаляем все остальные
foreach (var layout in CloneDwg.GetLayoutList(db))
{
if (layout.Key != layoutHandle)
{
//Так. как CloneDwg.GetLayoutList() возвращает Хандл и
//Имя из штампа, то нужно узнать простое имя листа
string currentLayoutName = "";
if (db.TryGetObjectId(layout.Key, out layoutId))
{
if (layoutId.ObjectClass == Rtm.RXObject.GetClass(typeof(Db.Layout)))
{
if (!layoutId.IsErased && !layoutId.IsEffectivelyErased)
{
using (Db.Transaction operateDwgTrans = db.TransactionManager.StartTransaction())
{
Db.Layout acadLayout = operateDwgTrans.GetObject(layoutId, Db.OpenMode.ForWrite) as Db.Layout;
currentLayoutName = acadLayout.LayoutName;
}
//и тут нужно передать уже простое имя листа
try
{
//Autodesk.AutoCAD.Runtime.Exception: "eDelDoesNotExist"
layoutManager.DeleteLayout(currentLayoutName);
}
catch (Exception ex)
{
//LogView.WriteLine($"Err. layout {currentLayoutNmae}, ex: {ex.Message}");
//throw;
Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog($"Message: {ex.Message};\n Trace: {ex.StackTrace}!\n");
}
}
}
}
}
}
}
}
}
Db.HostApplicationServices.WorkingDatabase = oldDb;
}
internal class CloneDwg
{
public static Dictionary<Db.Handle, string> GetLayoutList(Db.Database db)
{
Dictionary<Db.Handle, string> result = new Dictionary<Db.Handle, string>();
using (Db.Transaction operateDwgTrans = db.TransactionManager.StartTransaction())
{
Db.DBDictionary spaces = operateDwgTrans.GetObject(db.LayoutDictionaryId, Db.OpenMode.ForWrite) as Db.DBDictionary;
foreach (Db.DBDictionaryEntry curSpace in spaces)
{
Db.ObjectId curSpaceId = curSpace.Value;
Db.Layout acadLayout = operateDwgTrans.GetObject(curSpaceId, Db.OpenMode.ForWrite) as Db.Layout;
if (acadLayout.LayoutName == "Model") continue;
result.Add(acadLayout.Handle, acadLayout.LayoutName);
}
}
return result;
}
}