2016-10-26 93 views
1

我在LibreOffice的許多工作表中都有很多數據 - ADDRESS列和DATA列 - 我想要統計每個地址出現的次數,並將其存入NUM_ADDR列。例如: -如何統計OpenOffice/LibreOffice BASIC中的重複條目?

ADDR    | DATA    | NUM_ADDR 
00000000bbfe22d0 | 876d4eb163886d4e | 1 
00000000b9dfffd0 | 4661bada6d4661ba | 1 
00000000b9dfc3d0 | 5d4b40b4705d4b40 | 1 
00000000b9def7d0 | 8f8570a5808f8570 | 1 
00000000b9de17d0 | 63876d4eb163886d | 1 
00000000b9dddfd0 | 6d4eb163886d4eb1 | 3 
00000000b9dddfd0 | 705d4b40b4705d4b | 
00000000b9dddfd0 | b4705d4b40b4705d | 
00000000b7df83d0 | 40b4705d4b40b470 | 1 
00000000b7d607d0 | 705d4b40b4705d4b | 1 
... 

在做的事情我手動使用上的每個地址的COUNTIF功能,但我發現,宏會節省時間,從長遠來看。下面是我到目前爲止,因爲以前的功能已確定的數據的長度(行數),存儲在RowCounter一個片段:

Dim CountedAddr(RowCounter, RowCounter) as String 
Dim CountedAddrPtr as Integer 
Dim CurrentCell as Object 
Dim i as Integer 

CountedAddrPtr = 0 

' Populate CountedAddr array 
For i = 1 to RowCounter-1 
    CurrentCell = CurrentSheet.getCellByPosition(0, i) 
    If Not CurrentCell.String In CountedAddr(?) Then 
    CurrentSheet.getCellByPosition(2, i).Value = 1 ' for debugging 
    CountedAddr(CountedAddrPtr, 0) = CurrentCell.String 
    CountedAddrPtr = CountedAddrPtr + 1 
    Else 
    CurrentSheet.getCellByPosition(2, i).Value = 0 ' for debugging 
    EndIf 
Next 

' For each unique address, count number of occurances 
For i = 0 to UBound(CountedAddr()) 
    For j = 1 to RowCounter-1 
    If CurrentSheet.getCellByPosition(0, j).String = CountedAddr(i, 0) Then 
     CountedAddr(i, 1) = CountedAddr(i, 1)+1 
    EndIf 
    Next 
Next 

' Another function to populate NUM_ADDR from CountedAddr array... 

所以我的第一個問題是:我們如何才能確定如果元素(當前單元格中的地址)在CountedAddr數組中(請參閱上面的(?))?其次,是否有更高效的方式來實現第二塊代碼?遺憾的是,排序不存在問題,因爲地址和數據的年代表形成了時間基礎。第三,整個社會是一個愚蠢的方式來解決這個問題嗎?

非常感謝軟件工作的硬件配合!

回答

0

諸如VB6 Collection之類的字典型對象對於查找項目非常有效,因爲它直接查找關鍵字,而不是循環遍歷長數組。我們的countedAddrs集合將存儲每個地址的計數。

Sub CountAddrs 
    Dim countedAddrs As New Collection 
    Dim oCurrentSheet As Object 
    Dim oCurrentCell As Object 
    Dim currentAddr As String 
    Dim i As Integer 
    Dim newCount As Integer 
    Dim rowCounter As Integer 
    Const ADDR_COL = 0 
    Const COUNT_COL = 2 

    oCurrentSheet = ThisComponent.CurrentController.ActiveSheet 
    rowCounter = 11 
    ' Populate countedAddrs array. 
    For i = 1 to rowCounter - 1 
     oCurrentCell = oCurrentSheet.getCellByPosition(ADDR_COL, i) 
     currentAddr = oCurrentCell.String 
     If Contains(countedAddrs, currentAddr) Then 
     ' Increment the count. 
     newCount = countedAddrs.Item(currentAddr) + 1 
     countedAddrs.Remove(currentAddr) 
     countedAddrs.Add(newCount, currentAddr) 
     oCurrentSheet.getCellByPosition(COUNT_COL, i).Value = newCount ' for debugging 
     Else 
     countedAddrs.Add(1, currentAddr) 
     oCurrentSheet.getCellByPosition(COUNT_COL, i).Value = 1 ' for debugging 
     EndIf 
    Next 
End Sub 

此代碼需要以下幫助函數。在大多數語言中,字典對象具有內置的這種功能,但基本相當簡單。

' Returns True if the collection contains the key, otherwise False. 
Function Contains(coll As Collection, key As Variant) 
    On Error Goto ErrorHandler 
    coll.Item(key) 
    Contains = True 
    Exit Function 
ErrorHandler: 
    Contains = False 
End Function 
+0

完美,謝謝!對BASIC(而不僅僅是OpenOffice和LibreOffice文檔)進行更好的調查可能會在未來取得更大的成果。 – calcium3000