大体でIT

-ちょっと使えるネタを紹介-

大体でIT

Excel VBAで複数のセル範囲を取得する方法について、ご紹介します。方法としては、Rangeだけを使う方法と、Unionを使う方法があります。結果から言うと、Unionは少し遅いので、セルを操作する回数が減る方法を考えて、Rangeを使ってセル範囲を操作した方がいいです。

はじめに

この記事では、複数のセル範囲を取得する方法についてご紹介します。

方法として、Rangeを使う方法と、Unionを使う方法を解説します。

Rangeを使う方が簡単で、複数のセル範囲を文字列で記載して、Rangeの引数として使えば、複数のセル範囲を取得できます。

ただし、Rangeは255文字の制限があるのがネックです。

Uunionは、文字の制限は特にないです。しかし、少し遅いです。

では、RangeとUnionで、複数のセル範囲を取得する方法について、解説していきます。

この記事で紹介すること

  • 複数のセル範囲を取得する方法

本記事の内容を動画でまとめています

目次から見たい項目へ移動すると便利ですよ。

目次

ポイントとなるVBAコード

初めに、ポイントとなるVBAコードを記載しておきます。

VBAコードだけ確認したい場合に、ご活用ください。

'Rangeを使う
Range("A1,B2,C3,B4,A5").Select

'Unionを使う
Union(Range("A1"), Range("B2"), Range("C3"), Range("B4"), Range("A5")).Select

では、解説していきます。

VBAで複数のセル範囲を取得

複数のセル範囲を取得する方法について、ご紹介します。

複数のセル範囲を取得できると、複数の範囲を、一括で処理することができるので、高速化ができます。

複数のセル範囲を取得する方法について、2パターンご紹介します。

Rangeの中に文字列を作成する方法と、Unionを使う方法です。

Rangeを使う

まず、簡単なRangeを使って、複数のセル範囲を取得する方法です。

やり方としては、複数のセル範囲の文字列を作れば、できます。

こんな感じの文字列を作成します。

「"A1,B2,C3,B4,A5"」

という文字列です。

複数のセル範囲を選択

では、複数のセル範囲を文字列で作成して、Rangeを使ってセルを選択してみます。

Sub TEST1()
    
    'Rangeで複数のセル範囲を選択
    Range("A1,B2,C3,B4,A5").Select
    
End Sub

実行してみます。

複数のセル範囲を文字列で作成してRangeで複数のセル範囲を選択

複数のセル範囲を、選択できました。

複数のセル範囲に、値を一括で入力

セル範囲が取得できれば、一括で処理をすることができます。

複数のセル範囲に、一括で、「"1"」を入力してみます。

Sub TEST2()
    
    'Rangeで複数のセル範囲に、値を一括で入力
    Range("A1,B2,C3,B4,A5") = 1
    
End Sub

実行してみます。

複数のセル範囲に、一括で文字を入力した結果

複数のセル範囲に、一括で文字を入力できました。

一括で処理できるということは、それだけ高速で動かせるということです。

VBAを高速化したい場合に、検討してみる価値ありです。

255文字を超えて入力するとエラー

ただし、Rangeの注意点は、Rangeに入力できる文字数は、「255文字」ということです。

255文字を超えて入力してしまうと、エラーとなってしまいます。

ついでに、やってみます。

Sub TEST3()
        
    '255文字を超える文字列をRangeに入力(エラーとなります)
    Range("A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20,A21,A22,A23,A24,A25,A26,A27,A28,A29,A30,A31,A32,A33,A34,A35,A36,A37,A38,A39,A40,A41,A42,A43,A44,A45,A46,A47,A48,A49,A50,A51,A52,A53,A54,A55,A56,A57,A58,A59,A60,A61,A62,A63,A64,A65,A66,A67").Select
    
End Sub

Rangeの中に無理やり、「258」文字の文字列を入力してみました。

実行します。エラーとなります。

Rangeの中に、255文字を超えて文字列を入力した結果

結果は、エラーとなりました。

制限なく、入力できればいいんですけどね。

残念です。

Unionを使う

もう一つ、複数のセル範囲を取得する方法が、「Union」です。

Unionを使えば、複数のセル範囲を一つのオブジェクトとしてまとめることができます。

複数のセル範囲を選択

では、「A1」、「B2」、「C3」、「B4」、「A5」のセル範囲を、Unionを使って一つにまとめてみます。

Sub TEST4()
    
    'Unionを使って複数のセル範囲を選択
    Union(Range("A1"), Range("B2"), Range("C3"), Range("B4"), Range("A5")).Select
    
End Sub

実行してみます。

Unionを使って、複数のセル範囲を一つにまとめた結果

複数のセル範囲を選択できました。

複数のセル範囲を、一つのオブジェクトにまとめられています。

複数のセル範囲に、一括で値を入力

同じように、複数のセル範囲を、まとめられると一括で文字入力ができます。

セルに一括で、「"A"」を入力してみます。

Sub TEST5()
    
    'Unionを使って、複数のセル範囲に値を入力
    Union(Range("A1"), Range("B2"), Range("C3"), Range("B4"), Range("A5")) = "A"
    
    
End Sub

実行してみます。

Unionで複数のセル範囲をまとめて一括でセルに文字を入力した結果

