NX 6 ASSIGNING FIND NUMBER ATTRIBUTE AT DRAWING LEVEL
NX 6 ASSIGNING FIND NUMBER ATTRIBUTE AT DRAWING LEVEL
(OP)
I have searched on this forum and have found some useful information.
http://www.eng-tips.com/viewthread.cfm?qid=209171
I have found code submitted in the above link, and I modified it to be the code below. I am wanting code that will modify and assign Find Number attribute data at the master assembly drawing level to all of the components in that drawing. From what I have read on this site, the attributes at the master assembly drawing level are called "Object Attributes." It is important to note that the attribute does not need to be the same as it is on the part level (we may have several drawings that refer to a part, but each drawing may use different find numbers to refer to that particular part). That is why I will only be assigning the Find Number attribute at the drawing level. I do not want to pull Part Attributes.
I also read on this site that you should be able to use Excel to do this. In the drawing, you would go to Tools > Spreadsheet > Click the 'Addins' Tab > Choose Extract Attributes > Modify The Attributes You Need > Click Update NX Part. This works except for one problem. If there are multiple instances of a certain component in your assembly (ie. 4 of the same wheels on a car or if you packed your ANT you would see WHEEL x4), updating the attributes only update one of the components in the ANT. We are using Excel 2010, and I know this isn't fully supported yet. This may be the reason that it does not work for multiple instances of the same component. Has anyone else experienced this? Plus, I noticed it looks like it tries to update all of the attributes, which can be several thousand rows, and it can be time consuming.
The code that I modified will give the user an input box to input a find number. It then assigns it to a "CALLOUT" attribute, which is a user added attribute (column) in the ANT. You could call this "FIND NO" or anything really. As long as you added the corresponding column to you ANT, it will show up. This code, however, only modifies the work part attribute. I need something that will go through and prompt the user to assign a FIND NUMBER for each component, not the drawing part file.
Ideally, if there are multiple instances of the same component in your assembly drawing (if you packed your ANT you would see some components with a "x" and the number of times they appeared in the assembly drawing), the user would only have to enter the FIND NUMBER once for that particular part.
A couple of points to note:
1) The main reason behind this is time. I know in the ANT you can right click > properties > attributes > and assign the attribute for each component, but this will be very cumbersome and time consuming for a very large assembly. I did notice that if you pack all and right click a packed component and assign the attribute that it WILL assign that attribute to all of the packed components. This is great because when you use the Parts List, you will see that number instead of a "...".
2) One possible procedure would be to use Excel update method to assign the FIND NUMBER attributes to all individual components. Then, pack all and right click each packed component and assign its find number. I am wanting a smoother process, though.
Here is the code that I modified. Any help on this would be greatly appreciated. I am still learning code. All that really needs to be done is instead of assigning the find number for the drawing file, look at each component and assign the find numbers for them using an input box that appears. I do not currently know enough about the API to do this. It currently calls the work part and not the components. Also, maybe if you could create an array that populates with each part name and find number as you enter it. Then, on the next component, you could compare that part name and see if it exists in the array. If it does, it gets the find number you already assigned to it, and it goes to the next component in the assembly. If not, it gets what you enter in the box. The array is updated, and you go to the next component in the assembly. That is how I was planning on solving only entering the FIND NUMBER once for each component. I do not want to enter a FIND NUMBER for every instance, but I'll take any help at this point.
Here is the modified code, and thanks in advance.
'-----START-----
Option Strict Off
Imports System
Imports NXOpen
Imports System.Windows.Forms
Imports NXOpenUI
Module NXJournal
Sub Main
Dim PrevNo As string
Dim Cur_Desc As String
Dim theSession As Session = Session.GetSession()
Dim Attrer As Integer
' ----------------------------------------------
' Check Attributes exist and get Strings
' ----------------------------------------------
Try
PrevNo = thesession.Parts.Display.GetStringAttribute("Callout")
Catch exc As NXException
'PrevNo = "XXXXX-XX"
Attrer = 1
End Try
'Try
'PrevPartNo = thesession.Parts.Work.GetStringAttribute("DB_PART_NAME")
'Catch exc As NXException
'PrevPartNo = "XXXXX-XX"
'Attrer = 1
'End Try
' ----------------------------------------------
' New CALLOUT prompt
' ----------------------------------------------
Try
Cur_Desc = thesession.Parts.Display.GetStringAttribute("Callout")
Catch exc As NXException
Cur_Desc = ""
Attrer = 1
End Try
dim Desc = NXInputBox.GetInputString("ENTER FIND NUMBER", "Callout",Cur_Desc)
Desc = desc.ToUpper()
' ----------------------------------------------
' Update Attributes
' ----------------------------------------------
Dim session_UndoMarkId1 As Session.UndoMarkId
session_UndoMarkId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Assign Attributes")
'theSession.Parts.Work.SetAttribute("DB_PART_NAME", PartNo)
'theSession.Parts.Work.SetAttribute("DB_DWG_NO", DrgNo)
theSession.Parts.Work.SetAttribute("Callout", Desc)
end_prog:
End Sub
End Module
'----END----
http://www.eng-tips.com/viewthread.cfm?qid=209171
I have found code submitted in the above link, and I modified it to be the code below. I am wanting code that will modify and assign Find Number attribute data at the master assembly drawing level to all of the components in that drawing. From what I have read on this site, the attributes at the master assembly drawing level are called "Object Attributes." It is important to note that the attribute does not need to be the same as it is on the part level (we may have several drawings that refer to a part, but each drawing may use different find numbers to refer to that particular part). That is why I will only be assigning the Find Number attribute at the drawing level. I do not want to pull Part Attributes.
I also read on this site that you should be able to use Excel to do this. In the drawing, you would go to Tools > Spreadsheet > Click the 'Addins' Tab > Choose Extract Attributes > Modify The Attributes You Need > Click Update NX Part. This works except for one problem. If there are multiple instances of a certain component in your assembly (ie. 4 of the same wheels on a car or if you packed your ANT you would see WHEEL x4), updating the attributes only update one of the components in the ANT. We are using Excel 2010, and I know this isn't fully supported yet. This may be the reason that it does not work for multiple instances of the same component. Has anyone else experienced this? Plus, I noticed it looks like it tries to update all of the attributes, which can be several thousand rows, and it can be time consuming.
The code that I modified will give the user an input box to input a find number. It then assigns it to a "CALLOUT" attribute, which is a user added attribute (column) in the ANT. You could call this "FIND NO" or anything really. As long as you added the corresponding column to you ANT, it will show up. This code, however, only modifies the work part attribute. I need something that will go through and prompt the user to assign a FIND NUMBER for each component, not the drawing part file.
Ideally, if there are multiple instances of the same component in your assembly drawing (if you packed your ANT you would see some components with a "x" and the number of times they appeared in the assembly drawing), the user would only have to enter the FIND NUMBER once for that particular part.
A couple of points to note:
1) The main reason behind this is time. I know in the ANT you can right click > properties > attributes > and assign the attribute for each component, but this will be very cumbersome and time consuming for a very large assembly. I did notice that if you pack all and right click a packed component and assign the attribute that it WILL assign that attribute to all of the packed components. This is great because when you use the Parts List, you will see that number instead of a "...".
2) One possible procedure would be to use Excel update method to assign the FIND NUMBER attributes to all individual components. Then, pack all and right click each packed component and assign its find number. I am wanting a smoother process, though.
Here is the code that I modified. Any help on this would be greatly appreciated. I am still learning code. All that really needs to be done is instead of assigning the find number for the drawing file, look at each component and assign the find numbers for them using an input box that appears. I do not currently know enough about the API to do this. It currently calls the work part and not the components. Also, maybe if you could create an array that populates with each part name and find number as you enter it. Then, on the next component, you could compare that part name and see if it exists in the array. If it does, it gets the find number you already assigned to it, and it goes to the next component in the assembly. If not, it gets what you enter in the box. The array is updated, and you go to the next component in the assembly. That is how I was planning on solving only entering the FIND NUMBER once for each component. I do not want to enter a FIND NUMBER for every instance, but I'll take any help at this point.
Here is the modified code, and thanks in advance.
'-----START-----
Option Strict Off
Imports System
Imports NXOpen
Imports System.Windows.Forms
Imports NXOpenUI
Module NXJournal
Sub Main
Dim PrevNo As string
Dim Cur_Desc As String
Dim theSession As Session = Session.GetSession()
Dim Attrer As Integer
' ----------------------------------------------
' Check Attributes exist and get Strings
' ----------------------------------------------
Try
PrevNo = thesession.Parts.Display.GetStringAttribute("Callout")
Catch exc As NXException
'PrevNo = "XXXXX-XX"
Attrer = 1
End Try
'Try
'PrevPartNo = thesession.Parts.Work.GetStringAttribute("DB_PART_NAME")
'Catch exc As NXException
'PrevPartNo = "XXXXX-XX"
'Attrer = 1
'End Try
' ----------------------------------------------
' New CALLOUT prompt
' ----------------------------------------------
Try
Cur_Desc = thesession.Parts.Display.GetStringAttribute("Callout")
Catch exc As NXException
Cur_Desc = ""
Attrer = 1
End Try
dim Desc = NXInputBox.GetInputString("ENTER FIND NUMBER", "Callout",Cur_Desc)
Desc = desc.ToUpper()
' ----------------------------------------------
' Update Attributes
' ----------------------------------------------
Dim session_UndoMarkId1 As Session.UndoMarkId
session_UndoMarkId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Assign Attributes")
'theSession.Parts.Work.SetAttribute("DB_PART_NAME", PartNo)
'theSession.Parts.Work.SetAttribute("DB_DWG_NO", DrgNo)
theSession.Parts.Work.SetAttribute("Callout", Desc)
end_prog:
End Sub
End Module
'----END----





