Edit NX expressions Through NX Journal Userform

Hi all,

I want to create an userform in NX, which is showing existing Expressions and their values in Textboxes, and asks user to edit it. When user edits the values and hit OK , it edits the values in expressions.

Thanks & Regards,
Vivek

When you mention a "userform", do you mean an NX block styler dialog form or a Windows user form (winform)?

If you are interested in using winforms, there is an article here that describes their use:
http://nxjournaling.com/content/using-winforms-journals
The example code allows you to display and edit attribute values, but showing/editing expressions would be quite similar.

Yes I am talking about same winforms shown in link shared above.When I copy paste I am able to create simple form with lable , TextBox and buttons.

What I want to do is :
I have a heavier Parametric assembly having lots of interpart expressions. So to create a user form (winform) which shows me desires Expressions (that I want to change..) with their current values in TextBox, and then user can edit it , and submit so userform edit the values in nx expressions and assembly will be changed parametrically.

I will be glad if you can share a simple example program , which shows current features Expressions I.e. p1 , p2,.. in text box , and asks user to edit, submit.

Regards & Thanks,
Vivek

I hope I will get some guidance on that....

For this purpose (Only editing expression) using spreadsheet is the easiest way.

1. Run excel app from NX (Go through other journals, You can find a lot of posts)
2. Export all expression to excel
3. Keep a MSGbox with VBYes or No option to pause the journal.
4. Update values in excel.
5. Msgbox OK "VBYes" to continue the journal.
6. Read values from excel.
7. Update expression.

Regards,

Joe

Hi Joe,

Thanks for reply.
But we are already using an External Excel sheet. But what client want is to add an NX internal something. We don't have a license of Block Styler. And so the option left is to create userform.

So if you can help me and show me example code as I asked in previous comments, it will be very helpful for me.

Regards,
Vivek

Check the link provided above, If you want use form method. It is not that easy to write code to create new complex form with notepad. You need Visual Studio to design the form and convert it to code then modify its properties as per your requirements. There are plenty of options in form design how you want your list to be shown. This for adding hardware from TCE using a form (Might not be well construed code). This will give you info about how forms will work on NX.

' NX Add Hardware
' Journal created by Alto on 10-06-2015

Option Strict Off
Imports System.Drawing
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports System.Windows.Forms
Imports System.Windows.Forms.MessageBox
Imports System.IO
Imports System.Collections
Imports System.Environment
Imports Microsoft.VisualBasic

Module AddHardware1
Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display
Dim theUI As UI = UI.GetUI
Dim ufs As UFSession = UFSession.GetUFSession
Dim lw As ListingWindow = theSession.ListingWindow
Sub Main()

Dim form As UserSymbolForm = New UserSymbolForm(theSession, theUI)
Dim Partno As String = Nothing
' lw.Open()
Do
Try
If form.ShowDialog = DialogResult.Cancel Then Exit Sub
If form.Getthehardwareno(Partno) = True Then
form.Close()
Call Addpart(Partno)
End If
Catch err1 As ObjectDisposedException
' lw.WriteLine(err1.ToString)
Exit Do
End Try
Loop
' form.Close()
' lw.Close()

End Sub
Sub Addpart(Partno As String)

Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Add Component")
theSession.SetUndoMarkName(markId1, "Add Component")

'theSession.Parts.SetNonmasterSeedPartData("@DB/" & PartNo & "/" & PartRev)
'Dim basePart1 As BasePart = Nothing
'Try
' Dim partLoadStatus1 As PartLoadStatus = Nothing
' basePart1 = theSession.Parts.Open("@DB/" & PartNo & "/" & PartRev, partLoadStatus1)
' partLoadStatus1.Dispose()

'Catch exc As Exception
' basePart1 = theSession.Parts.FindObject("@DB/" & PartNo & "/" & PartRev)
'End Try

'Dim part1 As Part = CType(basePart1, Part)

Dim basePoint1 As Point3d = Nothing
UserSelectScreenPos("Select screen position to add Hardware", basePoint1)
'New Point3d(0.0, 0.0, 0.0)
Dim orientation1 As Matrix3x3
orientation1.Xx = 1.0
orientation1.Xy = 0.0
orientation1.Xz = 0.0
orientation1.Yx = 0.0
orientation1.Yy = 1.0
orientation1.Yz = 0.0
orientation1.Zx = 0.0
orientation1.Zy = 0.0
orientation1.Zz = 1.0
Dim partLoadStatus2 As PartLoadStatus = Nothing

Dim component1 As Assemblies.Component
Dim PreviewComponentOnAdd1 As Boolean
PreviewComponentOnAdd1 = theSession.Preferences.Assemblies.PreviewComponentOnAdd
PreviewComponentOnAdd1 = True

component1 = workPart.ComponentAssembly.AddComponent("@DB/" & Partno, "MODEL", Partno, basePoint1, orientation1, -1, partLoadStatus2)
partLoadStatus2.Dispose()

Dim constrain1 As Positioning.Constraint = Nothing
Dim constraintReference1 As Positioning.ConstraintReference
Dim mycomp As Object = Nothing
If SelectComponent("Select a reference Component where the Hardware need to constraint with ", mycomp) = Selection.Response.Cancel Then
Return
End If
Dim component2 As Assemblies.Component = mycomp
Dim componentPositioner1 As Positioning.ComponentPositioner
componentPositioner1 = workPart.ComponentAssembly.Positioner
componentPositioner1.ClearNetwork()
componentPositioner1.BeginAssemblyConstraints()
constrain1 = componentPositioner1.CreateConstraint()
Dim Edgeonparent As Object = Nothing
Dim P1 As Point3d
If UserSelectEdge("Select edge to attach Hardware", Edgeonparent, P1) = Selection.Response.Cancel Then
Return
End If
Dim edge1 As Edge = Edgeonparent
Dim componentConstraint1 As Positioning.ComponentConstraint = CType(constrain1, Positioning.ComponentConstraint)
componentConstraint1.ConstraintType = Positioning.Constraint.Type.Concentric
constraintReference1 = componentConstraint1.CreateConstraintReference(component2, edge1, False, False, False)
Dim EdgeonHardware As Object = Nothing
Dim P2 As Point3d
If UserSelectEdge("Select edge on Hardware to constrain", EdgeonHardware, P2) = Selection.Response.Cancel Then
Return
End If
Dim edge2 As Edge = EdgeonHardware
' Dim edge2 As Edge = CType(component1.FindObject("PROTO#.Features|REVOLVED(2)|EDGE * [CURVE 5 0] * [CURVE 6 0] {(0.0475,0.0822724133595,-0.048)(-0.095,0,-0.048)(0.0475,-0.0822724133595,-0.048) REVOLVED(2)}"), Edge)
Dim constraintReference2 As Positioning.ConstraintReference
constraintReference2 = componentConstraint1.CreateConstraintReference(component1, edge2, False, False, False)
constrain1.GetConstraintStatus()

End Sub

Function UserSelectEdge(ByVal prompt As String, ByRef selObj As TaggedObject, ByRef selPoint As Point3d) As Selection.Response

'Allow user to interactively select an edge

Dim title As String = "Select an edge"
Dim includeFeatures As Boolean = False
Dim keepHighlighted As Boolean = False
Dim selAction As Selection.SelectionAction = Selection.SelectionAction.ClearAndEnableSpecific
Dim scope As Selection.SelectionScope = Selection.SelectionScope.AnyInAssembly
Dim selectionMask_array(6) As Selection.MaskTriple

'Set the selection criteria to any edge
'TODO: Add point on surface
selectionMask_array(0).Type = UFConstants.UF_solid_type
selectionMask_array(0).Subtype = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE
selectionMask_array(0).SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE

selectionMask_array(1).Type = UFConstants.UF_line_type
selectionMask_array(1).Subtype = UFConstants.UF_all_subtype

selectionMask_array(2).Type = UFConstants.UF_circle_type
selectionMask_array(2).Subtype = UFConstants.UF_all_subtype

selectionMask_array(3).Type = UFConstants.UF_conic_type
selectionMask_array(3).Subtype = UFConstants.UF_all_subtype

