Reputation: 2649
This is a LibreOffice Calc macro. The goal is to filter unique data from a column on one worksheet, paste it on another worksheet, and then sort the pasted values. However, the output column is not getting sorted.
With sheets "final" and "lists", data is being read from $final.$m2:$m100
and is ending up in column $lists.$C
, starting at $lists.$C2
. The filtering works correctly, grabbing only the unique rows including empty cells (which is desired).
There are three subs/functions:
runit
(for testing)filterDistinct
(filter the data, set up the ranges)sortRange
(sort the results)Do you see anything wrong with the code?
sub runit
filterDistinct( "final", "$m2:$m100", "lists", "$C2", false, false)
end sub
Sub filterDistinct( _
strSourceSheet As String, _
strSourceRange As String, _
strTargetSheet As String, _
strTargetCell As String, _
Optional bContainsHeader As Boolean, _
Optional bCaseSensitive As Boolean _
)
GlobalScope.BasicLibraries.loadLibrary("Tools")
' Uses a Filter to copy distinct rows from the
' specified Source Range into a new Range that starts from the specified Target Cell.
'
' <strSourceRange> : specifies the Range to find distinct rows in, e.g. "A1:B99".
' <strTargetCell> : specifies the Cell to put the first found distinct row in, e.g. "D1".
' <bContainsHeader> : OPTIONAL - pass TRUE if the Source Range contains a Header.
' <bCaseSensitive> : OPTIONAL - pass TRUE if case matters while searching for distinct rows.
Dim oSheet As Object, oTargetSheet As Object, oSourceRange As Object, oTargetRange As Object, oFilter As Object
oSheet = ThisComponent.getSheets().getByName(strSourceSheet)
oSourceRange = oSheet.getCellRangebyName( strSourceRange )
oTargetSheet = ThisComponent.getSheets().getByName(strTargetSheet)
oTargetRange = oTargetSheet.getCellRangebyName( strTargetCell )
oTargetSortRange = oTargetSheet.getCellRangebyName( "$C1:$C40000" )
'msgbox oSheet.getName()
'msgbox oSourceRange.AbsoluteName
'msgbox oTargetSheet.getName()
'msgbox oTargetRange.AbsoluteName
'msgbox oTargetSortRange.AbsoluteName
'sortRange( oTargetSortRange, 0, 1 )
'exit sub
oFilter = oSourceRange.createFilterDescriptor( True )
oFilter.SkipDuplicates = True
oFilter.CopyOutputData = True
oFilter.OutputPosition = oTargetRange.CellAddress
If Not IsMissing( bContainsHeader ) Then oFilter.ContainsHeader = bContainsHeader
If Not IsMissing( bCaseSensitive ) Then oFilter.IsCaseSensitive = bCaseSensitive
oSourceRange.filter( oFilter )
sortRange( oTargetSortRange, 1, 1 )
End Sub
' sorts the cell range xRange by the iColumn (0 = first) column in IsAscending (=T/F) order:
function sortRange( _
xRange As Object, _
iColumn As Integer, _
IsAscending As Boolean _
)
GlobalScope.BasicLibraries.loadLibrary("Tools")
Dim oSortDesc(4) As New com.sun.star.beans.PropertyValue
Dim aSortFields As Object
' Dim oField As New com.sun.star.sheet.TableFilterField2
'oField.Field=0
'oField.Operator=com.sun.star.sheet.FilterOperator2.NOT_EMPTY
'oFilterDesc.setFilterFields2(Array(oField))
' define the fields to sort
aSortFields = New com.sun.star.util.SortField
aSortFields.Field = iColumn
aSortFields.SortAscending = IsAscending
' define the sort descriptor
oSortDesc(0) = new com.sun.star.beans.PropertyValue
oSortDesc(0).Name = "SortFields"
oSortDesc(0).Value = aSortFields
oSortDesc(1) = new com.sun.star.beans.PropertyValue
oSortDesc(1).Name = "ContainsHeader"
oSortDesc(1).Value = true
oSortDesc(2) = new com.sun.star.beans.PropertyValue
oSortDesc(2).Name = "IsCaseSensitive"
oSortDesc(2).Value = False
oSortDesc(3) = new com.sun.star.beans.PropertyValue
oSortDesc(3).Name = "ContainsHeader"
oSortDesc(3).Value = True
' Select the range and sort it.
' ThisComponent.getCurrentController.select( xRange )
msgbox xRange.AbsoluteName
xRange.Sort( oSortDesc )
'dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
end function
Upvotes: 0
Views: 674
Reputation: 13790
There are several small problems.
iColumn
must be 0 to use the first and only column.aSortFields
should be an array.sortRange
it is used as a subroutine, not a function. It may still work, but it's not right.Here is example working code based on Listing 6.28: Descending sort in a Calc document from Andrew's macro document.
Sub doSort
oSheet = ThisComponent.getSheets().getByIndex(0)
oTargetSortRange = oSheet.getCellRangebyName( "$C1:$C40000" )
sortRange( oTargetSortRange, 0, 1 )
End Sub
' sorts the cell range xRange by the iColumn (0 = first) column in IsAscending (=T/F) order:
Sub sortRange( _
xRange As Object, _
iColumn As Integer, _
IsAscending As Boolean _
)
Dim oSortDesc(0) As New com.sun.star.beans.PropertyValue
Dim aSortFields(0) As New com.sun.star.util.SortField
aSortFields(0).Field = iColumn
aSortFields(0).SortAscending = IsAscending
oSortDesc(0).Name = "SortFields"
oSortDesc(0).Value = aSortFields()
xRange.Sort( oSortDesc )
End Sub
Upvotes: 1