Hello, everyone. I am appreciating all the members helping us. Now I have a small problem for making a small project. I should get an ObjectId from saved string. my code does not work and get an error.
Here is my code.
//item.OId is string type variable.
Handle h = new Handle(Int64.Parse(item.OId, NumberStyles.AllowHexSpecifier));
ObjectId id = ObjectId.Null;
database.TryGetObjectId(h, out id);
Could someone help me? Thank you in advance.
Solved! Go to Solution.
Solved by _gile. Go to Solution.
I'm not sure what or why you are trying to do this. AutoCAD takes care of assigning handles to entities. Why are you trying to create a new handle?
I should get ObjectId with string value(e.g 2127225809680).
ObjectId objid = database.GetObjectId(false, new Handle(Convert.ToInt64(item.OId)), 0);
here item.OId is string type value. but I get this error.
In my opinion this error occurs while getting handle value.
Here my another trying code. item.OId is string value(converted from ObjectId).
if (database.TryGetObjectId(new Handle(long.Parse(item.OId)), out ObjectId id))
{
Application.ShowAlertDialog(id.ToString());
}
But get this error.
Thank you.
if (long.TryParse(item.OId,System.Globalization.NumberStyles.HexNumber,System.Globalization.CultureInfo.CurrentCulture,
out long value))
{
if (database.TryGetObjectId(new Handle(long.Parse(item.OId)), out ObjectId id))
{
Application.ShowAlertDialog(id.ToString());
oid = id;
}
}
After running this code I get oid=0. How can I solve this problem,
Hi,
It looks like there's some confusion between ObjectId and Handle.
Extract from this topic of the documentation:
"Handles are persistent between AutoCAD sessions, so they are the best way of accessing objects if you need to export drawing information to an external file which might later need to be used to update the drawing. The ObjectId of an object in a database exists only while the database is loaded into memory. Once the database is closed, the ObjectId assigned to an object no longer exist and maybe different the next time the database is opened. "
So, in the same session, non need to store naything else than the ObjectId, in different sessions you have to store the Handle (as string) to be able to get the new ObjectId in a new session.
Now I am using this code, but this does not work.
here strhandle is a string value that has already been stored.
ObjectId oid=ObjectId.Null;
if (long.TryParse(strhandle, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.CurrentCulture,
out long value))
{
if (database.TryGetObjectId(new Handle(value), out ObjectId id))
{
oid = id;
Application.ShowAlertDialog(oid.ToString());
}
}
@goldhorse.million a écrit :
Now I am using this code, but this does not work.
What do you mean with "does not work" means ?
If 'TryParse' returns false, that means 'strhandle' is not a valid hex number.
If TryGetObjectId returns false, that means that the created Handle does not correspond to an ObjectId.
The code from this reply handles these cases.
@goldhorse.million a écrit :here strhandle is a string value that has already been stored.
How did you get this string value ?
Before closing some AutoCAD document I saved ObjectId and Handle of selected Polylines in Json document.
After someone opening this document I should select Polylines(with stored Handle and ObjectId) programatically.
The current problem is getting ObjectId from the exact handle value. Your help is an oasis in the desert.
Now I get only correct Handle value(e.g E8CA5). Almost done, a little left. Is there any way to solve this problem?
my current code from your hint.
long entityHandleLongInt = Convert.ToInt64(strhandle, 16);
Handle handle = new Handle(entityHandleLongInt);
Application.ShowAlertDialog(handle.ToString());
oid = database.GetObjectId(false, handle, 0);
Sorry, it is difficult for me to understand what you mean.
The following command examples do work.
[CommandMethod("SAVEHANDLES")]
public void SaveHandles()
{
if ((short)Application.GetSystemVariable("DWGTITLED") == 0)
{
Application.ShowAlertDialog("Save the drawing before running the command again");
return;
}
var doc = Application.DocumentManager.MdiActiveDocument;
var ed = doc.Editor;
var selection = ed.GetSelection();
if (selection.Status != PromptStatus.OK)
return;
string[] lines =
selection.Value.GetObjectIds()
.Select(id => id.Handle.ToString())
.ToArray();
string filename = Path.ChangeExtension(doc.Name, "txt");
File.WriteAllLines(filename, lines);
}
[CommandMethod("SELECTHANDLES")]
public static void SelectHandles()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
string filename = Path.ChangeExtension(doc.Name, "txt");
if (!File.Exists(filename))
{
Application.ShowAlertDialog($"{Path.GetFileName(filename)} not found");
return;
}
string[] handles = File.ReadAllLines(filename);
var ids = new List<ObjectId>();
foreach ( string handle in handles )
{
if (long.TryParse(handle, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out long result))
{
if (db.TryGetObjectId(new Handle(result), out ObjectId id))
{
ids.Add(id);
}
}
}
ed.SetImpliedSelection(ids.ToArray());
}
Thanks _gile, but this code get only Handle value to decimal value. You know why? Or can I make Polyline to selection state with Handle?
@goldhorse.million a écrit :
Thanks _gile, but this code get only Handle value to decimal value. You know why?
I still don't understand what you mean.
The first command (SAVEHANDLES) writes the handles (as strings) to a .txt file (one handle per line).
The second command (SELECTHANDLES) reads the .txt file and tries to convert each handle to an ObjectId, then selects the entities in the drawing that match the valid ObjectIds.
@goldhorse.million a écrit :
Or can I make Polyline to selection state with Handle?
This seems to be another issue. Please, don't add more confusion.
This code does not work.
db.TryGetObjectId(new Handle(result), out ObjectId id
Here result is correct long type value. It works correctly until code gets the "result"-long value.
If, by : "does not work" you mean: returns "false", then there is no object with this handle in the drawing.
If, by some mystery, the "TryGetObjectId" method is not recognized on your computer, you can replace:
if (db.TryGetObjectId(new Handle(result), out ObjectId id))
{
ids.Add(id);
}
with:
ObjectId id;
try
{
id = db.GetObjectId(false, new Handle(result), 0);
ids.Add(id);
}
catch
{
ed.WriteMessage ($"\nInvalid handle: {handle}");
}
Hi, _gile. I received and ran your code. Encouraged by your help, I keep trying.
You will find interesting problems here. Please watch my video.
First Alert Dialogs are showed when reading saved Handle values. Here "0" is string value of ObjectId.
That code is following.
ObjectId oid=ObjectId.Null;
long entityHandleLongInt = Convert.ToInt64(item.hndle, 16);
Handle handle = new Handle(entityHandleLongInt);
Application.ShowAlertDialog(handle.ToString());
try
{
oid = database.GetObjectId(false, handle , 0);
}
catch
{
ed.WriteMessage($"\nInvalid handle: {handle}");
}
Application.ShowAlertDialog(oid.ToString());
Second alert dialogs are showing when I select multiple polylines. Code is followings.
Application.ShowAlertDialog(pl.Handle.ToString());
The polylines of the stored handle and the polylines selected with the mouse are the same object.
And as alert dialog shows, the handles are same too.
but "oid = database.GetObjectId(false, new Handle(Convert.ToInt64(item.hndle)), 0);" function fails so I see "Invalid handle: E8CA9" message all the time.
Is it a database problem? I think almost reached. I always appreicate your help.
Sorry, I do not understand what you're doing.
Here's a video showing the how the commands from reply #13 work.
I typically store handles as strings either in xdata or an xrecord, then use the Handle class to reinstantiate.
ObjectIds can change, so there's no point in storing them.
Storing the handle looks like this:
var dbObj = acTr.GetObject(id, OpenMode.ForRead);
string handleToStore = dbObj.Handle.ToString();
// TODO write string somewhere
To get an ObjectId from a string handle I use the following, very similar to yours:
/// <summary>
/// Given a handle, return an associated ObjectId
/// </summary>
/// <param name="handle">The handle.</param>
/// <returns></returns>
public static ObjectId GetObjectIDFromHandle(string handle)
{
try
{
// Convert hexadecimal string to 64-bit int
long ln = Convert.ToInt64(handle, 16);
// Now create a Handle from the long integer
Handle hn = new Handle(ln);
// And attempt to get an ObjectId for the Handle
ObjectId id = Active.Database.GetObjectId(false, hn, 0);
// return the objectID if it exists, ObjectId.Null if it doesn't
if (id.IsEffectivelyErased || id.IsErased) return ObjectId.Null;
return id;
}
catch
{
return ObjectId.Null;
}
}
Reviewing my code, I'd replace Active.Database with a database parameter.
Question: why are you getting the ObjectID via the handle if you already have the object?
item.hndle //<- hndle typo?
Hope this helps.
Can't find what you're looking for? Ask the community or share your knowledge.