【この記事について】本記事のコードは、2026年10月22日に Windows の Excel(Microsoft 365 / バージョン 16.0)で実際に動かし、結果を確かめたものだけを載せています。エラーメッセージの文言も、このときに表示されたものをそのまま書いています。Excel のバージョンや設定によって、表示や動きが違うことがあります。メソッドの仕様は Microsoft Learn の「Worksheet.Copy メソッド」を同じ日に確認しました(出典は記事末尾)。大事なブックで試す前に、必ずコピーしたブックで動かしてください。
VBAでシートをコピーするには、Worksheets("ひな形").Copy After:=Worksheets(Worksheets.Count) の1行を書きます。これで「ひな形」シートが一番うしろにコピーされます。After:= を Before:= にすれば前に、引数を何も付けなければ新しいブックにコピーされます。
ただ、コピーしたあとに ActiveSheet.Name = "10月" と名前を付ける書き方は、コピー元が非表示のシートだと別のシートの名前を書き換えてしまいます。実機で試したところ、非表示のシートは「10月」にならず、まったく関係のない「隠し」シートが「10月」に変わりました。この記事では、基本の書き方と、こうした事故を起こさない書き方の両方を、実機で動かした結果つきで紹介します。

🔎 あわせて確認されている記事
まず結論|シートをコピーする書き方は3つだけ
| やりたいこと | 書き方 |
|---|---|
| 同じブックの一番うしろにコピー | Worksheets("ひな形").Copy After:=Worksheets(Worksheets.Count) |
| 同じブックの一番まえにコピー | Worksheets("ひな形").Copy Before:=Worksheets(1) |
| 新しいブックにコピー | Worksheets("ひな形").Copy |
Before と After はどちらか片方だけ指定します。Microsoft Learn にも「After を指定する場合、Before を指定することはできません」と書かれています。
コピーしたシートの名前は、何もしないと 「ひな形 (2)」のように、元の名前のうしろに番号が付きます(実機で確認)。名前を付けたいときは、次の章のように ActiveSheet.Name で付けます。
基本のコード|コピーして名前を付ける
月ごとの集計表を「ひな形」から作る、という事務でよくある場面で書きます。この章のコードは、「ひな形」シートが表示されているときに使ってください。非表示のときの書き方は、あとの章で紹介します。
一番うしろにコピーして「10月」にする
Sub CopySheetToEnd()
Worksheets("ひな形").Copy After:=Worksheets(Worksheets.Count)
ActiveSheet.Name = "10月"
End Sub
Worksheets.Count はシートの枚数なので、Worksheets(Worksheets.Count) は「一番うしろのシート」です。コピーすると、できたシートがアクティブになるので、次の行の ActiveSheet がコピーしたシートを指します。
一番まえにコピーする
Sub CopySheetToFront()
Worksheets("ひな形").Copy Before:=Worksheets(1)
ActiveSheet.Name = "表紙用"
End Sub
12か月分をまとめて作る
Sub CopyTwelveMonths()
Dim i As Long
For i = 1 To 12
Worksheets("ひな形").Copy After:=Worksheets(Worksheets.Count)
ActiveSheet.Name = i & "月"
ActiveSheet.Range("A1").Value = i & "月分"
Next i
End Sub
実機では「1月」〜「12月」の12枚が順にでき、各シートの A1 に「1月分」〜「12月分」が入りました。ひな形に入れておいた数式(例:B2 の =1+1)も、コピーしたシートにそのまま残ります。同じ名前のシートがすでにあると2回目で止まるので、試すときは「1月」〜「12月」を消してから動かしてください。For Next の書き方はこちらにまとめています。

