to all
I have a small function which extract all the CAE.FEElement from a user supplied group name . In the "main" function I later loop through the returned array of CAE.FEElement. At the end the "main" program some data is extracted from each element and written to a .csv file. The format of the data is
Elm ID, Result 1, Result 2, Result 3
and so on on for every elements
All works as intended but I have noticed that the elements are not listed by increasing ID. It may even be a bit "random".
so the question is
Is there a way of "sorting" the array of CAE.FEElement() before the For Each ... Next Loop so that when I write the (final)" data to the csv file the element are sorted by increasing ID?
Code
-------
Function GetGroupElements(ByRef theCAEGroup As CAE.CaeGroup) As CAE.FEElement()
'Function returns an array list of CAE.FEElement within a user supplied CAE.CaeGroup
Dim elementList As ArrayList = New ArrayList
For Each obj As TaggedObject In theCAEGroup.GetEntities()
If TypeOf (obj) Is CAE.FEElement Then
Dim theElement As CAE.FEElement = obj
elementList.Add(theElement)
End if
Next obj
Return elementList.ToArray(GetType(CAE.FEElement))
End Function
Dim arrFEElmInGroupTarget() As CAE.FEElement = GetGroupElements(caeGrouptarget)
For Each FEElm as CAE.FEElement In thearrFEElm
'Get the element ID
Dim theFEElmID as Double = FEElm.Label
'do something
Next FEElm
re: sorting CAE.FEElements
I'd suggest using a list of type (CAE.FEElement) instead of an array list. By doing so, you can use the list object's .Sort method; you'll need to write a custom function to tell the list how to sort the FEElements, but it is really easy. You can find out more about sorting lists of objects here.
re: sorting CAE.FEElements
Thanks. had the vague idea of sorting by Elm ID within the function GetGroupElements() just before returning the array
I do get your point/suggestion (I think) about returning a list
Function GetGroupElements(ByRef theCAEGroup As CAE.CaeGroup) As List(Of CAE.FEElement)
Thanks
Regards
re: sorting CAE.FEElements - AddressOf() not recognised
Did a bit of reading and the .Sort option is starting to make sense. I have therefore copied (without any shame) the code from the link provided (and also a couple of line from the msn website). I have one problem as the code doesn't like the use of AddressOf. See code below recognised
#Region "Import Options"
Option Strict Off
Imports System
Imports System.IO
Imports System.Collections
Imports System.Collections.Generic
Imports System.Threading
Imports System.Array
Imports System.Globalization
Imports NXOpen
Imports NXOpenUI
Imports NXOpen.UF
Imports System.Windows.Forms
Imports NXOpen.BlockStyler
#End Region
Module Module1
#Region "Variables declaration"
Public Dim theSession As Session = Session.GetSession()
Public Dim theUISession As UI = UI.GetUI
Public Dim theLW As ListingWindow = theSession.ListingWindow
Public Dim strMacroName as String = "test"
Public theNXMessageBox As NXMessageBox = theUISession.NXMessageBox
Public theNXMessageBoxTitle As String = strMacroName
'Public Dim theSimPart As NXOpen.CAE.SimPart = theSession.Parts.BaseWork
Dim ufs As UFSession = UFSession.GetUFSession()
#End Region
'--------------------------------
Sub Main()
theLW.Open()
Dim i,j,k,m,n As Integer
Dim iError As Integer = 0
Dim workSimPart As CAE.SimPart = CType(theSession.Parts.BaseWork, CAE.SimPart)
'get input from user. A group containing all the elements to process
'Allocate element in group selected to arrFEElmInGroupTarget() by calling function GetGroupElements()
Dim caeGroup1 As CAE.CaeGroup = CType(ChooseOneItem("Group containing all 1D elements", workSimPart.CaeGroups.ToArray()), CAE.CaeGroup)
Dim arrFEElmInGroupTarget() As CAE.FEElement = GetGroupElements(caeGroup1)
REM 'Dim arrFEElmID(0 To Ubound(arrFEElmInGroupTarget)) As Integer
REM For Each FEElm As CAE.FEElement In arrFEElmInGroupTarget
REM 'arrFEElmID(i) = FEElm.Label
REM Dim theFEElmID as Integer = FEElm.Label
REM theLW.WriteLine("Element ID is " & theFEElmID.ToString)
REM i +=1
REM Next FEElm
End Sub
#Region "Create group display for user"
Function ChooseOneItem(ByRef prompt As String, ByRef objs() As NXObject) As NXObject
If objs.Length = 1 Then Return objs(0)
Dim opts(13) As String
Dim a As Integer = 0
Dim ii, resp, z As Integer
Dim n_choices As Integer = objs.Length
Dim choices(n_choices) As String
For ii = 0 To n_choices - 1
choices(ii) = objs(ii).Name
If choices(ii) Is Nothing Or choices(ii).Equals("") Then choices(ii) = objs(ii).ToString
Next
Do
If (n_choices - a) < 14 Then
z = n_choices - a
Else
z = 14
End If
For ii = 0 To z - 1
opts(ii) = choices(a + ii)
Next
If ((z = 14) And ((a + z) < n_choices)) Then opts(13) = "More..."
ufs.Ui.LockUgAccess(UFConstants.UF_UI_FROM_CUSTOM) ' in case running a journal
resp = ufs.Ui.DisplayMenu(prompt, 0, opts, z)
ufs.Ui.UnlockUgAccess(UFConstants.UF_UI_FROM_CUSTOM) ' in case running a journal
Select Case resp
Case 1 ' Back
If (a = 0) Then Return Nothing
a = a - 13
Case 2 ' Cancel
Return Nothing
Case 18 ' More ...
If ((a + z) < n_choices) Then a = a + 13
Case Else ' Picked one
Return objs(a + resp - 5)
End Select
Loop While True
Return Nothing ' can't really get here
End Function
#End Region
#Region "get elements in group selected"
Function GetGroupElements(ByRef caeGroup As CAE.CaeGroup) As CAE.FEElement() 'As List(Of CAE.FEElement)
Dim elementList As ArrayList = New ArrayList
For Each obj As TaggedObject In caeGroup.GetEntities()
Try
Dim element As CAE.FEElement = CType(obj, CAE.FEElement)
If Not element Is Nothing Then
elementList.Add(element)
End If
Catch
End Try
Next
'list before sorting
For Each FEElm As CAE.FEElement In elementList
Dim theFEElmID as Integer = FEElm.Label
theLW.WriteLine("At Rank " & elementList.IndexOf(FEElm).ToString & " Element ID is: " & theFEElmID.ToString)
'theLW.WriteLine("Element ID is " & theFEElmID.ToString)
Next FEElm
'sort by Element Label (smallest to highest)
elementList.Sort(AddressOf FEElmByID)
'list after sorting
For Each FEElm As CAE.FEElement In elementList
Dim theFEElmID as Integer = FEElm.Label
theLW.WriteLine("At Rank " & elementList.IndexOf(FEElm).ToString & " Element ID is: " & theFEElmID.ToString)
Next FEElm
Return elementList.ToArray(GetType(CAE.FEElement))
End Function
Private Function FEElmByID(ByVal x As CAE.FEElement, ByVal y As CAE.FEElement) As Integer
'from NXjournaling website
'custom comparison function will take two objects (or structures, or values, etc) as input
'and must return a value that indicates the ranking of these two objects.
'When comparing two values, let's call them x and y, there are three possible outcomes:
'x > y, meaning x comes after y in the sort
'x < y, meaning x comes before y in the sort
'x = y, meaning in a sorted list either could come first
'the List.Sort method will interpret the comparison function return value:
'return value > 0: x > y
'return value < 0: x < y
'return value = 0: x = y
Dim FEElmID1 AS Integer = x.Label
Dim FEElmID2 AS Integer = y.Label
'If x.Label Is Nothing AndAlso y.Label Is Nothing Then
'Return 0
'ElseIf x.Label Is Nothing Then
'Return 0
'ElseIf y.Label Is Nothing Then
'Return 0
'Else 'Compare x to y
If x.Label > Y.Label Then Return 1
If x.Label < Y.Label Then Return -1
'FEEM ID (Label) cannot be equal!
'Return x.Label.CompareTo(y.Label)
'End If
End Function
#End Region
End Module
Thanks
Regards
sorting FE elements
You are still using an arraylist; try using a list (of CAE.FEElement).
Dim elementList as New List(Of CAE.FEElement)
sorting FE elements - Workign with a List(Of CAE.FEElement)
Thanks. Looks like it is working (well my test seems to work!). I also tweaked the function GetGroupElements() to return a list. see code below
#Region "Import Options"
Option Strict Off
Imports System
Imports System.IO
Imports System.Collections
Imports System.Collections.Generic
Imports System.Threading
Imports System.Array
Imports System.Globalization
Imports NXOpen
Imports NXOpenUI
Imports NXOpen.UF
Imports System.Windows.Forms
Imports NXOpen.BlockStyler
#End Region
Module Module1
#Region "Variables declaration"
Public Dim theSession As Session = Session.GetSession()
Public Dim theUISession As UI = UI.GetUI
Public Dim theLW As ListingWindow = theSession.ListingWindow
Dim ufs As UFSession = UFSession.GetUFSession()
#End Region
'--------------------------------
Sub Main()
theLW.Open()
Dim i,j,k,m,n As Integer
Dim workSimPart As CAE.SimPart = CType(theSession.Parts.BaseWork, CAE.SimPart)
'get input from user. A group containing all the elements to process
'Allocate element in group selected to arrFEElmInGroupTarget() by calling function GetGroupElements()
Dim caeGroup1 As CAE.CaeGroup = CType(ChooseOneItem("Group containing all 1D elements", workSimPart.CaeGroups.ToArray()), CAE.CaeGroup)
Dim arrFEElmInGroupTarget() As CAE.FEElement = GetGroupElements(caeGroup1).ToArray
For Each FEElm As CAE.FEElement In arrFEElmInGroupTarget
Dim theFEElmID as Integer = FEElm.Label
theLW.WriteLine("Element ID is " & theFEElmID.ToString)
i +=1
Next FEElm
End Sub
'------------------------------
Function GetGroupElements(ByRef caeGroup As CAE.CaeGroup) As List(Of CAE.FEElement)
GetGroupElements = New List(Of CAE.FEElement)
For Each obj As TaggedObject In caeGroup.GetEntities()
Try
Dim element As CAE.FEElement = CType(obj, CAE.FEElement)
If Not element Is Nothing Then
elementList.Add(element)
GetGroupElements.Add(element)
End If
Catch
End Try
Next
'list before sorting
For Each FEElm As CAE.FEElement In GetGroupElements 'elementList
Dim theFEElmID as Integer = FEElm.Label
theLW.WriteLine("At Rank " & GetGroupElements.IndexOf(FEElm).ToString & " Element ID is: " & theFEElmID.ToString)
Next FEElm
'sort by Element Label (smallest to highest)
GetGroupElements.Sort(AddressOf FEElmByID)
theLW.WriteLine("")
'list after sorting
For Each FEElm As CAE.FEElement In GetGroupElements 'elementList
Dim theFEElmID as Integer = FEElm.Label
theLW.WriteLine("At Rank " & GetGroupElements.IndexOf(FEElm).ToString & " Element ID is: " & theFEElmID.ToString)
Next FEElm
End Function
'------------------------------
Private Function FEElmByID(ByVal x As CAE.FEElement, ByVal y As CAE.FEElement) As Integer
'from NXjournaling website
'custom comparison function will take two objects (or structures, or values, etc) as input
'and must return a value that indicates the ranking of these two objects.
'When comparing two values, let's call them x and y, there are three possible outcomes:
'x > y, meaning x comes after y in the sort
'x < y, meaning x comes before y in the sort
'x = y, meaning in a sorted list either could come first
'the List.Sort method will interpret the comparison function return value:
'return value > 0: x > y
'return value < 0: x < y
'return value = 0: x = y
If x.Label > Y.Label Then Return 1
If x.Label < Y.Label Then Return -1
End Function
'------------------------------
Function ChooseOneItem(ByRef prompt As String, ByRef objs() As NXObject) As NXObject
If objs.Length = 1 Then Return objs(0)
Dim opts(13) As String
Dim a As Integer = 0
Dim ii, resp, z As Integer
Dim n_choices As Integer = objs.Length
Dim choices(n_choices) As String
For ii = 0 To n_choices - 1
choices(ii) = objs(ii).Name
If choices(ii) Is Nothing Or choices(ii).Equals("") Then choices(ii) = objs(ii).ToString
Next
Do
If (n_choices - a) < 14 Then
z = n_choices - a
Else
z = 14
End If
For ii = 0 To z - 1
opts(ii) = choices(a + ii)
Next
If ((z = 14) And ((a + z) < n_choices)) Then opts(13) = "More..."
ufs.Ui.LockUgAccess(UFConstants.UF_UI_FROM_CUSTOM) ' in case running a journal
resp = ufs.Ui.DisplayMenu(prompt, 0, opts, z)
ufs.Ui.UnlockUgAccess(UFConstants.UF_UI_FROM_CUSTOM) ' in case running a journal
Select Case resp
Case 1 ' Back
If (a = 0) Then Return Nothing
a = a - 13
Case 2 ' Cancel
Return Nothing
Case 18 ' More ...
If ((a + z) < n_choices) Then a = a + 13
Case Else ' Picked one
Return objs(a + resp - 5)
End Select
Loop While True
Return Nothing ' can't really get here
End Function
End Module
Thanks
Regards