5.

Excel VBAでシートをコピーする方法|Copyの使い方と位置指定・名前変更

編集

Excel VBAでワークシートをコピーするには、WorksheetオブジェクトのCopyメソッドを使う。最も基本的な書き方は Worksheets("Sheet1").Copy で、これだけでシート全体(セルの値・数式・書式・図形などを含む)を丸ごと複製できる。コピー先を指定したい場合は引数 After:= または Before:= を付け、別ブックへ複製することも可能である。本記事では、基本構文からコピー先の位置指定、コピー後のシート参照と名前変更、値だけのコピーとの違い、複数シートの一括コピー、そして実務でつまずきやすい落とし穴までを、最小限のコードとともに整理する。

この記事の要点
  • シート全体のコピーは Worksheets("Sheet1").Copy が基本。これだけで同じブック内に複製が作られる。
  • 引数を省くと新しいブックが作られる。同一ブック内に置きたいときは After:=Before:= でコピー先の位置を指定する。
  • コピー直後はコピーで作られたシートがアクティブになるため、ActiveSheet でコピー先シートを参照できる。
  • シート名の変更は ActiveSheet.Name = "新しい名前"。同名シートがあるとエラーになる点に注意。
  • 「値だけ」を別シートに移したいときはシートコピーではなく、Range.CopyPasteSpecial を使う。

基本:ワークシートをコピーする

ワークシートのコピーには、Worksheetオブジェクトに用意された Copy メソッドを使う。引数を一切指定しない場合、コピーされたシートは新しいブックとして開かれる。

' Sheet1 を新しいブックにコピーする

Worksheets("Sheet1").Copy

同じブックの中に複製を作りたい場合は、後述の After:= または Before:= を指定する。なお Worksheets("Sheet1") の代わりに、シートのインデックス番号(左から数えた位置)を使った Worksheets(1) や、シートのオブジェクト名を使った Sheet1 といった書き方でも同じ対象を指定できる。シート名は実行時に変更され得るため、堅牢にしたいときはオブジェクト名やインデックスを使う選択肢も検討するとよい。

コピー先の位置を指定する(After / Before)

同じブック内で、特定のシートの「後ろ」または「前」に複製を挿入したい場合は、引数 After:= または Before:= にコピー先の基準となるシートを渡す。AfterBefore は同時には指定できない。

' Sheet1 のコピーを Sheet1 の直後に挿入する

Worksheets("Sheet1").Copy After:=Worksheets("Sheet1")

 

' Sheet1 のコピーを Sheet2 の直前に挿入する

Worksheets("Sheet1").Copy Before:=Worksheets("Sheet2")

ブックの末尾(いちばん右)に追加したい場合は、最後のシートの後ろを指定する。シート総数は Worksheets.Count で取得できる。

' Sheet1 のコピーをブックの末尾に追加する

Worksheets("Sheet1").Copy After:=Worksheets(Worksheets.Count)

主な指定パターンを次の表にまとめる。

書き方 コピー先
Worksheets("Sheet1").Copy 新しいブックとして開く
.Copy After:=Worksheets("Sheet2") Sheet2 の直後(同じブック内)
.Copy Before:=Worksheets("Sheet2") Sheet2 の直前(同じブック内)
.Copy After:=Worksheets(Worksheets.Count) ブックの末尾
.Copy Before:=Worksheets(1) ブックの先頭

コピー後のシートを参照する(ActiveSheet)

Copy メソッドの実行直後は、コピーによって新しく作られたシートがアクティブな状態になる。そのため、続けて ActiveSheet を参照すれば、いま作ったコピー先シートを操作できる。

Worksheets("Sheet1").Copy After:=Worksheets(Worksheets.Count)

 

' 直後はコピーで作られたシートがアクティブになっている

ActiveSheet.Range("A1").Value = "コピーしました"

後の操作で他のシートを選択する処理が入り得る場合は、コピー直後にオブジェクト変数へ控えておくと参照が安定する。

Dim ws As Worksheet

Worksheets("Sheet1").Copy After:=Worksheets(Worksheets.Count)

Set ws = ActiveSheet

 

' 以降は ws で確実にコピー先シートを参照できる

ws.Range("A1").Value = "コピーしました"

コピーしたシートの名前を変更する

シート名は、Worksheetオブジェクトの Name プロパティに文字列を代入して変更する。コピー直後の ActiveSheet、または控えておいたオブジェクト変数に対して設定する。

Worksheets("Sheet1").Copy After:=Worksheets(Worksheets.Count)

ActiveSheet.Name = "コピー結果"

シート名にはExcelの仕様上の制約があり、すでに同じ名前のシートが存在する場合や、使用できない文字を含む場合はエラーになる。シート名に使えない文字や上限の長さなどの制約は後述のFAQでも触れる。

「値だけコピー」との違い(Range.Copy + PasteSpecial)

ここまでの Worksheet.Copyシートそのものを増やす操作である。一方、「既存のシートに、別シートの計算結果の値だけを貼り付けたい」「数式ではなく確定値として残したい」という目的のときは、シートコピーではなくセル範囲のコピーを使う。Range.Copy でコピーし、貼り付け先で PasteSpecial を使うと、値・書式・数式などを選んで貼り付けられる。

' Sheet1 の A1:C10 の「値だけ」を Sheet2 の A1 起点に貼り付ける

