Automate parts list export

Is there anyway to automate the process of exporting parts lists to *.csv files via NX Open ?

The right click on parts list and export to csv is not being recorded to a journal.

Parts lists are not well covered by journaling commands yet. However, I did find a sample from GTAC that should get you started. It will output a text file representation of the parts list. It will not directly output a CSV file for you, though. You'll have to parse this file and do some custom cleanup depending on what you get and what you want...

[vbnet]'a slight modification of the code
'based on GTAC sample: output parts list to text file

'Document ID: nx_api2964
'Date: Jun-13-2007
'Product: NX
'Submit By: Steve Labout

Option Strict Off

Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.UI
Imports NXOpen.Utilities

Module output_parts_list_to_text_file

Dim s As Session = Session.GetSession()
Dim ufs As UFSession = UFSession.GetUFSession()
Dim lw As ListingWindow = s.ListingWindow

Sub Main()
lw.open
Dim my_plist As NXOpen.Tag = NXOpen.Tag.Null
Dim dispPart As NXOpen.Tag = s.Parts.Display.Tag

my_plist = GetPlistTag(dispPart)

If my_plist <> NXOpen.Tag.Null Then

Dim filename As String = "c:\Temp\plist_out.txt"

'master_model
'top_level_only
'leaves_only
ufs.Plist.ListToFile(my_plist, filename, 1, "")

End If

End Sub

Public Function GetPlistTag(ByRef partTag As NXOpen.Tag) As NXOpen.Tag

Dim tempTag As NXOpen.Tag = NXOpen.Tag.Null
Dim type As Integer
Dim subtype As Integer

Do
ufs.Obj.CycleObjsInPart(partTag, _
UFConstants.UF_tabular_note_type, tempTag)

ufs.Obj.AskTypeAndSubtype(tempTag, type, subtype)

If subtype = UFConstants.UF_parts_list_subtype Then
Return tempTag
End If

Loop Until tempTag = NXOpen.Tag.Null

End Function

Public Function GetUnloadOption(ByVal dummy As String) As Integer

Return Session.LibraryUnloadOption.Immediately

End Function

End Module[/vbnet]

Wow . . . was getting really crazy thinking of how to go about it. This sure solves my problem. I can modify the text file as I wish after getting the output.

Thanks a lot :)

Hello and thank you.

If I am exporting the file manually, I can choose the format settings: i.e. tabs between columns. Is there a possibility to change these settings in this journal?

Am I right, that I need to change the line with >>ufs.Plist.ListToFile(my_plist, filename, 1, "")<< because the method UF_PLIST_list_to_file does not supply this ability?

What is exactly inside my_plist to make it different? Would it be possible to write it via System.IO.StreamWriter?

Best regards

"Is there a possibility to change these settings in this journal?"

In this journal, no. The Plist.ListToFile function writes your parts list to a text file as it appears on the drawing. You would need to either parse the output file and reformat it to your liking or process the parts list itself, doing your own export.

Thank you so far! I tried to parse the output file, but this does not work. I ´ve got sometimes empty columns and cells and I couldn´t find a way to convert it to my needs.

Let me ask you an other question...
I tried to do my own export, but all I get is:

$~C , $~Q , , , , , , , , ,

How do I get the attribute-linked text of the cell?

I recommend that you try the .GetEvaluatedText method. What it does is take the underlying "automatic" text and return what is displayed on the screen. Some examples of its use can be found:

http://nxjournaling.com/content/extract-object-attributes-drawing-notes

http://nxjournaling.com/content/w36754

Exactly what I was looking for

Is it possible that parts lists of older versions (NX 7.5) are still there somewhere even after they were deleted? This program exports a previous parts list without taking care of modifications made with NX9. If I use the program with newer parts, everything works like expected. I have already tried to delete the parts list with a following part cleanup without success. It is still somewhere... Do you have any ideas how to treat this problem?

Thank you very much and best regards!

I would normally suggest a part cleanup, but you have already tried that...

If the .ListToFile function is not performing as expected, you might need to contact GTAC with your code and part file. They will be able to determine if it is a bug in the API function and if so, create a fix in a future version.

Hello

I wrote something wrong last time. It was just an coincidence that we formerly used the original NX-parts list template. It has nothing to do with NX7.5 / NX9. Figured out there is an other parts list on hidden layer 0 in this case. In this strange part the journal exports the layer 0 list and not the right one from my parts list template. How can I ignore the wrong list and just export the right one?

Thank you and best regards

I had some trouble with a "dummy" parts list showing up on layer 0 in one of my journals a while ago. I reported it to GTAC and it is supposed to be fixed in NX 11.0.1.

Until I can upgrade to NX 11, I've been using a layer check on the parts list. Perhaps you can make use of the technique (sample code below).

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.UI
Imports NXOpen.Utilities

Module Module1

Dim theSession As Session = Session.GetSession()
Dim 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 my_plist As NXOpen.Tag = NXOpen.Tag.Null
Dim dispPart As NXOpen.Tag = theSession.Parts.Display.Tag

