Advertisement
Guest User

Untitled

a guest
Sep 22nd, 2019
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. REM  *****  BASIC  *****
  2. REM Remove duplicates
  3. Dim oDialog1 As Object, oDoc As Object, bInProgress As Boolean
  4.  
  5. Sub RemoveDuplicates
  6.     oDoc = ThisComponent
  7.     bInProgress = False
  8.  
  9.     Dim oController As Object, oSel As Object
  10.     oController = oDoc.getCurrentController
  11.     oSel = oDoc.getCurrentSelection()
  12.  
  13.     InitLanguage
  14.  
  15.     On Error GoTo errorExit
  16.     If not oSel.supportsService("com.sun.star.sheet.SheetCellRange") then
  17.         MsgBox getText(0) ' But other types of selection also possible, like frames, not only multiselection
  18.         Err = 14 ' Invalid parameter
  19.     End If
  20.  
  21.     Dim sourceAddress
  22.     sourceAddress = oSel.getRangeAddress
  23.  
  24.     If oSel.supportsService("com.sun.star.sheet.SheetCell") then
  25.         ExtendSingleSelection(oSel, oController)
  26.     Else
  27.         ClipSelectionToUsedArea(oSel, oController)
  28.     End If
  29.     On Error GoTo 0
  30.     oSel = oDoc.getCurrentSelection()
  31.  
  32.     DialogLibraries.LoadLibrary("RemoveDuplicates")
  33.     oDialog1 = CreateUnoDialog( DialogLibraries.RemoveDuplicates.Options )
  34.     UpdateDialogUI
  35.     cbIncludeTitle ' Take dialog-defined checked state into account
  36.     If oDialog1.Execute() = 0 Then ' Cancel/error -> restore original selection
  37.         oController.select(oSel.Spreadsheet.getCellRangeByPosition(sourceAddress.StartColumn, _
  38.                                                                    sourceAddress.StartRow, _
  39.                                                                    sourceAddress.EndColumn, _
  40.                                                                    sourceAddress.EndRow))
  41.     End If
  42. errorExit:
  43. End Sub
  44.  
  45. Sub UpdateDialogUI
  46.     oDialog1.GetControl("OptionHint").Text = getText(5)
  47.     oDialog1.GetControl("btnSelectAll").Label = getText(3)
  48.     oDialog1.GetControl("cbTitle").Label = getText(4)
  49.     oDialog1.GetControl("btnOK").Label = getText(6)
  50.     oDialog1.GetControl("btnCancel").Label = getText(7)
  51.     oDialog1.GetControl("Label1").Text = getText(8)
  52. End Sub
  53.  
  54. Sub UpdateListBoxItems (hasTitle As Boolean)
  55.     Dim oSel, lbList
  56.     oSel = oDoc.getCurrentSelection()
  57.     lbList = oDialog1.GetControl("lbList")
  58.     Dim ColDesc()
  59.     If hasTitle Then
  60.         Dim FirstRowRange As Object ' First row of selection
  61.         FirstRowRange = oSel.getCellRangeByPosition(0, 0, oSel.Columns.Count - 1, 0)
  62.         ColDesc = FirstRowRange.getDataArray()(0)
  63.     Else
  64.         Dim i As Long, sPrefix As String
  65.         ColDesc = oSel.Columns.ElementNames
  66.         sPrefix = getText(2)
  67.         For i = lBound(ColDesc) To uBound(ColDesc)
  68.             ColDesc(i) = sPrefix & ColDesc(i)
  69.         Next i
  70.     End If
  71.     lbList.setVisible(False) ' this speeds up the update manyfold
  72.     lbList.removeItems(0, lbList.getItemCount())
  73.     lbList.addItems(ColDesc, 0)
  74.     btnSelectAllClick
  75.     lbList.setVisible(True)
  76. End Sub
  77.  
  78. Sub ExtendSingleSelection(oSel As Object, oController As Object)
  79. Dim oCursor
  80.     oCursor = oSel.SpreadSheet.createCursorByRange(oSel)
  81.     oCursor.collapseToCurrentRegion()
  82.     If ((oCursor.Columns.Count = 1) And (oCursor.Rows.Count = 1)) Then
  83.         MsgBox getText(1)
  84.         Err = 14 ' Invalid parameter
  85.     End If
  86.     oController.select(oCursor)
  87. End Sub
  88.  
  89. Sub ClipSelectionToUsedArea(oSel As Object, oController As Object)
  90.     Dim cursor As Object, curAddr As Object, newAddr As Object, modified As Boolean
  91.     newAddr = oSel.getRangeAddress
  92.     modified = False
  93.     cursor = oSel.SpreadSheet.createCursor()
  94.     cursor.gotoStartOfUsedArea(False)
  95.     curAddr = cursor.getRangeAddress()
  96.     If (newAddr.StartColumn < curAddr.StartColumn) Then
  97.         newAddr.StartColumn = curAddr.StartColumn
  98.         modified = True
  99.     End If
  100.     If (newAddr.StartRow < curAddr.StartRow) Then
  101.         newAddr.StartRow = curAddr.StartRow
  102.         modified = True
  103.     End If
  104.     cursor.gotoEndOfUsedArea(False)
  105.     curAddr = cursor.getRangeAddress()
  106.     If (newAddr.EndColumn > curAddr.EndColumn) Then
  107.         newAddr.EndColumn = curAddr.EndColumn
  108.         modified = True
  109.     End If
  110.     If (newAddr.EndRow > curAddr.EndRow) Then
  111.         newAddr.EndRow = curAddr.EndRow
  112.         modified = True
  113.     End If
  114.     If ((newAddr.StartColumn > newAddr.EndColumn) Or _
  115.         (newAddr.StartRow > newAddr.EndRow) Or _
  116.         ((newAddr.StartColumn = newAddr.EndColumn) And _
  117.          (newAddr.StartRow = newAddr.EndRow))) Then
  118.         ' Selection outside of used area / collapsed to single cell -> Invalid parameter
  119.         MsgBox getText(1)
  120.         Err = 14
  121.     End If
  122.     If (modified) Then
  123.         oController.select(oSel.SpreadSheet.getCellRangeByPosition(newAddr.StartColumn, _
  124.                                                                    newAddr.StartRow, _
  125.                                                                    newAddr.EndColumn, _
  126.                                                                    newAddr.EndRow))
  127.     End If
  128. End Sub
  129.  
  130. Function CheckDup(rowStr As String, byRef UniqueColl)
  131.     CheckDup = True
  132.     On Error GoTo duplicateRow
  133.     UniqueColl.Add(1, rowStr) ' Fails if exists
  134.    CheckDup = False
  135. duplicateRow:
  136. End Function
  137.  
  138. Function GetCellRangeAddress(oSheet, StartColumn, StartRow, EndColumn, EndRow)
  139.     Dim CellRangeAddress As New com.sun.star.table.CellRangeAddress
  140.     CellRangeAddress.Sheet = oSheet.RangeAddress.Sheet
  141.     CellRangeAddress.StartColumn = StartColumn
  142.     CellRangeAddress.EndColumn = EndColumn
  143.     CellRangeAddress.StartRow = StartRow
  144.     CellRangeAddress.EndRow = EndRow
  145.     GetCellRangeAddress = CellRangeAddress
  146. End Function
  147.  
  148. Function GetCellAddress(oSheet, Column, Row)
  149.     Dim CellAddress As New com.sun.star.table.CellAddress
  150.     CellAddress.Sheet = oSheet.RangeAddress.Sheet
  151.     CellAddress.Column = Column
  152.     CellAddress.Row = Row
  153.     GetCellAddress = CellAddress
  154. End Function
  155.  
  156. Sub MoveCells(oSheet, StartColumn, StartRow, EndColumn, EndRow, NewRow)
  157.     oSheet.copyRange(GetCellAddress(oSheet, StartColumn, NewRow), _
  158.                      GetCellRangeAddress(oSheet, StartColumn, StartRow, EndColumn, EndRow))
  159. End Sub
  160.  
  161. Sub RemoveCells(oSheet, StartColumn, StartRow, EndColumn, EndRow)
  162.     oSheet.removeRange(GetCellRangeAddress(oSheet, StartColumn, StartRow, EndColumn, EndRow), _
  163.                        com.sun.star.sheet.CellDeleteMode.UP)
  164. '   Alternatively, to not shift the data below the range upwards
  165. '   oSheet.getCellRangeByPosition(left, top, right, bottom).clearContents(&HFFFFFFFF)
  166. End Sub
  167.  
  168. Function GetRowString(aDataRow(), aCompInd()) As String
  169.     Dim l As Long, u As Long
  170.     l = lBound(aCompInd)
  171.     u = uBound(aCompInd)
  172.     If (l = u) Then
  173.         GetRowString = aDataRow(aCompInd(l))
  174.     Else
  175.         Dim NewArr(l To u), i As Long
  176.         For i = l To u
  177.             NewArr(i) = aDataRow(aCompInd(i))
  178.         Next i
  179.         GetRowString = Join(NewArr, Chr(1))
  180.     End If
  181. End Function
  182.  
  183. ' Returns 1 if successful, 0 otherwise
  184. Function doRemove() As Long
  185.  
  186.     Dim StartTime As Date
  187.     StartTime = Now()
  188.  
  189.     Dim bResult As Boolean, bModified As Boolean
  190.     bResult = False
  191.     bModified = False
  192.  
  193.     Dim oUndoManager As Object
  194.  
  195.     oDoc.lockControllers()
  196.     oDoc.addActionLock()
  197.     oUndoManager = ThisComponent.getUndoManager()
  198.     oUndoManager.enterUndoContext("Remove Duplicates")
  199.     On Error GoTo cleanup
  200.  
  201.     Dim oSel As Object, oAddress As Object, aDataArray(), selectedLst(), bHasTitle As Boolean
  202.     oSel = oDoc.getCurrentSelection()
  203.     oAddress = oSel.getRangeAddress()
  204.     aDataArray = oSel.getDataArray()
  205.  
  206.     selectedLst = oDialog1.GetControl("lbList").getSelectedItemsPos()
  207.     bHasTitle = oDialog1.GetControl("cbTitle").getState() > 0
  208.  
  209.     Dim FirstRow As Long, LastRow As Long
  210.     FirstRow = lBound(aDataArray)
  211.     If bHasTitle Then
  212.         FirstRow = FirstRow + 1
  213.     End If
  214.     LastRow = uBound(aDataArray)
  215.  
  216.     Dim ProgressBar As Object
  217.     ProgressBar = oDialog1.GetControl("ProgressBar1")
  218.     ResetProgress(ProgressBar, FirstRow, LastRow)
  219.  
  220.     Dim UnionArray As New Collection, LastRowDone As Long, nUnique As Long, Pos As Long, checkStr As String
  221.     LastRowDone = FirstRow - 1
  222.     nUnique = 0
  223.     For Pos = FirstRow To LastRow
  224.         checkStr = GetRowString(aDataArray(Pos), selectedLst)
  225.         If (CheckDup(checkStr, UnionArray)) Then ' Duplicate
  226.             If (nUnique > 0) Then
  227.                 If (nUnique < (Pos - FirstRow)) Then
  228.                     MoveCells(oSel.Spreadsheet, _
  229.                               oAddress.StartColumn, _
  230.                               oAddress.StartRow + Pos - nUnique, _
  231.                               oAddress.EndColumn, _
  232.                               oAddress.StartRow + Pos - 1, _
  233.                               oAddress.StartRow + LastRowDone + 1)
  234.                     bModified = True
  235.                 End If
  236.                 LastRowDone = LastRowDone + nUnique
  237.                 nUnique = 0
  238.             End If
  239.         Else ' Unique
  240.             nUnique = nUnique + 1
  241.         End If
  242.  
  243.         If ((Pos > FirstRow) And (Pos Mod 100 = 0)) Then
  244.             ' Check if cancelled
  245.             If (Not bInProgress) Then Err = 18 ' Interrupted by user
  246.             StepProgress(ProgressBar, 100)
  247.         End If
  248.     Next Pos
  249.  
  250.     If (nUnique > 0) Then
  251.         If (nUnique < (Pos - FirstRow)) Then
  252.             MoveCells(oSel.Spreadsheet, _
  253.                       oAddress.StartColumn, _
  254.                       oAddress.StartRow + Pos - nUnique, _
  255.                       oAddress.EndColumn, _
  256.                       oAddress.StartRow + Pos - 1, _
  257.                       oAddress.StartRow + LastRowDone + 1)
  258.             bModified = True
  259.         End If
  260.         LastRowDone = LastRowDone + nUnique
  261.     End If
  262.  
  263.     If (LastRowDone < LastRow) Then
  264.         RemoveCells(oSel.Spreadsheet, _
  265.                     oAddress.StartColumn, _
  266.                     oAddress.StartRow + LastRowDone + 1, _
  267.                     oAddress.EndColumn, _
  268.                     oAddress.StartRow + LastRow)
  269.         bModified = True
  270.     End If
  271.  
  272.     ' Make sure to set it to 100% before reporting success: it could not account yet for the last <100 elements
  273.     SetProgress(ProgressBar, LastRow)
  274.  
  275.     ' Select the resulting area
  276.     oDoc.getCurrentController().select( _
  277.         oSel.Spreadsheet.getCellRangeByPosition(oAddress.StartColumn, _
  278.                                                 oAddress.StartRow, _
  279.                                                 oAddress.EndColumn, _
  280.                                                 oAddress.StartRow + LastRowDone))
  281.  
  282.     bResult = True
  283.  
  284. cleanup:
  285.     oUndoManager.leaveUndoContext()
  286.     oDoc.unLockControllers()
  287.     oDoc.removeActionLock()
  288.  
  289.     Dim TotalCount As Long, DuplicatesCount As Long, Message As String
  290.     Message = getText(9) & Format((Now()-StartTime), "[s]") & getText(10) & Chr$(13)
  291.     If (bResult) Then
  292.         doRemove = 1
  293.         TotalCount = LastRow - FirstRow + 1
  294.         DuplicatesCount = LastRow - LastRowDone
  295.         If (DuplicatesCount > 0) Then
  296.             Message = Message & getText(11) & DuplicatesCount & getText(12) & Chr$(13) & _
  297.                                 getText(13) & TotalCount - DuplicatesCount & getText(14)
  298.         Else
  299.             Message = Message & getText(15)
  300.         End If
  301.     Else
  302.         doRemove = 0
  303.         If (Err = 18) Then
  304.             Message = Message & getText(16)
  305.         Else
  306.             Message = Message & getText(17)
  307.         End If
  308.         If (bModified) Then
  309.             Message = Message & getText(18)
  310.         Else
  311.             Message = Message & getText(19)
  312.         End If
  313.     End If
  314.     MsgBox Message
  315.     If (Not bResult And bModified) Then oUndoManager.Undo()
  316. End Function
  317.  
  318. Sub ResetProgress(ByRef ProgressBar, nMinVal As Long, nMaxVal As Long)
  319.     With ProgressBar
  320.         .setRange(nMinVal, nMaxVal)
  321.         .setValue(nMinVal)
  322.     End With
  323. End Sub
  324.  
  325. Sub SetProgress(ByRef ProgressBar, nVal As Long)
  326.     ProgressBar.setValue(nVal)
  327. End Sub
  328.  
  329. Sub StepProgress(ByRef ProgressBar, nStep As Long)
  330.     With ProgressBar
  331.         .setValue(.getValue() + nStep)
  332.     End With
  333. End Sub
  334.  
  335. Sub btnCancelClick
  336.     If (bInProgress) Then
  337.         oDialog1.GetControl("btnCancel").Enable = False ' Prevent second Cancel
  338.         bInProgress = False
  339.     Else
  340.         oDialog1.endExecute()
  341.     End If
  342. End Sub
  343.  
  344. Sub btnOKClick
  345.     bInProgress = True
  346.     ' Only Cancel button is enabled in the process
  347.     oDialog1.GetControl("btnSelectAll").Enable = False
  348.     oDialog1.GetControl("cbTitle").Enable = False
  349.     oDialog1.GetControl("btnOK").Enable = False
  350.     oDialog1.GetControl("lbList").Enable = False
  351.     oDialog1.endDialog(DoRemove())
  352. End Sub
  353.  
  354. Sub btnSelectAllClick
  355.     Dim lbList, count As Long, i As Long
  356.     lbList = oDialog1.GetControl("lbList")
  357.     count = lbList.getItemCount()
  358.     Dim SelectItems(count) As Integer
  359.     For i = 0 To count - 1
  360.         SelectItems(i) = i
  361.     Next i
  362.     lbList.selectItemsPos(SelectItems, true)
  363. End Sub
  364.  
  365. Sub cbIncludeTitle
  366.     UpdateListBoxItems(oDialog1.GetControl("cbTitle").getState() > 0)
  367. End Sub
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement