Excel 2007では、いくつかのプロパティやメソッドが追加されています。 WorkbookオブジェクトのHasVBProjectプロパティも新しいプロパティです。 HasVBProjectプロパティは、ブックにマクロが含まれているかどうかを返します。Sub Sample1() MsgBox Workbooks(2).HasVBProject End SubSub ○○〜End Subというプロシージャが存在すれば、もちろんマクロが含まれていると認識されますし、標準モジュールやUserFormが追加されていても、マクロが含まれていることになります。 非常に便利なHasVBProjectプロパティですが、残念ながらExcel 2007でしか使えません。 では、Excel 2003以前のVBAで、任意のブックにマクロが含まれているかどうかを判定することはできないのでしょうか。 もちろん可能です。 ここでは、2つのブックを開き、2番目のブックにマクロが含まれているかどうかを調べてみましょう。 2番目のブックは、新規作成したままの状態で「名前を付けて保存」してください。 ファイル名や保存するフォルダは、ご自由にどうぞ。 なお、これ以降のマクロはVBEにアクセスします。マクロでVBEにアクセスするには、Excelの[ツール]-[マクロ]-[セキュリティ]で[セキュリティ]ダイアログボックスを開き、[信頼のおける発行元]タブにある[Visual Basicプロジェクトへのアクセスを信頼する]チェックボックスをオンにしてください。 そのほか、特別な参照設定などは必要ありません。 VBEのモジュールにアクセスするには、まずVBEオブジェクトを利用します。 VBEオブジェクトはVBE全体を表すオブジェクトです。 Excel上で開いているブックは、VBEで見ると「VBAProject」と表示されます。 このVBProjectもオブジェクトとして操作可能です。 次のコードは、VBEで現在開いているVBProjectをイミディエイトウィンドウに出力します。Sub Sample2() Dim i As Long Debug.Print Application.VBE.VBProjects.Count & "個のVBProject" For i = 1 To Application.VBE.VBProjects.Count Debug.Print Application.VBE.VBProjects(i).Filename Next i End Subブックには「Sheet1」や「ThisWorkbook」などのDocumentモジュールがあります。 また、標準モジュールやUserFormを挿入することもできます。 そうした、プロシージャの記述場所である"モジュール"は、VBComponentオブジェクトとして表されます。 次のコードは、2番目のブックに存在するすべてのモジュールを調べます。Sub Sample3() Dim vbc As Object For Each vbc In Workbooks(2).VBProject.VBComponents Debug.Print vbc.Name & vbTab & vbc.Type Next vbc End SubVBComponentオブジェクトのTypeプロパティは、次の値を返します。 「ActiveX デザイナ」は特別な開発環境でしか使用しませんので、解説を割愛します。 ブックが標準で持っている「Sheet1」「ThisWorkbook」などのDocumentモジュールはTypeプロパティが100を返します。 したがって、Typeプロパティが「100でない」VBComponentオブジェクトが存在したら、それはマクロが存在すると判断してもいいでしょう。Sub Sample4() Dim vbc As Object, flag As Boolean For Each vbc In Workbooks(2).VBProject.VBComponents If vbc.Type <> 100 Then flag = True End If Next vbc If flag Then MsgBox "マクロが存在します" Else MsgBox "マクロは存在しません" End If End Subこれで、標準モジュールやUserFormの存在を判定できます。 しかし、ブックの「Sheet1」や「ThisWorkbook」にもプロシージャは記述できます。 Documentモジュールにプロシージャが記述されているかどうかは、次のようにして調べられます。 プロシージャを記述するコードウィンドウはCodeModuleオブジェクトとして操作できます。 CodeModuleオブジェクトにはコードウィンドウ内の全行数を返すCountOfLinesプロパティと任意の行が、どのプロシージャに属するかを返すProcOfLineプロパティがあります。 これらを組み合わせて、コードウィンドウ内に1つ以上のプロシージャが存在するかどうかを判定します。Sub Sample5() Dim vbc As Object, flag As Boolean, I As Long, buf As String For Each vbc In Workbooks(2).VBProject.VBComponents If vbc.Type <> 100 Then flag = True Else For I = 1 To vbc.CodeModule.CountOfLines buf = vbc.CodeModule.ProcOfLine(I, 0) Next I End If Next vbc If flag Or buf <> "" Then MsgBox "マクロが存在します" Else MsgBox "マクロは存在しません" End If End Subとりあえず、これでマクロが存在するかどうかは判定できました。 上記のSample5は省略した部分も多く、決して洗練されたコードではありませんが、VBAからVBEを操作するマクロは奥が深いので、本稿ではここまでとします。