
Excel VBAで複数のブックを扱うとき、ActiveWorkbook を使うことがあります。
ただ、実務用マクロや配布用Excelでは、ActiveWorkbook に頼りすぎると事故ることがあります。
理由はシンプルです。
ActiveWorkbookは、マクロが入っているブックではなく、現在アクティブなブックを指すからです。
結論
ActiveWorkbook は現在アクティブなブックを指します。
つまり、画面上でいま前面にあるブックです。
マクロが入っているブックとは限りません。
そのため、
- ユーザーが別ブックをクリックする
- 処理中に別ブックが前面に出る
- 複数ブックを開いた状態で実行する
- テンプレートや作業中ブックが混在する
と、意図しないブックを操作してしまう可能性があります。
マクロが入っているブックを操作したいなら ThisWorkbook を使います。
外部ブックを操作するなら、Workbooks.Open の戻り値を Workbook 変数に入れて、targetWb のような変数で明示的に操作します。
ActiveWorkbook が悪いのではなく、使いどころを間違えると事故る、という話です。
ThisWorkbookとは
ThisWorkbook は、そのVBAコードが入っているブックを指します。
例えば、マクロ入りツールブック自身を操作したい場合に使います。
向いている場面は次のようなものです。
- マクロ入りツールブック自身を操作する
- 設定シートを読む
- ログシートへ書き込む
- ツール内部の情報を参照する
たとえば、マクロツール内の設定シートを読むなら、ThisWorkbook を使う方が分かりやすいです。
ActiveWorkbookとは
ActiveWorkbook は、現在アクティブになっているブックを指します。
画面上で前面にあるブックです。
そのため、マクロが入っているブックとは限りません。
ユーザーが別のブックをクリックすれば、対象が変わる可能性があります。
自分用の一時的な作業補助で、「いま開いているブックを処理する」と明確に決めている場合には使えます。
ただし、業務用マクロや配布用Excelでは注意が必要です。
比較表
| 書き方 | 指す対象 | 向いている場面 | 注意点 |
|---|---|---|---|
| ThisWorkbook | VBAコードが入っているブック | ツールブック自身の設定・ログ操作 | 外部ブック操作には向かない |
| ActiveWorkbook | 現在アクティブなブック | 自分用の軽い作業補助 | 対象が変わりやすい |
| Workbook変数 | 明示的に代入したブック | 複数ブック処理・外部ファイル操作 | 変数管理が必要 |
ActiveWorkbookで起きやすい事故
実務では、複数のExcelブックを同時に開くことがよくあります。
例えば、
- 調書
- 一覧表
- テンプレート
- 統合マスタ
- チェック表
- 過年度成果
- 修正後ファイル
などです。
この状態で ActiveWorkbook に頼ると、処理対象がずれることがあります。
よくある事故は次のようなものです。
- 違うブックに値を書き込んでしまう
- 開いた外部ブックではなく、元のブックを保存してしまう
- テンプレートブックを操作するつもりが、作業中ブックを操作してしまう
- ユーザーが途中で別ブックをクリックして対象が変わる
- マクロ実行中に別ブックが前面に出て、処理対象がずれる
- 他人の環境で実行したときに再現しづらい事故になる
- エラーで止まらず、別ブックに普通に書き込まれてしまう
特に怖いのは、エラーにならずに普通に処理が進んでしまうケースです。
危ない書き方
例えば、次のような書き方は対象が曖昧です。
ActiveWorkbook.Sheets(1).Range("A1").Value = "処理済み"
このコードは、現在アクティブなブックの1枚目のシートに書き込みます。
つまり、どのブックに書き込むかは、実行時の画面状態に依存します。
自分のPCでは問題なく動いても、他人のPCや別の操作手順では、違うブックに書き込む可能性があります。
安全寄りの考え方
マクロが入っているブックを操作するなら、ThisWorkbook を使います。
ThisWorkbook.Worksheets("設定").Range("A1").Value = "処理済み"
外部ファイルを開いて処理するなら、開いたブックを変数に入れます。
Dim targetWb As Workbook
Set targetWb = Workbooks.Open("C:\sample\sample.xlsx")
targetWb.Worksheets(1).Range("A1").Value = "処理済み"
このように、targetWb という変数に入れておけば、どのブックを操作しているかが明確になります。
実務配布では処理対象ブックを明示する方が安全です。
確認用VBAコード
以下は、ThisWorkbook と ActiveWorkbook の違いを確認するためのサンプルです。
複数のブックを開いた状態で実行すると、違いが分かりやすいです。
ご注意
以下のVBAコードは、動作イメージを確認するためのサンプルです。
実行前に必ずExcelファイルのバックアップを作成してください。
業務で使用しているファイルに、いきなり貼り付けて実行しないでください。
Excelのバージョンや設定により、動作が異なる場合があります。
Public Sub CheckWorkbookDifference()
MsgBox "ThisWorkbook: " & ThisWorkbook.Name & vbCrLf & _
"ActiveWorkbook: " & ActiveWorkbook.Name, vbInformation
End Sub
このコードは、ファイル保存・削除・外部通信を行いません。
マクロが入っているブック名と、現在アクティブなブック名を表示するだけです。
ActiveWorkbookを使ってもよい場面
ActiveWorkbook を全面否定するものではありません。
例えば、次のような場面では使えることがあります。
- 自分だけが使う一時的なマクロ
- 現在前面のブックを処理すると明確に決めている処理
- 複数ブックを扱わない簡単な作業補助
- 処理前に対象ブックを人間が確認する運用
ただし、業務用マクロや配布用Excelでは、利用者がどう操作するか分かりません。
そのため、ActiveWorkbook 依存を減らした方が安全です。
実務配布での考え方
業務用Excelでは、
「どのブックの」
「どのシートを」
「何のために操作しているか」
がコード上で読めることが大事です。
ActiveWorkbook.Sheets(1) は楽ですが、処理対象が曖昧です。
特に、保存や書き込み処理を ActiveWorkbook 依存にするのは注意が必要です。
実務配布では、
- ツールブックを操作するなら
ThisWorkbook - 外部ブックを開くなら
Workbook変数 - シートも
Worksheet変数で明示 -
SelectやActivateに頼りすぎない - 処理対象をログに残す
- 実行前後に人間確認できる設計にする
という考え方が無難です。
まとめ
ActiveWorkbook は現在アクティブなブックを指します。
マクロが入っているブックとは限りません。
ThisWorkbook はそのVBAコードが入っているブックを指します。
複数ブックを開く実務では、ActiveWorkbook に頼りすぎると、意図しないブックを操作する事故が起きやすくなります。
外部ブックを操作するなら、Workbook 変数で対象を固定する方が安全です。
ActiveWorkbook が悪いのではなく、使いどころを間違えると事故ります。
実務配布では処理対象ブックを明示する。
これが、Excel VBAで別ブックを扱うときの基本だと思います。
詳しい解説はこちら: