
Excel VBAで別ブックを操作するときに、次の3つで迷うことがあります。
ThisWorkbookActiveWorkbookWorkbooks
どれもブックを扱うためのものですが、指している対象が違います。
この違いを曖昧にしたまま書くと、別ブック操作で意図しないブックを書き換える事故につながることがあります。
結論
ThisWorkbook、ActiveWorkbook、Workbooks は似ていますが、指しているものが違います。
-
ThisWorkbookはVBAコードが入っているブック -
ActiveWorkbookはいまアクティブなブック -
Workbooksは開いているブック全体の集合
ツールブック自身を操作するなら ThisWorkbook。
いま前面のブックを対象にする一時処理なら ActiveWorkbook。
開いているブックを名前で指定したり、外部ブックを開いたりするなら Workbooks。
ただし、実務配布では ActiveWorkbook 依存を減らす方が安全です。
外部ブックを開く場合は、Workbooks.Open したブックを Workbook 変数で受けて、targetWb や templateWb のように対象ブックを明示するのが無難です。
ThisWorkbookとは
ThisWorkbook は、VBAコードが入っているブックを指します。
たとえば、マクロ入りツールブック自身を操作したい場合に使います。
向いている場面は次のようなものです。
- マクロ付きツール本体を操作する
- 設定シートを読む
- マスタシートを参照する
- ログシートへ書き込む
- メニューシートや内部処理用シートを扱う
ユーザーが別のブックを前面にしていても、ThisWorkbook が指す対象は変わりません。
そのため、ツールブック自身の設定やログを扱う場合には分かりやすいです。
一方で、ユーザーが開いた別ブックを操作する用途には向きません。
ActiveWorkbookとは
ActiveWorkbook は、現在アクティブになっているブックを指します。
つまり、画面上でいま前面にあるブックです。
ここが事故の入口になりやすいところです。
ActiveWorkbook は、マクロが入っているブックとは限りません。
ユーザーが別ブックをクリックしたり、処理中に別ブックが前面に出たりすると、対象が変わる可能性があります。
自分用の一時的な作業補助で、「いま前面のブックに対して処理する」と明確に決めている場合には使えます。
ただし、配布用Excelや業務用マクロでは注意が必要です。
Workbooksとは
Workbooks は、Excelで開いているブック全体の集合です。
たとえば、次のように開いているブックを名前で指定できます。
Workbooks("Book1.xlsx").Worksheets(1).Range("A1").Value = "確認"
また、外部ブックを開くときにも使います。
Workbooks.Open "C:\sample\sample.xlsx"
ただし、名前違いや未オープンのブックを指定するとエラーになります。
同名ブックやファイル名変更にも注意が必要です。
実務では、Workbooks.Open したブックは Workbook 変数で受ける方が安全です。
比較表
| 種類 | 指す対象 | 向いている場面 | 注意点 |
|---|---|---|---|
| ThisWorkbook | VBAコードが入っているブック | ツール本体の設定・マスタ・ログ操作 | 別ブック操作には向かない |
| ActiveWorkbook | 現在アクティブなブック | いま前面のブックを対象にする一時処理 | 複数ブック環境では対象がズレやすい |
| Workbooks | 開いているブック全体の集合 | 名前指定、外部ブックを開く処理 | 名前違い、未オープン、同名ブックに注意 |
| Workbook変数 | 特定のブックを変数に固定 | 複数ブック処理、配布用マクロ | 変数管理が必要 |
危ない書き方
複数ブックを扱う処理で、次のように書くと対象が曖昧になります。
ActiveWorkbook.Sheets(1).Range("A1").Value = "処理済み"
このコードは、現在アクティブなブックの1枚目のシートに書き込みます。
つまり、どのブックに書き込むかは、実行時の画面状態に依存します。
自分のPCでは問題なく動いても、他人のPCや別の操作順では、違うブックに書き込む可能性があります。
安全寄りの書き方
ツールブック自身を操作するなら、ThisWorkbook を使います。
ThisWorkbook.Worksheets("設定").Range("A1").Value = "処理済み"
外部ブックを開いて操作するなら、Workbooks.Open の戻り値を Workbook 変数で受けます。
Dim targetWb As Workbook
Dim targetWs As Worksheet
Set targetWb = Workbooks.Open("C:\sample\sample.xlsx")
Set targetWs = targetWb.Worksheets(1)
targetWs.Range("A1").Value = "処理済み"
このように書くと、どのブックのどのシートを操作しているかが読みやすくなります。
実務配布では対象ブックを明示する方が安全です。
Workbooks.Openしたブックは変数で受ける
外部ブックを開く場合、開いた直後にそのブックがアクティブになることがあります。
そのため、ActiveWorkbook でも一見動くことがあります。
ただし、その状態に頼ると、処理が複雑になったときに事故りやすくなります。
Set targetWb = Workbooks.Open("C:\sample\sample.xlsx")
のように、開いたブックを変数で受けておけば、その後は targetWb を使って明示的に操作できます。
- 入力元なら
sourceWb - テンプレートなら
templateWb - 出力先なら
outputWb - 処理対象なら
targetWb
のように意味のある名前を付けると、コードを読んだときに意図が分かりやすくなります。
確認用VBAコード
以下は、ThisWorkbook、ActiveWorkbook、Workbooks の違いを確認するためのサンプルです。
マクロが入っているブック名、現在アクティブなブック名、開いているブック数を表示します。
複数ブックを開いた状態で試すと、違いが分かりやすいです。
ご注意
以下のVBAコードは、動作イメージを確認するためのサンプルです。
実行前に必ずExcelファイルのバックアップを作成してください。
業務で使用しているファイルに、いきなり貼り付けて実行しないでください。
Excelのバージョンや設定により、動作が異なる場合があります。
Public Sub CheckWorkbookObjects()
MsgBox "ThisWorkbook: " & ThisWorkbook.Name & vbCrLf & _
"ActiveWorkbook: " & ActiveWorkbook.Name & vbCrLf & _
"開いているブック数: " & Workbooks.Count, vbInformation
End Sub
このコードは、ファイル保存・削除・外部通信を行いません。
ブック名と開いているブック数を表示するだけです。
実務配布での考え方
別ブック操作では、
「どのブックの」
「どのシートを」
「何のために操作しているか」
がコード上で読めることが大事です。
業務用Excelでは、調書、一覧表、テンプレート、マスタ、チェック表など、複数ブックを同時に開くことがあります。
その状態で ActiveWorkbook に頼ると、いま前面のブックに処理対象を任せることになります。
これは便利な反面、対象がズレるリスクがあります。
実務配布では、ThisWorkbook や Workbook 変数を使って、対象ブックを明示する設計を優先した方が無難です。
まとめ
ThisWorkbook はVBAコードが入っているブックです。
ActiveWorkbook はいまアクティブなブックです。
Workbooks は開いているブック全体の集合です。
ツールブック自身を操作するなら ThisWorkbook。
いま前面のブックを処理すると明確に決めているなら ActiveWorkbook。
外部ブックを開くなら Workbooks.Open。
そして、Workbooks.Open したブックは Workbook 変数で受ける。
実務配布では対象ブックを明示する。
別ブック操作では対象をコード上で明示する。
この考え方が、Excel VBAのブック操作事故を減らすうえで大事です。
詳しい解説はこちら: