Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations KootK on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

NX 6 ASSIGNING FIND NUMBER ATTRIBUTE AT DRAWING LEVEL

Status
Not open for further replies.

MrMike87

Mechanical
Feb 26, 2012
2
I have searched on this forum and have found some useful information.


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----
 
Replies continue below

Recommended for you

Here is an rudimentary journal that I hope will help you get started. Change value of the module level attributeTitle constant to the title of your callout attribute before you run it. I advise testing on a small, non-production assembly file.

Code:
'Journal to recursively walk through the assembly structure
' 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 [URL unfurl="true"]www.nxjournaling.com[/URL]
'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

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor