文字列の抽出と計算 3.VBA:半角スペースの利用 ⑥
今回のテーマ
前回と同じテーマです。
一つのセルに、3桁の数字が3つあります。これらは、半角スペースで区切られています。この数字について、真ん中のグループの和を求めてみましょう。
文字列の分割と区切り文字の置き換え
Aさんは半角スペースで区切っているのに、Bさんは「_」で区切っていて、これらのデータが混在している。そんな場合は、どうすればよいでしょうか。
シート上で「_」を「 」に置き換えてからマクロを実行すればよいのですが、毎回そのような手間を掛けたくない方には、以下の方法を紹介します。
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 Cells(i, 1).Replace What:="_", Replacement:=" ", LookAt:=xlPart For j = 1 To 3 ' エラーを無視する On Error Resume Next splitResult(i, j) = Split(Cells(i, 1))(j - 1) Next j If IsNumeric(splitResult(i, 2)) = True Then Cells(iMax + 1, 2) = Cells(iMax + 1, 2) + splitResult(i, 2) End If Next End Sub
修正したのは、この個所です。
Cells(i, 1).Replace What:="_", Replacement:=" ", LookAt:=xlPart
今回は、Replaceメソッドを使用しています。
"_"を置換します(What:="_")
" "に置換します(Replacement:=" ")
部分一致で置換します(LookAt:=xlPart)
といった具合です。なお、「部分一致」などの部分を省略した場合、直前の検索条件が適用されます。従って、重要なパラメーターは必ず指定しないと、意図した結果にならない恐れがあります。
シート上の元データを書き換えるのは困る、という場合は、一旦変数に入れて処理しましょう。
Sub myCalc() Dim i As Long Dim j As Long Dim iMax As Long Dim str As String 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 str = Replace(Cells(i, 1), "_", " ") For j = 1 To 3 ' エラーを無視する On Error Resume Next splitResult(i, j) = Split(str)(j - 1) Next j If IsNumeric(splitResult(i, 2)) = True Then Cells(iMax + 1, 2) = Cells(iMax + 1, 2) + splitResult(i, 2) End If Next End Sub
変数「str」に、Replace関数で置換した結果を代入して使用しています。
Replaceメソッドが、複数の範囲を一度に処理するのに対し、
Replace関数は、一つの文字列について置換した結果を返すものです。
違いを理解したうえで、使い分けましょう。
おわりに
今回の方法に対する評価(私見)は、以下の通りです。
メリット :
- 「_」で区切られていても、正しく処理することができる。
デメリット:
- 「 」や「_」以外で区切られていた場合は、正しい結果にならない。
入力のルールが曖昧だったり、正しくルールが守られないと、「例外」データが多数発生します(私も、あまり偉そうなことは言えません)。これらは、マクロ処理の天敵です。置換などでデータを正しくすることも可能ですが、本来は「ルールを守らせる」ことに注力すべきかと思います(とてもとても難しいですが)。
(おわり)