selectionMask_array(4).Type = UFConstants.UF_spline_type
selectionMask_array(4).Subtype = UFConstants.UF_all_subtype

selectionMask_array(5).Type = UFConstants.UF_solid_silhouette_type
selectionMask_array(5).Subtype = UFConstants.UF_all_subtype

selectionMask_array(6).Type = UFConstants.UF_section_edge_type
selectionMask_array(6).Subtype = UFConstants.UF_all_subtype

'This line allows the user to select from any view:
ufs.Ui.SetCursorView(0)

Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObject(prompt, _
title, scope, selAction, _
includeFeatures, keepHighlighted, selectionMask_array, _
selObj, selPoint)
If resp = Selection.Response.ObjectSelected OrElse resp = Selection.Response.ObjectSelectedByName Then
Return Selection.Response.Ok
Else
Return Selection.Response.Cancel
End If

End Function
Function UserSelectScreenPos(ByVal prompt As String, ByRef selPoint As Point3d) As Selection.DialogResponse
'Allow user to interactively select a screen position
Dim view As NXOpen.View = Nothing
Return theUI.SelectionManager.SelectScreenPosition(prompt, view, selPoint)
End Function

Function SelectComponent(ByVal prompt As String, ByRef selObj As NXObject) As Selection.Response

Dim title As String = "Select a component"
Dim includeFeatures As Boolean = False
Dim keepHighlighted As Boolean = False
Dim selAction As Selection.SelectionAction = Selection.SelectionAction.ClearAndEnableSpecific
Dim cursor As Point3d
Dim scope As Selection.SelectionScope = Selection.SelectionScope.AnyInAssembly
Dim selectionMask_array(0) As Selection.MaskTriple

With selectionMask_array(0)
.Type = UFConstants.UF_component_type
.Subtype = UFConstants.UF_all_subtype
End With

Dim resp As Selection.Response = theUI.SelectionManager.SelectObject(prompt, _
title, scope, selAction, _
includeFeatures, keepHighlighted, selectionMask_array, _
selObj, cursor)
If resp = Selection.Response.ObjectSelected OrElse resp = Selection.Response.ObjectSelectedByName Then
Return Selection.Response.Ok
Else
Return Selection.Response.Cancel
End If

End Function

End Module

_
Partial Class UserSymbolForm
Inherits System.Windows.Forms.Form

Public Sub New(ByVal session As Session, ByVal ui As UI)
MyBase.New()
Dim theSession As Session = session
Dim theUI As UI = ui

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call
Me.Button1.Text = "Ok"
Me.BringToFront()

End Sub

Public Function Getthehardwareno(ByRef Partno As String) As Boolean
If Me.DialogResult = Windows.Forms.DialogResult.OK Then
Partno = Me.ComboBox4.Text
End If
Return True
End Function

