eAlreadyInDb error in C# Autocad
I want to modify my attdef value but my code returns an error on sentence : "acBlktblRec.AppendEntity(acText);". error is : "eAlreadyInDb"
This is my code:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.ApplicationServices;
using System.Reflection;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
namespace LinkedIn
{
public class Initialization : IExtensionApplication
{
#region Commands
[CommandMethod("LISelectSet")]
public void cmdEdSelectSet()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
Database db = HostApplicationServices.WorkingDatabase;
// get the value enterd from user
PromptStringOptions pstringopt = new PromptStringOptions("\nEnter the string:");
//pstringopt.Message = "\nEnter the string";
pstringopt.AllowSpaces = true;
string ResStringInput;
PromptResult prstringress = ed.GetString(pstringopt);
if (prstringress.Status != PromptStatus.OK) return;
ResStringInput = prstringress.StringResult;
PromptSelectionOptions prSelOpts = new PromptSelectionOptions();
prSelOpts.AllowDuplicates = false;
prSelOpts.MessageForAdding = "\nSelect dimention to measure";
prSelOpts.MessageForRemoval = "\nselect dimention to remove from selection";
prSelOpts.RejectObjectsFromNonCurrentSpace = false;
prSelOpts.RejectObjectsOnLockedLayers = true;
//prSelOpts.RejectPaperspaceViewport = true;
List<string> list = new List<string>();
TypedValue[] tValues = new TypedValue[1];
tValues[0] = new TypedValue((int)DxfCode.Start, "Dimension");
SelectionFilter selfil = new SelectionFilter(tValues);
PromptSelectionResult prSelRes = ed.GetSelection(prSelOpts, selfil);
if (prSelRes.Status != PromptStatus.OK) return;
Transaction trans = db.TransactionManager.StartTransaction();
SelectionSet selSet = prSelRes.Value;
Dimension dimentionobj;
double lenTotal = 0.0;
string lenelement;
//List<string> list = new List<string>();
foreach (SelectedObject selObj in selSet)
{
dimentionobj = trans.GetObject(selObj.ObjectId, OpenMode.ForRead) as Dimension;
lenTotal += dimentionobj.Measurement;
lenelement = ResStringInput + " x " + dimentionobj.Measurement.ToString();
list.Add(lenelement);
}
DBText acText = new DBText();
acText.SetDatabaseDefaults();
string[] terms = list.ToArray();
string[] animals2 = new string[] { "deer", "moose", "boars" };
int n = 0;
foreach (String item in animals2)
{
Database acCurDb = Application.DocumentManager.MdiActiveDocument.Database;
BlockTable acBlkTbl;
acBlkTbl = trans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord acBlktblRec;
acBlktblRec = trans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
ed.WriteMessage(item);
acText.Position = new Point3d(23, 11 + n * 4, 0);
acText.Height = 3.5;
acText.TextString = item;
n = n + 1;
acBlktblRec.AppendEntity(acText);
trans.AddNewlyCreatedDBObject(acText, true);
}
trans.Commit();
}
#endregion
#region Initialization
void IExtensionApplication.Initialize()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
AssemblyName appName = Assembly.GetExecutingAssembly().GetName();
object[] attrs = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
ed.WriteMessage(((AssemblyTitleAttribute)attrs[0]).Title + " " +
appName.Version.Major + "." + appName.Version.MajorRevision + "." +
appName.Version.Minor + " is loaded...");
}
void IExtensionApplication.Terminate()
{
}
#endregion
}
}
Re: eAlreadyInDb error in C# Autocad
Welcome to AUGI.
I think you need to read up on the AutoCAD .NET API.
Consider using a Try { } Catch { } block and wrapping your DBText creation, Transaction, etc with Using { } respectively.
Also, you already add the Database at the top of the method, so no need to repeatedly access same within your Foreach + animals2 loop (same for BlockTable, Transaction, etc).
HTH
Re: eAlreadyInDb error in C# Autocad
Quote:
Originally Posted by
BlackBox
Welcome to AUGI.
I think you need to read up on the AutoCAD .NET API.
Consider using a Try { } Catch { } block and wrapping your DBText creation, Transaction, etc with Using { } respectively.
Also, you already add the Database at the top of the method, so no need to repeatedly access same within your Foreach + animals2 loop (same for BlockTable, Transaction, etc).
HTH
Pls explain for more clarify, you can give me example ??
Re: eAlreadyInDb error in C# Autocad
Quote:
Originally Posted by
norman.yuan
I want to modify my attdef value but my code returns an error on sentence : "acBlktblRec.AppendEntity(acText);". error is : "eAlreadyInDb"
...
namespace LinkedIn
{
public class Initialization : IExtensionApplication
{
#region Commands
[CommandMethod("LISelectSet")]
public void cmdEdSelectSet()
{
....
DBText acText = new DBText();
acText.SetDatabaseDefaults();
string[] terms = list.ToArray();
string[] animals2 = new string[] { "deer", "moose", "boars" };
int n = 0;
foreach (String item in animals2)
{
Database acCurDb = Application.DocumentManager.MdiActiveDocument.Database;
BlockTable acBlkTbl;
acBlkTbl = trans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord acBlktblRec;
acBlktblRec = trans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
ed.WriteMessage(item);
acText.Position = new Point3d(23, 11 + n * 4, 0);
acText.Height = 3.5;
acText.TextString = item;
n = n + 1;
acBlktblRec.AppendEntity(acText);
trans.AddNewlyCreatedDBObject(acText, true);
}
trans.Commit();
}
#endregion
}
}
[/code]
I only wander into here occasionally.
To me, it is quite obvious why the code results in"eAlreadyInDb" error, because your code create a new DBText object outside the "foreach..." loop, and then inside the "foreach ...", you change the DBText's TextString and try to add the same DBObject to ModelSpace in each loop, thus the error. If your actual intention is to create 3 DBObjects with different TextString value, you need to create DBObject inside the "foreach..." loop. Also, you should move the code that create ModelSpace BlockTableRecord out of "foreach ...", and get used to use "using..." to start a transaction. Something like:
Code:
....
using (var tran=db.TRansactionManager.StartTransaction())
{
string[] animals2 = new string[] { "deer", "moose", "boars" };
BlockTable acBlkTbl = trans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord acBlktblRec = trans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
foreach (var item in animals2)
{
var acText=new DbText();
acTest.SetDatabaseDefault();
acText.Height=...
acText.Position=...
acText.TextString=item
acBlktblRec.AppendEntity(acText)
tran.AddNewlyCreatedObject(acText, true);
}
tran.Commit();
}
....
HTH