Excel VBAでワークシートを追加するとき、「新しいシートを作成するだけでなく、必ず一番最後へ追加したい」というケースがあります。
たとえば、毎月新しい集計シートを追加する処理や、処理結果を保存するための出力用シートを既存シートの後ろへ作成する場合です。
VBAではWorksheets.Addで新しいワークシートを作成できますが、追加位置を指定しなければ、必ずしもブックの末尾へ作成されるとは限りません。
末尾へ確実に追加するには、現在の最後のシートを取得し、After引数でそのシートの後ろを指定する方法が基本です。
ただし、実務ではSheetsとWorksheetsの違いや、追加したシートをその後の処理でどう扱うかも考えておく必要があります。
この記事では、VBAで最後のシートを取得して、その後ろへ新しいワークシートを追加する基本から、後から修正しやすいコードにするための考え方まで解説します。
✅ VBAで末尾にシートを追加する基本方法
VBAで末尾へシートを追加するときに重要なのは、単にWorksheets.Addを実行するだけではないという点です。Addメソッドには追加位置を指定できるBeforeとAfterがあり、末尾追加ではAfterを利用します。ここで誤解されやすいのが、「Addを実行すれば自動的に一番右へ追加される」という考え方です。シートの選択状態などに依存したコードは、ユーザーの操作やマクロの変更によって結果が変わる可能性があります。
業務用マクロでは、画面上の状態ではなくコード側で追加位置を明確にすることが大切です。まずは最後のワークシートを取得し、その後ろへ追加する基本形を確認しましょう。
・最後のワークシートの後ろへ追加するコード
現在のブックで最後にあるワークシートの後ろへ新しいシートを追加する場合は、次のように記述できます。
Sub AddWorksheetToEnd()
With ThisWorkbook
' 最後のワークシートの後ろへ新しいシートを追加
.Worksheets.Add After:=.Worksheets(.Worksheets.Count)
End With
End Sub
ポイントとなるのは、次の部分です。
.Worksheets(.Worksheets.Count)
Worksheets.Countによって、ブック内に存在するワークシートの枚数を取得します。
たとえば、ワークシートが5枚ある場合は、
Worksheets(5)
となり、5番目、つまり最後のワークシートを参照できます。
そのワークシートをAfterへ指定することで、
Worksheets.Add After:=最後のワークシート
という処理になります。
基本的な流れを整理すると、次のとおりです。
- シートを追加するブックを指定する
Worksheets.Countでワークシート数を取得する- 最後のワークシートを特定する
Afterに最後のワークシートを指定するWorksheets.Addで新しいワークシートを追加する
単に「シートを追加する」のではなく、現在のシート構成から末尾を判断して追加するのがポイントです。
・なぜAfterを指定してシートを追加するのか
新しいワークシートを追加するだけであれば、次のようなコードでも実行できます。
ThisWorkbook.Worksheets.Add
しかし、このコードから分かるのは「新しいワークシートを追加する」ということだけです。
「どの位置へ追加したいのか」という設計意図までは表現されていません。
一方、
With ThisWorkbook
.Worksheets.Add After:=.Worksheets(.Worksheets.Count)
End With
であれば、最後のワークシートを基準にして追加することが明確です。
実務では、シートの並び順自体に意味を持たせているブックがあります。
たとえば、
「入力」→「確認」→「集計」→「出力結果」
という順番で管理している場合、新しい出力結果シートを途中へ作成すると、利用者にとって分かりにくくなります。
追加位置をコードで指定しておけば、ユーザーがどのワークシートを選択しているかに依存しにくくなり、想定した位置へシートを作成できます。
1枚だけでなく複数のワークシートをまとめて追加したい場合は、Count引数やFor文を使う方法があります。複数枚を追加する場合の使い分けについては、「【VBA】複数シートを一括追加する方法|複数枚の作成と実務での使い分け」で詳しく解説しています。
✅ VBAでWorksheets.Countを使って最後のシートを取得する仕組み
Worksheets(.Worksheets.Count)という記述は、VBAに慣れていないと少し分かりにくく見えるかもしれません。しかし、この仕組みを理解しておくと、末尾への追加だけでなく「最後のワークシートを取得する」「最後のシートを基準に処理する」といったコードにも応用できます。ここで注意したいのは、シート番号を固定値で指定しないことです。
たとえばWorksheets(5)と書けば、ワークシートが増減したときに最後のシートではなくなります。実務ではユーザーがシートを追加したり削除したりすることもあるため、現在の枚数から最後の位置を判断する方が柔軟です。Countを単なる枚数取得としてではなく、「現在の末尾を求めるために利用する」と理解しておきましょう。
・Worksheets.Countから最後のシートを求める方法
たとえば、ブックに次の4枚のワークシートがあるとします。
入力
確認
集計
出力
この場合、
ThisWorkbook.Worksheets.Count
の結果は4です。
その値をワークシートのインデックスとして利用すると、
ThisWorkbook.Worksheets(4)
となり、「出力」シートを参照できます。
そのため、
With ThisWorkbook
.Worksheets.Add After:=.Worksheets(.Worksheets.Count)
End With
と記述すれば、「出力」の後ろへ新しいワークシートが追加されます。
後からワークシートが6枚に増えた場合でも、Worksheets.Countは自動的に6となるため、コード内のシート番号を修正する必要はありません。
これが、
Worksheets.Add After:=Worksheets(4)
のような固定値指定との大きな違いです。
業務ファイルではシート構成が変更される可能性があるため、現在の状態から末尾を判断するコードにしておくことが、再利用性や保守性の向上につながります。
・最後のワークシートを変数で保持する方法
処理が少し複雑になる場合は、最後のワークシートをオブジェクト変数へ格納する方法もあります。
Sub AddWorksheetAfterLast()
Dim lastWorksheet As Worksheet
With ThisWorkbook
' 現在の最後のワークシートを保持
Set lastWorksheet = .Worksheets(.Worksheets.Count)
' 最後のワークシートの後ろへ追加
.Worksheets.Add After:=lastWorksheet
End With
End Sub
単純に1枚追加するだけなら、ここまで分ける必要はありません。
しかし、その後の処理でも最後のワークシートを参照する場合や、コードが長くなる場合には、lastWorksheetという意味の分かる変数へ保持することで処理の目的を読み取りやすくできます。
「変数を増やせば保守性が上がる」というわけではなく、同じオブジェクトを何度も扱うか、変数にすることで意図が分かりやすくなるかを基準に判断するとよいでしょう。
✅ VBAで末尾に追加するときのSheetsとWorksheetsの違い
末尾へのシート追加を調べると、Sheets(Sheets.Count)とWorksheets(Worksheets.Count)の両方を見かけることがあります。一見すると同じように見えますが、厳密には対象となるコレクションが異なります。この違いを意識せずコードをコピーすると、グラフシートなどを含むブックで想定と異なる位置になる可能性があります。一般的な業務ブックではワークシートだけを使用していることも多いため、違いに気づきにくいポイントです。
しかし、末尾を「ブック全体の最後」と考えるのか、「ワークシートの中で最後」と考えるのかによって適切な書き方が変わります。後からシート構成が変わっても意図した動作を維持するために、両者の違いを整理しておきましょう。
・Worksheetsで最後のワークシートを基準にする方法
今回のように、ワークシートだけを対象として末尾へ新しいワークシートを追加するのであれば、Worksheetsを使用すると処理の意図が分かりやすくなります。
With ThisWorkbook
.Worksheets.Add After:=.Worksheets(.Worksheets.Count)
End With
Worksheetsコレクションは、Excelのワークシートを対象にします。
一方、Sheetsはワークシートだけでなくグラフシートなども含む、より広いコレクションです。
そのため、
Sheets(Sheets.Count)
と
Worksheets(Worksheets.Count)
は、ブックの構成によって同じシートを指すとは限りません。
通常のワークシートだけで構成されたブックでは結果が同じように見えますが、実務コードでは「何を最後と定義するのか」を明確にして使い分けることが重要です。
今回の記事では、新しいワークシートを既存ワークシートの末尾へ追加することを目的としているため、基本コードではWorksheetsを使用しています。
・Sheetsを使ってブック全体の一番右へ追加する方法
「最後のワークシート」ではなく、ブックに存在するすべての種類のシートを基準として一番右へ追加したい場合は、Sheetsを利用できます。
Sub AddWorksheetToRightEnd()
With ThisWorkbook
' ブック全体で最後にあるシートの後ろへ追加
.Worksheets.Add After:=.Sheets(.Sheets.Count)
End With
End Sub
ここでは、新しく追加するものはワークシートなのでWorksheets.Addを使用し、追加位置の基準にはSheetsを使用しています。
つまり、
.Sheets(.Sheets.Count)
でブック全体の最後にあるシートを取得し、その後ろへ新しいワークシートを追加しています。
通常のワークシートしか存在しないブックでは、前半で紹介した次のコードとの違いを意識する機会は少ないでしょう。
.Worksheets.Add After:=.Worksheets(.Worksheets.Count)
しかし、グラフシートなどが含まれる可能性がある場合には意味が変わります。
実務では、単に「最後」と考えるのではなく、
- 最後のワークシートの後ろなのか
- ブック全体で一番右にあるシートの後ろなのか
を仕様として明確にしておくことが大切です。
✅ VBAで末尾に追加したシートを変数で取得する方法
末尾へシートを追加しただけで処理が終了するケースは、実務ではそれほど多くありません。追加した後にシート名を変更したり、見出しを入力したり、データを書き込んだりすることが一般的です。ここでよくあるのが、追加後にActiveSheetを使って新しいシートを操作する方法です。短いコードでは問題なく動作するように見えますが、途中に別シートを選択する処理が追加されると対象が変わる可能性があります。
また、「末尾に追加したのだから最後のシートを再取得すればよい」という位置依存のコードも、処理が複雑になるほど分かりにくくなります。追加した時点でそのワークシートを変数へ保持しておくと、後続処理の対象を明確にできます。
・追加したワークシートをWorksheet変数で保持する方法
Worksheets.Addで追加したワークシートは、Worksheet型の変数へ格納できます。
Sub AddWorksheetAndGetReference()
Dim newWorksheet As Worksheet
With ThisWorkbook
' 末尾へ追加したワークシートを変数で保持
Set newWorksheet = .Worksheets.Add( _
After:=.Worksheets(.Worksheets.Count))
End With
' 追加したワークシートへ初期値を設定
newWorksheet.Range("A1").Value = "入力項目"
End Sub
このコードでは、新しく追加されたワークシートをnewWorksheetへ直接格納しています。
処理の流れは次のとおりです。
newWorksheetをWorksheet型として宣言する- 現在の最後のワークシートを取得する
- その後ろへ新しいワークシートを追加する
- 追加したワークシートを
newWorksheetへ格納する newWorksheetを使って後続処理を行う
この書き方にしておけば、
ActiveSheet.Range("A1").Value = "入力項目"
のように、現在選択されているシートへ依存する必要がありません。
また、追加後に改めて、
Worksheets(Worksheets.Count)
からシートを取得し直す必要もありません。
「作成したシートを、その場で取得して以降の処理に使用する」という流れがコードから読み取りやすくなるため、後から処理を追加するときにも対象を追いやすくなります。
・追加した末尾シートへ名前を付ける場合
追加したシートを変数で保持しておけば、名前の変更も同じオブジェクトに対して行えます。
Sub AddWorksheetWithName()
Dim newWorksheet As Worksheet
With ThisWorkbook
' 最後のワークシートの後ろへ追加
Set newWorksheet = .Worksheets.Add( _
After:=.Worksheets(.Worksheets.Count))
End With
' 追加したワークシートに名前を設定
newWorksheet.Name = "作業用"
End Sub
この方法なら、「追加したシートはどれなのか」をシート番号などから探し直す必要がありません。
ただし、すでに「作業用」という名前のシートが存在する場合、同じ名前へ変更しようとするとエラーになります。
実務では、シート名の重複確認や、すでに存在する場合に追加するのか再利用するのかまで考えておく必要があります。
特に同じマクロを何度も実行できる業務ファイルでは、単純な追加と命名だけで完成とせず、再実行時の動作も確認しておきましょう。
追加したワークシートへ名前を設定する場合は、Nameプロパティの使い方だけでなく、既存シートとの名前の重複にも注意が必要です。シート追加と命名を詳しく確認したい場合は、「【VBA】シートを追加して名前を付ける方法|Sheets.Add・Nameプロパティの実務活用」も参考にしてください。
✅ VBAで別ブックの末尾へシートを追加するときの考え方
複数のExcelファイルを扱うマクロでは、シートを末尾へ追加する対象ブックを間違えないことが重要です。ActiveWorkbookや対象を省略したWorksheetsは、実行時の状態によって参照先が変わる可能性があります。特に処理途中で別ブックを開くマクロでは、「最初は動いていたのに処理を追加したら別ファイルへシートが作成された」といった問題につながります。
末尾追加では、追加先だけでなく「最後のシートをどのブックから取得しているか」も一致させなければなりません。別ブックを扱う場合ほど、対象オブジェクトをコード上で明確にすることが大切です。画面上でブックを切り替えるのではなく、ブックオブジェクトを基準に処理を組み立てましょう。
・Workbook変数を使って追加先を明確にする方法
すでに対象となるブックをWorkbook型の変数で保持している場合は、その変数を基準に末尾を取得できます。
Sub AddWorksheetToTargetWorkbook()
Dim targetWorkbook As Workbook
Dim newWorksheet As Worksheet
' 今回はマクロを保存しているブックを対象とする
Set targetWorkbook = ThisWorkbook
With targetWorkbook
' 対象ブックの最後のワークシートの後ろへ追加
Set newWorksheet = .Worksheets.Add( _
After:=.Worksheets(.Worksheets.Count))
End With
End Sub
この例では説明を分かりやすくするためThisWorkbookを代入していますが、実際には別の処理で開いたブックなどをtargetWorkbookへ設定して使用できます。
大切なのは、
targetWorkbook.Worksheets
を基準に、追加先と最後のワークシートの取得先を同じブックに統一することです。
別ブックへの追加方法そのものを実装するときは、ブックの取得方法や開閉処理まで含めて設計する必要があります。
今回の末尾追加では、「対象ブックが決まった後、そのブック内のどこへ追加するか」という役割に分けて考えると、コードを整理しやすくなります。
別のExcelブックへシートを追加する場合は、末尾位置だけでなく、追加先となるWorkbookオブジェクトを正しく指定することが重要です。別ブックへの追加方法については、「【VBA】ブックを指定してシートを追加する方法」で詳しく解説しています。
✅ VBAで末尾にシートを追加するときの実務上の注意点
末尾追加は1行でも記述できますが、実務では「一番右へ作成された」という結果だけを確認して終わらせないことが大切です。特に、マクロの再実行、シート名の重複、対象ブックの変更はトラブルにつながりやすいポイントです。
また、後続処理でActiveSheetを使い続けると、コードの追加や変更によって操作対象が変わる可能性があります。さらに、シートの並び順だけを頼りに対象を特定すると、ユーザーによる並べ替えの影響を受けることがあります。業務で継続的に使用するマクロでは、「末尾に作る」ことと「作ったシートを正しく扱う」ことを分けずに考える必要があります。最後に、安全に利用するための確認事項を整理しておきましょう。
・末尾追加のコードで確認しておきたいポイント
実務で使用する場合は、次のような点を確認しておくと安全です。
- 追加先のブックが正しく指定されているか
- 「末尾」が最後のワークシートなのか、ブック全体の一番右なのか
- 同じマクロを再実行しても問題ないか
- シート名を設定する場合、同名シートが存在しないか
- 追加したシートを後続処理で正しく参照できているか
ActiveSheetなど画面の選択状態へ必要以上に依存していないか
たとえば、毎月1回だけ新しいシートを追加するマクロでも、利用者が誤って2回実行すれば2枚作成されます。
毎回新しいシートを追加する仕様なら問題ありませんが、「特定のシートがなければ準備する」という目的であれば、存在確認を行ってから追加する方が適しています。
また、既存シートをひな形として同じレイアウトのシートを末尾へ増やしたい場合は、空のワークシートを作成するAddではなく、既存シートをCopyする方法が適していることもあります。
「新しい空シートが必要なのか」「既存シートを複製したいのか」まで整理してから処理方法を選ぶことが、不要なコードを増やさないポイントです。
毎回新しいシートを作成する必要がない場合は、既存シートの有無を確認してから追加する方法も有効です。再実行による重複作成を防ぎたい場合は、「【VBA】シートがなければ作成する方法|存在確認して安全に追加する実務コード」もあわせて確認してみてください。
✅ まとめ:VBAで最後のシートを取得して末尾へ安全に追加しよう
VBAでシートを末尾へ追加するときは、Worksheets.Addだけでなく、最後のシートを取得してAfterへ指定することが基本です。ただし、WorksheetsとSheetsでは「最後」と判断する対象が異なるため、ブックの構成に合わせて選ぶ必要があります。
また、追加したシートを後から操作する場合は、ActiveSheetへ依存するよりもWorksheet型の変数へ保持する方が処理対象を明確にできます。別ブックを扱う場合も、追加先と最後のシートの取得先を同じWorkbookオブジェクトに統一することが重要です。単に末尾へ追加するだけではなく、その後の利用方法まで考えてコードを組み立てることで、仕様変更にも対応しやすくなります。
Afterを指定すると最後のシートの後ろへ追加できるWorksheets.Countで現在の最後のワークシートを求められるWorksheetsとSheetsでは「最後」の対象範囲が異なる- ブック全体の一番右へ追加するなら
Sheets(Sheets.Count)を基準にできる - 追加したシートはWorksheet型の変数へ保持すると扱いやすい
ActiveSheetに依存しすぎないことで後から処理を変更しやすくなる- 別ブックでは追加先と末尾の取得先を同じブックに統一する
- 再実行やシート名の重複も考慮して実務コードを設計する
まずはAfter:=Worksheets(Worksheets.Count)の仕組みを理解し、そのうえで「どのブックの、どの種類のシートを基準に末尾とするのか」を明確にしてみてください。シートの追加位置と追加後の参照方法まで意識することで、より安全で保守しやすいVBA処理につながります。