my_plist = GetPlistTag(dispPart)

If my_plist <> NXOpen.Tag.Null Then

Dim filename As String = "c:\Temp\plist_out.txt"

'master_model
'top_level_only
'leaves_only
theUfSession.Plist.ListToFile(my_plist, filename, 1, "")
lw.WriteLine("parts list exported")
Else
lw.WriteLine("no parts list found")
End If

lw.Close()

End Sub

Function GetPlistTag(ByRef partTag As NXOpen.Tag) As NXOpen.Tag

Dim pListTags() As Tag = Nothing
Dim numPartsLists As Integer

theUfSession.Plist.AskTags(pListTags, numPartsLists)

For Each tempTag As Tag In pListTags
Dim myPlist As Annotations.Table = Utilities.NXObjectManager.Get(tempTag)
If myPlist.Layer = 0 Then
Continue For
Else
Return tempTag
End If
Next

Return Nothing

End Function

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

I also tried a For Each Loop, but didn't get it working... *facepalm* Works perfect, thank you.

I should note that the code above will only return the tag of the first valid (not on layer 0) parts list that it finds. If you have NX setup to use multiple parts lists, you will need to change the code accordingly.

This code works like a charm until NX10.

In NX11 every special character in the text is replaced by a weird sign: �

If I do the export manually, it will have the expected sign (example Ø in the text file)

Is there any workaround or a new method to export parts lists?

Best regards!

I don't know of any new, similar functions added or why the existing function no longer works as it used to. I do know that NX expanded its support for unicode characters in NX 10 or 11; I suspect that you may be experiencing a character encoding issue. I suggest contacting GTAC directly to see if they are aware of the issue and/or have a work-around.

Hello,

Seems to be a bug...

I got this running by making my own export with help of your website. I go through all cells and catch the text which is forwarded to a txt-file.

Is there any possiblity to get rid of the part where I put the Partslist-Tag into the List (Of Tag)? Seems odd, but i don't know why i can't remove the Appendix .Item(0) while just using a single Tag. Any suggestions?

Option Strict Off

Imports System
Imports NXOpen
Imports System.Collections.Generic
Imports NXOpen.UF
Imports NXOpen.UI
Imports NXOpen.Utilities

Module output_parts_list_to_text_file

Dim s As Session = Session.GetSession()
Dim ufs As UFSession = UFSession.GetUFSession()

Sub Main()

Dim my_plist_Tag As NXOpen.Tag = NXOpen.Tag.Null
Dim dispPart As NXOpen.Tag = s.Parts.Display.Tag
my_plist_Tag = GetPlistTag(dispPart)

If my_plist_Tag <> NXOpen.Tag.Null Then

Dim my_plist As New List(Of Tag)
my_plist.Add(my_plist_Tag)

Dim filename As String = "c:\Temp\plist_out.txt"

Dim numSections As Integer = 0
ufs.Tabnot.AskNmSections(my_plist.Item(0), numSections)

Dim numRows As Integer = 0
ufs.Tabnot.AskNmRows(my_plist.Item(0), numRows)

Dim numCols As Integer = 0
ufs.Tabnot.AskNmColumns(my_plist.Item(0), numCols)

Dim rowTag As Tag = Nothing
Dim colTag As Tag = Nothing
Dim cellTag As Tag = Nothing

Dim Stream As new System.IO.StreamWriter(filename)

Stream.WriteLine("============================================================")
Stream.WriteLine("@Part list level:")

For j As Integer = 0 To numRows - 1

ufs.Tabnot.AskNthRow(my_plist.Item(0), j, rowTag)

For k As Integer = 0 To numCols - 1

ufs.Tabnot.AskNthColumn(my_plist.Item(0), k, colTag)
ufs.Tabnot.AskCellAtRowCol(rowTag, colTag, cellTag)
Dim cellText As String = ""
Dim evalCellText As String = ""
ufs.Tabnot.AskCellText(cellTag, cellText)
ufs.Tabnot.AskEvaluatedCellText(cellTag, evalCellText)

Stream.Write(evalCellText)

If k < (numCols - 1) Then
Stream.Write(vbtab)
end If

Next

Stream.Write(vbNewLine)
Next

Stream.Close

End If

End Sub

Public Function GetPlistTag(ByRef partTag As NXOpen.Tag) As NXOpen.Tag

Dim tempTag As NXOpen.Tag = NXOpen.Tag.Null
Dim type As Integer
Dim subtype As Integer

Do
ufs.Obj.CycleObjsInPart(partTag, _
UFConstants.UF_tabular_note_type, tempTag)

ufs.Obj.AskTypeAndSubtype(tempTag, type, subtype)

If subtype = UFConstants.UF_parts_list_subtype Then
Return tempTag
End If

Loop Until tempTag = NXOpen.Tag.Null

End Function

Public Function GetUnloadOption(ByVal dummy As String) As Integer

Return Session.LibraryUnloadOption.Immediately

End Function

End Module

Anywhere you see "my_plist.Item(0)", replace it with "my_plist_Tag" and you should be good to go.