[LibreOffice/OpenOffice Basic] 実用例 (1) 飛び飛びのセルのデータを抜き出す (間引きする)

本ページは「Excel で学ぶ Visual Basic for Applications (VBA)」内のページ
実用例 (1) 飛び飛びのセルのデータを抜き出す (間引きする)」を LibreOffice/OpenOffice Basic に対応させたものである。

これまで、LibreOffice/OpenOffice Basic の基礎を学んで来た。

ここからは、LibreOffice/OpenOffice Basic を実用的に活用する例をいくつか紹介する。
本ページでは「飛び飛びのセルのデータを抜き出す (間引きする)」ことを扱う。

例えば、「1列のデータの偶数番目のデータのみを別の列に詰めてコピーする」など である。

シンプルな実装例

今、下図のようなデータがシートに存在するとしよう。



このデータのうち、偶数行だけを取り出して別の列 (例えば B 列) にコピーしたいとする。
そのような操作はデータ数を減らす目的でしばしば行われる。

それを最もシンプルな方法で実現したのが以下の LibreOffice/OpenOffice Basic プログラムである。
(このプログラムの実行方法は「第一回:プログラムを書き始めるまでの準備」参照)

Sub appli01_01()

Dim n As Long, i As Long

    n = 30

    ThisComponent.addActionLock()
    For i = 0 To n - 1
        If (i + 1) Mod 2 = 0 Then
            ThisComponent.Sheets(0).getCellByPosition(1, i \ 2).Value = _
                ThisComponent.Sheets(0).getCellByPosition(0, i).Value
        End If
    Next i
    ThisComponent.removeActionLock()
End Sub


実行すると、以下のように 1 列目のデータの偶数番目の行が 2 列目に詰めてコピーされる。




他人が変更しやすいよう改造

実用上は上のマクロで十分であろうが、「データ数を 30 に決め打ちしている」、
「プログラムを良く理解していないと、『3行置きのコピーに変更』などに対応できない」 などの問題がある。

そこで、中身を理解していなくても変更が可能なように改造したのが以下のプログラムである。
from_row、to_row、skip_col、initial_col の4 つの変数の初期値を変更するだけで 動作を変更できる。

データ数を自動取得し、計算時間を減らすために For 文の Step 指定で必要な行を拾う方式にしている。

変数に負の数が代入されたときの警告などは行っていないので、 各自で実装してみると良いだろう。


Sub appli01_02()

Dim n As Long, i As Long

Dim from_col As Long, to_col As Long
Dim skip_row As Long, initial_row As Long

Dim max_row As Long

' #### 以下の4つの数字を変更してください。

    from_col = 1     ' 1列目から (A列)
    to_col = 2       ' 2列目に   (B列)

    skip_row = 2     ' 何行おきにデータを取るか
    initial_row = 1  ' 最初のデータは何行目とするか

' #### 以下実装。変更不要。

    Dim sheet As Object, rang As Object, cur As Object
    sheet = ThisComponent.Sheets(0)
    rang = sheet.getCellRangeByName("A1")
    cur = sheet.createCursorByRange(rang)
    cur.gotoEndOfUsedArea(True)
    max_row = cur.Rows.Count

    n=0
    For i = max_row - 1 To 0 Step -1
        If ThisComponent.Sheets(0).getCellByPosition(from_col - 1, i).getType() <> _
                com.sun.star.table.CellContentType.EMPTY Then
            Exit For
        End If
        n = n + 1
    Next i

    n = max_row - n

    ThisComponent.addActionLock()
    For i = initial_row To n Step skip_row
        If ThisComponent.Sheets(0).getCellByPosition(from_col - 1, i - 1).getType() <> _
            com.sun.star.table.CellContentType.EMPTY Then
            ThisComponent.Sheets(0).getCellByPosition(to_col - 1, (i - initial_row) \ skip_row).Value = _
                ThisComponent.Sheets(0).getCellByPosition(from_col - 1, i - 1).Value
        End If
    Next i
    ThisComponent.removeActionLock()
End Sub




←[LibreOffice/OpenOffice Basic] 微分方程式の数値的解法 (3) 汎用性を高める[LibreOffice/OpenOffice Basic] 実用例 (2) グラフを自動的に描く→

Excel で学ぶ Visual Basic for Applications (VBA)に戻る