'Form overrides dispose to clean up the component list.
_
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
_
Private Sub InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button()
Me.Button2 = New System.Windows.Forms.Button()
Me.ComboBox1 = New System.Windows.Forms.ComboBox()
Me.Label1 = New System.Windows.Forms.Label()
Me.PictureBox1 = New System.Windows.Forms.PictureBox()
Me.Label2 = New System.Windows.Forms.Label()
Me.ComboBox2 = New System.Windows.Forms.ComboBox()
Me.Label3 = New System.Windows.Forms.Label()
Me.ComboBox3 = New System.Windows.Forms.ComboBox()
Me.Label4 = New System.Windows.Forms.Label()
Me.Label5 = New System.Windows.Forms.Label()
Me.Button3 = New System.Windows.Forms.Button()
Me.ComboBox4 = New System.Windows.Forms.ComboBox()
Me.Button4 = New System.Windows.Forms.Button()
CType(Me.PictureBox1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'Button1
'
Me.Button1.DialogResult = System.Windows.Forms.DialogResult.OK
Me.Button1.Location = New System.Drawing.Point(28, 253)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(75, 23)
Me.Button1.TabIndex = 0
Me.Button1.Text = "Ok"
Me.Button1.UseVisualStyleBackColor = True
'
'Button2
'
Me.Button2.DialogResult = System.Windows.Forms.DialogResult.Cancel
Me.Button2.Location = New System.Drawing.Point(191, 253)
Me.Button2.Name = "Button2"
Me.Button2.Size = New System.Drawing.Size(75, 23)
Me.Button2.TabIndex = 1
Me.Button2.Text = "Cancel"
Me.Button2.UseVisualStyleBackColor = True
'
'ComboBox1
'
Me.ComboBox1.FormattingEnabled = True
Me.ComboBox1.Items.AddRange(New Object() {"SCREWS", "INSERTS", "WASHERS", "RIVETS"})
Me.ComboBox1.Location = New System.Drawing.Point(25, 25)
Me.ComboBox1.Name = "ComboBox1"
Me.ComboBox1.Size = New System.Drawing.Size(156, 21)
Me.ComboBox1.TabIndex = 2
'
'Label1
'
Me.Label1.AutoSize = True
Me.Label1.Location = New System.Drawing.Point(22, 9)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(81, 13)
Me.Label1.TabIndex = 3
Me.Label1.Text = "Select category"
'
'PictureBox1
'
Me.PictureBox1.Location = New System.Drawing.Point(210, 47)
Me.PictureBox1.Name = "PictureBox1"
Me.PictureBox1.Size = New System.Drawing.Size(200, 179)
Me.PictureBox1.TabIndex = 4
Me.PictureBox1.TabStop = False
' Me.PictureBox1.Image = Image.FromFile("C:\Users\Joe\Desktop\Study\Images\IntialImage.Jpg")
Me.PictureBox1.Image = Image.FromFile("C:\Users\Joe\Desktop\Study\Images\IntialImage.Jpg")
'Label2
'
Me.Label2.AutoSize = True
Me.Label2.Location = New System.Drawing.Point(223, 25)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(94, 13)
Me.Label2.TabIndex = 5
Me.Label2.Text = "Hardware Preview"
'
'ComboBox2
'
Me.ComboBox2.FormattingEnabled = True
Me.ComboBox2.Location = New System.Drawing.Point(25, 77)
Me.ComboBox2.Name = "ComboBox2"
Me.ComboBox2.Size = New System.Drawing.Size(156, 21)
Me.ComboBox2.TabIndex = 6
'
'Label3
'
Me.Label3.AutoSize = True
Me.Label3.Location = New System.Drawing.Point(22, 58)
Me.Label3.Name = "Label3"
Me.Label3.Size = New System.Drawing.Size(97, 13)
Me.Label3.TabIndex = 7
Me.Label3.Text = "Select Subcategoy"
'
'ComboBox3
'
Me.ComboBox3.FormattingEnabled = True
Me.ComboBox3.Location = New System.Drawing.Point(25, 139)
Me.ComboBox3.Name = "ComboBox3"
Me.ComboBox3.Size = New System.Drawing.Size(156, 21)
Me.ComboBox3.TabIndex = 8
'
'Label4
'
Me.Label4.AutoSize = True
Me.Label4.Location = New System.Drawing.Point(22, 110)
Me.Label4.Name = "Label4"
Me.Label4.Size = New System.Drawing.Size(86, 13)
Me.Label4.TabIndex = 9
Me.Label4.Text = "Select Hardware"
'
'Label5
'
Me.Label5.AutoSize = True
Me.Label5.Location = New System.Drawing.Point(27, 178)
Me.Label5.Name = "Label5"
Me.Label5.Size = New System.Drawing.Size(60, 13)
Me.Label5.TabIndex = 10
Me.Label5.Text = "Select Size"
'
'Button3
'
Me.Button3.Location = New System.Drawing.Point(272, 253)
Me.Button3.Name = "Button3"
Me.Button3.Size = New System.Drawing.Size(75, 23)
Me.Button3.TabIndex = 11
Me.Button3.Text = "Help"
Me.Button3.UseVisualStyleBackColor = True
'
'ComboBox4
'
Me.ComboBox4.FormattingEnabled = True
Me.ComboBox4.Location = New System.Drawing.Point(30, 205)
Me.ComboBox4.Name = "ComboBox4"
Me.ComboBox4.Size = New System.Drawing.Size(151, 21)
Me.ComboBox4.TabIndex = 12
'
'Button4
'
Me.Button4.Location = New System.Drawing.Point(110, 253)
Me.Button4.Name = "Button4"
Me.Button4.Size = New System.Drawing.Size(75, 23)
Me.Button4.TabIndex = 13
Me.Button4.Text = "Apply"
Me.Button4.UseVisualStyleBackColor = True
'
'UserSymbolForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(428, 298)
Me.Controls.Add(Me.Button4)
Me.Controls.Add(Me.ComboBox4)
Me.Controls.Add(Me.Button3)
Me.Controls.Add(Me.Label5)
Me.Controls.Add(Me.Label4)
Me.Controls.Add(Me.ComboBox3)
Me.Controls.Add(Me.Label3)
Me.Controls.Add(Me.ComboBox2)
Me.Controls.Add(Me.Label2)
Me.Controls.Add(Me.PictureBox1)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.ComboBox1)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.Button1)
Me.Name = "UserSymbolForm"
Me.Text = "Hardware Selection"
CType(Me.PictureBox1, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
Me.PerformLayout()

End Sub
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents Button2 As System.Windows.Forms.Button
Friend WithEvents ComboBox1 As System.Windows.Forms.ComboBox
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents PictureBox1 As System.Windows.Forms.PictureBox
Friend WithEvents Label2 As System.Windows.Forms.Label
Friend WithEvents ComboBox2 As System.Windows.Forms.ComboBox
Friend WithEvents Label3 As System.Windows.Forms.Label
Friend WithEvents ComboBox3 As System.Windows.Forms.ComboBox
Friend WithEvents Label4 As System.Windows.Forms.Label
Friend WithEvents Label5 As System.Windows.Forms.Label
Friend WithEvents Button3 As System.Windows.Forms.Button
Friend WithEvents ComboBox4 As System.Windows.Forms.ComboBox
Friend WithEvents Button4 As System.Windows.Forms.Button

Private Sub ComboBox1_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged

Dim Screwslist() As String = {"HEXHEAD", "CSK"}
Dim Insertslist() As String = {"ADD Inserts TYPE HERE", "C"}
Dim Helicoilslist() As String = {"ADD Helicoils TYPE HERE", "C"}
Dim Rivetslist() As String = {"ADD Rivets TYPE HERE", "C"}

ComboBox2.Items.Clear()
If ComboBox1.SelectedIndex = 0 Then
ComboBox2.Items.AddRange(Screwslist)
ElseIf ComboBox1.SelectedIndex = 1 Then
ComboBox2.Items.AddRange(Insertslist)
ElseIf ComboBox1.SelectedIndex = 2 Then
ComboBox2.Items.AddRange(Helicoilslist)
ElseIf ComboBox1.SelectedIndex = 3 Then
ComboBox2.Items.AddRange(Rivetslist)
End If

End Sub

Dim hexhead() As String = {"NAS1801-3", "NAS1801-3"}
Dim CSK() As String = {"ADD SCREWS TYPE HERE", "C"}

Private Sub ComboBox2_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles ComboBox2.SelectedIndexChanged

ComboBox3.Items.Clear()
If ComboBox2.SelectedIndex = 0 Then
ComboBox3.Items.AddRange(hexhead)
ElseIf ComboBox2.SelectedIndex = 1 Then
ComboBox3.Items.AddRange(CSK)
End If
End Sub

Private Sub ComboBox3_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles ComboBox3.SelectedIndexChanged

Dim NAS1801length() As String = {"NAS1801-3-6/3", "NAS1801-3-10/3"}
Dim CSK1() As String = {"ADD SCREWS length HERE", "C"}

ComboBox4.Items.Clear()
If ComboBox3.SelectedIndex = 0 Then
PictureBox1.Image = Image.FromFile("C:\Users\Joe\Desktop\Study\Images\" & hexhead(0) & ".jpg")
ComboBox4.Items.AddRange(NAS1801length)
ElseIf ComboBox3.SelectedIndex = 1 Then
ComboBox4.Items.AddRange(CSK1)
PictureBox1.ImageLocation = "C:\Users\Joe\Desktop\Study\Images\" & hexhead(1) & "jpg"
End If
End Sub
Private Sub ComboBox4_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles ComboBox4.SelectedIndexChanged

End Sub

Private Sub PictureBox1_Click(sender As System.Object, e As System.EventArgs) Handles PictureBox1.Click
PictureBox1.ImageLocation = "C:\Users\Joe\Desktop\Study\Images\"
End Sub
End Class

Regards,

Joe

Hii Joe,

Thanks for reply.

I tried some trial & error method and ran this code.I have also installed Visual Studio 2015,too and referenced NXOpen API to it. Here is the following code, I am struggling with.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim theSession As NXOpen.Session = NXOpen.Session.GetSession()
Dim workPart As NXOpen.Part = theSession.Parts.Work
Dim exp1 As NXOpen.Expression = CType(workPart.Expressions.FindObject("p1"), NXOpen.Expression)
Dim exp2 As NXOpen.Expression = CType(workPart.Expressions.FindObject("p2"), NXOpen.Expression)
Dim exp3 As NXOpen.Expression = CType(workPart.Expressions.FindObject("p3"), NXOpen.Expression)
Dim unit1 As NXOpen.Unit = CType(workPart.UnitCollection.FindObject("MilliMeter"), NXOpen.Unit)
Dim markId1 As Session.UndoMarkId
workPart.Expressions.EditWithUnits(exp1,Unit1, TextBox1.Text)
workPart.Expressions.EditWithUnits(exp2,Unit1, TextBox2.Text)
workPart.Expressions.EditWithUnits(exp3,Unit1, TextBox3.Text)
theSession.Preferences.Modeling.UpdatePending = False
Dim nErrs1 As Integer
nErrs1 = theSession.UpdateManager.DoUpdate(markId1)
Me.Close
End Sub

When this code is executed, it will find P1 , P2 & P3 then will edit/replace the values with the values entered in TextBox.

But the problem is that if someone edit name of the expression from P1 to say X1 in NX , this form will be outdated as it will just try to find P1.

I want to link expressions with userforms in a such a way that if someone edit expressions in NX it will show updated info in Userform and vice versa
-user can modify Both Name/Value of expressions at both places (in NX or userform)and get updated info at Both.

Regards,
Vivek

One way of getting the correct expressions would be to get the expressions of the particular feature that you are interested in. A feature object has a .GetExpressions method that will return the expressions that control the feature parameters. The problem now becomes: "how do we find the correct feature all the time?". Fortunately, a feature object can have attributes assigned to it; the code example below makes use of a feature that has a custom attribute assigned to it. The code looks through the features of the current work part until it finds one with an attribute titled "myblock", the attribute value is not important (it can have any value). When writing/testing the code, I created a simple part file with a block feature in it and gave the feature an attribute titled "myblock". If the code finds this feature, it will display a form with the three expressions displayed (length, width, and height values). The user can enter new names or values for the expressions. Note that this code is to illustrate one way to do this; the code does almost no error checking. It would be very easy to enter values that would cause errors; production code should be made more robust than what is shown below.

Option Strict Off
Imports System
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports NXOpen
Imports NXOpen.UF

Module Module2

Public theSession As Session = Session.GetSession()
Public theUfSession As UFSession = UFSession.GetUFSession()

Dim theUI As UI = UI.GetUI()
Dim lw As ListingWindow = theSession.ListingWindow

Sub Main()

Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "NXJ")

lw.Open()

Dim featureFound As Boolean = False
Dim blockExpressions As New List(Of Expression)
For Each tempFeat As Features.Feature In theSession.Parts.Work.Features
If tempFeat.HasUserAttribute("myblock", NXObject.AttributeType.String, -1) Then
featureFound = True
For Each tempExp As Expression In tempFeat.GetExpressions
blockExpressions.Add(tempExp)
Next

Exit For
End If
Next

If Not featureFound Then
theSession.DeleteUndoMark(markId1, "NXJ")
Return
End If

Dim expForm As New Form1
expForm.Expressions = blockExpressions
expForm.ShowDialog()

theSession.UpdateManager.DoUpdate(markId1)

lw.Close()

End Sub

Public Function GetUnloadOption(ByVal dummy As String) As Integer

'Unloads the image immediately after execution within NX
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately

End Function

End Module

Public Class Form1

Private fExpressions As New List(Of NXOpen.Expression)
Public Property Expressions() As List(Of NXOpen.Expression)
Get
Return fExpressions
End Get
Set(ByVal value As List(Of NXOpen.Expression))
fExpressions = value
End Set
End Property

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

'assumes there are 3 expressions in the list
'no error checking is done

txtExp1Name.Text = fExpressions.Item(0).Name
txtExp1Val.Text = fExpressions.Item(0).RightHandSide

txtExp2Name.Text = fExpressions.Item(1).Name
txtExp2Val.Text = fExpressions.Item(1).RightHandSide

txtExp3Name.Text = fExpressions.Item(2).Name
txtExp3Val.Text = fExpressions.Item(2).RightHandSide

End Sub

Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
Me.Close()
End Sub

Private Sub btnOk_Click(sender As Object, e As EventArgs) Handles btnOk.Click

Try
fExpressions.Item(0).SetName(txtExp1Name.Text)
Catch ex As nxopen.NXException

End Try
theSession.Parts.Work.Expressions.Edit(fExpressions.Item(0), txtExp1Val.Text)

Try
fExpressions.Item(1).SetName(txtExp2Name.Text)
Catch ex As nxopen.nxException

End Try
theSession.Parts.Work.Expressions.Edit(fExpressions.Item(1), txtExp2Val.Text)

Try
fExpressions.Item(2).SetName(txtExp3Name.Text)
Catch ex As nxopen.nxException

End Try
theSession.Parts.Work.Expressions.Edit(fExpressions.Item(2), txtExp3Val.Text)

Me.Close()
End Sub

End Class

_
Partial Class Form1
Inherits System.Windows.Forms.Form

'Form overrides dispose to clean up the component list.
_
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
_
Private Sub InitializeComponent()
Me.txtExp1Val = New System.Windows.Forms.TextBox()
Me.btnOk = New System.Windows.Forms.Button()
Me.btnCancel = New System.Windows.Forms.Button()
Me.txtExp1Name = New System.Windows.Forms.TextBox()
Me.txtExp2Name = New System.Windows.Forms.TextBox()
Me.txtExp2Val = New System.Windows.Forms.TextBox()
Me.txtExp3Name = New System.Windows.Forms.TextBox()
Me.txtExp3Val = New System.Windows.Forms.TextBox()
Me.SuspendLayout()
'
'txtExp1Val
'
Me.txtExp1Val.Location = New System.Drawing.Point(115, 37)
Me.txtExp1Val.Name = "txtExp1Val"
Me.txtExp1Val.Size = New System.Drawing.Size(155, 20)
Me.txtExp1Val.TabIndex = 1
'
'btnOk
'
Me.btnOk.Location = New System.Drawing.Point(20, 137)
Me.btnOk.Name = "btnOk"
Me.btnOk.Size = New System.Drawing.Size(106, 49)
Me.btnOk.TabIndex = 2
Me.btnOk.Text = "OK"
Me.btnOk.UseVisualStyleBackColor = True
'
'btnCancel
'
Me.btnCancel.Location = New System.Drawing.Point(164, 137)
Me.btnCancel.Name = "btnCancel"
Me.btnCancel.Size = New System.Drawing.Size(106, 49)
Me.btnCancel.TabIndex = 3
Me.btnCancel.Text = "Cancel"
Me.btnCancel.UseVisualStyleBackColor = True
'
'txtExp1Name
'
Me.txtExp1Name.Location = New System.Drawing.Point(20, 37)
Me.txtExp1Name.Name = "txtExp1Name"
Me.txtExp1Name.Size = New System.Drawing.Size(83, 20)
Me.txtExp1Name.TabIndex = 4
'
'txtExp2Name
'
Me.txtExp2Name.Location = New System.Drawing.Point(20, 63)
Me.txtExp2Name.Name = "txtExp2Name"
Me.txtExp2Name.Size = New System.Drawing.Size(83, 20)
Me.txtExp2Name.TabIndex = 6
'
'txtExp2Val
'
Me.txtExp2Val.Location = New System.Drawing.Point(115, 63)
Me.txtExp2Val.Name = "txtExp2Val"
Me.txtExp2Val.Size = New System.Drawing.Size(155, 20)
Me.txtExp2Val.TabIndex = 5
'
'txtExp3Name
'
Me.txtExp3Name.Location = New System.Drawing.Point(20, 89)
Me.txtExp3Name.Name = "txtExp3Name"
Me.txtExp3Name.Size = New System.Drawing.Size(83, 20)
Me.txtExp3Name.TabIndex = 8
'
'txtExp3Val
'
Me.txtExp3Val.Location = New System.Drawing.Point(115, 89)
Me.txtExp3Val.Name = "txtExp3Val"
Me.txtExp3Val.Size = New System.Drawing.Size(155, 20)
Me.txtExp3Val.TabIndex = 7
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(289, 205)
Me.Controls.Add(Me.txtExp3Name)
Me.Controls.Add(Me.txtExp3Val)
Me.Controls.Add(Me.txtExp2Name)
Me.Controls.Add(Me.txtExp2Val)
Me.Controls.Add(Me.txtExp1Name)
Me.Controls.Add(Me.btnCancel)
Me.Controls.Add(Me.btnOk)
Me.Controls.Add(Me.txtExp1Val)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
Me.PerformLayout()

End Sub
Friend WithEvents txtExp1Val As System.Windows.Forms.TextBox
Friend WithEvents btnOk As System.Windows.Forms.Button
Friend WithEvents btnCancel As System.Windows.Forms.Button
Friend WithEvents txtExp1Name As System.Windows.Forms.TextBox
Friend WithEvents txtExp2Name As System.Windows.Forms.TextBox
Friend WithEvents txtExp2Val As System.Windows.Forms.TextBox
Friend WithEvents txtExp3Name As System.Windows.Forms.TextBox
Friend WithEvents txtExp3Val As System.Windows.Forms.TextBox
End Class

Hiii,

The above code is running fine with slight modification in Visual Studio and showing output form with 6 textboxes.

But the same I play it is showing the following 3 errors.

Line 146 : 'components' is not declared.It may be inaccessible due to its protection level

Line 147 : 'components' is not declared.It may be inaccessible due to its protection level

Line 161 : End of the statement expected.

The last error for line 161 : i tried many things but not able to solve

Regards,
Vivek

Make sure that the following line was copied correctly (it is the one that declares the "components" variable):

Private components As System.ComponentModel.IContainer

It may have been a copy & paste error. I'd suggest creating a new file in notepad and then copy & paste all the code from the post above into the new text file. Save the text file with a ".vb" extension and run the code from the journal replay tool.

Hiii,

I tried to solve it but I am not getting rid of some errors, so try to again simplify my query.

Query : Link Desired NX expressions to WinForm

Background : (These below things are already done before Playing Journal)

1) I have an Assembly with 10 Expressions (Example)

