HOME > 即効テクニック集 > Excel VBA > その他関連のテクニック > ブックにマクロが含まれているかどうか調べる
その他関連のテクニック

ブックにマクロが含まれているかどうか調べる

(Excel 97/2000/2002/2003/2007)
Excel 2007では、いくつかのプロパティやメソッドが追加されています。
WorkbookオブジェクトのHasVBProjectプロパティも新しいプロパティです。
HasVBProjectプロパティは、ブックにマクロが含まれているかどうかを返します。

Sub Sample1()
  MsgBox Workbooks(2).HasVBProject
End Sub   
Sub ○○〜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 Sub   
VBComponentオブジェクトの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を操作するマクロは奥が深いので、本稿ではここまでとします。