Advertisement
Guest User

Untitled

a guest
Sep 20th, 2019
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. REM  *****  BASIC  *****
  2.  
  3. REM Remove duplicates
  4. Dim oDialog1 As Object, oDoc As Object, bInProgress As Boolean
  5.  
  6. Sub RemoveDuplicates
  7.     oDoc = ThisComponent
  8.     bInProgress = False
  9.  
  10.     Dim oController As Object, oSel As Object
  11.     oController = oDoc.getCurrentController
  12.     oSel = oDoc.getCurrentSelection()
  13.  
  14.     InitLanguage
  15.  
  16.     On Error GoTo errorExit
  17.     If not oSel.supportsService("com.sun.star.sheet.SheetCellRange") then
  18.         MsgBox getText(0) ' But other types of selection also possible, like frames, not only multiselection
  19.         Err = 14 ' Invalid parameter
  20.     End If
  21.  
  22.     Dim sourceAddress
  23.     sourceAddress = oSel.getRangeAddress
  24.  
  25.     If oSel.supportsService("com.sun.star.sheet.SheetCell") then
  26.         ExtendSingleSelection(oSel, oController)
  27.     Else
  28.         ClipSelectionToUsedArea(oSel, oController)
  29.     End If
  30.     On Error GoTo 0
  31.     oSel = oDoc.getCurrentSelection()
  32.  
  33.     DialogLibraries.LoadLibrary("RemoveDuplicates")
  34.     oDialog1 = CreateUnoDialog( DialogLibraries.RemoveDuplicates.Options )
  35.     UpdateDialogUI
  36.     cbIncludeTitle ' Take dialog-defined checked state into account
  37.     If oDialog1.Execute() = 0 Then ' Cancel/error -> restore original selection
  38.         oController.select(oSel.Spreadsheet.getCellRangeByPosition(sourceAddress.StartColumn, _
  39.                                                                    sourceAddress.StartRow, _
  40.                                                                    sourceAddress.EndColumn, _
  41.                                                                    sourceAddress.EndRow))
  42.     End If
  43. errorExit:
  44. End Sub
  45.  
  46. Sub UpdateDialogUI
  47.     oDialog1.GetControl("OptionHint").Text = getText(5)
  48.     oDialog1.GetControl("btnSelectAll").Label = getText(3)
  49.     oDialog1.GetControl("cbTitle").Label = getText(4)
  50.     oDialog1.GetControl("btnOK").Label = getText(6)
  51.     oDialog1.GetControl("btnCancel").Label = getText(7)
  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 As Object
  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, left, top, right, bottom)
  162.     oSheet.getCellRangeByPosition(left, top, right, bottom).clearContents(&HFFFFFFFF)
  163. End Sub
  164.  
  165. Function GetRowString(aDataRow(), aCompInd()) As String
  166.     Dim l As Long, u As Long
  167.     l = lBound(aCompInd)
  168.     u = uBound(aCompInd)
  169.     If (l = u) Then ' Shortcut for performance
  170.         GetRowString = aDataRow(aCompInd(l))
  171.     Else
  172.         Dim NewArr(l To u), i As Long
  173.         For i = l To u
  174.             NewArr(i) = aDataRow(aCompInd(i))
  175.         Next i
  176.         GetRowString = Join(NewArr, Chr(1))
  177.     End If
  178. End Function
  179.  
  180. ' Returns 1 if successful, 0 otherwise
  181. Function doRemove() As Long
  182.  
  183.     Dim StartTime As Date
  184.     StartTime = Now()
  185.  
  186.     Dim bResult As Boolean, bModified As Boolean
  187.     bResult = False
  188.     bModified = False
  189.  
  190.     Dim oUndoManager As Object
  191.  
  192.     oDoc.lockControllers()
  193.     oDoc.addActionLock()
  194.     oUndoManager = ThisComponent.getUndoManager()
  195.     oUndoManager.enterUndoContext("Remove Duplicates")
  196. '   On Error GoTo cleanup
  197.  
  198.     Dim oSel As Object, oAddress As Object, aDataArray(), selectedLst(), bHasTitle As Boolean
  199.     oSel = oDoc.getCurrentSelection()
  200.     oAddress = oSel.getRangeAddress()
  201.     aDataArray = oSel.getDataArray()
  202.  
  203.     selectedLst = oDialog1.GetControl("lbList").getSelectedItemsPos()
  204.     bHasTitle = oDialog1.GetControl("cbTitle").getState() > 0
  205.  
  206.     Dim FirstRow As Long, LastRow As Long
  207.     FirstRow = lBound(aDataArray)
  208.     If bHasTitle Then
  209.         FirstRow = FirstRow + 1
  210.     End If
  211.     LastRow = uBound(aDataArray)
  212.  
  213.     Dim ProgressBar As Object
  214.     ProgressBar = oDialog1.GetControl("ProgressBar1")
  215.     ResetProgress(ProgressBar, FirstRow, LastRow)
  216.  
  217.     Dim UniqueColl As New Collection, nDone As Long, Pos As Long
  218.     nDone = FirstRow - 1
  219.     For Pos = FirstRow To LastRow
  220.         If (Not CheckDup(GetRowString(aDataArray(Pos), selectedLst), UniqueColl)) Then ' Unique
  221.             nDone = nDone + 1
  222.             If (nDone < Pos) Then aDataArray(nDone) = aDataArray(Pos)
  223.         End If
  224.  
  225.         If ((Pos > 1) And (Pos Mod 100 = 0)) Then
  226.             ' Check if cancelled
  227.             If (Not bInProgress) Then Err = 18 ' Interrupted by user
  228.             StepProgress(ProgressBar, 100)
  229.         End If
  230.     Next Pos
  231.  
  232.     If (nDone < LastRow) Then
  233.         Dim nTop As Long, Bottom As Long
  234.         nTop = FirstRow - lBound(aDataArray)
  235.         nBottom = nDone - lBound(aDataArray)
  236.         ReDim Preserve aDataArray(FirstRow To nDone)
  237.         Dim oUniqueRange As Object
  238.         oUniqueRange =  oSel.getCellRangeByPosition(0, _
  239.                                                     nTop, _
  240.                                                     uBound(aDataArray(nDone)) - lBound(aDataArray(nDone)), _
  241.                                                     nBottom)
  242.         oUniqueRange.setDataArray(aDataArray)
  243.         RemoveCells(oSel.Spreadsheet, _
  244.                     oAddress.StartColumn, _
  245.                     oAddress.StartRow + nDone + 1, _
  246.                     oAddress.EndColumn, _
  247.                     oAddress.StartRow + LastRow)
  248.     End If
  249.  
  250.     ' Make sure to set it to 100% before reporting success: it could not account yet for the last <100 elements
  251.     SetProgress(ProgressBar, LastRow)
  252.  
  253.     bResult = True
  254.  
  255. cleanup:
  256.     On Error Resume Next
  257.     oUndoManager.leaveUndoContext()
  258.     oDoc.removeActionLock()
  259.     oDoc.unLockControllers()
  260.     On Error GoTo 0
  261.  
  262.     Dim TotalCount As Long, DuplicatesCount As Long, Message As String
  263.     Message = "Finished in " & Format((Now()-StartTime), "[s]") & " seconds." & Chr$(13)
  264.     If (bResult) Then
  265.         doRemove = 1
  266.         TotalCount = LastRow - FirstRow + 1
  267.         DuplicatesCount = LastRow - nDone
  268.         If (DuplicatesCount > 0) Then
  269.             Message = Message & "We found and deleted " & DuplicatesCount & " duplicated values." & Chr$(13) & _
  270.                                 "Now we have only " & TotalCount - DuplicatesCount & " unique vaues."
  271.         Else
  272.             Message = Message & "No duplicates found."
  273.         End If
  274.     Else
  275.         doRemove = 0
  276.         If (Err = 18) Then
  277.             Message = Message & "Cancelled. "
  278.         Else
  279.             Message = Message & "An error occured! "
  280.         End If
  281.         If (bModified) Then
  282.             Message = Message & "The changes will now be undone."
  283.         Else
  284.             Message = Message & "No changes have been made."
  285.         End If
  286.     End If
  287.     MsgBox Message
  288.     If (Not bResult And bModified) Then oUndoManager.Undo()
  289. End Function
  290.  
  291. Sub ResetProgress(ByRef ProgressBar, nMinVal As Long, nMaxVal As Long)
  292.     With ProgressBar
  293.         .setRange(nMinVal, nMaxVal)
  294.         .setValue(nMinVal)
  295.     End With
  296. End Sub
  297.  
  298. Sub SetProgress(ByRef ProgressBar, nVal As Long)
  299.     ProgressBar.setValue(nVal)
  300. End Sub
  301.  
  302. Sub StepProgress(ByRef ProgressBar, nStep As Long)
  303.     With ProgressBar
  304.         .setValue(.getValue() + nStep)
  305.     End With
  306. End Sub
  307.  
  308. Sub btnCancelClick
  309.     If (bInProgress) Then
  310.         oDialog1.GetControl("btnCancel").Enable = False ' Prevent second Cancel
  311.         bInProgress = False
  312.     Else
  313.         oDialog1.endExecute()
  314.     End If
  315. End Sub
  316.  
  317. Sub btnOKClick
  318.     bInProgress = True
  319.     ' Only Cancel button is enabled in the process
  320.     oDialog1.GetControl("btnSelectAll").Enable = False
  321.     oDialog1.GetControl("cbTitle").Enable = False
  322.     oDialog1.GetControl("btnOK").Enable = False
  323.     oDialog1.GetControl("lbList").Enable = False
  324.     oDialog1.endDialog(DoRemove())
  325. End Sub
  326.  
  327. Sub btnSelectAllClick
  328.     Dim lbList, count As Long, i As Long
  329.     lbList = oDialog1.GetControl("lbList")
  330.     count = lbList.getItemCount()
  331.     Dim SelectItems(count) As Integer
  332.     For i = 0 To count - 1
  333.         SelectItems(i) = i
  334.     Next i
  335.     lbList.selectItemsPos(SelectItems, true)
  336. End Sub
  337.  
  338. Sub cbIncludeTitle
  339.     UpdateListBoxItems(oDialog1.GetControl("cbTitle").getState() > 0)
  340. End Sub
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement