強制的に「マクロ有効」で開かせる。

「マクロ有効」でないと作業ができないようにさせる方法です。
外部のVBスクリプトを使います。   よく掲示板などで「マクロを使ってマクロを有効にする方法」のような類の質問を見かけます。マクロを含むワークブックを開く時に「マクロを有効にするか」の確認が表示されますが、この段階ではワークブックは開かれておらず、「無効」で開かれたならマクロにどのようなコードを書いても実行されません。
しかし、他のワークブックのマクロやVBスクリプトからワークブックが開かれる場合、セキュリティレベルが「最高」でなければ、そのワークブックは確認なく「マクロ有効」で開かれます。 この動作を利用して、単にワークブックを直接指定して「マクロ無効」で開く場合は作業するシートが表示されないような工夫をします。
VBスクリプト」とは?
「〜とはなんぞや」などを語るほどその歴史や背景を知っているわけではありませんから、単に私なりの説明です。
VBスクリプト」とは正式には「Visual Basic Scripting Edition」と言うそうですが、 Internet Explorer上で動作する「Java Script」と同様のブラウザのコントロール言語というようなイメージが強いと思います。
デスクトップ上から起動させる場合にWindows上では起動ファイルの拡張子によって登録されているプログラムが起動されるようになっていますが、その中で拡張子が「vbs」であるものが「VBスクリプト」として動作するのは、拡張子が「bat」のファイルがバッチファイルとして動作するのと似たものです。 この点でも「VBスクリプト」の方が細かい判断・分岐や繰り返しなどの記述も可能で、コンポーネントの操作ができる点も大きな利点です。 Excelのハンドリングもここではコンポーネントとしての操作になります。

VBスクリプト」作成環境について
VBスクリプト」そのものは拡張子が「*.vbs」となっていますが、実体はテキストファイルです。 記述の理解があるなら「メモ帳」だけでも作成できます。 Office System 2003などでは「Microsoft Script Editor」が搭載されているので、これを利用する方法もあるようですが私は利用したことはありません。
Microsoft Script Editorの画面
(この画像をクリックするとサンプルを収容した圧縮ファイルがダウンロードできます。)
この程度のスクリプトであれば、目視で記述をチェックしてから実際に起動させてしまって、エラーメッセージから修正していっても問題ないと思います。
エラーメッセージの表示
エラーが起きた場合はこのようにエラーの発生箇所と内容がメッセージ表示されます。
VBスクリプト」のヘルプについては上記の「Microsoft Script Editor」が搭載されているなら、そのヘルプの中に「VBScriptヘルプ」も含まれています。 「Microsoft Script Editor」が搭載されていない場合は、マイクロソフトのサイトから「Windows Script Version」や「scd56jp.exe」を検索してダウンロード後にインストールさせて下さい。

VBスクリプト」のコードサンプル
さて、このページの主題である「強制的に[マクロ有効]で開かせる」のコードに入っていきますが、まずは簡単な例としてワークブックを開くだけのコードを作ってみます。 特に「マクロ有効」に関する記述はありませんが、この記述で開かれるワークブックはExcelのセキュリティのレベルが「最高」でない限り確認メッセージなしに「マクロ有効」で開かれます。

'*******************************************************************************
'   Excelワークブックを開く処理@
'
'   作成者:井上治  URL:http://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'*******************************************************************************
Option Explicit
Const cnsBook = "TestBook1.xls"
Dim objExcelApp, strPath

' 本スクリプトファイルのフォルダ名の取得
With WScript
  strPath = Replace(.ScriptFullName, .ScriptName, "")