2) Among 10 expressions , I am interested in only 5 expressions.

3) I add comment "Interested" to those 5 expressions by going to Tools->Expressions-> (Expression I'm Interested in) -> Edit Comment -> (Enter the Comment : "Interested")

So I can just get those 5 expressions only in which I am interested. (I dont want to prefere going with Comments - you can suggest any other simple/easy logic to derive REQUIRED expressions among bunch of expressions)

What I want to do :

1) User Play the Journal

2) Journal launches WinForm

3) Journal will go to the all expressions in Tools->Expressions->Comment

5) It will derive only those expressions in which Comment field : Interested is written.

6) Now WinForm shows the Name and Values of those 5 expressions I am interested in, in TextBoxes

5) User selects his required Expressions, Edit the Name/Value in TextBoxes. Hits OKAY

6) Assembly is updated.

I hope my query & Logic sequence to solve my query are clear and simplified than my previous posts.

This is a conceptual sequence I thought and u can suggest easy steps , loops,logic etc to simplify as I don't know much about programming.

If I can get full example code for above sequences for NX 10, It will be very useful to me.

Regards,

Vivek

When you don't know how many expressions you have and don't know they name of it. You cant pre define the number of text boxes. You can go one by one expression or use list box(Might be a complicated one for usage in this case).