複数のセル範囲に、一括で「"A"」を入力することができました。

一括で入力できること自体は、高速化になります。

Unionを使って条件が一致したセル範囲をまとめる

Unionを使えば、条件が一致したセル範囲を、一つのオブジェクトにまとめることができます。

Unionに入力するセル範囲が一つだとエラーとなります。

Unionの注意点(範囲が1つだとエラーとなる)

Unionの注意点です。

Unionには、2つ以上のセル範囲を入力する必要があります。

これはエラーとなります。

Sub TEST6()
    
    'Unionの引数が一つの場合
    Union(Range("A1")).Select '←エラーとなります
    
End Sub

実行してみます。エラーとなります。

引数が一つだとエラー

Unionの引数に、セル範囲を一つだけ入力した場合エラーとなる

結果は、エラーとなりました。

Unionの引数には、2つ以上のセル範囲を入力しましょう。

繰り返してセル範囲をまとめる

「Union」に一回ですべてのセル範囲を入力するのは、ちょっと大変です。

なので、オブジェクト変数を使って、繰り返しセル範囲を入力すると便利です。

繰り返してセル範囲をまとめる

繰り返してセル範囲をまとめるVBAコードになります。

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

こんな感じで、「Set A = Union(A, セル範囲)」というのように繰り返しセル範囲を追加する感じで、セル範囲をまとめることができます。

では、実行してみます。

Unionを繰り返してセル範囲をまとめる

複数のセル範囲を取得することができました。

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

先ほどと同じ結果となります。

For文を使って繰り返してセル範囲をまとめる

こんな感じで、「Union」を使って、複数セル範囲を設定したい場合は、オブジェクト変数を使うと便利です。

条件が一致したセルをまとめる

では、先ほどの注意点を踏まえるのと、オブジェクト変数を使って、条件が一致したセル範囲を一つの変数にまとめてみます。

次の表を用意しました。

用意した表

用意した表

適当に、A、B、Cを入力しました。

この表の、「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」が入力されているセル範囲だけを、一括で選択することができました。

Unionを使って一括で処理すると高速化できるか

Unionを使って、一括で処理すると、高速化できるかを確認してみます。

結果から言うと、Unionで高速化はできませんでした。残念。

Unionはオブジェクトを扱うので、複数のセル範囲を一つにまとめるところで、時間がかかってしまいます。

では、実際にやってみます。

Unionを使って一括で罫線を引く

Unionを使って、複数のセル範囲をまとめて、一括で罫線を引いてみます。

こちらの表を使います。

使う表

使う表

5002行まで、文字が入力されています。

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

実行してみます。どれぐらい時間がかかるか。

Unionを使って、一括で罫線を引く

Unionを使って、条件が一致したセル範囲に一括で罫線を引いた結果

最後まで、罫線が引けています。

問題の時間です。

かかった時間

Unionを使って、条件が一致したセル範囲に一括で罫線を引くのにかかった時間

結果は、「122.3203 秒」です。

遅い感じがします。

では、次は、For文で、一つずつセルに罫線を引いた場合です。

1つの範囲ずつ罫線を引く

最初に、条件が一致したセル範囲に、「For」を使って一つずつ罫線を引く。というのをやってみます。

使うのは、先ほどと同じ、こちらの表です。

用意した表

用意した表

5002行まで、A、B、Cの文字が入力されています。

この表の「A」だけに罫線を引いてみます。

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

実行してみます。どれぐらい時間がかかるか。

For文で一つずつ罫線を引く

Forを使って一つずつのセルに罫線を引いた結果

文字「A」だけに、罫線を引けました。

かかった時間は、次のようになりました。

かかった時間

Forを使って一つずつのセルに罫線を引くのにかかった時間

結果は、「6.289063 秒」となりました。

圧倒的に、Unionより速くなりました。

難しいことはせずに、Forでループして、罫線を引いた方が速いです。

なので、Unionは、高速化には向いてないですね。

オートフィルタを使う

どうしても速くしたい場合は、オートフィルタを使う手があります。

一つずつ処理するから遅いので、オートフィルタを使って条件をフィルタして、罫線を引くと速くなります。

使うのは先ほどと同じ表です。

使った表

使った表

やってみます。

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 秒」となりました。

オートフィルタ、速いです。

ただ、実務では、こんな縦長の表ばかりではありませんからね。

列方向に長い表とかだと、フィルタする回数が増えますので、その分時間はかかってしまいます。

とはいえ、オートフィルタで罫線を引く回数を減らす方法もある、ということを覚えておいて損はないです。

おわりに

この記事では、複数のセル範囲を取得する方法についてご紹介しました。

方法として、Rangeを使う方法と、Unionを使う方法をご紹介しました。

Rangeで複数セルを取得する方法は、簡単だけれども、255文字の制約があるのがネックでした。

Unionは、オブジェクトを扱うので、少し遅いです。

高速化したい場合は、オートフィルタなどを使って、セルを処理する回数を減らすと速くなります。

参考になればと思います。最後までご覧くださいまして、ありがとうございました。

関連する記事から探す

カテゴリから探す

カテゴリから見たい項目を探すと便利ですよ。

サイト内を検索する

↓キーワードを入力する

アーカイブから探す