大体でIT

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

大体でIT

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

はじめに

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

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

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

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

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

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

この記事で紹介すること

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

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

目次

ポイントとなるVBAコード

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

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

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

'Unionを使う
With ActiveSheet
    Set a = Union(.Range("A1"), .Range("B2"), .Range("C3"), .Range("B4"), .Range("A5"))
End With
a.Select

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

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

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

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

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

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

Rangeを使う

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

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

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

『"A1,B2,C3,B4,A5"』

という文字列です。

複数のセル範囲を選択

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

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

実行してみます。

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

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

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

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

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

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

実行してみます。

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

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

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

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

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

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

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

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

Sub TEST3()
        
    '255文字を超える文字列をRangeに入力(エラーとなります)
    ActiveSheet.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を使って複数のセル範囲を取得
    With ActiveSheet
        Set a = Union(.Range("A1"), .Range("B2"), .Range("C3"), .Range("B4"), .Range("A5"))
    End With
    
    'セル範囲を選択
    a.Select
    
End Sub

実行してみます。

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

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

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

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

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

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

Sub TEST5()
    
    'Unionを使って複数のセル範囲を取得
    With ActiveSheet
        Set a = Union(.Range("A1"), .Range("B2"), .Range("C3"), .Range("B4"), .Range("A5"))
    End With
    
    'セル範囲に、文字を一括で入力
    a.Value = "A"
    
End Sub

実行してみます。

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

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

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

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

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

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

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

Unionの注意点です。

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

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

Sub TEST6()
    
    'Unionの引数が一つの場合
    With ActiveSheet
        Set a = Union(.Range("A1")) 'エラーとなります
    End With
    
End Sub

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

引数が一つだとエラー

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

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

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

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

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

次の表を用意しました。

用意した表

用意した表

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

この表の、『A』が入力されている、セル範囲をUnionを使ってまとめてみます。

Sub TEST7()
    
    With ActiveSheet
        For i = 1 To 10
            For j = 1 To 3
                
                '文字が「A」の場合
                If .Cells(i, j) = "A" Then
                    '最初
                    If a = "" Then
                        'セル範囲を設定
                        Set a = .Cells(i, j)
                    '2回目以降
                    Else
                        'Unionで複数のセル範囲を設定
                        Set a = Union(a, .Cells(i, j))
                    End If
                End If
                
            Next
        Next
    End With
    
    '複数のセル範囲を選択
    a.Select
    
End Sub

最初のセル範囲だけは、Unionを使わずに、セル範囲を変数へオブジェクトとして、代入しています。

先ほど説明したように、Unionには、一つのセル範囲だけを入力することができないためです。

では、実行してみます。

条件が一致したセル範囲のみ選択

Unionを使って、条件が一致したセル範囲を一つのオブジェクトにまとめた結果

文字『A』が入力されているセル範囲だけを、一括で選択することができました。

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

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

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

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

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

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

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

こちらの表を使います。

使う表

使う表

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

Unionを使って、文字『A』だけに、一括で罫線を引いてみます。

Sub TEST8()
    
    With ActiveSheet
        '最終行までループ
        For i = 1 To .Cells(Rows.Count, "A").End(xlUp).Row
            For j = 1 To 3
                
                '文字が「A」の場合
                If .Cells(i, j) = "A" Then
                    '最初
                    If a = "" Then
                        'セル範囲を設定
                        Set a = .Cells(i, j)
                    '2回目以降
                    Else
                        'Unionを使って、複数のセル範囲を設定
                        Set a = Union(a, .Cells(i, j))
                    End If
                End If
                
            Next
        Next
    End With
    
    '複数のセル範囲に、罫線を引く
    a.Borders.LineStyle = xlContinuous
        
End Sub

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

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

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

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

問題の時間です。

かかった時間

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

結果は、『122.3203 秒』です。

遅い感じがします。

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

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

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

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

用意した表

用意した表

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

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

Sub TEST9()
    
    With ActiveSheet
        '最終行までループ
        For i = 1 To .Cells(Rows.Count, "A").End(xlUp).Row
            For j = 1 To 3
                '文字が「A」の場合
                If .Cells(i, j) = "A" Then
                    'セルに罫線を引く
                    .Cells(i, j).Borders.LineStyle = xlContinuous
                End If
            Next
        Next
    End With
    
End Sub

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

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

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

文字『A』だけに、罫線を引けました。

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

かかった時間

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

結果は、『6.289063 秒』となりました。

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

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

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

オートフィルタを使う

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

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

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

使った表

使った表

やってみます。

1列ずつ、文字『"A"』でフィルタして、罫線を引いていくVBAコードです。

Sub TEST10()
    
    '1~3列でループする
    For i = 1 To 3
        
        '文字「A」で、フィルタする
        ActiveSheet.Range("A1").AutoFilter i, "A"
        
        'フィルタされたセルだけ、1列ずつ罫線を引く
        With ActiveSheet.Range("A1").CurrentRegion.Columns(i)
            .Resize(.Rows.Count - 1).Offset(1, 0).Borders.LineStyle = xlContinuous
        End With
        
        '全行を表示する
        ActiveSheet.ShowAllData
        
    Next
    
End Sub

実行してみます。

オートフィルタで、罫線を引いた結果

オートフィルタで条件をフィルタして罫線を引いた結果

最終列まで、罫線を引けています。

問題の時間です。

かかった時間

オートフィルタで条件をフィルタして罫線を引くのにかかった時間

結果は、『0.15625 秒』となりました。

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

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

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

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

おわりに

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

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

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

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

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

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

関連する記事から探す

カテゴリから探す

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

アーカイブから探す