'Start Form
For Each Myexpression As Expression In workPart.Expressions
'Keep only two textboxes in the form
'Go through one by one expression (Since yo never know the exact count and name of the expression)
Dim ExpName As String = Myexpression.Name
Dim ExpVal As Integer = Myexpression.Value
'Textbox1 value ExpName
'Textbox2 value Expval
'Edit textbox value
'On OK button click event update the expression and goto next
Next
'Close form on completion of for loop

Regards,

Joe

Hi Joe ,

I tried this code. But for single expression's Name & Value it is good.

But Suppose I have to show 5 equations from all equations , I need to assign a Name of Expression1 to TextBox1 , and its value to TextBox2.

Name of Expression2 to TextBox3 , Value to TextBox4
Name of Expression3 to TextBox5 , Value to TextBox6 and so on...

So how to do it?

In above post I have detailed the Query : as per below - please try to solve this

Query : Link Desired NX expressions to WinForm

Background : (These below things are already done before Playing Journal)
1) I have an Assembly with 10 Expressions (Example)

2) Among 10 expressions , I am interested in only 5 expressions.

3) I add comment "Interested" to those 5 expressions by going to Tools->Expressions-> (Expression I'm Interested in) -> Edit Comment -> (Enter the Comment : "Interested")

So I can just get those 5 expressions only in which I am interested. (I dont want to prefere going with Comments - you can suggest any other simple/easy logic to derive REQUIRED expressions among bunch of expressions)

What I want to do :
1) User Play the Journal

2) Journal launches WinForm

3) Journal will go to the all expressions in Tools->Expressions->Comment

5) It will derive only those expressions in which Comment field : Interested is written.

6) Now WinForm shows the Name and Values of those 5 expressions I am interested in, in TextBoxes

5) User selects his required Expressions, Edit the Name/Value in TextBoxes. Hits OKAY

6) Assembly is updated.

I hope my query & Logic sequence to solve my query are clear and simplified than my previous posts.

This is a conceptual sequence I thought and u can suggest easy steps , loops,logic etc to simplify as I don't know much about programming.

If I can get full example code for above sequences for NX 10, It will be very useful to me.

Regards,

Vivek

1. You have to one by one expression If you want a static win form. If you want all the expression to be shown at one time you need dynamic win form, based on your interested values (Unknown count). Google it for creating dynamic win form.

2. I just went through API document, unfortunately we can't tag the expressions based on comment (Maybe possible in later versions). I suggest a simple method add a common name before the expressions you are interested like "Interested_" so you can tag them in following way.

Sub Main()
Dim Mylist As New List(Of Expression)
For Each Myexpression As Expression In workPart.Expressions
If Myexpression.Name.Contains("Interested") = True Then
Mylist.Add(Myexpression)
End If
Next
'Create dynamic form based on Mylist.count or go by the method I explained earlier one by one expression in mylist

End Sub

Regards,

Joe

We can read the right hand side of the expression, which will contain the comment (the comment is preceded by "//"). I don't see any reason why searching for an expression based on its comment would not work.

There is code in this article that shows one way of getting the expression comment:
http://nxjournaling.com/content/expressions-query-existing-expressions

Oops, I was not aware of that...

Regards,

Joe

Hey Joe,

Thanks for reply.
But I don't know how to use all those expressions having INTERESTED as prefix one by one to textboxes. (taking from list to assigning values to textboxes-even the no. of textboxes is fixed and not dynamic)

It is now becoming more complicated. and without full code I don't think so I can go ahead due to it has been very tough programming for me.

I give up. :(

Regards & Thanks
Vivek

Don't give up!
I'm working on a demo that will find the expressions based on the comment and show (at least one of them) on a form.

Joe's suggestion of using a list box to show multiple expressions is a good one. I can see a single list box along with 2 text boxes (expression name, expression value) used to select an expression and edit it. This would work no matter how many expressions you had to work with.

Another potential option would be a "grid control"; I've used it in older versions of VB, but I'm not sure if it is available in VB.net. If it is available, it would provide a "spreadsheet like" interface. You could add or remove rows as needed at run time based on how many expressions are found in the file.

This is the method I am talking about it may not be fully functioning as I just created in VS (Not tested). Just modify it. if you need any update. The logic is same.

Option Strict Off
Imports System
Imports System.IO
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Collections
Imports System.Runtime.InteropServices
Imports NXOpen
Imports NXOpen.GeometricUtilities
Imports NXOpen.UF
Imports NXOpen.Assemblies
Imports NXOpenUI
Imports System.Collections.Generic

Module Editexpression

Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display
Dim theUI As UI = UI.GetUI
Dim ufs As UFSession = UFSession.GetUFSession
Dim lw As ListingWindow = theSession.ListingWindow

Sub Main()

lw.Open()
Dim Mylist As New List(Of Expression)
Dim Myexpression As Expression = Nothing
For Each Myexpression In workPart.Expressions
If Myexpression.RightHandSide.Contains("Interested") = True Then
Mylist.Add(Myexpression)
End If
Next

For i As Integer = 0 To Mylist.Count - 1
Dim form As Form2 = New Form2(theSession, theUI)
'Do
Try
form.TextBox1.Text = Mylist(i).Name
form.TextBox2.Text = Mylist(i).Value
If DialogResult.OK Then
Myexpression.RightHandSide = form.TextBox2.Text
theSession.Preferences.Modeling.UpdatePending = False
ElseIf DialogResult.Cancel Then
Exit Sub
End If

Catch err1 As ObjectDisposedException
lw.WriteLine(err1.ToString)
End Try
Next

End Sub

_
Partial Class Form2
Inherits System.Windows.Forms.Form

Public Sub New(ByVal session As Session, ByVal ui As UI)
MyBase.New()
Dim theSession As Session = session
Dim theUI As UI = ui
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
Me.BringToFront()

End Sub
'Form overrides dispose to clean up the component list.
_
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
_
Private Sub InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button()
Me.Button2 = New System.Windows.Forms.Button()
Me.Label1 = New System.Windows.Forms.Label()
Me.Label2 = New System.Windows.Forms.Label()
Me.TextBox1 = New System.Windows.Forms.TextBox()
Me.TextBox2 = New System.Windows.Forms.TextBox()
Me.SuspendLayout()
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(186, 108)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(75, 23)
Me.Button1.TabIndex = 0
Me.Button1.Text = "OK"
Me.Button1.UseVisualStyleBackColor = True
Me.Button1.DialogResult = DialogResult.OK
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(315, 108)
Me.Button2.Name = "Button2"
Me.Button2.Size = New System.Drawing.Size(75, 23)
Me.Button2.TabIndex = 1
Me.Button2.Text = "Cancel"
Me.Button2.UseVisualStyleBackColor = True
Me.Button2.DialogResult = DialogResult.Cancel
'
'Label1
'
Me.Label1.AutoSize = True
Me.Label1.Location = New System.Drawing.Point(29, 13)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(89, 13)
Me.Label1.TabIndex = 2
Me.Label1.Text = "Expression Name"
'
'Label2
'
Me.Label2.AutoSize = True
Me.Label2.Location = New System.Drawing.Point(304, 13)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(88, 13)
Me.Label2.TabIndex = 3
Me.Label2.Text = "Expression Value"
'
'TextBox1
'
Me.TextBox1.Location = New System.Drawing.Point(32, 30)
Me.TextBox1.Multiline = True
Me.TextBox1.Name = "TextBox1"
Me.TextBox1.Size = New System.Drawing.Size(229, 30)
Me.TextBox1.TabIndex = 4
'
'TextBox2
'
Me.TextBox2.Location = New System.Drawing.Point(315, 30)
Me.TextBox2.Multiline = True
Me.TextBox2.Name = "TextBox2"
Me.TextBox2.Size = New System.Drawing.Size(100, 30)
Me.TextBox2.TabIndex = 5
'
'Form2
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(469, 147)
Me.Controls.Add(Me.TextBox2)
Me.Controls.Add(Me.TextBox1)
Me.Controls.Add(Me.Label2)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.Button1)
Me.Name = "Form2"
Me.Text = "Edit Expression"
Me.ResumeLayout(False)
Me.PerformLayout()