Worksheets("Sheet1").Range("A1:C10").Copy

Worksheets("Sheet2").Range("A1").PasteSpecial Paste:=xlPasteValues

Application.CutCopyMode = False  ' コピーモードを解除

両者の使い分けの目安を次の表に示す。

やりたいこと 使うもの
シートを丸ごと複製してシート数を増やす Worksheet.Copy
既存シートに値だけ・書式だけを貼り付ける Range.CopyPasteSpecial

PasteSpecial の主な貼り付け種別には、値のみの xlPasteValues、書式のみの xlPasteFormats、すべての xlPasteAll などがある。クリップボードを経由するため、貼り付け後は Application.CutCopyMode = False でコピーモードを解除しておくとよい。

ループで複数のコピーを作る

同じシートを複数枚に増やしたい場合は、繰り返し処理の中で Copy を呼び出す。名前が重複するとエラーになるため、ループ変数などを使ってシート名が一意になるようにするのが定石である。

Dim i As Long

For i = 1 To 5

    Worksheets("ひな型").Copy After:=Worksheets(Worksheets.Count)

    ActiveSheet.Name = "支店" & i

Next i

上の例では、「ひな型」シートをブック末尾に5枚コピーし、それぞれ「支店1」~「支店5」という名前を付けている。コピー先を毎回 After:=Worksheets(Worksheets.Count) にしているのは、ループのたびにシート総数が1枚ずつ増えるため、常にその時点での末尾を基準にして順番どおりに並べるためである。配列に用意した名前リストを使って、固定の名称を順に割り当てる書き方もよく用いられる。多数のコピーを作るときは、後述の ScreenUpdating を併用すると動作が速くなり、画面のちらつきも抑えられる。

つまずきやすい落とし穴

よくある落とし穴と対処
  • 同名シートが存在するとエラー:すでに同じ名前のシートがある状態で ActiveSheet.Name に同じ名前を設定すると実行時エラーになる。ループでコピーするときは名前を一意にする。必要なら設定前に同名シートの有無を確認する。
  • コピー直後の参照は ActiveSheet:コピーで作られたシートには明示的な変数がないため、直後は ActiveSheet で参照する。間に別シートを選択する処理が入ると ActiveSheet がずれるので、必要なら Set ws = ActiveSheet で即座に控える。
  • 別ブックへのコピーは「対象シート+宛先シート」を明示:複数ブックを開いている場合、Workbooks("元.xlsx").Worksheets("Sheet1").Copy After:=Workbooks("先.xlsx").Worksheets(1) のように、コピー元と宛先の両方をブックから明示すると誤動作を避けられる。
  • 画面のちらつき・遅さは ScreenUpdating で抑える:多数のシートをコピーすると画面が激しく再描画される。処理の前に Application.ScreenUpdating = False、処理後に True に戻すと高速化できる。エラーで途中終了しても True に戻るよう、エラー処理の設計に注意する。
  • PasteSpecial 後はコピーモードを解除:Range.CopyPasteSpecial を使った後は、点滅する選択枠が残らないよう Application.CutCopyMode = False を実行する。

画面更新の抑制とエラー処理を組み合わせた、実務向けのひな型を示す。

Sub CopySheets()

    Dim i As Long

    Application.ScreenUpdating = False

    On Error GoTo Cleanup

 

    For i = 1 To 3

        Worksheets("ひな型").Copy After:=Worksheets(Worksheets.Count)

        ActiveSheet.Name = "資料" & i

    Next i

 

Cleanup:

    Application.ScreenUpdating = True

End Sub

よくある質問(FAQ)

Q. コピーしたシートを必ず末尾(いちばん右)に置くには?

A. After:=Worksheets(Worksheets.Count) を指定する。Worksheets.Count はシートの総数を返すため、Worksheets(Worksheets.Count) は常にいちばん右のシートを指す。その「後ろ」に挿入することで、コピーは必ず末尾に置かれる。

Q. 別のブックへシートをコピーするには?

A. After:= または Before:= に、宛先ブックのシートを指定する。たとえば Worksheets("Sheet1").Copy After:=Workbooks("別ブック.xlsx").Worksheets(1) のように書く。宛先ブックはあらかじめ開いておく必要がある。引数を省略した Worksheets("Sheet1").Copy は、コピー内容を中身とする新しいブックを作る動作になる。

Q. シート名に使えない文字や長さの制限はある?

A. シート名にはExcelの仕様上の制約があり、長さの上限があるほか、: \ / ? * [ ] といった文字は使用できない。これらを含む名前や、空文字、既存シートと同じ名前を Name に設定しようとすると実行時エラーになる。ユーザー入力などからシート名を組み立てる場合は、禁止文字を除去・置換してから設定すると安全である。

Q. コピーすると数式の参照先がずれない?

A. シートを丸ごとコピーした場合、シート内のセル同士を参照する数式はコピー先シート内で完結するよう調整される。一方、他のシートを名前で参照している数式は、参照先のシート名がそのまま保持される。意図と異なる参照になっていないか、コピー後に重要なセルを確認するとよい。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. マクロとボタンの紐づけ方法
  2. 開発タブの表示
  3. モジュールの名前変更方法
  4. エラー一覧
  5. シートのコピー
  6. デバッグで一行ずつ実行する方法
  7. 変数宣言時のSETありなしの違い
  8. if文で複数条件を指定する方法

最近更新/作成されたページ