This is part nine of our blog series about the SOLIDWORKS API. There are links to all other parts at the bottom of this post.
Today, we are diving into custom properties.
A custom property is a piece of data with a name, type and value. Within SOLIDWORKS, we generally use it to store data like the description, mass and author of a file.
It’s called custom because you can pick your own name and type; you get to create your own property.
But a custom property is not actually a SOLIDWORKS concept, it’s used by Microsoft for all kinds of Windows files. See for example Creating Custom Properties on the Microsoft App Development website.
In this blog post, we will explain how to with custom properties in the SOLIDWORKS API. We assume that you know what custom properties are. If you don’t, please read these two blog posts first:
To access the custom properties, click the File Properties button in the top bar of SOLIDWORKS.
These properties are bound to the file, to the entire model. To access these properties, get the CustomPropertyManager and pass an empty string for the name of the configuration.
An example in VBA:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Option Explicit Sub main() Dim swApp As SldWorks.SldWorks Set swApp = Application.SldWorks Dim swModel As ModelDoc2 Set swModel = swApp.ActiveDoc Dim swExtension As ModelDocExtension Set swExtension = swModel.Extension Dim customPropManager As CustomPropertyManager Set customPropManager = swExtension.CustomPropertyManager("") End Sub |
Now that you have access to the CustomPropertyManager, you can read, add or delete custom properties on the file level. See the next section What is the CustomPropertyManager?
Configurations are designed for slight variations of your model. If you only change the looks (or hide/show assembly components), you should use Display States. But if the geometry varies, you need configurations. We explain the speed differences in our ebook Secrets to SOLIDWORKS Performance.
Every configuration can have its own list of custom properties.
But be aware: if you add the same property to both the file and the configuration, SOLIDWORKS will use the configuration-specific one. See Don’t add a property in both the Custom and Configuration Specific tabs in our other post.
The code to access the configuration-specific properties is nearly identical to the code above. The only difference is that you pass the name of the configuration you want to access:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Option Explicit Sub main() Dim swApp As SldWorks.SldWorks Set swApp = Application.SldWorks Dim swModel As ModelDoc2 Set swModel = swApp.ActiveDoc Dim swExtension As ModelDocExtension Set swExtension = swModel.Extension Dim customPropManager As CustomPropertyManager Set customPropManager = swExtension.CustomPropertyManager("Configuration1") End Sub |
If you already have an IConfiguration object, you can access the custom property manager directly:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Option Explicit Sub main() Dim swApp As SldWorks.SldWorks Set swApp = Application.SldWorks Dim swModel As ModelDoc2 Set swModel = swApp.ActiveDoc Dim swConfiguration As Configuration Set swConfiguration = swModel.GetActiveConfiguration Dim customPropManager As CustomPropertyManager Set customPropManager = swConfiguration.CustomPropertyManager End Sub |
If a part has Weldment or Sheet Metal bodies, SOLIDWORKS will group identical bodies in cut list folders.
Other body types are not grouped, even when they are identical.
Cut lists are tricky to work with and there are two methods for finding all cut list folders, so I wrote a separate section: Custom properties for cut list folders.
Every big feature in SOLIDWORKS is a manager. The tabs above the feature tree are all managers:
We access custom properties in the API via the CustomPropertyManager. As you saw in Section 2, three SOLIDWORKS API objects have a CustomPropertyManager property:
These are the methods (+ the count property) you need most often:
If the method has a number behind it, that means it is the nth version of that API. Older versions are not removed but have either a bug or fewer parameters. It’s up to you to figure out which one it is, unfortunately.
There are two methods for getting the value of a custom property:
I usually wrap both of these methods because I don’t like them. Get6 uses a bunch of out parameters for the type and the resolved value, but I prefer to have two explicit methods for getting the raw value and getting the resolved value. Just to avoid future mistakes.
GetAll3 returns five arrays, hidden in objects, hidden in out parameters. Some of them are string arrays and the last one is a boolean array, hidden in an integer array, hidden in an object. It’s pretty annoying.
Luckily, the open-source framework SolidDNA (that we currently maintain) has most of these methods wrapped by now. Read more below in A user-friendly way: using SolidDNA.
There are two ways for writing the value of a custom property:
There is no API to check if a custom property exists, unfortunately. So, there are two ways for figuring that out:
You could also use GetAll3, but that just returns more data that you don’t need when you only want to know if a property exists.
I find it strange that you can only pass strings as values, even when the type is a number. What makes it even worse is that SOLIDWORKS localizes your numbers (and dates, for that matter), so it may use a comma or a dot as a separator. Windows, SOLIDWORKS and Excel all have their own separator setting, so this can go very wrong very easily.
This has created problems for me in the past. In the code that creates our Fastener Models library, I diligently replace commas with dots before writing a number (coming from Excel, user input or somewhere else) to a custom property. And after creating the files, we have a separate tool that checks the separator in all custom properties.
Number and date properties were so annoying to work with that I now only use text properties.
SOLIDWORKS supports a list of variables (see All available variables for custom properties (and cut lists) for the complete list) to be used in custom properties. You can enter these values manually, but some of them are also available from a dropdown. One example is the mass:
When the part names changes, the filename gets updated automatically. And on every rebuild (I assume), this value gets recalculated. The result is called the resolved value in code and the evaluated value in the user interface.
Every link to a variable needs to be surrounded by double quotes ” for it to work. But in code, those double quotes are already used for strings. So, we have to either escape these characters or enter them by their character number.
In VBA, you use chr(34) for the double quote character and you concatenate three strings into a single value:
1 |
In C#, you escape the double quote character inside a string by adding a backslash before each one:
1 |
You can use custom property values in equations and you can add the result of an equation to a custom property. But that has little to do with the API, so I added it to section 13 of How to use custom properties in equations.
In theory, every feature can contain custom properties. But in practice, only cut list folder features can have them.
There are two methods for finding all cut list folders: get all children of the solid body folder or traverse the entire feature tree and collect all cut list folders.
You only need the second method if you are working with sub-weldments because these features mess up your feature tree. I will always advise to not use sub-weldments because:
We explain how to work with the FeatureManager / feature tree in part 3 of this blog series: How to work with Features in the SOLIDWORKS API. To find the solid body folder (there is always only one) feature, we traverse the feature tree until we find it.
You might also be able to get the solid body folder by its name, but I suspect the feature to have a localized name in other locales so it’s better to use the type name.
The next step is getting all children/subfeatures of the solid body folder. All of its children are cut list folders. Here’s a full example to get all cut list folders (and their custom property count) in VBA:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | Option Explicit Sub main() Dim swApp As SldWorks.SldWorks, swModel As ModelDoc2 Set swApp = Application.SldWorks Set swModel = swApp.ActiveDoc Dim solidBodyFolder As Feature Set solidBodyFolder = GetSolidBodyFolder(swModel) Dim subFeature As Feature Set subFeature = solidBodyFolder.GetFirstSubFeature While Not subFeature Is Nothing Dim customPropManager As CustomPropertyManager Set customPropManager = subFeature.CustomPropertyManager Debug.Print customPropManager.Count Set subFeature = subFeature.GetNextSubFeature Wend End Sub Private Function GetSolidBodyFolder(swModel As ModelDoc2) As Feature Dim swFeat As Feature Set swFeat = swModel.IFirstFeature() While Not swFeat Is Nothing If swFeat.GetTypeName2 = "SolidBodyFolder" Then Set GetSolidBodyFolder = swFeat Exit Function End If Set swFeat = swFeat.IGetNextFeature Wend End Function |
If you have a need to go through the entire feature tree in a search for cut list folders, here’s how to do that:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Sub GetCutListFeaturesFromTree() Dim swApp As SldWorks.SldWorks, swModel As ModelDoc2 Set swApp = Application.SldWorks Set swModel = swApp.ActiveDoc Dim swFeat As Feature Set swFeat = swModel.FirstFeature While Not swFeat Is Nothing If swFeat.GetTypeName2 = "CutListFolder" Then Dim folder As BodyFolder Set folder = swFeat.GetSpecificFeature2 Debug.Print "Folder type: " & folder.GetCutListType End If Set swFeat = swFeat.GetNextFeature Wend End Sub |
The Document Manager API lets you view and edit some SOLIDWORKS file properties without having to open the model. It even works when you don’t have SOLIDWORKS installed.
You cannot use the Document Manager in macros though, so I use it in add-ins (to avoid opening the files) or for tools for users without SOLIDWORKS.
It’s hard to understate how much faster the Document Manager is compared to opening the models.
In our fastener add-in Lightning, we read custom properties at a rate of around 100 files per second. I still need to investigate if we can spin up more threads to speed this up even further.
Follow these steps in a C# project to read a custom property from a file:
Here’s how to read or write a custom property using the Document Manager API:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public static string GetCustomPropertyValue(string customPropertyName) { var classFactory = new SwDMClassFactory(); var application = classFactory.GetApplication("your document manager key here"); var document = (ISwDMDocument29) application.GetDocument("C:\\test\\part.sldprt", SwDmDocumentType.swDmDocumentPart, allowReadOnly: true, out var result); var currentValue = document.GetCustomProperty(customPropertyName, out var customPropertyType); document.CloseDoc(); return currentValue; } public static void SetCustomPropertyValue(string customPropertyName, string newValue) { var classFactory = new SwDMClassFactory(); var application = classFactory.GetApplication("your document manager key here"); var document = (ISwDMDocument29) application.GetDocument("C:\\test\\part.sldprt", SwDmDocumentType.swDmDocumentPart, allowReadOnly: true, out var result); document.SetCustomProperty(customPropertyName, newValue); document.Save(); document.CloseDoc(); } |
SolidDNA is an open-source framework to make the SOLIDWORKS API more modern and easier to work with. It was originally built by SOLIDWORKS legend Luke Malpass, but we took it over when he no longer had the time for it.
SolidDNA acts as a wrapper around the core SOLIDWORKS API, yet it still gives you access to the raw objects if there is no modern version of an API yet. If a SOLIDWORKS API topic is hard to understand or otherwise annoying, we create a more user-friendly version for it.
We have a few simple methods for custom properties:
1 2 3 4 5 6 7 8 9 10 | var model = SolidWorksEnvironment.Application.ActiveModel; model.GetCustomProperty("property name"); // Get a model property model.GetCustomProperty("property name", "config name"); // Get a configuration property model.GetCustomProperty("property name", "config name", true); // Get a resolved configuration property model.SetCustomProperty("property name", "value"); // Set a model property model.SetCustomProperty("property name", "value", "config name"); // Set a configuration property var customPropertyEditor = model.Extension.CustomPropertyEditor("config name"); customPropertyEditor.CustomPropertyExists("property name"); // use the custom property editor directly to get if a property exists |
The Model and ModelFeature classes have a CustomPropertyEditor property, plus methods to get, set and delete custom properties. Use the optional parameters for the configuration name and whether to get the resolved value.
If you miss a useful method, feel free to send in a pull request on GitHub. All our products are based on SolidDNA and we are actively working on it.
The first tab of the file properties window shows the Summary Info. Every Windows file can have these properties like the Author, Title and Subject.
But you do not access them as you do with custom properties, you also don’t get to choose the name of the field.
Instead, you use the ModelDoc2.SummaryInfo property and you pass the index of the field you want to get or set:
1 2 3 4 5 6 7 8 9 10 11 | Option Explicit Sub main() Dim swApp As SldWorks.SldWorks, swModel As ModelDoc2 Set swApp = Application.SldWorks Set swModel = swApp.ActiveDoc swModel.SummaryInfo(swSummInfoField_e.swSumInfoTitle) = "Rocket" Debug.Print swModel.SummaryInfo(swSummInfoField_e.swSumInfoAuthor) End Sub |
Now you know how to add, update custom properties via the SOLIDWORKS API.
But you don’t have to reinvent the wheel, so here are some products that may already do what you are looking for:
Subscribe to our newsletter and get our TimeSavers add-in for free.