2016-10-26 2 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과 같은 사전 형식 개체는 긴 배열을 반복하지 않고 직접 키를 찾기 때문에 항목을 찾는 데 효율적입니다. 아래의 Google 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 

이 코드에는 다음 도우미 기능이 필요합니다. 대부분의 언어에서 사전 객체에는이 기능이 내장되어 있지만 Basic은 다소 단순합니다.

' 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

완벽한 감사합니다! 아마도 OpenOffice와 LibreOffice 문서 대신에 BASIC에 대한 더 나은 조사가 미래에 더 유익 할 것입니다. – calcium3000

관련 문제