11.4 合計や平均を求める場合
この事例は、処理効率の向上に加えて最適な手段を使うとマクロの見栄えが良くなりますよっ!という事例です。

7.2 データがある最終行を知る方法のネタと7.4 ワークシートの関数を使う方法の合わせ技です。ある範囲の合計や平均を求めたいとき、範囲内のセルを1つずつコツコツ取得し集計する方法と、Worksheetfunctionの機能を使いサクっと求める方法がありますが、どう考えても後者の方が効率が良いですよ!
事例/ある列のデータの先頭から最終行までの合計を求める
わりと良くあるか分からないパターンです(笑)。どっかからもってきたCSVファイル(※)をエクセルマクロを使って編集したりDBへ登録する場合に、諸般の(?)事情からある列に入っている金額について知る必要があったとします。合計する範囲はデータの先頭から最後までです。

最初に地道に計算する探す例ですが、次の例ではA列のセルを2行目から1つずつチェックする処理を未入力のセルが見つかるまで延々行いますが、その間にL列の金額を取得し合計を求めています。やってることは単純なのに、パっと見は面倒なことをしてそうですね(笑)

ちなみに、CSVファイルは必ず先頭行が見出し、データは2行目以降、データがある行はA列は必ず何か入っている、見出し行のみもありえる(明細が0件)とし、サンプルコードでは金額の合計をメッセージボックスで表示しているだけです。

こういうCSVファイルだったとします。ダウンロードしてテストデータにお使い下さい。

Sub prcTotalCount1()

    '良くない例

    Dim lngLine As Long
    Dim lngTotal As Long

    lngLine = 1
    lngTotal = 0

    Do Until False

       '行が底に達したらループを終了します
       If lngLine = 65536 Then
         Exit Do
       End If

       '未入力のセルが見つかったときもループを終了します
       '判定の対象は、現在の行+1のセルです
       If (Range("A" & lngLine + 1)) = 0 Then
         Exit Do
       End If

       '次の行を検索するための行数カウント
       lngLine = lngLine + 1

       'L列の金額を取得しカウント
       lngTotal = lngTotal + CDbl(Range("L" & lngLine))

    Loop

    MsgBox "L列の合計は " & lngTotal & "円です"

End Sub
 ※このエクセルマクロはワークシート内へ記述するマクロです


次に、???.End(xlDown).RowWorksheetfunctionを使った例です。やりたいことと結果は同じですが、マクロはまったく別物だし、何よりこっちの方がイイことは言うまでもありません。データが多ければ多いほど、処理速度の差がハッキリ出ます。

もし、平均を求めたいときはWorksheetfunction.Averageを使えば一発で出ます。

Sub prcTotalCount2()

    '推奨例

    Dim lngLine As Long
    Dim lngTotal As Long

    lngTotal = 0

    'セルA2がカラであれば見出しのみなので合計は0円
    'セルA2がカラでなければ合計を算出
    If Len(Range("A2")) > 0 Then
    'セルA2に何か入っていれば底の行番号を取得
       lngLine = Range("A1").End(xlDown).Row
       lngTotal = Worksheetfunction.Sum( _
                      Range("L2:L" & lngLine) _
                      )
    End If

    MsgBox "L列の合計は " & lngTotal & "円です"

End Sub
 ※このエクセルマクロはワークシート内へ記述するマクロです
Copyright(C) 1999-2006 結城圭介。 All rights reserved