ADN Club > AutoCAD .NET API
Создание листов
Николай Коломоец:
Добрый день всем гуру программирования.
Есть модуль, который делает следующее:
1. создает набор листов, импортируя их с заранее заданного шаблона
2. создает на каждом новом листе видовой экран, с определенным содержимым
Суть проблемы: листы создаются, видовые экраны вроде бы как тоже создаются. Проблема заключается в следующем:
после создания листов, происходит фатальная ошибка при попытке сделать данный лист активным.
Если выполнить функцию отдельно для создания листов, отдельно для размещения видовых экранов на этих листах, и вторую функцию вызвать после закрытия чертежа с сохранением и повторного открытия, - все работает.
Ниже привожу код функции импорта листа с шаблона.
Код взят отсюда http://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-NET/files/GUID-5FA86EF3-DEFD-4256-BB1C-56DAC32BD868-htm.html.
Добавление в него как раз и фаталит:
--- Код - C# [Выбрать] ---public ObjectId ImportLayout(String fileName, ref String layName, ref String paperName, ref ObjectId newViewPortId, int paperNo) { // Get the current document and database Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // Specify the layout name and drawing file to work with string layoutName = layName; string filename = fileName; // Create a new database object and open the drawing into memory Database acExDb = new Database(false, true); acExDb.ReadDwgFile(filename, FileOpenMode.OpenForReadAndAllShare, true, ""); ObjectId layId = ObjectId.Null; using (DocumentLock dLock = acDoc.LockDocument(DocumentLockMode.ProtectedAutoWrite, null, null, true)) // Create a transaction for the external drawing { using (Transaction acTransEx = acExDb.TransactionManager.StartTransaction()) { // Get the layouts dictionary DBDictionary layoutsEx = acTransEx.GetObject(acExDb.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary; // Check to see if the layout exists in the external drawing if (layoutsEx.Contains(layoutName) == true) { // Get the layout and block objects from the external drawing Layout layEx = layoutsEx.GetAt(layoutName).GetObject(OpenMode.ForRead) as Layout; BlockTableRecord blkBlkRecEx = acTransEx.GetObject(layEx.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord; // Get the objects from the block associated with the layout ObjectIdCollection idCol = new ObjectIdCollection(); foreach (ObjectId id in blkBlkRecEx) { idCol.Add(id); } // Create a transaction for the current drawing using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // Get the block table and create a new block // then copy the objects between drawings BlockTable blkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForWrite) as BlockTable; using (BlockTableRecord blkBlkRec = new BlockTableRecord()) { int layoutCount = layoutsEx.Count - 1; blkBlkRec.Name = paperName + paperNo + layoutsEx.Count.ToString(); blkTbl.Add(blkBlkRec); acTrans.AddNewlyCreatedDBObject(blkBlkRec, true); acExDb.WblockCloneObjects(idCol, blkBlkRec.ObjectId, new IdMapping(), DuplicateRecordCloning.Ignore, false); // Create a new layout and then copy properties between drawings DBDictionary layouts = acTrans.GetObject(acCurDb.LayoutDictionaryId, OpenMode.ForWrite) as DBDictionary; // Добавка к коду LayoutManager layMan = LayoutManager.Current; using (Layout lay = new Layout()) { lay.LayoutName = paperName + paperNo; lay.AddToLayoutDictionary(acCurDb, blkBlkRec.ObjectId); acTrans.AddNewlyCreatedDBObject(lay, true); lay.CopyFrom(layEx); layId = lay.Id; newViewPortId = lay.Initialize(); // Тут ловим фатальную ошибку - Unhandled exception writing 0x0340 //layMan.CurrentLayout = lay.LayoutName; DBDictionary plSets = acTrans.GetObject(acCurDb.PlotSettingsDictionaryId, OpenMode.ForRead) as DBDictionary; // Check to see if a named page setup was assigned to the layout, // if so then copy the page setup settings if (lay.PlotSettingsName != "") { // Check to see if the page setup exists if (plSets.Contains(lay.PlotSettingsName) == false) { plSets.UpgradeOpen(); using (PlotSettings plSet = new PlotSettings(lay.ModelType)) { plSet.PlotSettingsName = lay.PlotSettingsName; plSet.AddToPlotSettingsDictionary(acCurDb); acTrans.AddNewlyCreatedDBObject(plSet, true); DBDictionary plSetsEx = acTransEx.GetObject(acExDb.PlotSettingsDictionaryId, OpenMode.ForRead) as DBDictionary; PlotSettings plSetEx = plSetsEx.GetAt(lay.PlotSettingsName).GetObject( OpenMode.ForRead) as PlotSettings; plSet.CopyFrom(plSetEx); } } } } } // Regen the drawing to get the layout tab to display //acDoc.Editor.Regen(); // Save the changes made acTrans.Commit(); acTrans.Dispose(); } } else { // Display a message if the layout could not be found in the specified drawing acDoc.Editor.WriteMessage("\nLayout '" + layoutName + "' could not be imported from '" + filename + "'."); } // Discard the changes made to the external drawing file acTransEx.Abort(); } // Close the external drawing file acExDb.Dispose(); } return layId; }
Дополнительно: в данном варианте (фатальная строка закомментирована) модуль работает, но после его выполнения чертеж ведет себя следующим образом:
1. находимся в пространстве модели - все нормально
2. переходим в пространство какого-то листа (например №5) - нормально
3. переходим в модель - нормально
4. переходим в пространство любого листа - попадаем на лист №5!!!
Конкретный вопрос - чего не хватает в коде, чтобы "финализировать" добавление листа в базу данных чертежа?
Александр Ривилис:
1. Прочитай мою подпись по поводу форматирования кода на форуме.
2. Давай свой файл шаблона чтобы было на чем тестировать.
3. Что касается фатальной ошибки, то lay у тебя не закрыт (транзакция не завершена), а ты пытаешься её использовать в layMan.CurrentLayout
Подозреваю, что проблема именно в этом. Вынеси этот код из транзакции.
Николай Коломоец:
Думал над этим. Но такая же проблема возникает в аналогичном коде уже в другой функции. Естественно, транзакция закрыта.
Высылаю повторно функцию копирования листа, и добавляю функцию вставки видового экрана. Также привожу фрагмент кода, вызывающего эти функции.
Вкладываю файл шаблона.
Создание листа по шаблону
--- Код - C# [Выбрать] ---public ObjectId ImportLayout(String fileName, ref String layName, ref String paperName, ref ObjectId newViewPortId, int paperNo) { // Get the current document and database Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // Specify the layout name and drawing file to work with string layoutName = layName; string filename = fileName; // Create a new database object and open the drawing into memory Database acExDb = new Database(false, true); acExDb.ReadDwgFile(filename, FileOpenMode.OpenForReadAndAllShare, true, ""); ObjectId layId = ObjectId.Null; using (DocumentLock dLock = acDoc.LockDocument(DocumentLockMode.ProtectedAutoWrite, null, null, true)) // Create a transaction for the external drawing { using (Transaction acTransEx = acExDb.TransactionManager.StartTransaction()) { // Get the layouts dictionary DBDictionary layoutsEx = acTransEx.GetObject(acExDb.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary; // Check to see if the layout exists in the external drawing if (layoutsEx.Contains(layoutName) == true) { // Get the layout and block objects from the external drawing Layout layEx = layoutsEx.GetAt(layoutName).GetObject(OpenMode.ForRead) as Layout; BlockTableRecord blkBlkRecEx = acTransEx.GetObject(layEx.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord; // Get the objects from the block associated with the layout ObjectIdCollection idCol = new ObjectIdCollection(); foreach (ObjectId id in blkBlkRecEx) { idCol.Add(id); } // Create a transaction for the current drawing using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // Get the block table and create a new block // then copy the objects between drawings BlockTable blkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForWrite) as BlockTable; using (BlockTableRecord blkBlkRec = new BlockTableRecord()) { int layoutCount = layoutsEx.Count - 1; blkBlkRec.Name = paperName + paperNo + layoutsEx.Count.ToString(); blkTbl.Add(blkBlkRec); acTrans.AddNewlyCreatedDBObject(blkBlkRec, true); acExDb.WblockCloneObjects(idCol, blkBlkRec.ObjectId, new IdMapping(), DuplicateRecordCloning.Ignore, false); // Create a new layout and then copy properties between drawings DBDictionary layouts = acTrans.GetObject(acCurDb.LayoutDictionaryId, OpenMode.ForWrite) as DBDictionary; // Добавка к коду LayoutManager layMan = LayoutManager.Current; using (Layout lay = new Layout()) { lay.LayoutName = paperName + paperNo; lay.AddToLayoutDictionary(acCurDb, blkBlkRec.ObjectId); acTrans.AddNewlyCreatedDBObject(lay, true); lay.CopyFrom(layEx); layId = lay.Id; newViewPortId = lay.Initialize(); // Тут ловим фатальную ошибку - Unhandled exception writing 0x0340 //layMan.CurrentLayout = lay.LayoutName; DBDictionary plSets = acTrans.GetObject(acCurDb.PlotSettingsDictionaryId, OpenMode.ForRead) as DBDictionary; // Check to see if a named page setup was assigned to the layout, // if so then copy the page setup settings if (lay.PlotSettingsName != "") { // Check to see if the page setup exists if (plSets.Contains(lay.PlotSettingsName) == false) { plSets.UpgradeOpen(); using (PlotSettings plSet = new PlotSettings(lay.ModelType)) { plSet.PlotSettingsName = lay.PlotSettingsName; plSet.AddToPlotSettingsDictionary(acCurDb); acTrans.AddNewlyCreatedDBObject(plSet, true); DBDictionary plSetsEx = acTransEx.GetObject(acExDb.PlotSettingsDictionaryId, OpenMode.ForRead) as DBDictionary; PlotSettings plSetEx = plSetsEx.GetAt(lay.PlotSettingsName).GetObject( OpenMode.ForRead) as PlotSettings; plSet.CopyFrom(plSetEx); } } } } } // Regen the drawing to get the layout tab to display //acDoc.Editor.Regen(); // Save the changes made acTrans.Commit(); acTrans.Dispose(); } } else { // Display a message if the layout could not be found in the specified drawing acDoc.Editor.WriteMessage("\nLayout '" + layoutName + "' could not be imported from '" + filename + "'."); } // Discard the changes made to the external drawing file acTransEx.Abort(); } // Close the external drawing file acExDb.Dispose(); } return layId; }
Создание видового экрана на этом листе
--- Код - C# [Выбрать] ---/*------------------------------------------------------------------------------------------------------------------*/ /* Процедура создания видового экрана, указывающего на нужный участок пространства модели, соответствующий странице */ /* Входные данные: */ /* newViewPortId - идентификатор нового видового экрана */ /* newLayoutId - идентификатор листа, на котором расположен ВЭ */ /* minPoint - левая нижняя точка ВЭ в пространстве модели */ /* maxPoint - правая верхняя точка ВЭ в пространстве модели */ /* startPoint - стартовая точка ВЭ: центр видового экрана */ /*------------------------------------------------------------------------------------------------------------------*/ private void CreateViewPort(ObjectId newViewPortId, ObjectId newLayoutId, Point3d minPoint, Point3d maxPoint, Point3d startPoint) { Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; DocumentLock docLock = doc.LockDocument(DocumentLockMode.ProtectedAutoWrite, null, null, true); using (docLock) { Database db = doc.Database; Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor; using (Transaction trx = db.TransactionManager.StartTransaction()) { LayoutManager layman = Autodesk.AutoCAD.DatabaseServices.LayoutManager.Current; Layout newLayout = trx.GetObject(newLayoutId, OpenMode.ForWrite) as Layout; // лист, на котором нужно разместить видовой экран // Тут фатальная ошибка. layman.CurrentLayout = newLayout.LayoutName; // делаем нужный лист текущи BlockTableRecord btr = trx.GetObject(newLayout.BlockTableRecordId, OpenMode.ForWrite) as BlockTableRecord; //ObjectId layoutId = newLayoutId; //Viewport viewprt = trx.GetObject(newViewPortId, OpenMode.ForWrite) as Viewport; /* создание нового видового экрана */ Viewport viewprt = new Viewport(); viewprt.SetDatabaseDefaults(); ObjectId viewPortId = btr.AppendEntity(viewprt); trx.AddNewlyCreatedDBObject(viewprt, true); // видовой экран создается на слое "_AM_ViewPort". Если такого слоя нет в текущем чертеже - он создается. // Цвет слоя - красный, слой - непечатаемый. Остальные значения - по умолчанию LayerTable layTab = trx.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable; // таблица слоев if (!(layTab.Has("_AM_ViewPort"))) { LayerTableRecord newLayer = new LayerTableRecord(); newLayer.Name = "_AM_ViewPort"; newLayer.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 1); newLayer.IsPlottable = false; layTab.UpgradeOpen(); layTab.Add(newLayer); trx.AddNewlyCreatedDBObject(newLayer, true); } viewprt.Layer = "_AM_ViewPort"; // формирование размеров видового экрана в листе viewprt.CenterPoint = startPoint.Add(new Vector3d(0, -0.15, 0)); viewprt.Height = maxPoint.Y - minPoint.Y + 0.3; viewprt.Width = maxPoint.X - minPoint.X; viewprt.CustomScale = 1; // масштаб ВЭ - 1:1. // "прицеливание" ВЭ на нужный фрагмент пространства модели viewprt.ViewCenter = new Point2d((maxPoint.X - minPoint.X) / 2 + minPoint.X, (maxPoint.Y - minPoint.Y) / 2 + minPoint.Y).Add(new Vector2d(0, -0.15)); viewprt.ViewHeight = maxPoint.Y - minPoint.Y + 0.3; viewprt.Locked = true; // ВЭ блокируется viewprt.Draw(); // перерисовать ВЭ viewprt.On = true; // включен и видим viewprt.Visible = true; ed.Regen(); // переприсвоение свойств всех слоев на видовом экране - перевод в белый цвет /*foreach (ObjectId layId in layTab) { LayerTableRecord layTabRec = trx.GetObject(layId, OpenMode.ForWrite) as LayerTableRecord; LayerViewportProperties layVPortProps = layTabRec.GetViewportOverrides(newViewPortId); layVPortProps.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 7); }*/ trx.Commit(); } } }
Вложения:
AM SPDS SHT - шаблон, который содержит листы. В данном случае применяется лист "КабЖурнал_Первый" для первого листа, "КабЖурнал_Второй" - для второго и последующих.
АТХ - исходный файл. который нужно разложить на листы
АТХ после программы как должно быть - результат работы программы, который требуется.
Николай Коломоец:
Немного причесал функции. по прежнему имею "Фатальная ошибка: Unhandled Access Violation Writing 0x034"
1. Функция импорта листов
--- Код - C# [Выбрать] ---public ObjectId ImportLayout(String fileName, ref String layName, ref String paperName, int paperNo) { // Get the current document and database ObjectId newViewPortId = ObjectId.Null; Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // Specify the layout name and drawing file to work with string layoutName = layName; string filename = fileName; // Create a new database object and open the drawing into memory Database acExDb = new Database(false, true); acExDb.ReadDwgFile(filename, FileOpenMode.OpenForReadAndAllShare, true, ""); ObjectId layId = ObjectId.Null; using (DocumentLock dLock = acDoc.LockDocument(DocumentLockMode.ProtectedAutoWrite, null, null, true)) // Create a transaction for the external drawing { using (Transaction acTransEx = acExDb.TransactionManager.StartTransaction()) { // Get the layouts dictionary DBDictionary layoutsEx = acTransEx.GetObject(acExDb.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary; // Check to see if the layout exists in the external drawing if (layoutsEx.Contains(layoutName) == true) { // Get the layout and block objects from the external drawing Layout layEx = layoutsEx.GetAt(layoutName).GetObject(OpenMode.ForRead) as Layout; BlockTableRecord blkBlkRecEx = acTransEx.GetObject(layEx.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord; // Get the objects from the block associated with the layout ObjectIdCollection idCol = new ObjectIdCollection(); foreach (ObjectId id in blkBlkRecEx) { idCol.Add(id); } // Create a transaction for the current drawing using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // Get the block table and create a new block // then copy the objects between drawings BlockTable blkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForWrite) as BlockTable; using (BlockTableRecord blkBlkRec = new BlockTableRecord()) { int layoutCount = layoutsEx.Count - 1; blkBlkRec.Name = paperName + paperNo + layoutsEx.Count.ToString(); blkTbl.Add(blkBlkRec); acTrans.AddNewlyCreatedDBObject(blkBlkRec, true); acExDb.WblockCloneObjects(idCol, blkBlkRec.ObjectId, new IdMapping(), DuplicateRecordCloning.Ignore, false); // Create a new layout and then copy properties between drawings DBDictionary layouts = acTrans.GetObject(acCurDb.LayoutDictionaryId, OpenMode.ForWrite) as DBDictionary; // Добавка к коду LayoutManager layMan = LayoutManager.Current; using (Layout lay = new Layout()) { lay.LayoutName = paperName + paperNo; lay.AddToLayoutDictionary(acCurDb, blkBlkRec.ObjectId); acTrans.AddNewlyCreatedDBObject(lay, true); lay.CopyFrom(layEx); layId = lay.Id; newViewPortId = lay.Initialize(); DBDictionary plSets = acTrans.GetObject(acCurDb.PlotSettingsDictionaryId, OpenMode.ForRead) as DBDictionary; // Check to see if a named page setup was assigned to the layout, // if so then copy the page setup settings if (lay.PlotSettingsName != "") { // Check to see if the page setup exists if (plSets.Contains(lay.PlotSettingsName) == false) { plSets.UpgradeOpen(); using (PlotSettings plSet = new PlotSettings(lay.ModelType)) { plSet.PlotSettingsName = lay.PlotSettingsName; plSet.AddToPlotSettingsDictionary(acCurDb); acTrans.AddNewlyCreatedDBObject(plSet, true); DBDictionary plSetsEx = acTransEx.GetObject(acExDb.PlotSettingsDictionaryId, OpenMode.ForRead) as DBDictionary; PlotSettings plSetEx = plSetsEx.GetAt(lay.PlotSettingsName).GetObject( OpenMode.ForRead) as PlotSettings; plSet.CopyFrom(plSetEx); } } } } } // Save the changes made acTrans.Commit(); } } else { // Display a message if the layout could not be found in the specified drawing acDoc.Editor.WriteMessage("\nLayout '" + layoutName + "' could not be imported from '" + filename + "'."); } // Discard the changes made to the external drawing file acTransEx.Abort(); } // Close the external drawing file acExDb.Dispose(); } return layId; }
Функция создания видового экрана
--- Код - C# [Выбрать] --- /*------------------------------------------------------------------------------------------------------------------*/ /* Процедура создания видового экрана, указывающего на нужный участок пространства модели, соответствующий странице */ /* Входные данные: */ /* newViewPortId - идентификатор нового видового экрана */ /* newLayoutId - идентификатор листа, на котором расположен ВЭ */ /* minPoint - левая нижняя точка ВЭ в пространстве модели */ /* maxPoint - правая верхняя точка ВЭ в пространстве модели */ /* startPoint - стартовая точка ВЭ: центр видового экрана */ /*------------------------------------------------------------------------------------------------------------------*/ private void CreateViewPort(ObjectId newLayoutId, Point3d minPoint, Point3d maxPoint, Point3d startPoint) { Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor; LayoutManager layman = LayoutManager.Current; DocumentLock docLock = doc.LockDocument(DocumentLockMode.ProtectedAutoWrite, null, null, true); using (docLock) { using (Transaction trx = db.TransactionManager.StartTransaction()) { Layout newLayout = trx.GetObject(newLayoutId,OpenMode.ForRead) as Layout; BlockTableRecord btr = trx.GetObject(newLayout.BlockTableRecordId, OpenMode.ForWrite) as BlockTableRecord; //ObjectId layoutId = newLayoutId; //Viewport viewprt = trx.GetObject(newViewPortId, OpenMode.ForWrite) as Viewport; /* создание нового видового экрана */ Viewport viewprt = new Viewport(); viewprt.SetDatabaseDefaults(); ObjectId viewPortId = btr.AppendEntity(viewprt); trx.AddNewlyCreatedDBObject(viewprt, true); // видовой экран создается на слое "_AM_ViewPort". Если такого слоя нет в текущем чертеже - он создается. // Цвет слоя - красный, слой - непечатаемый. Остальные значения - по умолчанию LayerTable layTab = trx.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable; // таблица слоев if (!(layTab.Has("_AM_ViewPort"))) { LayerTableRecord newLayer = new LayerTableRecord(); newLayer.Name = "_AM_ViewPort"; newLayer.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 1); newLayer.IsPlottable = false; layTab.UpgradeOpen(); layTab.Add(newLayer); trx.AddNewlyCreatedDBObject(newLayer, true); } viewprt.Layer = "_AM_ViewPort"; // формирование размеров видового экрана в листе viewprt.CenterPoint = startPoint.Add(new Vector3d(0, -0.15, 0)); viewprt.Height = maxPoint.Y - minPoint.Y + 0.3; viewprt.Width = maxPoint.X - minPoint.X; viewprt.CustomScale = 1; // масштаб ВЭ - 1:1. // "прицеливание" ВЭ на нужный фрагмент пространства модели viewprt.ViewCenter = new Point2d((maxPoint.X - minPoint.X) / 2 + minPoint.X, (maxPoint.Y - minPoint.Y) / 2 + minPoint.Y).Add(new Vector2d(0, -0.15)); viewprt.ViewHeight = maxPoint.Y - minPoint.Y + 0.3; viewprt.Locked = true; // ВЭ блокируется viewprt.Draw(); // перерисовать ВЭ viewprt.On = true; // включен и видим viewprt.Visible = true; ed.Regen(); // переприсвоение свойств всех слоев на видовом экране - перевод в белый цвет foreach (ObjectId layId in layTab) { LayerTableRecord layTabRec = trx.GetObject(layId, OpenMode.ForWrite) as LayerTableRecord; LayerViewportProperties layVPortProps = layTabRec.GetViewportOverrides(viewPortId); layVPortProps.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 7); } trx.Commit(); } } }
А также фрагмент функции, которая их поочередно вызывает
--- Код - C# [Выбрать] ---// Добавление новых листов по шаблону for (int i = 1; i<=pages; i++) { ObjectId layId; // идентификатор созданного листа if (paperNumber == 0) // многостраничный лист (напр. "3.4") или одностраничный (напр. "4") sheetNr = i.ToString(); else sheetNr = paperNumber.ToString() + "." + i.ToString(); layoutName = layDocName + i.ToString(); // имя листа // копирование листа из шаблона и создание на его основе нового листа в текущем документе layId = ImportLayout(FILENAME, ref laySourceName, ref layNameTempl, i); LayoutManager layMan = LayoutManager.Current; layMan.CurrentLayout = layoutName; // фатальная ошибка - на ВТОРОМ ЛИСТЕ // создание на листе видового экрана, указывающего на область в пространстве модели, соответствующую новому листу CreateViewPort(layId, curPageDownBorder, curPageUpBorder, startLayoutPoint); // присвоение номера листу - заполнение атрибутов штампа //PaperNumeration(layId, sheetNr, sheets); pageHeight = pageHeightSecPage; // высота рабочей области второго (и последующих) листа больше, чем первого. curPageUpBorder = curPageDownBorder.Add(new Vector3d(pageWidth, 0, 0)); laySourceName = layDocName + "_Второй"; // переход к шаблону второго (и последующего) листов curPageDownBorder = curPageUpBorder.Add(new Vector3d(-pageWidth, -pageHeight, 0)); // уточненная точка начала листа, с учетом высоты одной строки - округляется значение так, чтобы ВЭ попадал на начало строки всегда startLayoutPoint = new Point3d((pageWidth / 2 + leftStampSize), (pageHeight / 2 + auxStampHeight + 20) + pageHeightSecPageDifference, 0); }
Александр Ривилис:
Вот этот код у меня работает (вид не подбирается, но это добавишь сам). Проверь работает ли он у тебя. Если работает - сравнивай код и исправляй свой.
--- Код - C# [Выбрать] ---using System;using System.Runtime.InteropServices;using System.Reflection;using Autodesk.AutoCAD.Runtime;using Autodesk.AutoCAD.ApplicationServices;using Autodesk.AutoCAD.DatabaseServices;using Autodesk.AutoCAD.Geometry;using Autodesk.AutoCAD.EditorInput;using AcRx = Autodesk.AutoCAD.Runtime;using AcAp = Autodesk.AutoCAD.ApplicationServices;using AcDb = Autodesk.AutoCAD.DatabaseServices;using AcGe = Autodesk.AutoCAD.Geometry;using AcEd = Autodesk.AutoCAD.EditorInput; [assembly: CommandClass(typeof(Rivilis.ImportLayouts))] namespace Rivilis{ public class ImportLayouts { public ObjectId ImportLayout(string fileName, ref string layoutName, ref string paperName, ref ObjectId newViewPortId, int paperNo) { ObjectId newLayoutId = ObjectId.Null; using (Database templateDb = new Database(false, true) as Database) { templateDb.ReadDwgFile(fileName, FileOpenMode.OpenForReadAndAllShare, true, ""); Document doc = Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; Database db = doc.Database; LayoutManager layoutManager = LayoutManager.Current; string newLayoutName = layoutName + "_" + paperNo + "_" + (layoutManager.LayoutCount - 1); newLayoutId = layoutManager.GetLayoutId(newLayoutName); if (newLayoutId.IsNull) newLayoutId = layoutManager.CreateLayout(newLayoutName); using (Transaction trx = db.TransactionManager.StartTransaction()) { Layout newLayout = trx.GetObject(newLayoutId, OpenMode.ForWrite) as Layout; newViewPortId = newLayout.Initialize(); trx.Commit(); } layoutManager.CurrentLayout = newLayoutName; using (Transaction trx = db.TransactionManager.StartTransaction()) using (Transaction templateTrx = templateDb.TransactionManager.StartTransaction()) { DBDictionary layoutDictionary = trx.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary; DBDictionary templateLayoutDictionary = templateTrx.GetObject(templateDb.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary; if (!(templateLayoutDictionary.Contains(layoutName))) { ed.WriteMessage("\nTemplate does not contain a Layout with that name."); return newLayoutId; } Layout newLayout = trx.GetObject(newLayoutId, OpenMode.ForWrite) as Layout; Layout templateLayout = templateLayoutDictionary.GetAt(layoutName).GetObject(OpenMode.ForRead) as Layout; newLayout.CopyFrom(templateLayout); BlockTableRecord templateLayoutBtr = templateTrx.GetObject(templateLayout.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord; ObjectIdCollection objIdColl = new ObjectIdCollection(); foreach (ObjectId id in templateLayoutBtr) objIdColl.Add(id); BlockTable extBt = templateDb.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable; IdMapping map = new IdMapping(); db.WblockCloneObjects(objIdColl, newLayout.BlockTableRecordId, map, DuplicateRecordCloning.Replace, false); PlotSettingsValidator psv = PlotSettingsValidator.Current; psv.SetZoomToPaperOnUpdate(newLayout, true); templateTrx.Commit(); trx.Commit(); } } return newLayoutId; } [CommandMethod("CopyLayout")] public void MyCommand() { string layoutName = "КабЖурналИмпульс_Первый"; string paperName = ""; int paperNo = 1; AcDb.ObjectId newViewPortId = new AcDb.ObjectId(); ImportLayout(@"C:\AM SPDS SHT.dwg", ref layoutName, ref paperName, ref newViewPortId, paperNo); // Put your command code here } }}
Навигация
Перейти к полной версии