.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to convert string data to ObjectId.

20 REPLIES 20
SOLVED
Reply
Message 1 of 21
goldhorse.million
1421 Views, 20 Replies

How to convert string data to ObjectId.

 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. 

goldhorsemillion_0-1673470492508.png

 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.

20 REPLIES 20
Message 2 of 21
ed57gmc
in reply to: goldhorse.million

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?

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 3 of 21
_gile
in reply to: goldhorse.million

Hi,

 

Have a look at this recent reply.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 4 of 21
goldhorse.million
in reply to: _gile

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.

goldhorsemillion_0-1673506828497.png

In my opinion this error occurs while getting handle value.

Message 5 of 21
goldhorse.million
in reply to: ed57gmc

I need only ObjectId. Handle is needed for process to get ObjectId. Thank you.
Message 6 of 21
goldhorse.million
in reply to: ed57gmc

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.

goldhorsemillion_0-1673508194216.png

Thank you.

 

Message 7 of 21
goldhorse.million
in reply to: _gile

 

 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, 

Message 8 of 21
_gile
in reply to: goldhorse.million

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.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 9 of 21
goldhorse.million
in reply to: _gile

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());
    }
}   

 

Message 10 of 21
_gile
in reply to: goldhorse.million


@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 ?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 11 of 21
goldhorse.million
in reply to: _gile

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.

goldhorsemillion_0-1673622679528.pnggoldhorsemillion_1-1673622719697.png

 

 

long entityHandleLongInt = Convert.ToInt64(strhandle, 16);
Handle handle = new Handle(entityHandleLongInt);
Application.ShowAlertDialog(handle.ToString());
oid = database.GetObjectId(false, handle, 0);

 

Message 12 of 21
goldhorse.million
in reply to: _gile

Or can I select Polyline with Handle?

Message 13 of 21
_gile
in reply to: goldhorse.million

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());
        }

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 14 of 21
goldhorse.million
in reply to: _gile

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?

Message 15 of 21
_gile
in reply to: goldhorse.million


@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.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 16 of 21
goldhorse.million
in reply to: _gile

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.

Message 17 of 21
_gile
in reply to: goldhorse.million

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}");
}

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 18 of 21
goldhorse.million
in reply to: _gile

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.

Tags (2)
Message 19 of 21
_gile
in reply to: goldhorse.million

Sorry, I do not understand what you're doing.

Here's a video showing the how the commands from reply #13 work.

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 20 of 21

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.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report