Excel VBAに手を出してみる-その2

前回の続き。

まず、ExcelVBAではセルの列表示がA, B, C, ….ではなくて数字表示の方が良気がしたため表示設定を変更した。Excelのオプションから数式>R1C1参照形式を使用するのチェックを外せば良い。

指定の列に対して、(i+1行目の値)-(i行目の値)を計算し、セルに出力する(30行分)

ここでは同じ計算を行数分繰り返すことなので、For文的なものが登場するはず。ここでもここでやりたいことそのものが同じ計算を行数分繰り返す(For~Next)で紹介されていた。

コード

For文のカウンタ変数をcountと置いて繰り返し処理する。取り敢えず30行分実行してC列に結果を表示する。

Sub Hazimete_Sono2()
    Dim count As Long
    For count = 2 To 30
        Cells(count, 3).Value = Cells(count + 1, 1).Value - Cells(count, 1).Value
    Next count
End Sub
結果

値の無いセルは0として認識されているようだ。

説明

新しいことはFor文だけ。ただこのFor文、Cのように増分処理は書けないらしい。そのためかSTEPとかいうカウンタ変数の増分値を設定できる項目がある。

For 変数 = 初期値 To 終了値 Step 加算値
    繰り返したい処理
Next 変数

上記処理の結果を別シートに出力する

今回は数値を適当に置いているが、実際には1つのシートに1000×1000程度のデータを置いて処理させる。そのためデータ入力用シートと出力用シートで分けることを想定しており、必要となる処理。

コード
Sub Hazimete_Sono2()
    Dim count As Long
    For count = 2 To 30
        Worksheets("result").Cells(count, 3).Value = Worksheets("data").Cells(count + 1, 1).Value - Worksheets("data").Cells(count, 1).Value
    Next
End Sub
説明

入力用データをdataシート、結果出力用シートをresultシートと名前変更した。このとき、処理の右辺(代入側)のCellsにWorksheetsを付けなかった場合、アクティブセルがdataシートにあってもresultシートの値を拾って計算してしまっていた。シートをまたぐ処理を記述するなら明記しておかないといけないようだ。調べているとWorksheetsという書き方と単にSheetsという書き方があって困ったけど、違いについてはSheetsとWorksheetsって何が違うの?で説明されていた。

上記処理を30行目までではなく、列に入っている値の数だけ計算を実行する

ここまでやったことを組合せてみる。行数を取得してそれをFor文のカウンタ変数に入れてあげれば良い。ただ今回は数値は上から2行目から始まることが保証されていることにする。

コード
Sub Hazimete_Sono3()
    Dim count As Long
    Dim LastRow As Long

    'A列の最終行取得
    LastRow = Worksheets("data").Cells(Rows.count, 1).End(xlUp).Row
    MsgBox "最終行は" & LastRow & "です"
    Worksheets("result").Range("C1").Value = LastRow

    'A列のデータに対して演算
    For count = 3 To LastRow
        Worksheets("result").Cells(count, 3).Value = Worksheets("data").Cells(count + 1, 1).Value - Worksheets("data").Cells(count, 1).Value
    Next count
End Sub
結果

前のようにデータのない箇所も計算してしまい0とかになっていない。

説明

今回、行数をresultシートのC1セルに代入している。これまでCellsを使用していたが、RangeでC1代入としてみた。こっちの方が感覚的に分かりやすいが、繰り返し処理など実行する場合は使えないため普通はCellsを使用するらしい。

列方向にも同じことを繰り返す

カウンタ変数をもう1つ作ってFor文をネストすれば良さそう。dataシートに適当な数値をC列まで入れてみた。

コード

単純にネストしただけ。あとこれまでFor文のNextの後ろにカウンタ変数は書いていなかったけど、書いたほうが良いようだ。書き終えて思ったが、列によって行数が違う場合に対応できない。そのような状況にはならないし、別に難しいコードでも無いため現時点では割り切る。

Sub Hazimete_Sono3()
    Dim LastRow As Long
    Dim LastColumn As Long
    Dim RowCounter As Long
    Dim ColumnCounter As Long

    'A列の最終行取得
    LastRow = Worksheets("data").Cells(Rows.count, 1).End(xlUp).Row
    MsgBox "最終行は" & LastRow & "です"
    Worksheets("result").Range("C1").Value = LastRow

    '2行目の最終列取得
    LastColumn = Worksheets("data").Cells(2, Columns.count).End(xlToLeft).Column
    MsgBox "最終列は" & LastColumn & "です"
    Worksheets("result").Range("C2").Value = LastColumn

    '各列に対して演算
    For ColumnCounter = 1 To LastColumn
        For RowCounter = 3 To LastRow
            Worksheets("result").Cells(RowCounter, ColumnCounter + 1).Value = Worksheets("data").Cells(RowCounter + 1, ColumnCounter).Value - Worksheets("data").Cells(RowCounter, ColumnCounter).Value
        Next RowCounter
    Next ColumnCounter
End Sub
説明

行数取得のときと同じように、右側の最終列から取得する。最終列は「Columns.Count」で取得可能で、ワークシートの最終列はExcel 2003までなら256列で、Excel 2007以降なら16384らしい。