課題
Excelのマクロで社内ツールをつくると最初は良いのだが規模が大きくなってきたときに変更管理が悪夢になってきたので、GITのようなレポジトリ管理システムを使ってソースコードの変更をきちんと管理する必要が出てきた。VBEからでは1ファイルずつしかExportできないため一括Exportするための機能が欲しい
実装
汎用的にするため、別のExcelツールとして実装。選択したファイルのソースコードを,選択したファイルと同じフォルダにExportする(同名ファイルの存在チェックはしない)。ワークブックやシートにマクロを書くとエクスポートはできるのだがインポートするとクラスオブジェクトとしてインポートされてしまうが、目的はあくまでソースコード管理なのでワークシートやブックのマクロもExport対象とする。Active X Designerは開発環境のOffice 2024では廃止となっているので非対称。ローカルレポジトリにExcelのツールを保存して、コードをエクスポート、まとめてセントラルレポジトリにプッシュするような運用を想定
事前準備
- Microsoft Visual Basic for Applications Extentibility x.x に参照設定
- Excelのオプション→トラストセンター→マクロの設定で"VBA プロジェクトオブジェクトモデルへのアクセスを信頼する"をチェック
コード
Sub Export()
Dim wb As Workbook
With Application.FileDialog(msoFileDialogFilePicker)
.Filters.Clear
.AllowMultiSelect = False
.Filters.Add "Macro-enabled", "*.xlsm"
.Filters.Add "Macro-enabled (bin)", "*.xlsb"
.Filters.Add "Macro-enabled (old)", "*.xls"
.Filters.Add "Add-in", "*.xlsa"
.Filters.Add "Add-in (old)", "*.xla"
.Show
If .SelectedItems.Count <= 0 Then
MsgBox "Operation Cancelled", vbExclamation, "Operation Cancelled"
Exit Sub
Else
Set wb = Workbooks.Open(.SelectedItems.Item(1), False, True)
If wb.FullName <> ThisWorkbook.FullName Then
ActiveWindow.Visible = False
ThisWorkbook.Activate
End If
End If
End With
Dim vbc As VBComponent
Dim strExt As String
Dim blnExport As Boolean
Dim strPath As String
For Each vbc In wb.VBProject.VBComponents
blnExport = False
Select Case vbc.Type
Case VBIDE.vbext_ComponentType.vbext_ct_Document:
blnExport = True
strExt = ".dco"
Debug.Print "Exporting Document object: " & vbc.Name & strExt
Case VBIDE.vbext_ComponentType.vbext_ct_ActiveXDesigner:
Debug.Print "Skipping Active X Designer type: " & vbc.Name
Case VBIDE.vbext_ComponentType.vbext_ct_StdModule:
blnExport = True
strExt = ".bas"
Debug.Print "Exporting Standard Module: " & vbc.Name & strExt
Case VBIDE.vbext_ComponentType.vbext_ct_MSForm:
blnExport = True
strExt = ".frm"
Debug.Print "Exporting MS Form: " & vbc.Name & strExt
Case VBIDE.vbext_ComponentType.vbext_ct_ClassModule:
blnExport = True
strExt = ".cls"
Debug.Print "Exporting Class module: " & vbc.Name & strExt
Case Else:
Debug.Print "Skipping unsupported type: " & vbc.Name & "(" & CStr(vbc.Type) & ")"
End Select
If blnExport Then
strPath = wb.Path & "\" & vbc.Name & strExt
vbc.Export strPath
Debug.Print "Saved As " & strPath
End If
Next
If wb.FullName <> ThisWorkbook.FullName Then
Stop
wb.Close False
End If
End Sub