重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

VB6でExcelファイルを読み込み、各シートにマクロが使われているかを
知る方法を探しております。(ブック単位でもよいです)
Worksheetsオブジェクトのプロパティにはなさそうですし、
何か情報をお持ちの方、ご教授いただければと思います。

A 回答 (3件)

シートモジュールに限定して「マクロの有無」を判断するなら、#1 ご回答


のとおりです。

#2 は「マクロを含むブックか?」について書いたものです。このロジック
で判定できるかどうかテストコードを書いてみました。時間が無くて数件
しか検証してませんが、それなりに判定できそうです。プロジェクトが
保護されていても問題なさそうにみえます。なお、VBA です。

Sub SampleProc()

  Dim FileName As String
  FileName = Application.GetOpenFilename("Excel形式ファイル (*.xls), *.xls")
  If HasMacro(FileName) Then
    MsgBox "マクロあり"
  Else
    MsgBox "マクロ無し"
  End If

End Sub

' // ブックにマクロが含まれるか判定する
Public Function HasMacro( _
    ByVal XlsFileName As String _
) As Boolean

  Const XLS_FILE_HEADER = "D0 CF 11 E0 A1 B1 1A E1"
  Const SEARCH_KEY = "56 42 5F 4E 61 6D"

  Dim Buffer()   As Byte
  Dim Keys()    As Byte
  Dim v      As Variant
  Dim n      As Integer
  Dim i      As Long
  
  ' // データ読み込み
  n = FreeFile()
  ReDim Buffer(FileLen(XlsFileName))
  Open XlsFileName For Binary As #n
    Get #n, , Buffer
  Close #n
  ' // 一応ファイルヘッダをチェック
  i = 0
  For Each v In Split(XLS_FILE_HEADER, " ")
    If Buffer(i) <> CByte("&H" & v) Then
      Err.Raise 1000, , XlsFileName & "は XLS ではない"
    End If
    i = i + 1
  Next
  ' // 検索キー生成
  i = 0
  For Each v In Split(SEARCH_KEY, " ")
    ReDim Preserve Keys(i)
    Keys(i) = CByte("&H" & v)
    i = i + 1
  Next
  ' // Return
  HasMacro = CBool(InStrB(Buffer, Keys) > 0)

Bye_:
  Erase Buffer
  Erase Keys
  Exit Function
Err_:
  MsgBox Err.Description, vbCritical
  Resume Bye_
End Function
    • good
    • 1

*.xls ファイルをバイナリモードで開き、VBA が含まれる場合にのみ


存在しそうなデータがないか調べてみたら?

マクロ有りの場合は次のキーワードが含まれているのかもしれません。

  16進データ: 56 42 5F 4E 61 6D ---- 文字列で VB_Nam

精査してませんので、これで判定できるのかわかりませんけど^^;
Excelのバージョンによっても異なるかもしれません。

しかし、これで判定可能なら、VBA プロジェクトにアクセスしないで
済みます。つまり、

 ・Excel でブックを開く必要がない
 ・VBA プロジェクトへアクセスできない(ユーザー毎にマクロの
  セキュリティー設定を変更してもらう必要がない)

などのメリットが想像できます。

アイディアの提供のみですが、どんなもんでしょうか?
    • good
    • 0

チェック方法が無いので、VBAプロジェクトを全て読み出すしか無いでしょう。



通常はVBAプロジェクトへのアクセス制限が掛かっているので、ブックの設定で解除して置く必要があります。
http://office.microsoft.com/ja-jp/word/HP0308947 …

Sub sample()
Dim Pj As Object
For Each Pj In ActiveWorkbook.VBProject.VBComponents
With Pj.CodeModule
Debug.Print .Name & "/ " & .CountOfLines
Debug.Print .Lines(1, .CountOfLines)
End With
Next
End Sub


単純なチェックなら、プロシージャの開始文字 "Sub" や "End Sub" 等を検索すると良いかも知れませんね。

「モジュールの中身を検索して、特定の文字列の有無を知るには?」 
http://park11.wakwak.com/~miko/Excel_Note/14-02_ …
    • good
    • 0
この回答へのお礼

hana-hana3さんご回答ありがとうございます。

返事が遅くなり申し訳ありません。

こんな方法があるのですね。
大変勉強になりました。

有難う御座いました。

お礼日時:2007/10/04 11:04

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!