文字列の抽出と計算 3.VBA:半角スペースの利用 ④
今回のテーマ
前回と同じテーマです。
一つのセルに、3桁の数字が3つあります。これらは、半角スペースで区切られています。この数字について、真ん中のグループの和を求めてみましょう。
文字列の分割と最終行の取得
不幸にして、データの中に空白行がある場合、今までの方法では全て、最終行番号を正しく取得することができません。
↓前回のコード↓
Sub myCalc() Dim i As Long Dim j As Long Dim iMax As Long Dim splitResult() As Variant iMax = Cells(2, 1).End(xlDown).Row - 1 Cells(iMax + 1, 2) = 0 ' 二次配列を再宣言 ReDim splitResult(2 To iMax, 1 To 3) For i = 2 To iMax For j = 1 To 3 splitResult(i, j) = Split(Cells(i, 1))(j - 1) Next j Cells(iMax + 1, 2) = Cells(iMax + 1, 2) + splitResult(i, 2) Next End Sub
なぜなら「End(xlDown)」が「連続するデータの一番下」を指しているからです。
例↓)4行目に空白がある場合。
従って上記のマクロを実行すると、このように、正しくない結果になります。
そこで、次のようにコードを修正します。
Sub myCalc() Dim i As Long Dim j As Long Dim iMax As Long Dim splitResult() As Variant ' 最終行番号の取得 iMax = Cells(Rows.Count, 1).End(xlUp).Row - 1 Cells(iMax + 1, 2) = 0 ' 二次配列を再宣言 ReDim splitResult(2 To iMax, 1 To 3) For i = 2 To iMax For j = 1 To 3 splitResult(i, j) = Split(Cells(i, 1))(j - 1) Next j Cells(iMax + 1, 2) = Cells(iMax + 1, 2) + splitResult(i, 2) Next End Sub
修正したのは、この個所です。
' 最終行番号の取得 iMax = Cells(Rows.Count, 1).End(xlUp).Row - 1
Rows.Count はExcel シートの全行数です。Excel2013 であれば、1048576行あります。従って、修正箇所はこのように置き換えることができます。
' 最終行番号の取得 iMax = Cells(Rows.Count, 1).End(xlUp).Row - 1 ' ↓ iMax = Range("A1048576").End(xlUp).Row - 1
End(xlup) は、End(xldown) の逆です。空白行を全て飛び越し、何かが入力されている最初のセルまで一気にジャンプします。今回の場合でいえば、それは A6 です。従って修正箇所は、さらにこのように置き換えることができます。
' 最終行番号の取得 iMax = Range("A1048576").End(xlUp).Row - 1 ' ↓ iMax = Range("A6").Row - 1 ' ↓ iMax = 6 - 1 ' ↓ iMax = 5
これなら下から探しに行くため、途中に空白行があっても、正しく最終行番号を取得することができます。
ただしこのままでは、マクロはエラーになります。
「デバッグ」ボタンを押すと、エラー箇所がハイライト表示されています。
何もない、空っぽのセルの中身を半角スペースで区切らせようとしたため、このようなエラーが発生しました。
対処方法は幾つかありますが、一番簡単なのは、エラーを無視するという方法です。
Sub myCalc() Dim i As Long Dim j As Long Dim iMax As Long Dim splitResult() As Variant ' 最終行番号の取得 iMax = Cells(Rows.Count, 1).End(xlUp).Row - 1 Cells(iMax + 1, 2) = 0 ' 二次配列を再宣言 ReDim splitResult(2 To iMax, 1 To 3) For i = 2 To iMax For j = 1 To 3 ' エラーがあっても無視して処理を続ける On Error Resume Next splitResult(i, j) = Split(Cells(i, 1))(j - 1) Next j Cells(iMax + 1, 2) = Cells(iMax + 1, 2) + splitResult(i, 2) Next End Sub
追加したのは、次の一文です。
On Error Resume Next
結果は、↓のとおりです。
おわりに
今回の方法に対する評価(私見)は、以下の通りです。
メリット :
- 途中に空白行があっても、正しい結果が得られる。
デメリット:
- エラーを無視させているので、何が悪かったか分からない。
この方法では、次の判別がつきません。
- 書き忘れで空白になったのか
- 意図して空白になっているのか
これらを無視して強引に結果を出しているので、「大事故」につながる恐れがあり、注意が必要です。
(おわり)