add a row in parts list

Hello Team,
I need to add a row in Parts list . I searched in GTAC but unfortunately it is written in c.
I have shared the code. Please help me to change this code in .Net


#include
#include
#include
#include
#include
#include
#include
#include

#define UF_CALL(X) (report_error( __FILE__, __LINE__, #X, (X)))

static int report_error( char *file, int line, char *call, int irc)
{
if (irc)
{
char err[133],
msg[133];

sprintf(msg, "*** ERROR code %d at line %d in %s:\n+++ ",
irc, line, file);
UF_get_fail_message(irc, err);

/* NOTE: UF_print_syslog is new in V18 */

UF_print_syslog(msg, FALSE);
UF_print_syslog(err, FALSE);
UF_print_syslog("\n", FALSE);
UF_print_syslog(call, FALSE);
UF_print_syslog(";\n", FALSE);

if (!UF_UI_open_listing_window())
{
UF_UI_write_listing_window(msg);
UF_UI_write_listing_window(err);
UF_UI_write_listing_window("\n");
UF_UI_write_listing_window(call);
UF_UI_write_listing_window(";\n");
}
}

return(irc);
}

static int ask_object_layer(tag_t object)
{
logical
is_displayable;
UF_OBJ_disp_props_t
disp_props;

UF_CALL(UF_OBJ_is_displayable(object, &is_displayable));

if (is_displayable &&
!UF_CALL(UF_OBJ_ask_display_properties(object, &disp_props)))
return disp_props.layer;
else
return -1;
}

static tag_t ask_parts_list_tag(tag_t part, tag_t plist)
{
int
subtype,
type;

while (!UF_CALL(UF_OBJ_cycle_objs_in_part(part, UF_tabular_note_type,
&plist)) && (plist != NULL_TAG))
{
UF_CALL(UF_OBJ_ask_type_and_subtype(plist, &type, &subtype));
if ((subtype == UF_parts_list_subtype) &&
(ask_object_layer(plist) > 0)) return plist;
}

return NULL_TAG;
}

static logical prompt_for_an_integer(char *prompt, char *item, int *number)
{
int
irc,
resp;
char
menu[1][16];
int
da[1];

strncpy(&menu[0][0], item, 15);
menu[0][15] = '\0';
da[0] = *number;

resp = uc1607(prompt, menu, 1, da, &irc);
if (resp == 3 || resp == 4)
{
*number = da[0];
return TRUE;
}
else return FALSE;

}

static void do_it(void)
{
int
n,
where;
tag_t
part = UF_PART_ask_display_part(),
plist,
row;
double
height;

if ((plist = ask_parts_list_tag(part, NULL_TAG)) == NULL_TAG) return;

UF_CALL(UF_TABNOT_enable_automatic_update(TRUE));
UF_CALL(UF_TABNOT_ask_nm_rows(plist, &n));
where = n;

while (prompt_for_an_integer("Add row to Parts List", "After row", &where))
{
if (where > n) where = n;
UF_CALL(UF_TABNOT_ask_nth_row(plist, where-1, &row));
UF_CALL(UF_TABNOT_ask_row_height(row, &height));
UF_CALL(UF_PLIST_create_manual_row(height, &row));
UF_CALL(UF_TABNOT_add_row(plist, row, where));
n = n + 1;
}
}

/*ARGSUSED*/
void ufusr(char *param, int *retcode, int paramLen)
{
if (UF_CALL(UF_initialize())) return;
do_it();
UF_terminate();
}

int ufusr_ask_unload(void)
{
return (UF_UNLOAD_IMMEDIATELY);
}

Below is a version translated to VB.

'NXJournaling.com
'February 9, 2021

'add manual row(s) to an existing parts list
'based on GTAC sample: nx_api2778

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

Module plist_add_rows

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 myPlist As NXOpen.Tag = NXOpen.Tag.Null

myPlist = GetPlistTag(theSession.Parts.Display.Tag)

If myPlist = NXOpen.Tag.Null Then
lw.WriteLine("no parts list found")
Return
End If

Dim nRows As Integer
theUfSession.Tabnot.AskNmRows(myPlist, nRows)

