块插入循环错误!dbobji.cpp@8638:e不打开以进行写入

本文关键字:错误 循环 插入 dbobji cpp@8638 | 更新日期: 2023-09-27 18:26:30

好日子,

我正在创建一个程序来进行一些计算,并在用户单击的点插入一个块,然后重复计算并在用户点击的任何其他点插入,直到用户取消(请参阅下面的程序)。

该程序在用户单击的第一个点正确地完成了所有操作。然而,在while循环的第二次,用户单击某个点后,该程序会导致致命错误,并在没有插入块的情况下崩溃Autocad,崩溃错误消息:"内部错误:!dbobji.cpp@8638:eNotOpenForWrite"。

有人能帮我解释一下我的问题在哪里吗?

谢谢你,

using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using System.Collections.Generic;
using System.Linq;
[assembly: CommandClass(typeof(Level_Arrow.Program))]
namespace Level_Arrow
{
    public class Program
    {
        [CommandMethod("LevelCalc")]
        public static void InsertBLock(string[] args)
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = acDoc.Editor;
            Database db = acDoc.Database;
            Transaction tr = db.TransactionManager.StartTransaction();
            PromptStringOptions blkN1 = new PromptStringOptions("");
            blkN1.Message = "'nSpecify Block Name: ";
            blkN1.AllowSpaces = true;
            blkN1.DefaultValue = "Level Arrow";
            PromptResult BlkN2 = ed.GetString(blkN1);
            string blkName = BlkN2.StringResult.ToString();
            BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
            BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
            if (!bt.Has(blkName))
            {
                ed.WriteMessage("'nBlock not found.");
            }
            else
            {
                BlockTableRecord OrgBtr = (BlockTableRecord)tr.GetObject(bt[blkName], OpenMode.ForRead);
                PromptStringOptions pOptsUnitScale = new PromptStringOptions("");
                pOptsUnitScale.Message = "'nEnter drawing unit scale (m or mm): ";
                pOptsUnitScale.AllowSpaces = false;
                pOptsUnitScale.DefaultValue = "mm";
                PromptResult drgUnitsRes = ed.GetString(pOptsUnitScale);
                string drgUnits = drgUnitsRes.StringResult.ToLower();
                PromptDoubleOptions pOptsDrgScale = new PromptDoubleOptions("");
                pOptsDrgScale.Message = "'nEnter detail scale(1:_): ";
                PromptDoubleResult drgScale = ed.GetDouble(pOptsDrgScale);
                double drgScalem = drgScale.Value / 1000;
                double drgScalemm = drgScale.Value;
                PromptPointOptions ptBL = new PromptPointOptions("");
                ptBL.Message = "'nIndicate baseline: ";
                PromptPointResult ptBaseline = ed.GetPoint(ptBL);
                if (ptBaseline.Status == PromptStatus.Cancel) return;
                double yBase = ptBaseline.Value.Y;
                PromptDoubleOptions levelBL = new PromptDoubleOptions("");
                levelBL.Message = "'nSpecify Baseline level: ";
                PromptDoubleResult blLevel = ed.GetDouble(levelBL);
                double blLevelmm = blLevel.Value * 1000;
                double blLevelm = blLevel.Value;
                BlockReference insblkref;
                PromptPointOptions ptIns;
                Scale3d blkScale;
                AttributeReference ar;
                int a = 1;
                while (a == 1)
                {
                    using (DocumentLock LckDoc = acDoc.LockDocument())
                    {
                        using (tr)
                        {
                            ptIns = new PromptPointOptions("");
                            ptIns.Message = "'nSpecify insertion point: ";
                            PromptPointResult ptInsert = ed.GetPoint(ptIns);
                            if (ptInsert.Status == PromptStatus.Cancel) return;
                            double yInsert = ptInsert.Value.Y;
                            double ptVar = yInsert - yBase;
                            double ptLevel = 0;
                            ObjectId bdId = bt[blkName];
                            Point3d pt = ptInsert.Value;
                            insblkref = new BlockReference(pt, bdId);
                            insblkref.Rotation = 0;
                            if (drgUnits == "mm")
                            {
                                ptLevel = (blLevelmm + ptVar) / 1000;
                                blkScale = new Scale3d(drgScalemm, drgScalemm, drgScalemm);
                                insblkref.ScaleFactors = blkScale;
                            }
                            else if (drgUnits == "m")
                            {
                                ptLevel = blLevelm + ptVar;
                                blkScale = new Scale3d(drgScalem, drgScalem, drgScalem);
                                insblkref.ScaleFactors = blkScale;
                            }
                            double ptDisp = Math.Round(ptLevel, 3);
                            btr.AppendEntity(insblkref);
                            tr.AddNewlyCreatedDBObject(insblkref, true);
                            if (OrgBtr.HasAttributeDefinitions)
                            {
                                foreach (ObjectId id in OrgBtr)
                                {
                                    DBObject obj = tr.GetObject(id, OpenMode.ForRead);
                                    AttributeDefinition ad = obj as AttributeDefinition;
                                    if (ad != null && !ad.Constant)
                                    {
                                        ar = new AttributeReference();
                                        ar.SetAttributeFromBlock(ad, insblkref.BlockTransform);
                                        ar.Position = ad.Position.TransformBy(insblkref.BlockTransform);
                                        if (ad.Justify != AttachmentPoint.BaseLeft)
                                        {
                                            ar.AlignmentPoint.TransformBy(insblkref.BlockTransform);
                                        }
                                        if (ar.IsMTextAttribute)
                                        {
                                            ar.UpdateMTextAttribute();
                                        }
                                        ar.TextString = ptDisp.ToString();
                                        ObjectId arId = insblkref.AttributeCollection.AppendAttribute(ar);
                                        tr.AddNewlyCreatedDBObject(ar, true);
                                        break;
                                    }
                                }
                            }
                            tr.Commit();
                        } //Transaction end
                    } //Lock end
                    insblkref = null; //tried "insblkref.Dispose();" didn't work.
                } //while loop end
            }
        }
    }
}

块插入循环错误!dbobji.cpp@8638:e不打开以进行写入

我认为问题是这样的:

using (tr)

您早些时候声明了tr,稍后使用它(在第二个循环中)。通常,您会在声明周围放一个using语句(即用using (Transaction tr = db.TransactionManager.StartTransaction())替换Transaction tr = db.TransactionManager.StartTransaction();

原因是,在using块的末尾,传入的变量是关闭的&乐意这意味着你在完成交易之前就已经完成了交易。