和風スパゲティのレシピ

日本語でコーディングするExcelVBA

Nothingを受け取るUnionメソッドを作る

複数のRangeオブジェクトをまとめるにはUnionメソッドを利用します。

例えば「特定の条件を満たす行を削除」する際、
以下のコードで「Unionでまとめてから一括削除」することができます。

Dim rows削除行 As Range
Dim R As Long
For R = 2 To 最終行
    
    If ws処理シート.Cells(R, 1) = "○○" Then
        If rows削除行 Is Nothing Then
            Set rows削除行 = ws処理シート.Rows(R)
        Else
            Set rows削除行 = Union(rows削除行, ws処理シート.Rows(R))
        End If
    End If
    
Next

If Not rows削除行 Is Nothing Then
    rows削除行.Delete
End If

 
さてこのコードを書く際、面倒なのが、

If rows削除行 Is Nothing Then
    Set rows削除行 = ws処理シート.Rows(R)
Else
    Set rows削除行 = Union(rows削除行, ws処理シート.Rows(R))
End If

この部分です。

これ、

Set rows削除行 = Union(rows削除行, ws処理シート.Rows(R))

こう書くだけで動いてよ!
って思いますよね。


Nothing+Range("A1") = Range("A1") でいいじゃん!

と思うのですが、UnionメソッドはNothingを受け取らないため、
このIfステートメントがないと初回実行時に必ずエラーになります。


Unionって和集合(A ⋃ B)のことで、この記号「⋃」もUnionの頭文字なのに、
和集合の定理(A ⋃ ∅ = A)を満たさないのはいかがなものなのか。


ということで、いちいちUnionを分岐しなくていいように、
改良型Union関数を作ってしまいましょう。

それがこちら

' Union改
Function Union改(Arg1 As Range, Arg2 As Range) As Range
    If Arg1 Is Nothing Then
        Set Union改 = Arg2
    ElseIf Arg2 Is Nothing Then
        Set Union改 = Arg1
    Else
        Set Union改 = Union(Arg1, Arg2)
    End If
End Function
' 先ほどのコードがこちらに
Dim rows削除行 As Range
Dim R As Long
For R = 2 To 最終行
    
    If ws処理シート.Cells(R, 1) = "○○" Then
        Set rows削除行 = Union改(rows削除行, ws処理シート.Rows(R))
    End If
    
Next

If Not rows削除行 Is Nothing Then
    rows削除行.Delete
End If

メインコードが劇的にスッキリしましたね!

Ifひとつ減らすだけでもコードが4行も減りますし、
For内のインデントが減るだけでもだいぶ見違えるのが分かります。


この関数を持っておくと、Rangeオブジェクトの結合がとても楽になります。
Unionメソッドをよく使う人は、この機会に作ってみてください。


こんな風に、簡単だけどコード量が微妙に多いコードや、
メインロジックと全く関係のないコードは、汎用関数にしてしまいましょう。

作るのが簡単な割に効果は絶大で、
コードが書きやすく&読みやすくなります。


汎用関数に関する詳しい記事はこちらをどうぞ
www.limecode.jp