条件に一致した複数のセルを選択する(RangeプロパティとUnionメソッド)|Excel VBA |
ワークシートから、条件に一致するすべてのセルを選択する方法をご紹介します。
非連続のセルを選択するには、次のようにセルのアドレスをカンマで区切って指定します。
Range("A1,B3").Select
次のサンプル1は、条件に一致したセルのアドレスを変数Targetにカンマ区切りで次々と連結し、最後にそれらのセルを選択します。
Sub Sample1()
Dim c As Range, Target As String
For Each c In Selection
If c.Value > 50 Then
Target = Target & c.Address & ","
End If
Next c
If Right(Target, 1) = "," Then Target = Left(Target, Len(Target) - 1)
If Target <> "" Then Range(Target).Select
End Sub
このコードは、考え方として間違っていませんが、正常に動く場合と、エラーになる場合があります。それは、変数Targetの文字数が255を超えたときです。
セルを選択するRangeプロパティは、Range("A1")のようにセルのアドレス(またはセルに設定した名前)を文字列形式で指定します。このとき、指定できる文字列の長さは255文字までです。
この制限はあまり知られていないし、表示されるエラーメッセージにもそうした制限について書かれていないので、エラーの原因がわからずに悩むユーザーが多いです。
さらに、このエラーはアドレスを示す文字列の長さによるので、マクロを実行する環境によってエラーが発生したりしなかったりと原因と特定するのがやっかいなエラーなのです。
さて、255文字を超えるアドレスは指定できないのですから、何か別の手を使わなければなりません。こんなときは、複数セル範囲の集合を返すUnionメソッドを使います。
まず、Unionメソッドの動作を確認しましょう。次のコードは、セルA1とセルB3を選択します。
Union(Range("A1"), Range("B3")).Select
このUnionメソッドを使って、For...Each内で条件に一致したセル(制御変数c)を次々と合体させてやればいいわけです。
Sub Sample2()
Dim c As Range, Target As Range
For Each c In Selection
If c.Value > 50 Then
If Target Is Nothing Then '---(1)
Set Target = c
Else
Set Target = Union(Target, c) '---(2)
End If
End If
Next c
If Not Target Is Nothing Then Target.Select '---(3)
End Sub
条件に一致したセルは、Rangeオブジェクト型の変数Targetに格納します。すでに見つかったセルに、新しいセルを追加するのは(2)です。ただし、これだと1件目に見つかったセルでエラーになります。1件目の処理では、変数Targetに、まだ何も格納されていないからです。
そこで、(1)のように変数Targetにどこかのセルが格納されているかどうかを判定します。
最後に、見つかったセル(変数Target)を選択しますが、もし条件に一致するセルが1つもなかったとき、変数Targetは空のままです。何も格納されていない変数TargetをSelectするとエラーになるので、(3)でその判定をしています。