End With
' Excelのオブジェクトの参照を取得
Set objExcelApp = CreateObject("Excel.Application")
' 指定のワークブックを開く(同一フォルダ)
' ⇒リンク非更新、読み取り専用としています。
objExcelApp.Workbooks.Open strPath & cnsBook, False, True
' Excelウィンドウを表示
objExcelApp.Visible = True
Set objExcelApp = Nothing
このようにSubプロシージャなどを介さずに直接コード記述したものは、そのスクリプトファイルを開く時に実行されます。 Subプロシージャ、Functionプロシージャを記述した場合は、そのプロシージャを呼び出す記述が実行されないと実行されません。 あと、このようにExcelVBAと似たような記述になっていますが、いろいろと制限があるので、この点はヘルプなどを参考に進めていって下さい。 代表的(?)な制限事項としては次のようなものがあります。
  • 変数宣言にデータ型を指定できません。Variant型のみだと理解して下さい。
  • 行ラベルや、GotoGoSubステートメントは使えません。 On Errorステートメントにも当然Gotoは書けないので、エラー処理を行なう場合はResume Nextを使って実行コードの直後でエラー内容を判断しなければなりません。
    また、ForNextステートメントのNextの後ろに対応変数名を書くことができないなどの制限もあります。
  • 関数にも使用できないものがあります。例えばFormat関数、StrConv関数なども使用できません。
  • WindowsAPIDeclareステートメント)も使用できません。
これらの制限があってもオブジェクトとしてOfficeメンバをハンドリングできるのでこれらと組み合わせたり、APIの記述が使えなくてもTechNetスクリプトセンターなどを調べると相当な量の代替策が見つかります。

自動起動マクロは?
上記の「VBスクリプト」のコードでマクロは有効になります。
自動起動マクロについての動作は、通常マクロから他のブックを開いた時と同様にThisWorkbookモジュールの「Workbook_Open」プロシージャは起動されますが、標準モジュールの「Auto_Open」プロシージャの方は動作しません。 「Auto_Open」プロシージャを動作させたい場合は、「RunAutoMacrosメソッド」を発行させる必要があります。

'*******************************************************************************
'   Excelワークブックを開く処理A (Auto_Openマクロを起動させる)
'
'   作成者:井上治  URL:http://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'*******************************************************************************
Option Explicit
Const cnsBook = "TestBook2.xls"
Const xlAutoOpen = 1
Dim objExcelApp, objWbk, strPath

' 本スクリプトファイルのフォルダ名の取得
With WScript
  strPath = Replace(.ScriptFullName, .ScriptName, "")
End With
' Excelのオブジェクトの参照を取得
Set objExcelApp = CreateObject("Excel.Application")
' 指定のワークブックを開く(同一フォルダ)
' ⇒リンク非更新、読み取り専用としています。
Set objWbk = objExcelApp.Workbooks.Open(strPath & cnsBook, False, True)
' Excelウィンドウを表示
objExcelApp.Visible = True
' 自動起動マクロ(Auto_Open)があれば実行
objWbk.RunAutoMacros xlAutoOpen
Set objWbk = Nothing
Set objExcelApp = Nothing
先頭の画像をクリックしてダウンロードしたファイルの中の「TestWorkbookOpen2.vbs」を起動させると「TestBook2.xls」が開かれ自動起動マクロ「Auto_Open」が起動されますが、 サンプルではメッセージが表示されるだけにしてあります。 この記述では、対象ワークブックに「Auto_Open」プロシージャがない場合は、実行されないだけでエラーにはならないので、有無にかかわらずこのような記述にしても構いません。

自動起動ではない特定のマクロを実行するには
今度は特に自動起動になっていないマクロを任意に起動させ、そのマクロの終了後は対象ブックを閉じてしまうというサンプルを紹介します。 また、開かれるワークブック「TestBook3.xls」は、このサンプルの「VBスクリプト」のコードで開かれる場合は「読み取り専用」となるので、そうでない場合は警告メッセージを表示させるようにしてあります。
一過性の機能をマクロに持たせて実行後閉じてしまうので、印刷など場合によってはExcelウィンドウも非表示で良いこともありますが、動作確認用サンプルなのでExcelウィンドウは表示させています。

'*******************************************************************************
'   Excelワークブックを開く処理B (指定のマクロを起動させる)
'
'   作成者:井上治  URL:http://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'*******************************************************************************
Option Explicit
Const cnsBook = "TestBook3.xls"
Const cnsMacro = "TEST1"
Dim objExcelApp, objWbk, strPath

