ADN Club > AutoCAD .NET API

Создание листов

(1/5) > >>

Николай Коломоец:
Добрый день всем гуру программирования.

Есть модуль, который делает следующее:
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    }  }}

Навигация

[0] Главная страница сообщений

[#] Следующая страница

Перейти к полной версии