文字列の抽出と計算 3.VBA:半角スペースの利用 ⑥

はじめに

前回は、数値かどうかを判別してから足し算する仕組みを追加しました。
infoment.hatenablog.com

今回も、前回の内容を改良してみましょう。

今回のテーマ

前回と同じテーマです。
一つのセルに、3桁の数字が3つあります。これらは、半角スペースで区切られています。この数字について、真ん中のグループの和を求めてみましょう。
f:id:Infoment:20180619063141p:plain


文字列の分割と区切り文字の置き換え

Aさんは半角スペースで区切っているのに、Bさんは「_」で区切っていて、これらのデータが混在している。そんな場合は、どうすればよいでしょうか。

f:id:Infoment:20180627064437p:plain

シート上で「_」を「 」に置き換えてからマクロを実行すればよいのですが、毎回そのような手間を掛けたくない方には、以下の方法を紹介します。

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関数は、一つの文字列について置換した結果を返すものです。
違いを理解したうえで、使い分けましょう。

f:id:Infoment:20180627072040p:plain

おわりに

今回の方法に対する評価(私見)は、以下の通りです。

メリット :

  • 「_」で区切られていても、正しく処理することができる。

デメリット:

  • 「 」や「_」以外で区切られていた場合は、正しい結果にならない。

入力のルールが曖昧だったり、正しくルールが守られないと、「例外」データが多数発生します(私も、あまり偉そうなことは言えません)。これらは、マクロ処理の天敵です。置換などでデータを正しくすることも可能ですが、本来は「ルールを守らせる」ことに注力すべきかと思います(とてもとても難しいですが)。

(おわり)