0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Excel VBAの全モジュールを一括エクスポートするマクロ(.bas/.cls/.frm)と、ハマりどころ

0
Posted at

Excel VBA のコードを Git で管理したり、バックアップしたりするために、ブック内の全モジュールをテキストファイルに書き出すマクロをまとめました。
あわせて、実際にやってみて引っかかった点も書いておきます。

環境

  • Windows 11 / Microsoft 365(Excel 64bit)
  • 参照設定なし(遅延バインディング)で動く書き方にしています

事前準備:VBAプロジェクトへのアクセスを許可する

VBA から VBProject を操作するには、Excel の設定変更が必要です。

「ファイル」→「オプション」→「トラスト センター」→「トラスト センターの設定」→「マクロの設定」で、
「VBA プロジェクト オブジェクト モデルへのアクセスを信頼する」 にチェックを入れます。

これをしていないと、ThisWorkbook.VBProject にアクセスした時点で次のエラーになります。

実行時エラー '1004':
プログラミングによる Visual Basic プロジェクトへのアクセスは信頼性に欠けます

この設定をオンにすると、他のマクロからもVBAのコードを書き換えられるようになります。使い終わったらオフに戻しておくのがおすすめです。会社のPCでは、ポリシーで変更できない場合もあります。

コード

Option Explicit

Public Sub ExportAllModules()
    Dim outDir As String
    outDir = ThisWorkbook.Path & "\src\"
    If Dir(outDir, vbDirectory) = "" Then MkDir outDir

    Dim comp As Object, ext As String, n As Long
    For Each comp In ThisWorkbook.VBProject.VBComponents
        Select Case comp.Type
            Case 1: ext = ".bas"     ' vbext_ct_StdModule(標準モジュール)
            Case 2: ext = ".cls"     ' vbext_ct_ClassModule(クラスモジュール)
            Case 3: ext = ".frm"     ' vbext_ct_MSForm(ユーザーフォーム。.frx も一緒に出る)
            Case 100: ext = ".cls"   ' vbext_ct_Document(シート・ThisWorkbook)
            Case Else: ext = ""
        End Select

        ' 中身が空のシートモジュールなどは書き出さない
        If ext <> "" And comp.CodeModule.CountOfLines > 0 Then
            comp.Export outDir & comp.Name & ext
            n = n + 1
        End If
    Next

    MsgBox n & " 個のモジュールを書き出しました:" & vbLf & outDir
End Sub

comp.Type の値は、参照設定(Microsoft Visual Basic for Applications Extensibility)を入れると vbext_ct_StdModule などの定数で書けます。参照設定なしでも動くように、ここでは数値で書いています。

ハマりどころ

1. 書き出したファイルは Shift_JIS

日本語環境の VBE が書き出すファイルは Shift_JIS(CP932)・改行 CRLF です。
UTF-8 前提のエディタで開くとコメントが文字化けします。VS Code なら右下のエンコード表示から「エンコード付きで再度開く」→「Japanese (Shift JIS)」で読めます。

2. ファイルの先頭に Attribute 行が入る

書き出したファイルの先頭には、次のような行が入ります。VBE 上では見えない行ですが、インポート時に必要なので消さないでください。

Attribute VB_Name = "Module1"

3. シートのモジュールは「インポートで戻せない」

Type = 100(シート・ThisWorkbook)のコードは .cls として書き出されますが、これをインポートするとシートのモジュールではなく、新しいクラスモジュールとして取り込まれます。
戻すときは、ファイルを開いて中身をコピーし、該当シートのモジュールに貼り付ける必要があります。

4. ユーザーフォームは .frx とセット

フォームは .frm(コード+レイアウト定義)と .frx(画像などのバイナリ)の2つが出力されます。インポートには両方が必要です。Git で管理するときも .frx を忘れずに。

5. VBAプロジェクトにパスワードがかかっていると読めない

ロックされたプロジェクトは VBComponents にアクセスできません。

Git で管理するときのコツ

  • 書き出し先(上の例では src フォルダ)をリポジトリにして、修正のたびに書き出し → コミット
  • .xlsm 本体はバイナリなので差分が見られません。差分はテキストの src 側で見ます
  • Shift_JIS のまま差分を見たい場合は、.gitattributes に *.bas diff=sjis を書き、git config diff.sjis.textconv "iconv -f cp932 -t utf-8" を設定すると読みやすくなります(iconv が使える環境の場合)

補足:Excelを開かずに書き出したい場合

この方法は、対象のブックを開いてマクロを実行する必要があります。
ブックを開くとマクロが動いてしまうファイルや、フォルダ内の大量のブックをまとめて書き出したい場合のために、Excel を起動せずにファイルから直接コードを読み出すツール(無料)を作りました。必要な方はどうぞ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?