別のブックにコピーする
新しいブックにコピーして保存する
Sub CopySheetToNewBook()
Worksheets("ひな形").Copy
ActiveWorkbook.SaveAs Filename:=ThisWorkbook.Path & "\ひな形_コピー.xlsx", _
FileFormat:=xlOpenXMLWorkbook
ActiveWorkbook.Close
End Sub
引数なしの Copy は、そのシート1枚だけが入った新しいブックを作り、そのブックがアクティブになります。続けて ActiveWorkbook.SaveAs で保存し、Close で閉じています。実機では、マクロのあるブックと同じフォルダに「ひな形_コピー.xlsx」ができ、開くとひな形の数式も残っていました。
マクロのない .xlsx で保存しているので、取引先に送る提出用のファイルを作るときに便利です。
複数のシートをまとめて新しいブックにする
Sub CopyTwoSheetsToNewBook()
Worksheets(Array("ひな形", "集計")).Copy
End Sub
Array でシート名を並べると、その全部が1つの新しいブックにコピーされます。実機では「ひな形」と「集計」の2枚が入ったブックができました。
開いている別のブックにコピーする
Sub CopyToOtherBook()
Dim dst As Workbook
Set dst = Workbooks("提出用.xlsx")
ThisWorkbook.Worksheets("ひな形").Copy After:=dst.Worksheets(dst.Worksheets.Count)
End Sub
「提出用.xlsx」を先に開いておくのが条件です。開いていないと Workbooks("提出用.xlsx") の行で「実行時エラー9」で止まります。ThisWorkbook(マクロが入っているブック)と dst(コピー先)を書き分けると、どのブックの話なのかが読み違えにくくなります。
なお Microsoft Learn には、コピー元とコピー先は同じ Excel の中で開いている必要があり、そうでないと実行時エラー1004になると書かれています。Excel を2つ別々に起動して開いたブックどうしではコピーできません。
実機で止まったエラー6つと直し方
「ひな形」「集計」「隠し」の3枚が入ったブックで、わざと失敗させて表示を確かめました。
| やったこと | 表示されたエラー | 直し方 |
|---|---|---|
| すでにある「集計」という名前を付けた | 実行時エラー1004「この名前は既に使用されています。別の名前を入力してください。」 | 先に同じ名前があるか調べる(次の章) |
| 「abc」があるのに「ABC」を付けた | 同上(1004「この名前は既に使用されています。」) | シート名は大文字・小文字を区別しない。別の名前にする |
| 「10/22」という名前を付けた | 実行時エラー1004「入力されたシートまたはグラフの名前が正しくありません。」 | 「/」などの使えない記号を「-」などに置き換える |
| 32文字の名前を付けた | 同上(1004「…名前が正しくありません。」) | 31文字以内にする(31文字は通った) |
| 「ひな形」を「ひな型」と書き間違えた | 実行時エラー9「インデックスが有効範囲にありません。」 | シート名をシートの見出しからコピーして貼る |
| ブックの構成を保護した状態でコピーした | 実行時エラー1004「ブックは保護されています。変更できません。」 | 保護を解除してからコピーする(パスワードは管理者に確認) |
名前のエラーで止まったとき、コピーそのものはもう終わっています。実機では「ひな形 (2)」というシートが残りました。もう一度動かす前に、このシートを消しておかないと、また名前がぶつかります。
エラー番号ごとの詳しい原因は、それぞれの記事にまとめています。


