块插入循环错误!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
}
}
}
}
我认为问题是这样的:
using (tr)
您早些时候声明了tr,稍后使用它(在第二个循环中)。通常,您会在声明周围放一个using语句(即用using (Transaction tr = db.TransactionManager.StartTransaction())
替换Transaction tr = db.TransactionManager.StartTransaction();
。
原因是,在using块的末尾,传入的变量是关闭的&乐意这意味着你在完成交易之前就已经完成了交易。