Excel VBAでActiveWorkbookを使うと事故る理由
Excel VBAでは、ActiveWorkbook という書き方がよく出てきます。
名前だけ見ると、何となく便利そうです。
実際、便利です。
ただし、業務用マクロや配布用Excelで何となく使うと、意図しないブックを操作してしまう事故につながることがあります。
特に、複数のExcelブックを開きながら作業する実務では注意が必要です。
この記事では、Excel VBAで ActiveWorkbook を使うと、なぜ事故が起きやすいのかを実務目線で整理します。
ActiveWorkbookは便利だが、業務マクロでは事故りやすい
ActiveWorkbook は、現在アクティブになっているブックを指します。
つまり、画面上でいま前面にあるブックです。
ここが重要です。
ActiveWorkbook は、マクロが入っているブックとは限りません。
マクロが入っているブックを操作しているつもりでも、別のブックが前面に出ていれば、そちらが ActiveWorkbook になります。
そのため、
- 違うブックに値を書き込む
- 想定外のブックを保存する
- テンプレートではなく作業中ブックを操作する
- ユーザーが別ブックをクリックして対象が変わる
といった事故が起きます。
自分だけが使う短いマクロなら、気づいて直せるかもしれません。
しかし、他人に配布するExcelや、長期運用する業務用マクロでは、この曖昧さが事故の入口になります。
結論:処理対象が決まっているならActiveWorkbookに頼らない方が安全
結論から言うと、処理対象が決まっているなら、ActiveWorkbook に頼らない方が安全です。
ActiveWorkbook は、現在アクティブなブックを指します。
マクロが入っているブックとは限りません。
ユーザー操作や画面切り替えで、対象が変わる可能性があります。
そのため、業務用マクロでは、
- マクロが入っているブックを操作するなら
ThisWorkbook - 外部ファイルを開いて処理するなら
Workbook変数 - テンプレートブックを扱うなら
templateWb - 処理対象ブックを扱うなら
targetWb
のように、対象を明示した方が安全です。
配布用Excelでは、ActiveWorkbook 依存を減らすのが無難です。
ActiveWorkbookとは何か
ActiveWorkbook は、現在アクティブになっているExcelブックを指します。
分かりやすく言うと、画面上で前面にあるブックです。
例えば、次のような状態を考えます。
- A.xlsm:マクロが入っているブック
- B.xlsx:作業中のブック
- C.xlsx:テンプレートとして開いたブック
このとき、ユーザーが B.xlsx をクリックして前面に出していれば、ActiveWorkbook は B.xlsx になります。
マクロが入っている A.xlsm ではありません。
つまり、ActiveWorkbook は「VBAコードが入っているブック」ではなく、「いまアクティブなブック」です。
この性質が便利な場面もあります。
しかし、業務マクロでは、処理対象の取り違えにつながることがあります。
ActiveWorkbookで起きやすい事故
ActiveWorkbook を安易に使うと、次のような事故が起きやすくなります。
- 違うブックに値を書き込んでしまう
- 開いた外部ブックではなく、元のブックを保存してしまう
- テンプレートブックを操作するつもりが、作業中ブックを操作してしまう
- ユーザーが途中で別ブックをクリックして対象が変わる
- マクロ実行中に別ブックが前面に出て、処理対象がずれる
- 他人の環境で実行したときに再現しづらい事故になる
特に怖いのは、間違ったブックを操作しても、すぐに気づかないことです。
エラーで止まればまだ分かりやすいです。
しかし、別ブックに普通に値を書き込めてしまうと、後から気づくまで事故が見えません。
業務ファイルでは、こういう静かな事故が一番怖いです。
ThisWorkbookとの違い
ThisWorkbook は、そのVBAコードが入っているブックを指します。
一方で、ActiveWorkbook は、いまアクティブなブックを指します。
この違いはかなり重要です。
| 書き方 | 指すもの | 実務での注意 |
|---|---|---|
| ThisWorkbook | VBAコードが入っているブック | ツールブック自身を操作したいときに向く |
| ActiveWorkbook | 現在アクティブなブック | 前面ブックが変わると対象も変わる |
| Workbooks(“名前.xlsx”) | 指定した名前のブック | 名前違いや未オープンに注意 |
| Workbook変数 | 変数に入れた特定のブック | 処理対象を固定しやすい |
自分のツールブック内の設定シートやログシートを操作したいなら、ThisWorkbook の方が安全です。
例えば、
ThisWorkbook.Worksheets("設定").Range("A1").Value
のように書けば、マクロが入っているブックの「設定」シートを指します。
一方、
ActiveWorkbook.Worksheets("設定").Range("A1").Value
と書くと、現在アクティブなブックの「設定」シートを見に行きます。
もし別ブックが前面にあれば、その別ブックを見に行くことになります。
ActiveWorkbookを使ってもよい場面
ActiveWorkbook を絶対に使ってはいけないわけではありません。
使ってよい場面もあります。
例えば、
- ユーザーが現在開いているブックを対象にするマクロ
- 「いま開いているブックに対して実行する」と明確に決めている処理
- 一時的な作業補助マクロ
- 自分だけが使うマクロ
- 対象ブックをユーザーに選ばせる前提の軽い処理
こういう場合は、ActiveWorkbook が便利なこともあります。
ただし、業務ファイルを変更する処理では注意が必要です。
特に、
- 値を書き込む
- シートを編集する
- 保存する
- 印刷する
- ファイル出力する
といった処理では、対象ブックを明示した方が安全です。
ActiveWorkbook が悪いのではありません。
使いどころを間違えると事故る、という話です。
業務用マクロではWorkbook変数に入れる
外部ファイルを開いて処理する場合は、Workbooks.Open の戻り値を Workbook 変数に入れるのが安全寄りです。
例えば、次のような考え方です。
Dim targetWb As Workbook
Set targetWb = Workbooks.Open("ファイルパス")
このようにしておけば、その後は targetWb を使って操作できます。
ただし、この記事では実ファイルパスを使うコードは出しません。
重要なのは、考え方です。
外部ブックを開いたら、そのブックを変数に入れる。
そして、その変数を使って操作する。
こうすると、ActiveWorkbook に頼らずに済みます。
例えば、
targetWb.Worksheets("Sheet1").Range("A1").Value
のように書けば、「targetWbのSheet1のA1」と明示できます。
さらに安全にするなら、シートも Worksheet 変数に入れます。
Dim targetWs As Worksheet
Set targetWs = targetWb.Worksheets("Sheet1")
業務用マクロでは、「どのブックの、どのシートを操作しているか」がコード上で読めることが大事です。
危ない書き方と安全寄りの書き方
危ない書き方の代表例は、対象が曖昧なコードです。
例えば、
ActiveWorkbook.Sheets(1).Range("A1").Value = "確認"
このコードは、現在アクティブなブックの1枚目のシートに値を書き込みます。
しかし、どのブックがアクティブかは、その瞬間のExcel画面に依存します。
複数ブックを開いていると、意図しないブックが対象になる可能性があります。
一方で、自分のツールブック内のシートを操作したいなら、次のように書いた方が安全です。
ThisWorkbook.Worksheets("設定").Range("A1").Value = "確認"
外部ブックを操作するなら、次のように Workbook 変数で対象を固定します。
Dim targetWb As Workbook
Dim targetWs As Worksheet
Set targetWb = Workbooks("対象ブック.xlsx")
Set targetWs = targetWb.Worksheets("Sheet1")
targetWs.Range("A1").Value = "確認"
このように書くと、「どのブックのどのシートか」が見えやすくなります。
業務用マクロでは、この明示性が大事です。
コピペで試せる確認用VBAコード
以下は、ThisWorkbook と ActiveWorkbook の違いを確認するための短いコードです。
複数のブックを開いた状態で試すと、違いが分かりやすくなります。
ご注意
以下のVBAコードは、動作イメージを確認するためのサンプルです。
実行前に必ずExcelファイルのバックアップを作成してください。
業務で使用しているファイルに、いきなり貼り付けて実行しないでください。
Excelのバージョンや設定により、動作が異なる場合があります。
Public Sub CheckWorkbookDifference()
MsgBox "ThisWorkbook: " & ThisWorkbook.Name & vbCrLf & _
"ActiveWorkbook: " & ActiveWorkbook.Name, vbInformation
End Sub
このコードは、ファイルを保存したり、削除したり、外部通信をしたりしません。
表示するのは、
ThisWorkbookのブック名ActiveWorkbookのブック名
だけです。
複数のExcelブックを開いた状態で、別のブックを前面にしてから実行すると、違いが分かる場合があります。
ThisWorkbook はコードが入っているブックです。
ActiveWorkbook は、現在アクティブなブックです。
この違いを体感しておくと、Workbook系の事故を減らしやすくなります。
維持DX的にはどう考えるか
維持DX的には、実務配布用Excelでは ActiveWorkbook 依存をできるだけ減らした方がよいと考えています。
建設コンサル実務では、複数のExcelブックを同時に開くことがよくあります。
例えば、
- 調書
- 一覧表
- テンプレート
- 統合マスタ
- チェック表
- 過年度成果
- 修正後ファイル
などです。
このような状況で、「いまアクティブなブック」を前提に処理すると、対象がずれる可能性があります。
だからこそ、
- この処理で使うブックはどれか
- この処理で書き込むシートはどれか
- この処理で参照するブックはどれか
をコード上で明示することが大事です。
維持DXのツール設計でも、処理対象の明示、ログ化、人間確認を重視しています。
マクロが賢く見えることより、あとから確認できること。
これが実務では重要です。
関連して読みたい記事
Workbook系の書き方で迷う場合は、次の記事も関連します。
- Excel VBAでThisWorkbookとActiveWorkbookは何が違うのか
- Excel VBAで別ブックを操作するときのThisWorkbook・ActiveWorkbook・Workbooksの違い
- Excel VBAでSelectを使ってはいけないと言われる理由
- Excel VBAでWorkbooks.Openしたブックを安全に操作する方法
ActiveWorkbook の事故は、Select や Activate の多用ともつながりやすいです。
「今アクティブなもの」に頼るほど、処理対象が見えにくくなります。
まとめ
ActiveWorkbook は、現在アクティブなブックを指します。
マクロが入っているブックとは限りません。
複数ブックを開く実務では、意図しないブックを操作する事故が起きやすくなります。
ツールブックを操作するなら、ThisWorkbook が安全です。
外部ブックを操作するなら、Workbook 変数で対象を固定する方が安全です。
ActiveWorkbook が悪いのではありません。
使いどころを間違えると事故る、ということです。
業務用マクロや配布用Excelでは、処理対象ブックを明示することを意識しましょう。
維持DXノートについて
維持DXノートでは、建設コンサル実務や土木実務で使うExcel/VBAツール、Word・Excel帳票の整理を支援する小さなツールの開発メモを公開しています。
無料で使えるExcelツールも公開していますので、業務用Excelツールや帳票作成の効率化に関心がある方は、あわせてご覧ください。
関連する無料Excelツール
維持DXでは、
橋梁点検・維持管理業務向けのExcel VBAツールを無料公開しています。
- 橋梁点検調書の作成支援ツール
- 評価結果一覧作成ツール
- 旧様式から2024様式への移行支援ツール
- 成果整合確認ツール
いずれも、
実務で発生しやすい
- 転記作業
- 写真貼付
- 一覧作成
- 旧成果移行
- 整合確認
の負担を減らすための補助ツールです。
以下のフォームにメールアドレスを入力すると、
ダウンロードURLを自動返信メールでお送りします。
ご注意
ダウンロードURLは、入力いただいたメールアドレス宛に自動返信で送信されます。
ダウンロードしたExcelでマクロが実行できない場合は、
右クリック → プロパティ →「許可する」 をチェック後、再度開いてください。
(Windowsのセキュリティ機能により初回実行時にブロックされる場合があります)


コメント