A persistent ID never changes. It is persistent.
So if a user changes the name of a feature, you can still get it by its ID. This makes IDs great for finding back objects.
But the SOLIDWORKS API has a lot of different IDs, which can be confusing for developers.
In this post, I will list all of them.
This table is a complete overview of all identifiers we talk about here. I grouped them and added links to examples.
I’ll start with the top-level model and work my way down to sketches, edges and dimensions.
The good news is that models have a unique identifier. The bad news is that we cannot access this ID through the API. I asked API Support and they confirmed this for me. Only the SOLIDWORKS developers can use this identifier.
Because there is no persistent ID for a model, you need to use either the file path (if the model is saved) or the title (if the model is not saved yet). SOLIDWORKS makes sure the model title is unique, but you can mess this up via the API if you really want to.
These object types have a single integer as their unique identifier, which is not the same as a Persistent Reference ID. It is persistent over multiple SOLIDWORKS sessions, though.
Just be careful that the ID is unique only on one particular assembly level. A subassembly can use the same number for one of its components. That makes this component ID annoying to work with, in my opinion. Luckily, components also have a Persistent Reference ID.
The second difference is that this value is not saved in the model, so it is not persistent across sessions.
Edges can also have a Tracking ID, which I’ll discuss later.
Sketches don’t have a unique identifier (their features do), but each sketch segment within that sketch does have an ID.
Sketch segment IDs are unique because they consist of two integers (in VBA) or longs (in C#), for example: 12-42.
But that combination of numbers is not unique within the sketch, a different element type (line, arc, etc) can use the same numbers. So you also need to combine it with the element type and the sketch name. That means you better wrap the whole thing and create a SketchSegmentID class. Here’s mine:
The API documentation does not say that the Sketch Segment ID is persistent, so I assume it is not.
Nearly every object in SOLIDWORKS (that does not have an integer or a persistent reference ID) is identified by its name and most objects have a Name property with a getter and a setter. You can use these names for short-term actions, but don’t trust them to stay the same across SOLIDWORKS sessions because users can change these names.
Dimensions IDs are weird. They don’t have a number, only a name. But there are three different levels:
If you print these, you get the following:
The user can choose the Name property. If you want to be able to select a dimension using SelectByID2, you need to use the return value of GetNameForSelection.
I don’t know when you would need the full name, maybe when you work within an assembly?
Each ID value is unique within a model and it generally stays the same, even across SOLIDWORKS sessions. There is a remark in the docs, though, that it can change with rebuilds, but I don’t remember that actually being a problem for my software.
Once you obtained a selected object with SelectionManager.GetSelectedObject6, you can get its persistent reference ID by calling ModelDocExtensions.GetPersistReference3. This method returns an object that you need to cast to a byte array (in C#, at least). You could use integers, but the values never exceed 255. An example:
This identifier is a byte array, but the array length is not the same for all object types. The most common lengths are 16 and 20 bytes, but I just found a face that used 491 bytes. In my products, I only check if the array is at least 16 bytes long, nothing else.
If you need to know the length in advance, you can call GetPersistReferenceCount3 first. Be sure to read the performance warning there, though.
My advice is to never pass around persistent IDs as byte arrays, always create your own wrapper objects because the whole thing is a single object. I do the same for file paths, I don’t just pass around strings because that string can be:
When you create a specific object for that goal (or even derived objects, like a drawing path), your list of arguments becomes clearer and you can have all error checks for paths in one place.
When writing macros or add-ins, you will often need to store a persistent ID for later use. You can get back the object it belongs to by calling GetObjectByPersistReference3 and casting it to the correct type.
Once you have obtained the object by its persistent ID, you can select it again. There are two ways for this:
You can use Tracking IDs when you work with geometry and want to track entities across modeling operations. It only works in file types that create geometry, so parts and assemblies. Even though drawings are secretly assemblies.
An edge will not have the same persistent ID after you split the body it belongs to, but the tracking ID will stay the same. The lifetime of these IDs is also different because they are not persistent. They get reassigned after a rebuild, so you should only use them to build up geometry. This is probably the reason why I have never used them yet.
Tracking IDs are only built to be used by developers, so normal SOLIDWORKS users will never see these.
All the building blocks of geometry can have a tracking ID:
Assigning IDs is actually pretty straightforward:
If you now perform an operation, like splitting a body, an edge that is split into two edges will have the same tracking ID in each body.
I created a nice overview of all identifiers and other IDs in the SOLIDWORKS API.
The list includes every type that has a single-integer identifier, as well as double-integer IDs for sketch segments and persistent reference IDs. I have also included links to the API Docs and links to examples.