Dim rowNum As Integer
While GetInteger(rowNum)
'lw.WriteLine("nRows: " & nRows.ToString)
If rowNum > nRows Then rowNum = nRows
If rowNum < 0 Then rowNum = 0
'lw.WriteLine("rowNum: " & rowNum.ToString)
Dim rowTag As Tag
theUfSession.Tabnot.AskNthRow(myPlist, Math.Max(rowNum - 1, 0), rowTag)
'lw.WriteLine("rowTag: " & rowTag.ToString)
Dim height As Double
theUfSession.Tabnot.AskRowHeight(rowTag, height)
'lw.WriteLine("height: " & height.ToString)
Dim newRowTag As Tag
theUfSession.Plist.CreateManualRow(height, newRowTag)
'lw.WriteLine("new row tag: " & newRowTag.ToString)
theUfSession.Tabnot.AddRow(myPlist, newRowTag, rowNum)
'lw.WriteLine("new row added")
nRows += 1
End While

lw.Close()

End Sub

Function GetPlistTag(ByVal 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

Function GetInteger(ByRef input As Integer) As Boolean

Dim answer As String = ""
Do
'input box: prompt and title
answer = NXInputBox.GetInputString("After row", "Add row to parts list")
If String.IsNullOrEmpty(answer) Then
Return False
End If
Loop Until Integer.TryParse(answer, input)
Return True

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

Thank you! Thank you so much.

Bhavya

Hi Team,
I tried to consolidate GTAC code and this one but parts lists row are adding infinite. not sure what mistake Ihave done.( please forgive me I am new to coding. I usually refer this site and GTAC). Please help me.
I am trying to add a row when Plist_ignore_member is set to 1 and manual row will add information from lw item id, description,and qty of plist ignore member

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

Module plist_add_rows

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

Dim theUI As UI = UI.GetUI()
Dim lw As ListingWindow = theSession.ListingWindow
Dim theAttr As String = ""
Sub Main()

Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "NXJ")
theAttr = "PLIST_IGNORE_MEMBER"
Dim root As Component = theSession.Parts.Display.ComponentAssembly.RootComponent
reportComponentChildren(root)
lw.Open()

Dim myPlist As NXOpen.Tag = NXOpen.Tag.Null

myPlist = GetPlistTag(theSession.Parts.Display.Tag)

If myPlist = NXOpen.Tag.Null Then
lw.WriteLine("no parts list found")
Return
End If

Dim nRows As Integer
theUfSession.Tabnot.AskNmRows(myPlist, nRows)

Dim rowNum As Integer
While GetInteger(rowNum)
'lw.WriteLine("nRows: " & nRows.ToString)
If rowNum > nRows Then rowNum = nRows
If rowNum < 0 Then rowNum = 0
'lw.WriteLine("rowNum: " & rowNum.ToString)
Dim rowTag As Tag
theUfSession.Tabnot.AskNthRow(myPlist, Math.Max(rowNum - 1, 0), rowTag)
'lw.WriteLine("rowTag: " & rowTag.ToString)
Dim height As Double
theUfSession.Tabnot.AskRowHeight(rowTag, height)
'lw.WriteLine("height: " & height.ToString)
Dim newRowTag As Tag
theUfSession.Plist.CreateManualRow(height, newRowTag)
'lw.WriteLine("new row tag: " & newRowTag.ToString)
theUfSession.Tabnot.AddRow(myPlist, newRowTag, rowNum)
'lw.WriteLine("new row added")
nRows += 1
End While

lw.Close()

End Sub

Public Sub reportComponentChildren(ByVal comp As Component)
Dim c_part As Part = Nothing

For Each child As Component In comp.GetChildren()

Try
c_part = CType(child.Prototype, Part)
Dim attrs1 As NXObject.AttributeInformation() = c_part.GetAttributeTitlesByType(NXObject.AttributeType.String)

For Each attr1 As NXObject.AttributeInformation In attrs1

If attr1.Title.Equals(theAttr) Then
lw.WriteLine(vbLf & "Part: " & c_part.FullPath)
Dim attrValue As String = c_part.GetStringAttribute(attr1.Title)
lw.WriteLine(" " & theAttr & ": " & attrValue)

End If
Next
Catch ex As Exception
lw.WriteLine("+++ " & child.Name & " is unloaded.")
End Try

reportComponentChildren(child)
Next
End Sub