RE: NX 6 ASSIGNING FIND NUMBER ATTRIBUTE AT DRAWING LEVEL
CODE
' will run on assemblies or piece parts
' will step through all components of the displayed part
' and prompt for/add a "callout" attribute to each component
' modification of code posted at www.nxjournaling.com
'NX 7.5, native
'February 29, 2012
Option Strict Off
Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies
Module NXJournal
Public theSession As Session = Session.GetSession()
Public ufs As UFSession = UFSession.GetUFSession()
Public lw As ListingWindow = theSession.ListingWindow
Dim componentList As New Dictionary(Of String, String)
Dim blnCancel As Boolean = False
'***** change the value of the following constant to your desired attribute title
Const attributeTitle As String = "MYCALLOUT"
'*******************************************
Sub Main()
Dim workPart As Part = theSession.Parts.Work
Dim dispPart As Part = theSession.Parts.Display
Dim blnGatheringInfo As Boolean = True
Dim i As Integer
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Invisible, "Start")
lw.Open()
For i = 0 To 1
Try
Dim c As ComponentAssembly = dispPart.ComponentAssembly
If Not IsNothing(c.RootComponent) Then
reportComponentChildren(c.RootComponent)
End If
Catch e As Exception
theSession.ListingWindow.WriteLine("Failed: " & e.ToString)
End Try
blnGatheringInfo = False
Next
'lw.WriteLine("Done processing")
lw.Close()
theSession.SetUndoMarkName(markId1, "Add callout attributes")
theSession.SetUndoMarkVisibility(markId1, Nothing, Session.MarkVisibility.Visible)
End Sub
'**********************************************************
Sub reportComponentChildren(ByVal comp As Component)
For Each child As Component In comp.GetChildren()
'*** insert code to process component or subassembly
If blnCancel Then
Exit Sub
Else
processComponent(child)
reportComponentChildren(child)
End If
Next
End Sub
'**********************************************************
Sub processComponent(ByRef myComp As Component)
Dim previousValue As String = ""
Dim currentValue As String = ""
If blnCancel Then
Exit Sub
End If
If componentList.ContainsKey(myComp.DisplayName) Then
'component is in list
previousValue = componentList.Item(myComp.DisplayName)
'add code to validate attribute value here
Try
'is the attribute set on this component, and does it match the value in the list?
currentValue = myComp.GetStringAttribute(attributeTitle)
If currentValue <> previousValue Then
myComp.SetAttribute(attributeTitle, previousValue)
End If
Catch ex As ApplicationException
If InStr(ex.ToString, "Attribute not found") > 0 Then
'component is in list but does not have the attribute, create attribute and set to value in list
myComp.SetAttribute(attributeTitle, previousValue)
Else
'some other error occurred
lw.WriteLine("## Error: " & ex.ToString)
End If
End Try
Else
'component is not yet in list
Try
'it is possible the component has the attribute assigned from a previous run
'or manual entry, but the component has not been processed yet by this run
currentValue = myComp.GetStringAttribute(attributeTitle)
If ValueExists(currentValue) Then
'attribute has been assigned, but the value is already in use by a different component
AssignAttribute(myComp)
Else
'attribute has been assigned and is unique among components processed so far
componentList.Add(myComp.DisplayName, currentValue)
End If
Catch ex As ApplicationException
If InStr(ex.ToString, "Attribute not found") > 0 Then
'component does not have attribute
AssignAttribute(myComp)
Else
'some other error occurred
lw.WriteLine("## Error: " & ex.ToString)
End If
End Try
End If
End Sub
'**********************************************************
Function ValueExists(ByVal value As String) As Boolean
For Each key As String In componentList.Keys
If value = componentList.Item(key) Then
Return True
Exit Function
End If
Next
Return False
End Function
'**********************************************************
Sub AssignAttribute(ByRef theComponent As Component)
Dim newValue As String = ""
Dim temp As String = ""
Dim i As Integer = 1
Do While ValueExists(i.ToString)
i += 1
Loop
Do
temp = newValue
newValue = InputBox("Enter value of " & attributeTitle & " for component: " & theComponent.DisplayName, theComponent.DisplayName, i.ToString)
If newValue = "" Then
'user pressed cancel
blnCancel = True
Exit Sub
End If
If ValueExists(newValue) Then
MsgBox("Value: " & newValue & " is already in use, please enter a new value", MsgBoxStyle.Exclamation + MsgBoxStyle.OkOnly, "Error")
End If
'add code to validate entered value
Loop While ValueExists(newValue)
componentList.Add(theComponent.DisplayName, newValue)
theComponent.SetAttribute(attributeTitle, newValue)
End Sub
'**********************************************************
Public Function GetUnloadOption(ByVal dummy As String) As Integer
Return Session.LibraryUnloadOption.Immediately
End Function
'**********************************************************
End Module
www.nxjournaling.com