End Sub
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents Button2 As System.Windows.Forms.Button
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents Label2 As System.Windows.Forms.Label
Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
Friend WithEvents TextBox2 As System.Windows.Forms.TextBox
End Class
End Module

Regards,

Joe

Thanks very much for supporting, This is what I have done till now.

Please suggest me to find expressions by Listing method in below form (which is suggested by Joe) i.e. please add appropriate list code into following existing code.

Option Strict Off
Imports System
Imports NXOpen

Module Module1

Private Const _attributeTitle As String = "Model"
Public ReadOnly Property AttributeTitle() As String
Get
Return _attributeTitle
End Get
End Property

Private _attributeValue As String = ""
Public Property AttributeValue() As String
Get
Return _attributeValue
End Get
Set(ByVal value As String)
_attributeValue = value
End Set
End Property

Sub Main()

Dim theSession As Session = Session.GetSession()
'If IsNothing(theSession.Parts.Work) Then
'active part required
'Return
'End If

Dim workPart As Part = theSession.Parts.Work
Dim lw As ListingWindow = theSession.ListingWindow
lw.Open()

Const undoMarkName As String = "NXJ form demo journal"
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

'create new form object
Dim myForm As New Form1
myForm.ShowDialog()
lw.Close()

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

Public Class Form1
'Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Dim str As String = TextBox1.Text
'Dim n As Integer = 0

'End Sub
End Class

_
Partial Class Form1
Inherits System.Windows.Forms.Form

'Form overrides dispose to clean up the component list.
_
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
_
Private Sub InitializeComponent()
Dim theSession As NXOpen.Session = NXOpen.Session.GetSession()
Dim workPart As NXOpen.Part = theSession.Parts.Work
Dim exp1 As NXOpen.Expression = CType(workPart.Expressions.FindObject("p1"), NXOpen.Expression)
Dim exp2 As NXOpen.Expression = CType(workPart.Expressions.FindObject("p2"), NXOpen.Expression)
Dim exp3 As NXOpen.Expression = CType(workPart.Expressions.FindObject("p3"), NXOpen.Expression)

Me.Button1 = New System.Windows.Forms.Button()
Me.Button2 = New System.Windows.Forms.Button()
Me.Label1 = New System.Windows.Forms.Label()
Me.Label2 = New System.Windows.Forms.Label()
Me.Label3 = New System.Windows.Forms.Label()
Me.TextBox1 = New System.Windows.Forms.TextBox()
Me.TextBox2 = New System.Windows.Forms.TextBox()
Me.TextBox3 = New System.Windows.Forms.TextBox()

Me.SuspendLayout()

'Button1
'
Me.Button1.Location = New System.Drawing.Point(515, 485)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(226, 63)
Me.Button1.TabIndex = 1
Me.Button1.Text = "OK"
Me.Button1.UseVisualStyleBackColor = True
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(798, 485)
Me.Button2.Name = "Button2"
Me.Button2.Size = New System.Drawing.Size(226, 63)
Me.Button2.TabIndex = 1
Me.Button2.Text = "Cancel"
Me.Button2.UseVisualStyleBackColor = True
'
'Label1
'
Me.Label1.AutoSize = True
Me.Label1.Location = New System.Drawing.Point(598, 83)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(40, 13)
Me.Label1.TabIndex = 2
Me.Label1.Text = exp1.Name
'
'Label2
'
Me.Label2.AutoSize = True
Me.Label2.Location = New System.Drawing.Point(598, 173)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(40, 13)
Me.Label2.TabIndex = 2
Me.Label2.Text = exp2.Name
'
'Label3
'
Me.Label3.AutoSize = True
Me.Label3.Location = New System.Drawing.Point(598, 264)
Me.Label3.Name = "Label3"
Me.Label3.Size = New System.Drawing.Size(40, 13)
Me.Label3.TabIndex = 2
Me.Label3.Text = exp3.Name
'
'TextBox1
'
Me.TextBox1.Location = New System.Drawing.Point(695, 80)
Me.TextBox1.Name = "TextBox1"
Me.TextBox1.Text = exp1.value
Me.TextBox1.Size = New System.Drawing.Size(170, 20)
Me.TextBox1.TabIndex = 3
'
'TextBox2
'
Me.TextBox2.Location = New System.Drawing.Point(695, 170)
Me.TextBox2.Name = "TextBox2"
Me.TextBox2.Text = exp2.value
Me.TextBox2.Size = New System.Drawing.Size(170, 20)
Me.TextBox2.TabIndex = 3
'
'TextBox3
'
Me.TextBox3.Location = New System.Drawing.Point(695, 264)
Me.TextBox3.Name = "TextBox3"
Me.TextBox3.Text = exp3.value
Me.TextBox3.Size = New System.Drawing.Size(170, 20)
Me.TextBox3.TabIndex = 3

'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(1097, 560)
Me.Controls.Add(Me.TextBox3)
Me.Controls.Add(Me.TextBox2)
Me.Controls.Add(Me.TextBox1)
Me.Controls.Add(Me.Label3)
Me.Controls.Add(Me.Label2)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.Button1)
Me.Name = "Form1"
Me.Text = "Form1"

Me.ResumeLayout(False)
Me.PerformLayout()

End Sub
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents Button2 As System.Windows.Forms.Button
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents Label2 As System.Windows.Forms.Label
Friend WithEvents Label3 As System.Windows.Forms.Label
Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
Friend WithEvents TextBox2 As System.Windows.Forms.TextBox
Friend WithEvents TextBox3 As System.Windows.Forms.TextBox

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim theSession As NXOpen.Session = NXOpen.Session.GetSession()
Dim workPart As NXOpen.Part = theSession.Parts.Work
Dim exp1 As NXOpen.Expression = CType(workPart.Expressions.FindObject("p1"), NXOpen.Expression)
Dim exp2 As NXOpen.Expression = CType(workPart.Expressions.FindObject("p2"), NXOpen.Expression)
Dim exp3 As NXOpen.Expression = CType(workPart.Expressions.FindObject("p3"), NXOpen.Expression)
Dim unit1 As NXOpen.Unit = CType(workPart.UnitCollection.FindObject("MilliMeter"), NXOpen.Unit)
Dim markId1 As Session.UndoMarkId
workPart.Expressions.EditWithUnits(exp1,Unit1, TextBox1.Text)
workPart.Expressions.EditWithUnits(exp2,Unit1, TextBox2.Text)
workPart.Expressions.EditWithUnits(exp3,Unit1, TextBox3.Text)
theSession.Preferences.Modeling.UpdatePending = False
Dim nErrs1 As Integer
nErrs1 = theSession.UpdateManager.DoUpdate(markId1)

End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Me.Close()
End Sub
End Class

Regards & Thanks,
Vivek

Below is my example that looks for expressions with the comment "interested" and shows one of them on a form for editing.

Option Strict Off
Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF

Module Module1

Public theSession As Session = Session.GetSession()
Public theUfSession As UFSession = UFSession.GetUFSession()
Public Const commentText As String = "Interested"

Dim theUI As UI = UI.GetUI()
Dim lw As ListingWindow = theSession.ListingWindow

Sub Main()

Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "NXJ")

lw.Open()

Dim myExpressions As New List(Of Expression)
For Each temp As Expression In theSession.Parts.Work.Expressions

If temp.RightHandSide.Contains("//") Then
'expression contains comment
Dim expComment As String = ""
expComment = temp.RightHandSide.Substring(temp.RightHandSide.IndexOf("//") + 2).Trim
'lw.WriteLine("comment: " & expComment)
If expComment.ToUpper = commentText.ToUpper Then
myExpressions.Add(temp)
End If
End If

Next

