Contents
この記事でできること
- VBAでシートを別のブック(Excelファイル)にコピーできる
- シートを別ブックに移動できる(元ブックからは消える)
- 複数シートを一括で別ブックにコピーできる
- 月別シートを個別ファイルに分割保存できる
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
—
どんな場面で使う?
- 拠点別・部門別の売上シートを本社用ブックにまとめて提出するとき
- 月別シート(1月〜12月)を個別のExcelファイルに分割して配布するとき
- 特定のシートだけを抜き出して、社外に渡す用のブックを作りたいとき
- テンプレートシートを新規ブックにコピーして、新しい案件用ファイルを自動作成したいとき
- 条件に合う行を別シートにコピーした後、そのシートごと別ブックに切り出したいとき
シートのコピー・移動は手動でもできるが、枚数が多いと時間がかかるしミスしやすい。VBAなら配列にシート名を列挙するだけで一括処理できる。
—
完成イメージ(Before / After)
Before(手動で繰り返し):
- シートタブを右クリック →「移動またはコピー」
- コピー先ブックを選択
- 「コピーを作成する」にチェック
- 「OK」をクリック
- …これを5シート分繰り返し
- コピー先を間違えて、別ファイルにシートが増殖
After(VBAで自動化):
- マクロを実行
- 指定シートが別ブックにコピー(または移動)される
- 完了メッセージが表示される
—
拠点別の売上シートを本社用ブックに手作業でコピーしていた。シートタブを右クリック→「移動またはコピー」→コピー先ブックを選択→「コピーを作成する」にチェック…を5拠点分。毎月やるのに15分かかっていたし、コピー先ブックを間違えて違うファイルにシートが増殖したこともある。VBAのSheets.Copyを使うようにしてからは、5シート分のコピーが数秒で終わるようになった。この記事で、手作業のコピー地獄から抜け出してほしい。
シートのコピー・移動を手動で繰り返すのは、ミスの温床。VBAに任せよう。
なお、「シート」ではなく「ファイル」をコピー・移動したい場合は ファイルを別フォルダにコピー・移動する方法 を参照。また、逆に複数ブックのデータを1つに統合したい場合は 複数Excelファイルを1つに統合 を参照。
—
コピーと移動の違い
処理を始める前に、コピーと移動の違いを確認する。
| コピー(Sheets.Copy) | 移動(Sheets.Move) | |
|---|---|---|
| 元シート | 残る | なくなる |
| 危険度 | 低い(元が残る) | 高い(元からなくなる) |
| ブック内最後の1シートに対して | 実行可能 | エラー(ブックには最低1シート必要) |
| 同名シートがコピー先にある場合 | 自動リネーム(例: Sheet1 (2)) | 自動リネーム |
移動はシートが元ブックからなくなる破壊的操作です。 移動を使う場合は、必ず事前にバックアップを取ってください。
—
実行前の準備
バックアップを取る(必須)
移動(Sheets.Move)は元ブックからシートがなくなる操作です。 必ず元ブックをコピーしてバックアップを取ってください。コピーだけの場合も、念のためバックアップを推奨する。
コピー先ブックを開いておく(別ブックにコピーする場合)
Sheets.Copy After:=Workbooks("コピー先.xlsx")... のように書くとき、コピー先ブックが開いていないとエラーになる。事前にExcelで開いておくか、コード内で Workbooks.Open で開く。
Excelをマクロ有効ブック(.xlsm)で保存する
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
—
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す - VBE(Visual Basic Editor)が開く
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
- 白い画面(コードウィンドウ)が表示される
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
Alt + F8→ マクロ名を選んで「実行」
—
コード(最小版)– 1シートを別ブックにコピーする
まずはこれだけで動く。Sheets.Copy で1枚のシートを別ブックの末尾にコピーする。
'============================================================
' ■ 1シートを別ブックにコピー(最小版)
' → コピー先ブックは事前に開いておく
' ※ ThisWorkbook = このマクロが入っているブック
' (ActiveWorkbook とは異なる。通常は ThisWorkbook を使う)
'============================================================
Sub CopySheetToAnotherBook()
Dim srcBook As Workbook
Dim dstBook As Workbook
' ★ マクロが入っているブック(コピー元)
Set srcBook = ThisWorkbook
' ★ コピー先ブック名を書き換える(事前に開いておく)
Set dstBook = Workbooks("コピー先.xlsx")
' ★ コピーするシート名を書き換える
srcBook.Worksheets("売上データ").Copy _
After:=dstBook.Sheets(dstBook.Sheets.Count)
MsgBox "シートのコピーが完了しました。", vbInformation
End Sub
ポイント:
After:=dstBook.Sheets(dstBook.Sheets.Count)でコピー先ブックの末尾にコピーされる。なぜdstBook.Sheets.Countを使うかというと、コピー先の最後のシートの「後ろ」を指定することで、常に末尾に追加できるからだAfterをBeforeに変えると、指定シートの前にコピーされる- コピーではなく移動したい場合は、
.Copyを.Moveに変える。ただし元ブックからシートがなくなるので注意 - コピー先ブックは事前にExcelで開いておくこと。開いていないと「インデックスが有効範囲にありません」エラーが出る。自動で開きたい場合はファイルの開閉を参照
- コピー先に同名シートがある場合、自動的に「売上データ (2)」のようにリネームされる。リネームを避けたい場合は、事前にシート名の存在チェックを行うとよい
—
コード(応用版)– 複数シートの一括コピー/新規ブックへのコピー
応用1: 複数シートを別ブックに一括コピー
配列で指定した複数シートをまとめて別ブックにコピーする。
'============================================================
' ■ 複数シートを別ブックに一括コピー
' → 配列でシート名を指定。ループでコピー
'============================================================
Sub CopyMultipleSheets()
Dim srcBook As Workbook
Dim dstBook As Workbook
Dim sheetNames As Variant
Dim i As Long
Dim count As Long
Set srcBook = ThisWorkbook
' ★ コピー先ブック名を書き換える(事前に開いておく)
Set dstBook = Workbooks("コピー先.xlsx")
' ★ コピーするシート名を書き換える
sheetNames = Array("東京", "大阪", "名古屋", "福岡", "札幌")
count = 0
For i = LBound(sheetNames) To UBound(sheetNames)
' シートが存在するかチェック
If SheetExists(srcBook, CStr(sheetNames(i))) Then
srcBook.Worksheets(CStr(sheetNames(i))).Copy _
After:=dstBook.Sheets(dstBook.Sheets.Count)
count = count + 1
Else
MsgBox "シートが見つかりません:" & sheetNames(i), vbExclamation
End If
Next i
MsgBox count & " シートのコピーが完了しました。", vbInformation
End Sub
'============================================================
' ■ 補助関数: シートが存在するかチェック
'============================================================
Private Function SheetExists(wb As Workbook, sheetName As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Set ws = wb.Worksheets(sheetName)
On Error GoTo 0
SheetExists = Not ws Is Nothing
End Function
応用2: シートを新規ブックにコピーして保存
Sheets.Copy を引数なしで呼ぶと、新規ブックが自動で作られ、そこにシートがコピーされる。
'============================================================
' ■ シートを新規ブックにコピーして保存
' → 引数なしの Copy で新規ブックが作られる
' → 保存先パスを指定して保存
'============================================================
Sub CopySheetToNewBook()
Dim savePath As String
' ★ 保存先のフルパスを書き換える
savePath = "C:\Users\(ユーザー名)\Desktop\売上データ_コピー.xlsx"
' シートを新規ブックにコピー(引数なし = 新規ブック作成)
ThisWorkbook.Worksheets("売上データ").Copy
' 新規ブックがアクティブになっているので保存
ActiveWorkbook.SaveAs savePath, FileFormat:=xlOpenXMLWorkbook
ActiveWorkbook.Close SaveChanges:=False
MsgBox "新規ブックに保存しました:" & vbCrLf & savePath, vbInformation
End Sub
ポイント:
Sheets.Copy(引数なし)で新規ブックが自動作成される。手動でWorkbooks.Addする必要はない- コピー直後は新規ブックが
ActiveWorkbookになる FileFormat:=xlOpenXMLWorkbookは.xlsx形式で保存。マクロ付きで保存したい場合はxlOpenXMLWorkbookMacroEnabled(.xlsm)に変える- 同名ファイルが既に存在すると上書き確認ダイアログが表示される
—
コード(実務版)– 月別シートを別ブックに分割保存
1つのブックに「1月」「2月」…「12月」のシートがある場合に、各シートを個別のExcelファイルとして保存する。月次報告書の配布や、拠点別データの振り分けに便利。
'============================================================
' ■ 月別シートを別ブックに分割保存(実務版)
' → 指定シートを1枚ずつ新規ブックにコピーして保存
' → スキップ対象(目次・集計)は除外
' → 保存先フォルダがなければ自動作成
'============================================================
Sub SplitSheetsByMonth()
Dim srcBook As Workbook
Dim ws As Worksheet
Dim saveFolderPath As String
Dim saveFilePath As String
Dim count As Long
Dim skipCount As Long
Dim fso As Object
' ★ 保存先フォルダを書き換える(末尾の \ を忘れずに)
saveFolderPath = "C:\Users\(ユーザー名)\Desktop\月別分割\"
' ★ スキップするシート名(目次や集計シートなど)
Dim skipSheets As Variant
skipSheets = Array("目次", "集計")
Set srcBook = ThisWorkbook
Set fso = CreateObject("Scripting.FileSystemObject")
' 保存先フォルダがなければ作成
If Not fso.FolderExists(saveFolderPath) Then
fso.CreateFolder saveFolderPath
End If
' 確認ダイアログ
Dim msg As String
msg = "各シートを個別のExcelファイルに分割保存します。" & vbCrLf & _
"保存先:" & saveFolderPath & vbCrLf & vbCrLf & _
"実行しますか?"
If MsgBox(msg, vbYesNo + vbQuestion) = vbNo Then
Set fso = Nothing
Exit Sub
End If
count = 0
skipCount = 0
For Each ws In srcBook.Worksheets
' 非表示シートをスキップ
If ws.Visible <> xlSheetVisible Then
skipCount = skipCount + 1
GoTo NextSheet
End If
' スキップ対象のシートをスキップ
' ※ GoTo NextSheet は VBA でスキップ処理を書く定番パターン。
' ネストが深くならず可読性が高い
If IsInArray(ws.Name, skipSheets) Then
skipCount = skipCount + 1
GoTo NextSheet
End If
' 保存ファイル名を作成(シート名 + .xlsx)
saveFilePath = saveFolderPath & ws.Name & ".xlsx"
' シートを新規ブックにコピー
ws.Copy
' 新規ブックを保存して閉じる
On Error Resume Next
ActiveWorkbook.SaveAs saveFilePath, FileFormat:=xlOpenXMLWorkbook
If Err.Number <> 0 Then
MsgBox "保存に失敗しました:" & ws.Name & vbCrLf & _
Err.Description, vbExclamation
ActiveWorkbook.Close SaveChanges:=False
Err.Clear
On Error GoTo 0
GoTo NextSheet
End If
On Error GoTo 0
ActiveWorkbook.Close SaveChanges:=False
count = count + 1
NextSheet:
Next ws
Set fso = Nothing
MsgBox "完了しました。" & vbCrLf & _
"保存:" & count & " シート" & vbCrLf & _
"スキップ:" & skipCount & " シート" & vbCrLf & _
"保存先:" & saveFolderPath, vbInformation
End Sub
'============================================================
' ■ 補助関数: 値が配列に含まれるかチェック
'============================================================
Private Function IsInArray(val As String, arr As Variant) As Boolean
Dim i As Long
For i = LBound(arr) To UBound(arr)
If arr(i) = val Then
IsInArray = True
Exit Function
End If
Next i
IsInArray = False
End Function
使い方:
- コード内の
saveFolderPathを自分の保存先フォルダに書き換える skipSheetsにスキップしたいシート名を追加・削除する- Alt + F8 →「SplitSheetsByMonth」を選択して実行
- 確認ダイアログで「はい」を押す
- 各シートが個別の .xlsx ファイルとして保存される
保存先フォルダの自動作成: 保存先フォルダが存在しない場合、FileSystemObject の CreateFolder で自動作成する。MkDir ではなく FileSystemObject を使っている理由は、パスの存在確認(FolderExists)とフォルダ作成を同じオブジェクトで統一的に扱えるからだ。ファイルの存在確認も参考にしてほしい。
スキップ対象の管理: skipSheets = Array("目次", "集計") でスキップするシート名を管理。追加・削除は Array(...) 内を変更するだけ。補助関数 IsInArray で配列内に値が含まれるかチェックしている。Dictionaryを使えばより高速に判定できるが、シート数が数十枚程度なら配列ループで十分だ。
GoTo NextSheet の設計: VBAには Continue For がないため、ループ内でスキップするには GoTo ラベルを使うのが定番パターンだ。ネストを深くせずに読みやすいコードが書ける。
ファイル名の規則: シート名がそのままファイル名になる。シート名に \ / : * ? " < > | が含まれると保存に失敗するので注意。
複数シートに同じ処理を一括実行する方法(ヘッダー挿入や書式設定など)は 複数シートを一括処理する方法 を参照。
—
よくある落とし穴5選
1. Copy のつもりで Move を使い、元シートが消えた
自分もこれをやらかした。Sheets.Move を使ったら元ブックからシートが消えた。Move は「移動」だから当然なのだが、Copy のつもりで書いていた。メソッド名の1文字違いで元データを失いかけた。バックアップがあったから助かったが、冷や汗ものだった。
対策: Copy と Move は意味が全く違う。まずは Copy で試し、移動が必要な場合のみ Move を使う。Move を使うときは必ずバックアップを取る。
2. コピー先ブックが開いていなくてエラー
原因: Workbooks("コピー先.xlsx") は開いているブックのみ参照できる。閉じているブックを指定すると「インデックスが有効範囲にありません」エラーになる。
対策: コピー先ブックを事前にExcelで開いておく。またはコード内で Workbooks.Open を使って開く。
3. 数式が外部参照に変わってしまう
原因: コピー元シートに他のシートを参照する数式(例: =Sheet2!A1)があると、コピー後に外部参照(=[元ブック.xlsm]Sheet2!A1)に変わる。
対策: 数式ではなく値だけコピーしたい場合は、Sheets.Copy ではなく、新規シートを作って PasteSpecial xlPasteValues で値のみ貼り付ける。
4. ブック内最後の1シートを Move するとエラー
原因: Excelのブックには最低1枚のシートが必要。最後の1シートを Move しようとすると「オブジェクトが必要です」エラーになる。
対策: Move を実行する前にシート数をチェックする。If srcBook.Worksheets.Count <= 1 Then で事前に判定。
5. シート名にファイル名に使えない文字が含まれている
原因: シート名をファイル名に使って保存する場合(実務版)、シート名に \ / : * ? " < > | が含まれていると保存に失敗する。
対策: シート名からこれらの文字を除去するか、事前にシート名を変更しておく。
---
FAQ
Q1: コピー先ブックが閉じている場合、自動で開いてコピーしたい
Workbooks.Open でコピー先ブックを開いてからコピーする:
Dim dstBook As Workbook
Set dstBook = Workbooks.Open("C:\Users\(ユーザー名)\Desktop\コピー先.xlsx")
ThisWorkbook.Worksheets("売上データ").Copy _
After:=dstBook.Sheets(dstBook.Sheets.Count)
dstBook.Save
dstBook.Close
Q2: コピーしたシートの名前を変えたい
コピー直後は、コピーされたシートがアクティブになる。そのタイミングで名前を変更する:
ThisWorkbook.Worksheets("売上データ").Copy _
After:=dstBook.Sheets(dstBook.Sheets.Count)
' コピー直後のアクティブシートが、コピーされたシート
ActiveSheet.Name = "売上データ_202603"
Q3: シートではなくファイルをコピー・移動したい
シート単位ではなくファイル単位でコピー・移動する方法は ファイルを別フォルダにコピー・移動する方法 を参照。
Q4: 複数ブックのデータを1つに統合したい(逆の操作)
分割ではなく統合したい場合は 複数Excelファイルを1つに統合 を参照。
Q5: コピー後に元ブックのシートを削除したい
Copy した後に元シートを削除すれば、実質 Move と同じ動作になる。削除前に確認ダイアログを入れると安全:
' コピー
ThisWorkbook.Worksheets("売上データ").Copy _
After:=dstBook.Sheets(dstBook.Sheets.Count)
' 確認してから元シートを削除
If MsgBox("元シートを削除しますか?", vbYesNo + vbExclamation) = vbYes Then
Application.DisplayAlerts = False ' 削除確認を抑制
ThisWorkbook.Worksheets("売上データ").Delete
Application.DisplayAlerts = True
End If
---
まとめ
Sheets.Copy After:=で別ブックの末尾にシートをコピーできるSheets.Copy(引数なし)で新規ブックにコピーできるSheets.Moveは元ブックからシートがなくなる。必ずバックアップを取ってから使う- コピー先ブックは事前に開いておく必要がある
- 月別シートの分割保存は、ループ + 引数なし Copy + SaveAs で実現できる
シートのコピー・移動は、月次報告や拠点別データの配布など、実務で頻繁に使う操作だ。まずは最小版で1シートのコピーを試し、動きを確認してから応用版・実務版に進むのがおすすめだ。自分は最初、月別シートの分割保存に30分かかっていたが、実務版マクロを導入してからは数秒で12ファイルが自動生成されるようになった。配布先ごとにファイルを分けたい業務では特に効果が大きいので、ぜひ試してみてほしい。分割保存で作ったファイルをブックの保存の仕組みで自動バックアップしたり、CSV書き出しで他システム用に変換したりと、組み合わせの幅が広い。
関連記事
- ファイルを別フォルダにコピー・移動する方法 -- シートではなくファイル単位のコピー・移動はこちら
- 複数Excelファイルを1つに統合 -- 逆に複数ブックのデータを1つにまとめたい場合
- 複数シートを一括処理する方法 -- 1ファイル内の複数シートに同じ処理を実行
- シート名の取得・一括変更・存在チェックする方法 -- コピー前後のシート名を管理したい場合
- Excelファイルを自動で開いて処理して閉じる方法 -- コピー先ブックの自動オープン・クローズ
---
次にやりたくなること
- ファイルを別フォルダにコピー・移動する方法: 分割保存したファイルを別フォルダに整理したい場合
- 複数Excelファイルを1つに統合: 逆に、分割されたファイルを1つに統合したい場合
---
もっとカスタマイズしたい場合
「特定条件のシートだけ別ブックに振り分けたい」「コピー後にシート名を日付付きに変えたい」「コピーと同時にPDF出力もしたい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できる。
相談時に伝えると話が早い情報:
- Excel のバージョン / OS
- シートの枚数と構成(月別/拠点別など)
- コピー先のブック名またはフォルダ構成
- コピー後に行いたい処理(リネーム、書式変更など)


コメント