2016-10-26 13 views
1

ADDRESS列とDATA列のLibreOfficeの多くのシートにはかなりのデータがありますが、それぞれのアドレスが発生した回数をカウントしたい場合は、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機能を使用しますが、私はマクロが長期的に時間を節約することを発見しました。

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... 

だから私の最初の質問がされています:ここで私は、以前の機能が既にRowCounterに格納されたデータの長さ(行数)を、決定したことを考えると、これまで持っているものの抜粋ですどのように我々は判断することができます要素(現在のセルのアドレス)が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

関連する問題