'For Each temp As Expression In myExpressions
' lw.WriteLine("name: " & temp.Name)
'Next

Dim expForm As New Form1
expForm.Expressions = myExpressions
expForm.ShowDialog()

theSession.UpdateManager.DoUpdate(markId1)

lw.Close()

End Sub

Public Function GetUnloadOption(ByVal dummy As String) As Integer

'Unloads the image immediately after execution within NX
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately

End Function

End Module

Public Class Form1

Private fExpressions As New List(Of NXOpen.Expression)
Public Property Expressions() As List(Of NXOpen.Expression)
Get
Return fExpressions
End Get
Set(ByVal value As List(Of NXOpen.Expression))
fExpressions = value
End Set
End Property

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

'no error checking is done

txtExp1Name.Text = fExpressions.Item(0).Name
txtExp1Val.Text = fExpressions.Item(0).RightHandSide.Substring(0, fExpressions.Item(0).RightHandSide.IndexOf("//"))

End Sub

Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
Me.Close()
End Sub

Private Sub btnOk_Click(sender As Object, e As EventArgs) Handles btnOk.Click

Try
fExpressions.Item(0).SetName(txtExp1Name.Text)
Catch ex As NXOpen.NXException

End Try
theSession.Parts.Work.Expressions.Edit(fExpressions.Item(0), txtExp1Val.Text & "//" & commentText)

Me.Close()

End Sub

End Class

_
Partial Class Form1
Inherits System.Windows.Forms.Form

'Form overrides dispose to clean up the component list.
_
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
_
Private Sub InitializeComponent()
Me.txtExp1Name = New System.Windows.Forms.TextBox()
Me.txtExp1Val = New System.Windows.Forms.TextBox()
Me.btnOk = New System.Windows.Forms.Button()
Me.btnCancel = New System.Windows.Forms.Button()
Me.SuspendLayout()
'
'txtExp1Name
'
Me.txtExp1Name.Location = New System.Drawing.Point(23, 38)
Me.txtExp1Name.Name = "txtExp1Name"
Me.txtExp1Name.Size = New System.Drawing.Size(92, 20)
Me.txtExp1Name.TabIndex = 0
'
'txtExp1Val
'
Me.txtExp1Val.Location = New System.Drawing.Point(121, 38)
Me.txtExp1Val.Name = "txtExp1Val"
Me.txtExp1Val.Size = New System.Drawing.Size(188, 20)
Me.txtExp1Val.TabIndex = 1
'
'btnOk
'
Me.btnOk.Location = New System.Drawing.Point(23, 103)
Me.btnOk.Name = "btnOk"
Me.btnOk.Size = New System.Drawing.Size(133, 59)
Me.btnOk.TabIndex = 2
Me.btnOk.Text = "OK"
Me.btnOk.UseVisualStyleBackColor = True
'
'btnCancel
'
Me.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel
Me.btnCancel.Location = New System.Drawing.Point(176, 103)
Me.btnCancel.Name = "btnCancel"
Me.btnCancel.Size = New System.Drawing.Size(133, 59)
Me.btnCancel.TabIndex = 3
Me.btnCancel.Text = "Cancel"
Me.btnCancel.UseVisualStyleBackColor = True
'
'Form1
'
Me.AcceptButton = Me.btnOk
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.CancelButton = Me.btnCancel
Me.ClientSize = New System.Drawing.Size(335, 186)
Me.Controls.Add(Me.btnCancel)
Me.Controls.Add(Me.btnOk)
Me.Controls.Add(Me.txtExp1Val)
Me.Controls.Add(Me.txtExp1Name)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
Me.PerformLayout()

End Sub

Friend WithEvents txtExp1Name As System.Windows.Forms.TextBox
Friend WithEvents txtExp1Val As System.Windows.Forms.TextBox
Friend WithEvents btnOk As System.Windows.Forms.Button
Friend WithEvents btnCancel As System.Windows.Forms.Button
End Class

Hey NX Journaling & Joe

The above code ran successfully and solved the purpose. Thanks very very much for help.

But new problem occurring is that , not technical but Logical -adding comment will show //*Comment* after dimensions in NX.

i.e. 400//Interested mm
If anyone edit the dimension , suppose 500mm and erased or forgot to add //Interested then it will also be removed from tools-> expressions-> comments. Which will create problem when form is launched Next time.

So this solution is rejected by my Sr Engineer.

Now, only two logic left
1) Adding unique KEYWORD as prefix/suffix in Name of Expressions , and find expressions based on that Keyword and list those and run as previous.

2) Or every NX expression has/should have unique ID and so we can edit the value/Name and it is reflected wherever that expression is used. So by using that kind of ID ...

Regards,
Vivek

I suggest a simple prefix, add a common name before the expressions you are interested like "Interested_" so you can tag them in following way.

Dim Mylist As New List(Of Expression)
For Each Myexpression As Expression In workPart.Expressions
If Myexpression.Name.Contains("Interested") = True Then
Mylist.Add(Myexpression)
End If
Next

Regards,

Joe

Hey Joe,

I tried the same. I have Got it working.

Thanks Joe and NX Journaling (Name - I dont know)

Regards,
Vivek

Hey Joe & NX Journaling,

Thanks for the above help.

Now I want to add image in my form , but the problem is that it should be played in Teamcenter.

So how can I give a path to Image location for Teamcenter:

Concerned Code :

Me.PictureBox1.ImageLocation = "C:\Users\.....\Desktop\Picture1.jpg"

Regards,
Vivek

Is the image saved in Teamcenter or is it saved on the normal filesystem?

If the image is in the filesystem, the code you have should work (assuming the location is correct). If other people are going to use the journal, the image will need to be saved in a common location (network drive).

If you have an author license to compile the code, I'm pretty sure that the image can be added as a resource and becomes part of the .dll file when the project is compiled.

Hii, NX Journaling

Above concerned code works fine for one particular system.

But as I have to submit the journal in Teamcenter, the above kind of path will not work.

I don't know much about how to give a ImageLocation in NX journal or in Teamcenter so as per you told the following these 2 Logic:

1) Make an Image an Internal part of NX Journal. So IMAGE will go anywhere the Journal will go.

2) Save IMAGE as dataset in Teamcenter in particular ID. And then giving a path of that ID--> Image Dataset.

For both ways I dont know the code , where and how to add code and give a path.

I prefer to go with 1st way , and if it is not succeeded , will move on 2nd way.

So please help me.

Regards and Thanks,
Vivek

My first suggestion, and I think the easiest to implement, is to save the image in a common network location. The code that you currently have only works on your computer, because the image location given is on the local "C:\" drive. When you run the journal, the image shows up as expected because the image file is saved on your local C drive. When I run the journal, it looks for the image in my local C drive, but cannot find it as it is not saved there (the image is only on your computer). If we both have access to a network drive (let's call it the "T:\" drive), then the image could be saved to a location such as "T:\images\pic1.jpg" and the journal could reference this location. In this case, the image would show up as expected for both of us because we both have access to the T drive and the image is saved there. Note that this would work best if your coworkers only have "read-only" access to the folder where the image is saved ("T:\images" in the example); so they cannot modify or delete the image file.

Hi ,

As a common location we have only Teamcenter. So any local or network drive will not solve the issue. I need something from that we can call the image from Teamcenter.

Regards,
Vivek

Follow this link to find how to add a image to VS project. Then compile the DLL file. You cant use .vb file anymore (Since it can't accept embedded object). Save the project and use the .dll (You can see this in project folder) to run the code in NX.

https://msdn.microsoft.com/en-us/library/aa984367(v=vs.71).aspx

Regards,

Joe

Hii Joe,

I have modified the code as per shown in link share by you, but it is showing some errors:

[WindowsApplication2 is a VS application project name and I want to embed image named ID.bmp , in a such a way that if whole code is copy pasted in teamcenter (or any pc) it will show the form with embedded image]

Regards & Thanks,
Vivek

Option Strict Off
Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF
Imports System.IO
Imports System.Reflection

Module Module1

Public theSession As Session = Session.GetSession()
Public theUfSession As UFSession = UFSession.GetUFSession()

Dim theUI As UI = UI.GetUI()
Dim lw As ListingWindow = theSession.ListingWindow

Sub Main()

Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "NXJ")