非表示のシートが絡むと、ActiveSheet が別のシートを指す
ここが、検索してもあまり出てこない落とし穴です。実機で確かめた結果は次のとおりでした。
- コピー元が非表示:コピーはできるが、できたシートも非表示のまま。しかもActiveSheet がコピーに切り替わらない。基本のコード(CopySheetToEnd)を動かすと、「ひな形 (2)」ではなく、その時アクティブだった「隠し」シートが「10月」に変わった
- 一番うしろのシートが非表示:
After:=Worksheets(Worksheets.Count)と書いても、コピーはその非表示シートの手前に入った - コピー元が「VeryHidden」(VBAでしか表示に戻せない非表示):実行時エラー1004「Worksheet クラスの Copy メソッドが失敗しました。」でコピー自体ができない
ひな形を非表示にして配る、というのは事務の現場でよくあるやり方です。そのブックで ActiveSheet.Name を使うと、エラーも出ずに別のシートの名前が黙って変わります。気づくのは、だいぶあとになってからです。
事故を起こさない書き方|コピーしたシートを確実につかむ
考え方は単純です。コピーする前に、いまあるシートの名前を全部メモしておき、コピーしたあとに「メモに無い名前のシート」を探す。それが今できたシートです。ActiveSheet にも、シートの並び順にも頼りません。
Function SheetExists(ByVal sheetName As String) As Boolean
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If StrComp(ws.Name, sheetName, vbTextCompare) = 0 Then
SheetExists = True
Exit Function
End If
Next ws
End Function
Function CopySheet(ByVal src As Worksheet) As Worksheet
Dim wb As Workbook
Dim ws As Worksheet
Dim oldNames As String
Set wb = src.Parent
For Each ws In wb.Worksheets ' コピー前のシート名を控える
oldNames = oldNames & "/" & ws.Name & "/"
Next ws
src.Copy After:=wb.Worksheets(wb.Worksheets.Count)
For Each ws In wb.Worksheets ' 控えに無い名前=今できたコピー
If InStr(oldNames, "/" & ws.Name & "/") = 0 Then
Set CopySheet = ws
Exit Function
End If
Next ws
End Function
Sub CopySheetSafely()
Dim ws As Worksheet
Dim newName As String
newName = "11月"
If SheetExists(newName) Then
MsgBox "「" & newName & "」は既にあります。", vbExclamation
Exit Sub
End If
Set ws = CopySheet(ThisWorkbook.Worksheets("ひな形"))
ws.Visible = xlSheetVisible ' 元が非表示でも見えるようにする
ws.Name = newName
End Sub
区切りに「/」を使っているのは、シート名に「/」は使えないからです(上の表のとおり、付けようとするとエラーになります)。だから「/ひな形/」のように挟めば、ほかの名前と取り違えません。SheetExists は vbTextCompare で比べているので、「abc」と「ABC」も同じ名前として見つけます。Excel の判定と同じです。
このコードを4つの状態のブックで動かし、4つとも「11月」が表示された状態ででき、ほかのシートの名前は変わらないことを確かめました。
| ブックの状態 | 結果 |
|---|---|
| 全部のシートが表示されている | 「11月」が一番うしろにできた |
| コピー元の「ひな形」が非表示 | 「11月」が表示された状態でできた。「ひな形」は非表示のまま |
| 一番うしろの「隠し」が非表示 | 「11月」は「隠し」の手前にできた。名前は正しく付いた |
| 上の2つが両方 | 同上。名前は正しく付いた |
すでに「11月」があるときは、コピーする前にメッセージを出して止まるので、「ひな形 (2)」のような残りかすもできません。
値だけのコピーを作る(数式を消して保存用にする)
同じ CopySheet を使うと、「今日の時点の数字を残しておく」コピーも作れます。
Sub CopySheetAsValues()
Dim ws As Worksheet
Set ws = CopySheet(ThisWorkbook.Worksheets("集計"))
ws.Visible = xlSheetVisible
ws.UsedRange.Value = ws.UsedRange.Value ' 数式を値に置き換える
ws.Name = "集計_" & Format(Date, "yyyymmdd")
End Sub
実機では「集計_20261022」ができ、A3 の =SUM(A1:A2) は 30 という値に変わりました。元の「集計」の A3 は数式のままです。「集計」が非表示のときも、一番うしろが非表示のときも、同じように動きました。
このやり方は、日付で名前を付けるので1日に1回だけ動かす前提です。同じ日に2回動かすと、名前のエラー(1004)で止まり、名前の付いていないコピーが残ります。
よくある質問
Q. コピーしたら「既にある名前が含まれています」と何度も聞かれます
A. それはシート名ではなく、ブックの中の「名前の定義」が重なっているときに出るメッセージです。VBAのコードの問題ではないので、名前の定義を整理します。直し方はこちらです。

Q. 手でシートをコピーしようとしても、メニューが押せません
A. ブックの構成が保護されていると、右クリックの「移動またはコピー」が押せません。VBAでも「ブックは保護されています。」で止まります。手で操作するときの確かめ方は、コピーできない原因をまとめた記事の「原因4」にあります。

Q. マクロを実行しようとしても動きません
A. コードの前に、マクロ自体が止められていることがあります。ファイルが .xlsm で保存されているか、ブロックされていないかを先に確かめてください。

Q. 変数を Dim で宣言しないとダメですか?
A. この記事のコードは、Option Explicit を付けたモジュールで動かしています。宣言しておくと、ws を sw と打ち間違えたときに、動かす前に教えてくれます。
まとめ
- シートのコピーは
Copy After:=(うしろ)・Copy Before:=(まえ)・Copy(新しいブック)の3つ - 名前を付けないと「ひな形 (2)」になる。名前は31文字以内、「/」などは使えない、大文字・小文字は同じ名前として扱われる
- 名前のエラーで止まってもコピーは終わっている。残ったシートを消してからやり直す
- コピー元が非表示だと、ActiveSheet がコピーを指さない。別のシートの名前が黙って変わる
- 事故を防ぐには、コピー前のシート名を控えて、控えに無いシートを探す(CopySheet 関数)
シートのコピーは1行で書けるぶん、「動いたから大丈夫」と思いやすい処理です。でも、ひな形を非表示にしたブックで使った瞬間に、別のシートの名前が変わります。この記事の CopySheet を1つ持っておけば、どんなブックでも同じように動きます。まずはコピーしたブックで、1回動かしてみてください。
次に読む


参考にした一次情報(2026年10月22日 確認)
Worksheet.Copy メソッド (Excel)|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/api/excel.worksheet.copy
Worksheet.Name プロパティ (Excel)|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/api/excel.worksheet.name
Worksheet.Visible プロパティ (Excel)|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/api/excel.worksheet.visible

コメント