Change Expression Units

The expression system in NX is "'unit aware" and can correctly handle a wide variety of unit types. This can make life easier since the designer no longer has to worry about unit conversions when creating expressions. Create a new length expression using units of centimeters, add an existing expression defined in inches to another defined in millimeters and you get the correct length expressed in centimeters.

This feature is a great way to reduce mistakes and capture design intent; however, it can also cause a few headaches. The company I work for recently contracted out some modeling work and we forgot to specify that we like to work in imperial units. We used ug_convert_part.exe to convert the part's base units so the files would play nice in our assemblies. Editing existing sketches prompted for dimensions in mm. I was a bit surprised to learn that interactive NX would not allow you to change an existing expression's units. As an alternative, I showed my coworker how to enter values such as "2.5in" so the input would be interpreted as inches, but this wasn't to his liking and he ended up remodeling the entire part. This struck me as a colossal waste of time and I started looking for ways to use NXOpen to convert the units of expressions. The result is the journal below.

Usage Notes

The journal, in its current form, will only convert length expressions from inch to mm (or vice-versa). If you need to convert expressions defined in other units such as feet or centimeters or if you need to convert expressions of area or volume; the journal will need to be modified for your requirements.

The journal will attempt to convert all length expressions defined as inch or mm. If you want to selectively convert certain expressions, again, the journal will need to be modified for your use.

There are several "writeline" statements that I used during testing to examine the output. Uncomment some or all of these if you would like to see a "report" of sorts.

The code was tested with NX 7.5 and should run on newer versions. It may even run on older versions, but I have not tested this.


Use the code at your own risk. Create a back up of your file before running the code. Nothing bad has happened during my testing, but I cannot claim to have tested every possibility. Should you find a bug, please contact me with a test file or procedure to reproduce it; email to

'January 14, 2014
'convert expressions with length units to part base units
'operates on the current work part
Option Strict Off
Imports System
Imports NXOpen
Module Module1
    Sub Main()
        Dim theSession As Session = Session.GetSession()
        Dim workPart As Part = theSession.Parts.Work
        If IsNothing(workPart) Then
            'active part required
        End If
        Dim lw As ListingWindow = theSession.ListingWindow
        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Convert Expression Units")
        Dim myUnit As Unit
        myUnit = workPart.UnitCollection.GetBase("length")
        'lw.WriteLine("part base length unit: " & myUnit.Abbreviation)
        Dim unitsToConvert As String = ""
        If workPart.PartUnits = BasePart.Units.Inches Then
            unitsToConvert = "mm"
            unitsToConvert = "in"
        End If
        'lw.WriteLine("expression units to convert: " & unitsToConvert)
        For Each myExp As Expression In workPart.Expressions
            'lw.WriteLine("name: " & myExp.Name)
            'lw.WriteLine("equation: " & myExp.Equation)
            'lw.WriteLine("rhs: " & myExp.RightHandSide)
            'lw.WriteLine("type: " & myExp.Type)
            '    If Not IsNothing(myExp.Units) Then
            '        lw.WriteLine("units: " & myExp.Units.Abbreviation)
            '        lw.WriteLine("value (in base units): " & myExp.Value)
            '    End If
            'Catch ex As NXException
            '    lw.WriteLine(ex.ErrorCode & ": " & ex.Message)
            'End Try
            'lw.WriteLine("interpart expression: " & myExp.RightHandSide.Contains("::").ToString)
            'the .value property returns the value in terms of the part's base units
            If myExp.Type.ToLower <> "number" Then
                'current expression is not a number (point, list, string, etc)
                'move to next expression
                Continue For
            End If
            If IsNothing(myExp.Units) Then
                'unitless (constant) expression
                Continue For
            End If
            If myExp.Units.Abbreviation = unitsToConvert Then
                'if we can parse the right hand side of the expression to a
                'double value, the expression "formula" is a simple numeric entry
                Dim theValue As Double
                If Double.TryParse(myExp.RightHandSide, theValue) Then
                    'the "formula" is a numeric entry
                    'lw.WriteLine("  parse success")
                    'lw.WriteLine("  parse value: " & theValue.ToString)
                    'the expression .Value will be returned in base units i.e. it will be converted for us
                    'set the .RightHandSide to the .Value and set the new units
                    myExp.RightHandSide = myExp.Value.ToString
                    myExp.Units = myUnit
                    'the "formula" is more complex than a simple numeric entry
                    'just convert units
                    myExp.Units = myUnit
                End If
            End If
    End Sub
    Public Function GetUnloadOption(ByVal dummy As String) As Integer
        'Unloads the image when the NX session terminates
        GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination
        '----Other unload options-------
        'Unloads the image immediately after execution within NX
        'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
        'Unloads the image explicitly, via an unload dialog
        'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Explicitly
    End Function
End Module