和風スパゲティのレシピ

日本語でコーディングするExcelVBA

複数のシートをまとめてコピー/移動する

複数のワークシートを一度にコピー/移動する方法を紹介します。

1つのワークシートをコピー/移動する場合と同じく、
Copy/Moveメソッドを使って実行します。


なお、この2メソッドは全く同じ書き方で実行できる、双子のようなメソッドです。

以降のサンプルコードと解説は、すべて「コピー」版で書きます。
シートの移動を行いたい方は、CopyをMoveに変えてご使用ください。

複数のシートを一括でコピーする

ワークシート名を指定してコピーする

シートリスト
このブックにある「集計表」「データ」の2シートを一括でコピーする場合は、
以下のコードを実行します。
 

Worksheets(Array("集計表", "データ")).Copy

 
Worksheetsプロパティは、配列を渡すと複数のシートを返してくれます

Array関数によってシート名が複数格納された配列を作って渡せば、複数のシートを取得することができますので、あとはそこからCopyメソッドを実行するだけですね。


Copyメソッドは単一のシートをコピーするときと同じように、Before/Afterを指定できます。

行き先を指定するサンプルコードは以下の通りです。

' 2つのシートを新しいブックとして出力する
Worksheets(Array("集計表", "データ")).Copy

' 2つのシートを「マスタ」シートの前へコピーする
Worksheets(Array("集計表", "データ")).Copy Before:=Worksheets("マスタ")

' 2つのシートを別のブックの最後尾へコピーする
Dim 移動先のブック As Workbook
Set 移動先のブック = Workbooks("○○.xlsx")
Worksheets(Array("集計表", "データ")).Copy _
    After:=移動先のブック.Worksheets(移動先のブック.Worksheets.Count)

 
特に、「引数を省略すると新規ブックに出力される」のは、
コードも短くなかなか便利です。

単一シートでも同じことができますので、この機会に覚えてしまいましょう。

ワークシート番号(インデックス)を指定してコピーする

シート名ではなく、シートのインデックス番号(左から何番目か)を指定する場合も、
同じようにArray関数を用いて記述します。

Worksheets(Array(1, 2)).Copy

"1"としてしまうと、1という名前のシートを取得してしまう点にご注意ください。

変数やオブジェクト名を指定してコピーする

変数やシートオブジェクト名を使う場合も、
上記の「シート名」「シート番号」のいずれかを利用することになります。

Dim wsデータ As Worksheet
Set wsデータ = Worksheets("データ")

Dim ws集計表 As Worksheet
Set ws集計表 = Worksheets("集計表")

' ↑の変数を使ってデータを集計するマクロがあり、そのあとにコピーをしたいときなど

' シート名を利用バージョン
Worksheets(Array(wsデータ.Name, ws集計表.Name)).Copy

' シート番号を利用バージョン
Worksheets(Array(wsデータ.Index, ws集計表.Index)).Copy

Worksheetは「.Name」でシート名を、「.Index」でシート番号を取得できます。
それをArray関数に渡すことで、目的のコピーを行うことができます。


ただし、「.Index」は、ワークシート以外のシート(グラフシートやマクロシート)があるファイルだと、正しくWorksheetを取得できません。

これらのシートを使う可能性がある場合は、「.Name」を使用しておけばOKです。

選択中の複数のシートをコピーする

シートリスト2

このように複数のシートを選択している場合は、

ActiveWindow.SelectedSheets.Copy

このコードでもコピーを行うことができます。


といっても、複数のシートを選択するには、

Worksheets(Array("集計表", "データ")).Select

と、Array関数が必要で、「じゃあSelectなんかしないでそのままCopyするわい」って話なので、使う場面はめったにないと思います。

ユーザーが手作業で選んだ複数のシートに対して、
マクロで処理を実行するときくらいですかね。

1枚ずつコピーした場合との違い

さて、一括コピーのコードに関しては以上ですが、
一つ知っておくべき仕様がありますので、そちらも解説します。


今回の2枚のシートをコピーする場合に、一括でやろうとせず、

' まず1枚だけ先にコピー
ThisWorkbook.Worksheets("集計表").Copy
Dim コピーで新規作成されたブック As Workbook
Set コピーで新規作成されたブック = ActiveWorkbook

' もう一枚のシートをコピーして追いかける
ThisWorkbook.Worksheets("データ").Copy _
    After:=コピーで新規作成されたブック.Worksheets(1)

というコードで行うこともできます。


シートのコピー自体はこれでも出来ているように見えますが、
実はこの二つの方法には大きな違いがあります。


例えば集計表のA1セルに、データシートのA列を合計する

集計表のA1セル =SUM(データ!A:A)

という数式が入っていたとしましょう。


Array関数を用いて一括でコピーした場合は、
コピー集計表の数式は、一緒にコピーした新データシートを参照する
ようになっています。

対して、1枚ずつ順番にコピーした場合は、
コピー集計表の数式は、原本のデータを参照したまま
になってしまいます。

複数シートコピー時のシート数式の仕様

つまり、2つのシートが数式でつながっているペアシートをコピーする場合は、
関数のペア関係を保つために、必ず一括方式(Array関数を使うバージョン)で行う必要がある
ということです。


これは手作業でも同じ仕様なので、このことを知っている方は多いかもしれません。

マクロで書いても同じことが起きますので、Array関数の勉強をサボってシートを1つずつコピーしないようにご注意ください。