Forum Discussion
RobbSalzmann
2 years agoValued Contributor II
The sorting posted so far relies on standard lexical ordering which produces an order that can be a bit strange for a business user:
This code will help sort things in a human, alphanumeric order:
Public Class MainClass
Public Function Main(si As SessionInfo, globals As BRGlobals, api As Object, args As ExtenderArgs) As Object
Try
Dim mbrLst As New MemberList()
Dim mbrDisplayOptions As MemberDisplayOptions = New MemberDisplayOptions() _
With{ .IncludeAllProperties = True, .IncludeMemberInfoForProperties = True}
Dim lstMembers As LIst(Of MemberInfo) =
BRApi.Finance.Metadata.GetMembersUsingFilter(si, "CorpAccounts", "A#[GAAP Account Structure].Base", True, Nothing, mbrDisplayOptions)
lstMembers.Sort(New AlphaNumericMemberInfoComparer())
mbrLst.AddMemberInfosToList(lstMembers)
Return mbrLst
Catch ex As Exception
Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
End Try
End Function
End Class
Public Class AlphaNumericMemberInfoComparer
Implements IComparer(Of MemberInfo)
Public Function Compare(x As MemberInfo, y As MemberInfo) As Integer Implements IComparer(Of MemberInfo).Compare
If x.Member.Name = y.Member.Name Then Return 0
Dim xParts() As String = Regex.Split(x.Member.Name, "(\d+)")
Dim yParts() As String = Regex.Split(y.Member.Name, "(\d+)")
For i As Integer = 0 To Math.Min(xParts.Length, yParts.Length) - 1
If xParts(i) <> yParts(i) Then
Return PartCompare(xParts(i), yParts(i))
End If
Next
Return xParts.Length.CompareTo(yParts.Length)
End Function
Private Shared Function PartCompare(x As String, y As String) As Integer
Dim a, b As Integer
Dim isNumericX As Boolean = Integer.TryParse(x, a)
Dim isNumericY As Boolean = Integer.TryParse(y, b)
If isNumericX And isNumericY Then
Return a.CompareTo(b)
End If
Return String.Compare(x, y, StringComparison.OrdinalIgnoreCase)
End Function
End Class
Alternate Sorting Result:
- JackLacava2 years agoCommunity Manager
That's neat. It could be further generalized by accepting a parameterized switch (SortOrder=<human/lcg>) and another one to switch between ordering by name or description (SortBy=<name/desc>).
- RobbSalzmann2 years agoValued Contributor II
Or, if you want something quick and LINQ-y, these will work to sort lists of MemberInfo:
''VB.net Public Sub AlphaNumericSort(ByRef members as List(Of MemberInfo) Dim sortedMembers As List(Of MemberInfo) = members _ .OrderBy(Function(memberInfo) _ If(Regex.Match(memberInfo.Member.Name, "\d+").Success, _ 'Evaluation, starts with a number? Integer.Parse(Regex.Match(memberInfo.Member.Name, "\d+").Value), _ 'True Part Integer.MaxValue)) _ 'False Part, put after all that start with a number .ToList() End Sub // C#: public void AlphaNumericSort(ref List members) { List sortedMembers = members .OrderBy ( memberInfo => Regex.Match(memberInfo.Member.Name, @"\d+").Success ? //Evaluation, starts with a number? int.Parse(Regex.Match(memberInfo.Member.Name, @"\d+").Value) : //True int.MaxValue //False, put after all that start with a number ).ToList(); }
Used like this:
Public Class MainClass Public Function Main(si As SessionInfo, globals As BRGlobals, api As Object, args As ExtenderArgs) As Object Try Dim mbrLst As New MemberList() Dim mbrDisplayOptions As MemberDisplayOptions = New MemberDisplayOptions() _ With{ .IncludeAllProperties = True, .IncludeMemberInfoForProperties = True} Dim lstMembers As List(Of MemberInfo) = BRApi.Finance.Metadata.GetMembersUsingFilter(si, "CorpAccounts", "A#[GAAP Account Structure].Base", True, Nothing, mbrDisplayOptions) '' Sort the members: AlphaNumericSort(lstMembers) mbrLst.AddMemberInfosToList(lstMembers) Return mbrLst Catch ex As Exception Throw ErrorHandler.LogWrite(si, New XFException(si, ex)) End Try End Function Public Sub AlphaNumericSort(ByRef members as List(Of MemberInfo) Dim sortedMembers As List(Of MemberInfo) = members _ .OrderBy(Function(memberInfo) _ If(Regex.Match(memberInfo.Member.Name, "\d+").Success, _ 'Evaluation, starts with a number? Integer.Parse(Regex.Match(memberInfo.Member.Name, "\d+").Value), _ 'True Part Integer.MaxValue)) _ 'False Part, put after all that start with a number .ToList() End Sub End Class
- IB26 days agoNew Contributor
Hi Robb,
Thank You for posting the sort code. I tried using the function but it gives me an error that the source is empty. I dont think that is the case. Any advice would be greatly appreciated.
Thank You,
Indu
Related Content
- 6 months ago
- 2 years ago