Good Day,
I'm creating a program to do a few calculations and insert a block at a point the user clicks on, then repeats the calc and insert at any other point the user clicks on until the user cancels (See program below).
The program does everything correctly at the first point the user clicks on. Yet the second time through the while loop, after the user clicks on a point, the program causes a fatal error and crashes Autocad without inserting the block, crash error message: “ Internal Error: !dbobji.cpp@8638: eNotOpenForWrite”.
Would someone please go through this and explain to me where my problem is?
Thank you,
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
}
}
}
}