I am struggling with a selection routine to run through a displayed assembly and select all left hand components (using our naming convention). The intent is to pre-select components inside the Assembly Navigator to then run the Mirror Assembly command. Mirror Assembly will accept pre-selection (essentially completing the first step in the dialog) and is not a journal recordable command.
In reference to the below code, .highlight only highlights the component in the display area and faintly highlights the component in the Assembly Navigator. On exiting the UI the highlighting stays and the faint selection goes away.
I've tried variations of both .Selection and theUI.SelectionManager methods without luck.
For Each cmp As Component In theSession.Parts.Display.ComponentAssembly.RootComponent.GetChildren
Dim isMirror As Boolean = cmp.Name.Substring(8, 1).ToLower = "l"
If isMirror Then
cmp.Highlight()
End If
Next cmp
re: selecting components
You can use the .RequestSelections function to select your desired entities. This should work in NX 11 or later. There is a journal here that shows its use:
https://nxjournaling.com/comment/5640#comment-5640
If you search for .GetNumSelectedObjects, you will find several journals that make use of pre-selected objects.
Selecting Components
.RequestSelections is a method I tried before. I'm curious if its due to the versioning we are in. We are using the 1973.4341 flavor, which is GM specific. We are updating next month though. My new code renders the following output.
Dim LhCompLst As New List(Of Component)
For Each cmp As Component In theSession.Parts.Display.ComponentAssembly.RootComponent.GetChildren
Dim isMirror As Boolean = cmp.Name.Substring(8, 1).ToLower = "l"
If isMirror Then
'cmp.Highlight()
LhCompLst.Add(cmp)
End If
Next cmp
theUI.SelectionManager.ClearGlobalSelectionList()
theUI.SelectionManager.RequestSelections(LhCompLst.ToArray)
lw.Open()
lw.WriteLine("number of selected components: " & theUI.SelectionManager.GetNumSelectedObjects.ToString)
For Each Comp In LhCompLst
lw.WriteLine(New String(Comp.Name))
Next Comp
re: select components
Is your assembly more than one level deep? I ask because the code above will only process the first level components of the current display part. If the structure is multiple levels deep, you will need a different approach. Here is one:
https://nxjournaling.com/content/creating-subroutine-process-all-compone...
Also, you might want to report out the name of each component in the assembly so that you can check to see if the result is what you expect.
Select Components
I apologize, I meant to attach the output to my last reply and didn't. See below. (replaced the PN's for confidentiality) So it's pulling the components and collecting them in the list but the SelectionManager is not recognizing the components in the list.
In terms of the levels of indentation, I do have code that goes deeper. Just ran into this issue with testing, I try to test with as little of variables as possible to help debug. My test assembly is only 1 level deep.
number of selected components: 0
XX-----1L.F01.0010
XX-----2L.F01.0019
XX-----3L.F01.0019
XX-----4L.F01.0019
XX-----5L.F01.0019
XX-----6L.F01.0019
XX-----7L.F01.0019
XX-----8L.F01.0019
XX-----9L.F01.0019
XX----10L.F01.0019
XX----11L.F01.0019
XX----12L.F01.0019
XX----13L.F01.0019
XX----14L.F01.0019
XX----15L.F01.0019
XX----16L.F01.0019
re: select components
The following code works for me on a small assembly. I took some "select component" code that I had and pasted in your check on the component name. For my testing, I shortened the component names, so I'm looking at a different character in the name than you are, but the idea is the same.
I'm not sure why this code would work and yours would not. The only difference I see, and it is a small one, is that I clear out the selection list before processing the components.
'NXJournaling.com
'April 21, 2023
'Select components based on name.
Option Strict Off
Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF
Module Module6
ReadOnly theSession As Session = Session.GetSession()
ReadOnly theUfSession As UFSession = UFSession.GetUFSession()
ReadOnly theUI As UI = UI.GetUI()
Dim lw As ListingWindow = theSession.ListingWindow
Sub Main()
If IsNothing(theSession.Parts.BaseWork) Then
'active part required
Return
End If
lw.Open()
If IsNothing(theSession.Parts.Display.ComponentAssembly.RootComponent) Then
'no components to process
Return
End If
Dim foundComponents As New List(Of Assemblies.Component)
theUI.SelectionManager.ClearGlobalSelectionList()
Try
Dim c As Assemblies.ComponentAssembly = theSession.Parts.Display.ComponentAssembly
processComponentChildren(c.RootComponent, foundComponents)
Catch e As Exception
theSession.ListingWindow.WriteLine("Failed: " & e.ToString)
End Try
theUI.SelectionManager.RequestSelections(foundComponents.ToArray)
lw.WriteLine("number of selected components: " & theUI.SelectionManager.GetNumSelectedObjects.ToString)
lw.Close()
End Sub
Sub processComponentChildren(ByVal comp As Assemblies.Component, ByRef componentList As List(Of Assemblies.Component))
For Each child As Assemblies.Component In comp.GetChildren()
lw.WriteLine("child.Name: " & child.Name)
Dim isMirror As Boolean = child.Name.Substring(3, 1).ToLower = "l"
If isMirror Then
lw.WriteLine("mirror component found")
componentList.Add(child)
End If
processComponentChildren(child, componentList)
Next
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
I finally got around to
I finally got around to looking at this code again and figured out the issue. With my code I am using the BlockStyler to host a number of quick functions (opening common directory locations, setting load behavior, etc) Selecting LH components in the navigator to have them pre-selected when running "Mirror Assembly" is the intent of this specific function.
The BlockStyler UI being active at the time RequestSelections is called with render a null output.
Is what I had to do is capture the run of the LH selection as a public boolean, deactivate all other buttons/functions in the UI, and throw a message to the user to close the UI to get their selections. The functional block of code is captured in an If statement (if LHrun = yes) after theDialog.dispose in Main and it functions as intended.
There may be a work around here like focusing the program to look at the session UI or something but placing the code in Main is a workable solution for my situation at the moment.
re: block styler
I don't have access to the block styler, so I don't have much experience with it. I'd suggest posting your question on the Siemens forum and/or asking Siemens support. I've had a few journaling related questions and Siemens support has been very helpful with providing a solution or finding a work-around.