参考元:【VBA】複数のセル範囲を取得【RangeとUnionを使います】
https://daitaideit.com/vba-range-union/
ポイントとなるVBAコード
'Rangeを使う
Range("A1,B2,C3,B4,A5").Select
'Unionを使う
Union(Range("A1"), Range("B2"), Range("C3"), Range("B4"), Range("A5")).Select
複数のセル範囲を選択
Sub TEST1()
'Rangeで複数のセル範囲を選択
Range("A1,B2,C3,B4,A5").Select
End Sub
実行結果:
複数のセル範囲に、値を一括で入力
Sub TEST2()
'Rangeで複数のセル範囲に、値を一括で入力
Range("A1,B2,C3,B4,A5") = 1
End Sub
実行結果:
注意:
255文字を超えて入力するとエラー
ただし、Rangeの注意点は、Rangeに入力できる文字数は、「255文字」ということです。
Unionを使って条件が一致したセル範囲をまとめる
Sub TEST7()
Dim A
Set A = Cells(1, 1) 'A1をオブジェクトとして変数に入力
Set A = Union(A, Cells(3, 1)) 'A3を追加
Set A = Union(A, Cells(5, 1)) 'A5を追加
'複数セル範囲を選択
A.Select
End Sub
For文を使ってセル範囲をまとめる
For文を使って、繰り返しセル範囲を追加するVBAコードは、こんな感じになります。
Sub TEST8()
Dim A
Set A = Nothing
For i = 1 To 5 Step 2
'1行目の場合
If A Is Nothing Then
Set A = Cells(i, 1) 'A1をオブジェクトとして変数に入力
'2行目以降
Else
Set A = Union(A, Cells(i, 1)) 'セル範囲を追加する
End If
Next
'複数セル範囲を選択
A.Select
End Sub
実行結果:
条件が一致したセルをまとめる
用意した表:
この表の、「A」が入力されている、セル範囲をUnionを使ってまとめてみます。
Sub TEST9()
Dim A
Set A = Nothing
For i = 1 To 10
For j = 1 To 3
'文字が「A」の場合
If Cells(i, j) = "A" Then
'最初
If A Is Nothing Then
'セル範囲を設定
Set A = Cells(i, j)
'2回目以降
Else
'Unionで複数のセル範囲を設定
Set A = Union(A, Cells(i, j))
End If
End If
Next
Next
'複数のセル範囲を選択
A.Select
End Sub
最初のセル範囲だけは、Unionを使わずに、セル範囲を変数へオブジェクトとして、代入しています。
先ほど説明したように、Unionには、一つのセル範囲だけを入力することができないためです。
Unionを使って一括で処理すると高速化できるか
文字「A」だけに、一括で罫線を引いてみます。
案1:
Unionを使って一括で罫線を引く
使う表:
Unionを使って、文字「A」だけに、一括で罫線を引いてみます。
Sub TEST10()
t = Timer
Dim A
Set A = Nothing
'最終行までループ
For i = 1 To 5002
For j = 1 To 3
'文字が「A」の場合
If Cells(i, j) = "A" Then
'最初
If A Is Nothing Then
'セル範囲を設定
Set A = Cells(i, j)
'2回目以降
Else
'Unionを使って、複数のセル範囲を設定
Set A = Union(A, Cells(i, j))
End If
End If
Next
Next
'複数のセル範囲に、罫線を引く
A.Borders.LineStyle = xlContinuous
Debug.Print Timer - t & " 秒"
End Sub
結果は、「122.3203 秒」です。
遅い感じがします。
案2:
1つの範囲ずつ罫線を引く
Sub TEST11()
t = Timer
'最終行までループ
For i = 1 To 5002
For j = 1 To 3
'文字が「A」の場合
If Cells(i, j) = "A" Then
'セルに罫線を引く
Cells(i, j).Borders.LineStyle = xlContinuous
End If
Next
Next
Debug.Print Timer - t & " 秒"
End Sub
結果は、「6.289063 秒」となりました。
圧倒的に、Unionより速くなりました。
案3:
オートフィルタを使う
1列ずつ、文字「"A"」でフィルタして、罫線を引いていくVBAコードです。
Sub TEST12()
t = Timer
'1~3列でループする
For i = 1 To 3
'文字「A」で、フィルタする
Range("A1").AutoFilter i, "A"
'フィルタされたセルだけ、1列ずつ罫線を引く
With Range("A1").CurrentRegion.Columns(i)
.Rows("2:" & .Rows.Count).Borders.LineStyle = xlContinuous
End With
'フィルタを解除
Range("A1").AutoFilter i
Next
Debug.Print Timer - t & " 秒"
End Sub
実行してみます。
結果は、「0.15625 秒」となりました。
オートフィルタ、速いです。
終わり
Unionは、オブジェクトを扱うので、少し遅いです。
高速化したい場合は、オートフィルタなどを使って、セルを処理する回数を減らすと速くなります。