lw.Open()

Dim myExpressions As New List(Of Expression)
For Each temp As Expression In theSession.Parts.Work.Expressions

If temp.Name.Contains("int") then
myExpressions.Add(temp)
End If

Next

'For Each temp As Expression In myExpressions
' lw.WriteLine("name: " & temp.Name)
'Next

Dim expForm As New Form1
expForm.Expressions = myExpressions
expForm.ShowDialog()

theSession.UpdateManager.DoUpdate(markId1)

lw.Close()

End Sub

Public Function GetUnloadOption(ByVal dummy As String) As Integer

'Unloads the image immediately after execution within NX
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately

End Function

End Module

Public Class Form1

Private fExpressions As New List(Of NXOpen.Expression)
Public Property Expressions() As List(Of NXOpen.Expression)
Get
Return fExpressions
End Get
Set(ByVal value As List(Of NXOpen.Expression))
fExpressions = value
End Set
End Property

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim myAssembly As System.Reflection.Assembly =_ System.Reflection.Assembly.GetExecutingAssembly()
Dim myStream As Stream = _ myAssembly.GetManifestResourceStream("WindowsApplication2.ID.bmp")
Dim image As New Bitmap(myStream)
Me.ClientSize = New Size(image.Width, image.Height)

Dim pb As New PictureBox
pb.Image = image
pb.Dock = DockStyle.Fill
Me.Controls.Add(pb)

txtExp1Name.Text = fExpressions.Item(0).Name
txtExp1Val.Text = fExpressions.Item(0).Value
txtExp2Name.Text = fExpressions.Item(1).Name
txtExp2Val.Text = fExpressions.Item(1).Value
txtExp3Name.Text = fExpressions.Item(2).Name
txtExp3Val.Text = fExpressions.Item(2).Value

End Sub

Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
Me.Close()
End Sub

Private Sub btnOk_Click(sender As Object, e As EventArgs) Handles btnOk.Click

Try
fExpressions.Item(0).SetName(txtExp1Name.Text)
Catch ex As NXOpen.NXException

End Try
theSession.Parts.Work.Expressions.Edit(fExpressions.Item(0), txtExp1Val.Text)

Try
fExpressions.Item(1).SetName(txtExp2Name.Text)
Catch ex As NXOpen.NXException

End Try
theSession.Parts.Work.Expressions.Edit(fExpressions.Item(1), txtExp2Val.Text)

Try
fExpressions.Item(2).SetName(txtExp3Name.Text)
Catch ex As NXOpen.NXException

End Try
theSession.Parts.Work.Expressions.Edit(fExpressions.Item(2), txtExp3Val.Text)

End Sub
End Class

Partial Class Form1
Inherits System.Windows.Forms.Form

'Form overrides dispose to clean up the component list.

Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.

Private Sub InitializeComponent()

Me.txtExp1Name = New System.Windows.Forms.Label()
Me.txtExp1Val = New System.Windows.Forms.TextBox()
Me.txtExp2Name = New System.Windows.Forms.Label()
Me.txtExp2Val = New System.Windows.Forms.TextBox()
Me.txtExp3Name = New System.Windows.Forms.Label()
Me.txtExp3Val = New System.Windows.Forms.TextBox()
Me.btnOk = New System.Windows.Forms.Button()
Me.btnCancel = New System.Windows.Forms.Button()
Me.PictureBox1 = New System.Windows.Forms.PictureBox()
CType(Me.PictureBox1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'txtExp1Name
'
Me.txtExp1Name.BackColor = System.Drawing.SystemColors.Control
Me.txtExp1Name.Location = New System.Drawing.Point(1001, 31)
Me.txtExp1Name.Name = "txtExp1Name"
Me.txtExp1Name.Size = New System.Drawing.Size(93, 20)
Me.txtExp1Name.TabIndex = 0
'
'txtExp1Val
'
Me.txtExp1Val.Location = New System.Drawing.Point(1130, 31)
Me.txtExp1Val.Name = "txtExp1Val"
Me.txtExp1Val.Size = New System.Drawing.Size(96, 20)
Me.txtExp1Val.TabIndex = 1
'
'txtExp2Name
'
Me.txtExp2Name.Location = New System.Drawing.Point(998, 79)
Me.txtExp2Name.Name = "txtExp2Name"
Me.txtExp2Name.Size = New System.Drawing.Size(96, 20)
Me.txtExp2Name.TabIndex = 1
'
'txtExp2Val
'
Me.txtExp2Val.Location = New System.Drawing.Point(1130, 79)
Me.txtExp2Val.Name = "txtExp2Val"
Me.txtExp2Val.Size = New System.Drawing.Size(96, 20)
Me.txtExp2Val.TabIndex = 1
'
'txtExp3Name
'
Me.txtExp3Name.Location = New System.Drawing.Point(998, 127)
Me.txtExp3Name.Name = "txtExp3Name"
Me.txtExp3Name.Size = New System.Drawing.Size(96, 20)
Me.txtExp3Name.TabIndex = 1
'
'txtExp3Val
'
Me.txtExp3Val.Location = New System.Drawing.Point(1130, 124)
Me.txtExp3Val.Name = "txtExp3Val"
Me.txtExp3Val.Size = New System.Drawing.Size(96, 20)
Me.txtExp3Val.TabIndex = 1
'
'btnOk
'
Me.btnOk.Location = New System.Drawing.Point(1015, 514)
Me.btnOk.Name = "btnOk"
Me.btnOk.Size = New System.Drawing.Size(133, 59)
Me.btnOk.TabIndex = 2
Me.btnOk.Text = "OK"
Me.btnOk.UseVisualStyleBackColor = True
'
'btnCancel
'
Me.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel
Me.btnCancel.Location = New System.Drawing.Point(1182, 514)
Me.btnCancel.Name = "btnCancel"
Me.btnCancel.Size = New System.Drawing.Size(133, 59)
Me.btnCancel.TabIndex = 3
Me.btnCancel.Text = "Cancel"
Me.btnCancel.UseVisualStyleBackColor = True
'
'PictureBox1
'
Me.PictureBox1.Location = New System.Drawing.Point(169, 76)
Me.PictureBox1.Name = "PictureBox1"
Me.PictureBox1.Size = New System.Drawing.Size(765, 417)
Me.PictureBox1.TabIndex = 4
Me.PictureBox1.TabStop = False
'
'Form1
'
Me.AcceptButton = Me.btnOk
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.CancelButton = Me.btnCancel
Me.ClientSize = New System.Drawing.Size(1465, 613)
Me.Controls.Add(Me.btnCancel)
Me.Controls.Add(Me.btnOk)
Me.Controls.Add(Me.txtExp1Val)
Me.Controls.Add(Me.txtExp1Name)
Me.Controls.Add(Me.txtExp2Val)
Me.Controls.Add(Me.txtExp2Name)
Me.Controls.Add(Me.txtExp3Val)
Me.Controls.Add(Me.txtExp3Name)
Me.Controls.Add(Me.PictureBox1)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
Me.PerformLayout()

End Sub

Friend WithEvents txtExp1Name As System.Windows.Forms.Label
Friend WithEvents txtExp1Val As System.Windows.Forms.TextBox
Friend WithEvents txtExp2Name As System.Windows.Forms.Label
Friend WithEvents txtExp2Val As System.Windows.Forms.TextBox
Friend WithEvents txtExp3Name As System.Windows.Forms.Label
Friend WithEvents txtExp3Val As System.Windows.Forms.TextBox
Friend WithEvents btnOk As System.Windows.Forms.Button
Friend WithEvents btnCancel As System.Windows.Forms.Button
Friend WithEvents PictureBox1 As PictureBox
End Class

Your Picture will not be convert into vb code for copy paste. You have to compile it and the compiled DLL file will have the image (It will store it in binary or whatever the format inside the DLL). You have to run the dll file to get the Picture. In this VS project folder you can see the DLL file "YourProject/bin/Debug/YourProject.dll".

Regards,

Joe