HOME > 即効テクニック > Excel VBA > セル操作関連のテクニック > 2つのセル範囲を入れ替える

即効テクニック

セル操作関連のテクニック

2つのセル範囲を入れ替える

(Excel 97/2000/2002/2003/2007)

選択されている2つのセル範囲を入れ替えるマクロを考えてみましょう。 プログラミングの基本的な考え方では、何かを入れ替えるときには、次のように処理します。

【AとBを入れ替える場合】 (1)Aを一時待避場所にコピーする (2)BをAにコピーする (3)一時待避場所からBにコピーする 2つの変数で入れ替えを行うには、次のようにします。
Sub Sample1()
    Dim A As Long, B As Long, swap As Long
    A = 123
    B = 789
    swap = A    ''swapにAを入れる
    A = B       ''AにBを入れる
    B = swap    ''Bにswapを入れる
End Sub
入れ替えの基本は以上です。この発想で、2つのセルを入れ替えてみましょう。 まず、セルA1とセルB1を入れ替えてみます。
Sub Sample2()
    Dim swap
    swap = Range("A1")
    Range("A1") = Range("B1")
    Range("B1") = swap
End Sub

マクロを実行してみると、セルA1とセルB1が入れ替わりました。 しかし、このマクロで入れ替わるのは、セルのデータだけです。セルに設定した書式などは変化しません。これではセルを入れ替えたことになりません。 では、次のようにセルをオブジェクト変数に待避してはどうでしょう。

Sub Sample3()
    Dim swap As Range
    Set swap = Range("A1")
    Range("A1") = Range("B1")
    Range("B1") = swap
End Sub

これでは失敗します。 オブジェクト変数にSetステートメントで代入すると、それは元のオブジェクトへの参照を作成したに過ぎません。Set swap = Range("A1") で変数swapにはセルA1が代入されますが、実際には変数swapはセルA1を参照しているだけです。 したがって、Range("A1") = Range("B1")とセルA1のデータを変更してしまうと、変数swapも一緒に変わってしまうのです。

この問題を解決するには、セルを変数に一時待避するのではなく、別のセルに待避してやります。しかし、一時待避として使用できるブランクセルは、どこにあるのでしょう。 それは、新しく挿入したワークシート上のセルです。

選択した2つのセル範囲を安全に入れ替えるには次のようにします。単一のセルではなく、複数のセル範囲を入れ替える場合にも対応してあります。

Sub Sample4()
    Dim swapSheet As Worksheet
    ''新しいシートを挿入します
    Set swapSheet = Worksheets.Add
    ''元のシートを開きます
    ActiveSheet.Next.Activate
    ''入れ替え開始
    Selection.Areas(1).Copy swapSheet.Range("A1")
    Selection.Areas(2).Copy Selection.Areas(1)
    swapSheet.Range("A1").CurrentRegion.Copy Selection.Areas(2)
    ''シート削除時のアラートを抑止
    Application.DisplayAlerts = False
    ''挿入したシートを削除
    swapSheet.Delete
    Application.DisplayAlerts = True
End Sub

新しいシートを挿入すると、新シートはアクティブシートの左に挿入されます。 したがって、元のシートに戻るときは「右隣」のシートを開けばいいです。右隣のシートはNextプロパティで取得できます。