Function GetPlistTag(ByVal 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

Function GetInteger(ByRef theAttr1 As Integer) As Boolean

'Dim answer As String = ""
'Do
'input box: prompt and title
'answer = NXInputBox.GetInputString("After row", "Add row to parts list")
'If String.IsNullOrEmpty(answer) Then
'Return False
'End If
'Loop Until Integer.TryParse(answer, theAttr1)
For theAttr1=0 to theAttr1=2
Return True

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

Bhavya

Based on your latest description, it sounds like you want to find a component that has the "plist ignore" attribute and add info for it to the parts list. Not knowing the specifics of your situation, let me ask a dumb question:
Why not just change the attribute value and allow NX to automatically add the info to the parts list?

So instead of looking for components that have been set to "ignore" and adding their info manually, change the ignore setting and let NX manage the parts list.

Hi,
I know the method which i explained looks silly. Actually in Parts list we can edit the level leaves only, Top model and Master only.
User will select Leaves only. Items like Castings and Machining, Users add casting items under Machining. So it will consider as an assembly. Now For an Top level assembly if they select Parts list as Leaves only then Casting item number will be visible so user asked me to automate the parts list where it has to select only Machining part. Hence i asked them to select plist_ignore_member as 1 for Machining , based on attribute i tried add a manual row in Parts list , enter the details.
Please correct me if this method is wrong to fix this type of parts list.

Right now user adding manual row in parts list adding information manually so they asked me for automation. Looking forward for help from NX automation experts
Thanks
Bhavya

Bhavya

It has been a while since I've edited parts list levels, but I think that you can de-select individual components in the "edit parts list levels" command. In the assembly navigator, expand the machined component so that you can see the cast subcomponent, right click on the parts list and choose "edit levels", make sure the "select/deselect subassemblies" toggle is turned off, now hold the CTRL key and select the component for the cast part. This should remove the cast part from the parts list.

See "adding and removing members" in the help file link below:
https://docs.plm.automation.siemens.com/tdoc/nx/12.0.2/nx_help/#uid:xid1...

I tried this too , didnt work

using System;
using NXOpen;
using NXOpen.Annotations;
using NXOpen.Assemblies;
using NXOpen.Routing;
using NXOpen.UF;
using NXOpen.Utilities;
using NXOpenUI;

class remove_specified_attribute_in_all_component_parts
{
static Session s = Session.GetSession();
public static UFSession ufs = UFSession.GetUFSession();
static ListingWindow lw = s.ListingWindow;
static UI theUI = UI.GetUI();
public static string theAttr = "";
public static string attrvalue = "RAHUL";

public static int numlist;

public static void Main()
{
theAttr = "PLIST_IGNORE_MEMBER";

Component root = s.Parts.Display.ComponentAssembly.RootComponent;
Component[] childerenToroot = root.GetChildren();
Tag[] plists;
int number;

ufs.Plist.AskTags(out plists, out number);
reportComponentChildren(childerenToroot[0], plists[0], root);
}

public static void reportComponentChildren(Component comp, Tag plist, Component roots)
{
Part c_part = null;
foreach (Component item in comp.GetChildren())
{

if (item.GetChildren().Length > 0)
{

try
{

// first search for the attribute in the component proto part
// because then we cannot delete the inherited component attribute
Component[] cChild = item.GetChildren();

c_part = (Part)cChild[0].Prototype;
string[] allattr = c_part.GetUserAttributesAsStrings();
string[] allattrcompo = cChild[0].GetUserAttributesAsStrings();

if (allattr[0] == attrvalue || allattrcompo[1] == attrvalue)
{
UFPlist.TraversalSettings Settinginfo = new UFPlist.TraversalSettings();
Settinginfo.leaves_only = false;
Settinginfo.top_level_only = false;
Settinginfo.master_model = true;
ufs.Plist.SetTraversalSettings(plist, ref Settinginfo);
ufs.Plist.Update(plist);
}

}
catch (Exception ex)
{
//lw.WriteLine("+++ " + child.Name + " is unloaded.");
}

//reportComponentChildren(child);
}
}
}

public static int GetUnloadOption(string dummy)
{
return (int)Session.LibraryUnloadOption.Immediately;
}

}

Bhavya