Excel VBAでは、Worksheets.Addを使って新しいワークシートを追加できます。
しかし、実務で複数のExcelブックを開きながらマクロを実行する場合、「シートを追加できたか」だけではなく、目的のブックへ正しく追加できたかが重要です。
例えば、マクロを保存しているブックとは別に「売上データ.xlsx」を開いて処理する場合、対象ブックを曖昧にしたコードでは、意図しないブックへシートを追加してしまう可能性があります。
特にActiveWorkbookは、その時点でアクティブになっているブックを対象とするため、処理途中で操作対象が変わるマクロでは注意が必要です。
このような誤操作を防ぐには、Workbookオブジェクトを明確に指定し、その配下にあるWorksheetsへ新しいシートを追加する設計が有効です。
この記事では、VBAで対象ブックを指定してシートを追加する基本から、ThisWorkbookとの違い、Workbook型の変数を利用した実務向けの書き方まで解説します。
✅ VBAでブックを指定してシートを追加する基本
VBAでシートを追加するとき、「Worksheets.Addを書けば目的のブックへ追加される」と考えてしまうことがあります。しかし、実務では複数のブックを同時に開くことがあり、対象ブックを曖昧にしたまま処理するのは安全ではありません。開発中には問題なく動いていても、利用者が別のブックを開いているだけで想定外の動作になる可能性があります。
また、処理対象がコードから読み取れないと、後から改修する担当者も「どのブックへ追加する処理なのか」を確認する必要があります。特に業務用マクロでは、Excelの現在の選択状態に頼るのではなく、コード側で操作対象を明確にすることが重要です。
・ThisWorkbookを指定してシートを追加する
マクロが保存されているブックへシートを追加したい場合は、ThisWorkbookを利用できます。
Sub AddSheetToThisWorkbook()
'マクロを保存しているブックへシートを追加
ThisWorkbook.Worksheets.Add
End Sub
このコードでは、
ThisWorkbook
└ Worksheets
└ Add
という関係で処理しています。
つまり、最初に対象となるブックをThisWorkbookで決め、そのブックのWorksheetsコレクションへ新しいワークシートを追加しています。
実務で重要なのは、単にコードを長くしているわけではないという点です。
例えば、
Worksheets.Add
だけでは、コードを読んだときに「どのブックへ追加するのか」が明確ではありません。
一方、
ThisWorkbook.Worksheets.Add
であれば、マクロを保存しているブックへ追加する処理だと判断できます。
複数ブックを扱う可能性があるマクロでは、このように対象を明示しておくことで意図しない操作を防ぎやすくなります。
・追加したシートをWorksheet変数で取得する
シートを追加した後に名前を変更したり、セルへ値を書き込んだりする場合は、追加されたシートをWorksheet型の変数へ格納しておくと扱いやすくなります。
Sub AddAndGetSheet()
Dim newSheet As Worksheet
'新しく追加したシートを取得
Set newSheet = ThisWorkbook.Worksheets.Add
'追加したシートへ初期値を設定
newSheet.Range("A1").Value = "作成日"
newSheet.Range("B1").Value = Date
End Sub
処理手順は次のとおりです。
newSheetをWorksheet型として宣言するThisWorkbook.Worksheets.Addでシートを追加する- 戻り値となる新しいシートを
newSheetへ格納する newSheetを利用して後続処理を行う
追加直後のシートはアクティブになりますが、
ActiveSheet.Range("A1").Value = "作成日"
のようにActiveSheetへ依存する必要はありません。
newSheetとして対象を保持しておけば、「今どのシートが選択されているか」ではなく「今回作成したシートはどれか」を基準として処理できます。
業務マクロでは、この違いが後から処理を追加するときにも重要になります。
新しく追加したシートへ任意の名前を設定する場合は、Nameプロパティを組み合わせます。Sheets.Addによる追加から名前の設定まで詳しく確認したい場合は、「【VBA】シートを追加して名前を付ける方法|Sheets.Add・Nameプロパティの実務活用」もあわせて参考にしてください。
✅ VBAのThisWorkbookとActiveWorkbookの違いを理解する
ブックを指定してシートを追加するとき、特に混同しやすいのがThisWorkbookとActiveWorkbookです。どちらもWorkbookを表すため似ていますが、必ず同じブックを指すわけではありません。
開発時に1つのブックしか開いていないと、この違いに気付かないままコードを作成してしまうことがあります。その状態で実際の業務環境へ移し、複数ブックを開いて使用すると、想定していないブックを操作する原因になります。どちらを使用するかは書き方の好みではなく、「どのブックを業務上の処理対象とするのか」で判断することが重要です。
・ThisWorkbookはマクロを保存しているブックを指定する
ThisWorkbookは、現在実行しているVBAコードが保存されているブックを表します。
例えば、
Sub AddSheet()
ThisWorkbook.Worksheets.Add
End Sub
とした場合、別のExcelブックが画面上で選択されていても、処理対象として明示しているのはThisWorkbookです。
例えば次のような状況を考えてみます。
業務ツール.xlsm ← VBAを保存
売上データ.xlsx ← 画面上で操作中
この状態で、
ThisWorkbook.Worksheets.Add
を実行するのであれば、コード上で指定している対象は「業務ツール.xlsm」です。
そのため、マクロ自身が保存されているブックを継続して操作する業務では、ThisWorkbookを利用すると対象を明確にできます。
・ActiveWorkbookは現在アクティブなブックを表す
一方、ActiveWorkbookは、その時点でExcel上のアクティブなブックを表します。
Sub AddSheetToActiveWorkbook()
ActiveWorkbook.Worksheets.Add
End Sub
例えば、
業務ツール.xlsm
売上データ.xlsx ← 現在アクティブ
という状態であれば、ActiveWorkbookとして扱われるのは「売上データ.xlsx」です。
これは、利用者が現在選択しているブックを対象に処理したい場合には便利です。
しかし、業務マクロで追加先が最初から決まっている場合は注意が必要です。
処理途中で別のブックを開いたり、ブックのアクティブ状態が変わったりすると、
ActiveWorkbook.Worksheets.Add
が指す対象も変わる可能性があります。
そのため、
「現在選択されているブックへ追加したい」
という明確な仕様がない限り、ActiveWorkbookへ安易に依存しない方が処理対象を管理しやすくなります。
・ThisWorkbookとActiveWorkbookを使い分ける基準
どちらを使うべきか迷った場合は、「誰が対象ブックを決めるのか」で考えると分かりやすくなります。
マクロ側で対象を固定する
↓
ThisWorkbookなどで明示
利用者が現在開いているブックを対象にする
↓
ActiveWorkbook
例えば、自社で使用する「月次集計ツール.xlsm」の中へ結果シートを作成するのであれば、ThisWorkbookを使う方が処理意図を明確にできます。
一方、「現在利用者が開いている任意のブックへシートを追加する」というツールであれば、ActiveWorkbookを使う設計にも意味があります。
重要なのは、ActiveWorkbookが悪いのではなく、目的を決めずに使うことを避けることです。
✅ VBAで特定のブックをWorkbook変数として指定する
実務では、マクロを保存しているブックへシートを追加するとは限りません。例えば、業務ツールから別の集計ブックを開き、そのブックへ新しいシートを作成する処理もあります。この場合にActiveWorkbookだけを頼りにすると、「現在どのブックがアクティブなのか」を常に意識しなければなりません。
また、ブック名をコード内の複数箇所へ直接記述すると、ファイル名変更時の修正漏れにもつながります。操作対象となるWorkbookを変数へ格納しておけば、その後の処理でも同じブックを明示的に利用でき、コードの役割も追いやすくなります。
・Workbook型の変数へ対象ブックを格納する
すでに開いている「売上データ.xlsx」へシートを追加する例を考えてみます。
Sub AddSheetToTargetWorkbook()
Dim targetBook As Workbook
Dim newSheet As Worksheet
'操作対象となるブックを取得
Set targetBook = Workbooks("売上データ.xlsx")
'対象ブックへ新しいシートを追加
Set newSheet = targetBook.Worksheets.Add
'追加したシートへ初期値を設定
newSheet.Range("A1").Value = "売上集計"
End Sub
このコードでは、最初に
Set targetBook = Workbooks("売上データ.xlsx")
として、操作対象をtargetBookへ格納しています。
その後は、
targetBook.Worksheets.Add
と記述できるため、どのブックへシートを追加しているのかが分かりやすくなります。
また、追加したシートについてもnewSheetへ格納しているため、
targetBook → 操作対象のブック
newSheet → 今回追加したシート
という役割を変数名から判断できます。
・ブック名を何度も直接指定しない理由
例えば、次のような書き方でも処理できます。
Workbooks("売上データ.xlsx").Worksheets.Add
一度しか対象ブックを使用しない短い処理なら、この書き方でも十分です。
しかし、その後にも同じブックへ処理を行う場合、
Workbooks("売上データ.xlsx").Worksheets("集計").Range("A1").Value = "売上"
Workbooks("売上データ.xlsx").Worksheets("集計").Range("B1").Value = Date
のように同じブック名を繰り返すと、コードが長くなります。
さらに、後からファイル名が変更された場合は、複数箇所を修正しなければなりません。
対象を最初に、
Set targetBook = Workbooks("売上データ.xlsx")
としておけば、後続処理ではtargetBookを利用できます。
ただし、ここでも変数化が常に正解というわけではありません。
1回しか参照しない簡単な処理まで細かく変数化すると、かえってコードを追いにくくなる場合があります。
対象ブックを後続処理でも繰り返し使用する場合や、処理対象を明確にしておきたい場合にWorkbook変数を利用するという考え方で使い分けるとよいでしょう。
✅ VBAで指定ブックの決まった位置にシートを追加する
対象ブックを正しく指定していても、シートの追加位置が曖昧では、ブック内のシート構成が想定と異なる場合があります。特に複数ブックを扱う処理では、「対象ブックは正しいが、追加位置はアクティブシートに依存していた」という設計を避けたいところです。
業務でシートの並び順が決まっている場合は、追加先となるブックだけでなく、どのシートの前後へ追加するのかまで同じWorkbookを基準として指定すると安全です。対象ブックと追加位置をセットで考えることで、利用者が現在どのシートを開いているかに左右されにくい処理にできます。
・指定ブック内のシートをAfterに指定する
例えば「売上データ.xlsx」の「入力」シートの後ろへ新しいシートを追加する場合は、次のように記述できます。
Sub AddSheetAfterInput()
Dim targetBook As Workbook
Dim newSheet As Worksheet
'操作対象となるブックを取得
Set targetBook = Workbooks("売上データ.xlsx")
'対象ブックの「入力」シートの後ろへ追加
Set newSheet = targetBook.Worksheets.Add( _
After:=targetBook.Worksheets("入力"))
End Sub
ポイントは、Worksheets.AddとAfterの両方で同じtargetBookを基準としていることです。
処理の流れは、
- 対象ブックを
targetBookへ格納する targetBook.Worksheets.Addで追加先ブックを指定するAfterでもtargetBook.Worksheets("入力")を指定する- 追加されたシートを
newSheetへ格納する
となります。
このように書いておけば、「どのブックの、どのシートを基準として追加するのか」がコード上から判断できます。
複数ブックを扱うVBAでは、単にシート追加を成功させるだけではなく、Workbook → Worksheetという対象関係を崩さずに記述することが、誤操作を防ぐポイントになります。
特定シートの前後ではなく、常にブック内の一番最後へ新しいシートを追加したい場合は、「【VBA】末尾にシートを追加する方法|最後のシートの後ろへ自動追加」で、最終シートを基準にした追加方法を詳しく解説しています。
✅ VBAで指定したブックが開いていない場合のエラーに注意する
Workbooks("売上データ.xlsx")のようにブック名を指定すれば、対象を明確にしてシートを追加できます。しかし、この書き方には「指定したブックがすでにExcelで開かれている」という前提があります。ファイルがパソコンや共有フォルダーに保存されているだけでは、Workbooksコレクションからそのブックを取得することはできません。
実務では、利用者が対象ファイルを開き忘れた状態でマクロを実行することも考えられます。開発者の環境では常に対象ブックを開いてテストしているため、この問題を見落とすこともあります。別ブックを操作するマクロでは、対象ファイルの存在だけでなく「現在Excelで開かれているか」まで意識して設計することが重要です。
・Workbooksで指定できるのは開いているブック
例えば、次のコードを考えてみます。
Sub AddSheetToTargetWorkbook()
Dim targetBook As Workbook
Set targetBook = Workbooks("売上データ.xlsx")
targetBook.Worksheets.Add
End Sub
「売上データ.xlsx」がすでに開かれていれば、targetBookとして取得できます。
一方、ファイル自体は存在していてもExcelで開かれていなければ、
Set targetBook = Workbooks("売上データ.xlsx")
で正常に取得できません。
ここで誤解しやすいのが、Workbooks("ファイル名")はパソコン内からファイルを検索しているわけではないという点です。
考え方としては、
Workbooks
↓
現在Excelで開かれているブックの集まり
となります。
そのため、
Workbooks("売上データ.xlsx")
は、「現在開かれているブックの中から売上データ.xlsxを取得する」という処理です。
ファイルを開く処理までマクロ側で行いたい場合は、別途Workbooks.Openを使用します。
ブックだけでなく、操作対象となるシートが存在するかどうかも事前に確認したい場合があります。「【VBA】シートがなければ作成する方法|存在確認して安全に追加する実務コード」では、シートの存在確認と新規追加を組み合わせる方法を解説しています。
✅ VBAでブックを開いてからシートを追加する
別ブックを処理するマクロでは、「利用者に対象ブックを開いてもらってから実行する」という運用もできますが、開き忘れによるエラーが発生しやすくなります。処理対象となるファイルがあらかじめ決まっている場合は、VBA側でブックを開いてから操作する方法も有効です。
ただし、ブックを開いた直後にActiveWorkbookへ頼ると、後から処理が追加されたときに対象が分かりにくくなることがあります。ブックを開いた結果をWorkbook変数として取得し、その変数を後続処理で使用する方が対象を明確にできます。特に「開く・シートを追加する・データを書き込む・保存する」と処理が続く場合、この設計が役立ちます。
・Workbooks.Openの戻り値をWorkbook変数へ格納する
例えば、指定したExcelファイルを開いてからシートを追加する場合は、次のように記述できます。
Sub OpenBookAndAddSheet()
Dim targetBook As Workbook
Dim newSheet As Worksheet
Dim filePath As String
'操作対象となるファイルのパス
filePath = "C:\業務データ\売上データ.xlsx"
'対象ブックを開いてWorkbook変数へ格納
Set targetBook = Workbooks.Open(filePath)
'開いたブックへ新しいシートを追加
Set newSheet = targetBook.Worksheets.Add
End Sub
処理手順は次のとおりです。
filePathへ対象ファイルのパスを設定するWorkbooks.Openで対象ブックを開く- 開いたWorkbookを
targetBookへ格納する targetBook.Worksheets.Addでシートを追加する- 作成されたWorksheetを
newSheetへ格納する
ここで重要なのは、
Workbooks.Open filePath
ActiveWorkbook.Worksheets.Add
とするのではなく、
Set targetBook = Workbooks.Open(filePath)
Set newSheet = targetBook.Worksheets.Add
としている点です。
前者でも直後であれば正常に動く場合があります。
しかし後から別の処理が追加されると、「その時点でActiveWorkbookは本当に売上データ.xlsxなのか」という確認が必要になります。
targetBookとして保持しておけば、後続処理でも対象ブックを明確にできます。
・ファイルパスを変数として分離しておく
短いコードであれば、
Set targetBook = Workbooks.Open("C:\業務データ\売上データ.xlsx")
としても問題ありません。
一方、後からファイルパスを変更したり、別の処理でも同じパスを利用したりする場合は、
Dim filePath As String
filePath = "C:\業務データ\売上データ.xlsx"
のように分けておくと修正箇所を把握しやすくなります。
さらに実務では、ファイルパスが毎月変化することもあります。
例えば、
C:\業務データ\2026年08月\売上データ.xlsx
C:\業務データ\2026年09月\売上データ.xlsx
のような運用であれば、パスをコードへ固定するより、年月から組み立てたり、設定用シートから取得したりする設計も考えられます。
シート追加処理そのものは同じでも、対象ブックをどのように取得するかを分離して考えることで、仕様変更へ対応しやすくなります。
✅ VBAで複数ブックを扱うときは対象を明確にする
複数ブックを扱うマクロで怖いのは、エラーが発生することだけではありません。コード自体は最後まで正常に実行されたにもかかわらず、別のブックへシートを追加したり、別のシートへ値を書き込んだりする方が問題になる場合があります。
特にActiveWorkbookやActiveSheetを多用すると、Excelの現在の状態によって処理対象が変化します。利用者から見ると「マクロは正常終了した」ように見えるため、誤操作に気付くのが遅れる可能性もあります。業務用VBAでは、エラーを防ぐだけでなく「間違った対象へ正常に処理してしまうこと」を防ぐ設計も重要です。
・WorkbookとWorksheetの役割を分けて管理する
例えば、別ブックへシートを追加した後、そのシートへデータを書き込む処理なら次のようにできます。
Sub CreateReportSheet()
Dim targetBook As Workbook
Dim newSheet As Worksheet
'操作対象となるブックを明確にする
Set targetBook = Workbooks("売上データ.xlsx")
'対象ブックへ新しいシートを追加
Set newSheet = targetBook.Worksheets.Add
'追加したシートへ初期情報を書き込む
With newSheet
.Range("A1").Value = "売上集計"
.Range("A2").Value = "作成日"
.Range("B2").Value = Date
End With
End Sub
このコードでは、
targetBook
↓
処理対象となるブック
newSheet
↓
targetBookへ今回追加したシート
という役割が明確です。
後続処理ではnewSheetを利用するため、
Range("A1").Value = "売上集計"
のように、対象シートを省略した記述も避けられます。
実務では、こうした省略が積み重なるほど「現在何を操作しているのか」が分かりにくくなります。
特に別の担当者がコードを改修する場合、対象ブックやシートが変数名から判断できるだけでも、処理を追いやすくなります。
・SelectやActivateを前提にしなくても処理できる
シートへ値を書き込むために、
targetBook.Activate
newSheet.Select
Range("A1").Value = "売上集計"
とする必要はありません。
すでにnewSheetを取得しているのであれば、
newSheet.Range("A1").Value = "売上集計"
と直接指定できます。
SelectやActivateが必要になる処理もありますが、単純なセル操作のためだけに画面上の選択状態を切り替える必要はありません。
直接オブジェクトを指定することで、コードを読んだときにも処理対象が分かりやすくなります。
また、利用者が画面上でどのシートを見ているかと、VBAが内部でどのシートを処理するかを切り離せるのもメリットです。
複数ブックを扱う処理は、シート追加だけでなくデータ転記でも対象ブックを明確にすることが重要です。抽出したデータを別のExcelブックへ出力する方法については、「【VBA】フィルター結果を別ブックにコピーする方法|自動転記で効率化する実践テクニック」も参考になります。
✅ VBAでブックを指定する方法を実務に合わせて使い分ける
ブックを指定する方法はいくつかあるため、「常にThisWorkbookを使えば安全」「ActiveWorkbookは使わない方がよい」と単純に決める必要はありません。重要なのは、業務上どのブックを処理対象とするのかを先に決めることです。マクロ自身のブックを処理する場合と、利用者が選択したブックを処理する場合では適切な指定方法が異なります。
また、決められた外部ファイルを自動処理するのであれば、ブックを開いてWorkbook変数へ保持する設計も考えられます。目的と指定方法が一致していれば、後からコードを見たときにも処理意図を理解しやすくなります。
・処理対象によってWorkbookの指定方法を選ぶ
基本的な判断基準を整理すると、次のようになります。
| 処理したいブック | 指定方法の例 |
|---|---|
| マクロを保存しているブック | ThisWorkbook |
| 現在アクティブなブック | ActiveWorkbook |
| 開いている特定のブック | Workbooks("ファイル名.xlsx") |
| VBAで新しく開いたブック | Set targetBook = Workbooks.Open(...) |
例えば、マクロ付きの集計ツール自身へ結果シートを作るのであれば、
Set newSheet = ThisWorkbook.Worksheets.Add
とすることで目的が明確になります。
すでに開かれている固定のブックなら、
Set targetBook = Workbooks("売上データ.xlsx")
とする方法があります。
VBA側でファイルを開くのであれば、
Set targetBook = Workbooks.Open(filePath)
として、開いた結果をそのまま保持できます。
どの方法でもシートを追加できますが、業務上の対象が何によって決まるのかを基準に選択することが大切です。
新しい空白シートを追加するのではなく、既存シートのレイアウトや数式を引き継いで複製したい場合は、「【VBA】シートをコピーして追加する方法|Copyメソッドで複製する実務コード」で、Copyメソッドを使った追加方法を解説しています。
✅ VBAで指定ブックへシートを追加する実務上の注意点
対象ブックを変数で管理していても、実際の運用条件まで考えなければ完全に安全とはいえません。例えば、ファイル名が変更されればWorkbooks("ファイル名")では取得できなくなりますし、ファイルを開く処理では指定したパスが存在しない可能性もあります。
また、読み取り専用で開かれたファイルや、利用者が保存せずに閉じた場合など、シート追加後の運用も考える必要があります。すべてのケースへ過剰なエラー処理を入れる必要はありませんが、どの条件を前提として動くマクロなのかは整理しておくべきです。特に複数の利用者が使う業務ツールでは、自分の環境だけで動くコードにしないことが重要です。
・ブック名や保存場所の変更を想定する
例えば、
Set targetBook = Workbooks("売上データ.xlsx")
は、ブック名が「売上データ_2026.xlsx」に変更されれば、そのままでは使用できません。
同様に、
filePath = "C:\業務データ\売上データ.xlsx"
も保存場所が変更されれば修正が必要です。
業務上ファイル名や保存先が固定されているのであれば、この方法でも問題ありません。
一方、頻繁に変更されるのであれば、設定値をワークシートから取得するなど、コードを直接修正しなくても変更できる仕組みを検討する余地があります。
重要なのは、最初から複雑な仕組みにすることではありません。
変更される可能性が高い情報と、固定された処理ロジックを必要に応じて分離することで、後から仕様変更へ対応しやすくなります。
・追加したシートを後続処理でも明示する
シート追加後に名前変更、データ転記、書式設定などを行う場合は、追加したシートを保持したまま処理する方が安全です。
Dim targetBook As Workbook
Dim newSheet As Worksheet
Set targetBook = Workbooks("売上データ.xlsx")
Set newSheet = targetBook.Worksheets.Add
'以降は今回追加したシートを明示して処理する
newSheet.Range("A1").Value = "集計結果"
こうしておけば、途中で別のシートがアクティブになっても、newSheetが示す対象は変わりません。
シートを追加する処理では、追加する瞬間だけでなく、追加したシートをその後どのように扱うのかまで考えて変数を設計すると、処理全体が分かりやすくなります。
シート追加後に利用者へそのシートを表示したい場合など、意図的にシートを選択・表示する処理が必要になることもあります。「【VBA】指定したシートを開く方法|Activate・Selectの使い方と実務応用を徹底解説」では、ActivateとSelectの使い分けや注意点を解説しています。
✅ まとめ:VBAではブックを明示してシートを安全に追加しよう
VBAでシートを追加するだけなら、Worksheets.Addを使った短いコードでも実現できます。しかし、複数ブックを扱う実務では、「どのブックへ追加するのか」を明確にすることが重要です。
特にActiveWorkbookやActiveSheetへ無意識に依存すると、Excelの状態によって処理対象が変わる可能性があります。WorkbookとWorksheetをそれぞれ変数として管理しておけば、操作対象をコード上で明確にしながら後続処理へつなげられます。
- マクロを保存しているブックは
ThisWorkbookで指定できる ActiveWorkbookは現在アクティブなブックを表すため、用途を理解して使用する- 開いている特定ブックは
Workbooks("ファイル名")から取得できる - 開いていないファイルは
Workbooks("ファイル名")だけでは取得できない Workbooks.Openの戻り値をWorkbook変数へ格納すると後続処理で扱いやすい- シート追加後はWorksheet変数へ保持すると処理対象を明確にできる
- 複数ブックを扱う処理では、SelectやActivateへの不要な依存を避ける
- ファイル名や保存場所が変更される業務では、変更箇所を分離する設計も検討する
実務で大切なのは、単にWorksheets.Addを実行することではなく、「どのブックを、どのシートを、何のために操作しているのか」がコードから判断できる状態にすることです。
対象ブックを明示してから新しいシートを取得する流れを身につけておけば、別ブックへの集計結果の出力や、複数ファイルを扱う自動化処理にも発展させやすくなります。