' 本スクリプトファイルのフォルダ名の取得
With WScript
  strPath = Replace(.ScriptFullName, .ScriptName, "")
End With
' Excelのオブジェクトの参照を取得
Set objExcelApp = CreateObject("Excel.Application")
' 自動起動マクロの抑止(イベント停止)
objExcelApp.EnableEvents = False
' 指定のワークブックを開く(同一フォルダ)
' ⇒リンク非更新、読み取り専用としています。
Set objWbk = objExcelApp.Workbooks.Open(strPath & cnsBook, False, True)
' Excelウィンドウを表示
objExcelApp.Visible = True
' 指定のマクロを実行
objExcelApp.Run "'" & objWbk.Name & "'!" & cnsMacro
' 指定ブックを閉じる
objWbk.Saved = True
objWbk.Close False
Set objWbk = Nothing
' イベント停止解除
objExcelApp.EnableEvents = True
' Excel終了
objExcelApp.Quit
Set objExcelApp = Nothing
先頭の画像をクリックしてダウンロードしたファイルの中の「TestWorkbookOpen3.vbs」を起動させると「TestBook3.xls」が開かれマクロ「TEST3」が起動されますが、 サンプルでは起動メッセージが表示され、3秒停止した後、終了メッセージが表示されるだけにしてあります。終了メッセージの後はExcelも終了します。
下記がそのマクロ(標準モジュール)です。

Option Explicit
' ■Sleep
Public Declare Sub Sleep Lib "KERNEL32.dll" (ByVal dwMilliseconds As Long)

' 指定マクロ
Public Sub TEST1()
' 起動メッセージ
MsgBox "指定のマクロが起動しました。", vbInformation
' 3秒停止
Sleep 3000
' 終了メッセージ
MsgBox "指定のマクロが終了しました。", vbInformation
End Sub
また、この「TestBook3.xls」には「Workbook_Open」プロシージャが搭載されていて、以下のように記述されています。

Option Explicit

' 読み取り専用で開かれたか確認
Private Sub Workbook_Open()
    If ThisWorkbook.ReadOnly <> True Then
        MsgBox "VBScript「TestWorkbookOpen3.vbs」から起動して下さい。"
        ThisWorkbook.Saved = True
        If Workbooks.Count <= 1 Then Application.Quit
        ThisWorkbook.Close False
    End If
End Sub
TestBook3.xls」を単独でマクロ有効で開くとメッセージが表示されて、そのまま閉じられてしまいます。 ですが、マクロ有効でないと利用できないような処置を行なう場合は、このような処置だけでは不足です。なぜなら、このメッセージはマクロ有効でなければ表示されません。 マクロ無効で開いた場合はこのワークブックは普通に利用できてしまいます。
これなら、通常、利用するワークシートをVeryHiddenで非表示にしておき、代わりのダミーシートを表示させておきます。ワークブックをパスワード付きで保護しておけばマクロ無効で開いた状態では利用できません。 一方で、起動されたマクロの方で保護解除や利用シートの表示などの作業をさせます。
さらに必要な対策は、利用シートが表示された状態で保存されないような対策ですが、マクロ有効な状態なら「Workbook_BeforeSave」イベントで初期状態に戻してやります。 ただ、これも「完璧」な方法とは言えません。残念ながら、途中でデザインモードに変更されると無意味だからです。
対応策としては、ワークブック内に登録データを保持するような方法を採らず、別個のデータファイルやMDBにマクロを使ってデータを登録するようにします。 ブックをマクロ有効で開いたら、常にデータファイルかMDBから直近の登録データを読み出して表示させてしまうようにすれば、以前に何か表示された状態で保存された状態でも登録データに置き換わります。 また、この方法なら利用するワークブックの方は毎回上書き保存させる必要はないので、読み取り専用で開くようにしてしまって構わないわけです。