ExcelVBAでソースコードを一括出力するには、VBAから実行することでソースコードを出力することが可能。
VBAソースコード一括出力()
ExcelVBAではクラスを一括で開放することがUI上からできなかったため、これもVBAから実行する。
VBAクラスモジュール一括開放()
サンプルソースコードは以下の通り。
このソースコードをVBAModule.batとしてテキストエディタで保存して、エクセルにモジュール追加することでマクロ呼び出しが可能となる。もしくは先頭行以外をそのままModuleを作成してコピペでも可。
ソースコード一括出力 & クラス一括開放
Attribute VB_Name = "VBAModule"
Sub VBAソースコード一括出力()
Dim VBComponent As Object
Dim CodeModule As Object
Dim FilePath As String
Dim ModuleType As String
Dim ext As String
Dim header As String
' エクスポート先のフォルダパスを指定します
With Application.FileDialog(msoFileDialogFolderPicker)
'最初に表示されるフォルダパスを指定
.InitialFileName = ThisWorkbook.Path
'ダイアログのタイトルを指定
.Title = "フォルダを選択してください"
'ダイアログを表示、結果を確認
If .Show = -1 Then
'選択されたフォルダパスを取得
FilePath = .SelectedItems(1) & "\"
End If
End With
header = ""
For Each VBComponent In ThisWorkbook.VBProject.VBComponents
Select Case VBComponent.Type
Case 1 ' 標準モジュール
ModuleType = "StandardModules"
ext = ".bas"
header = "Attribute VB_Name = """ & VBComponent.Name & """" & vbCrLf
Case 2 ' クラスモジュール
ModuleType = "ClassModules"
ext = ".cls"
header = "VERSION 1.0 CLASS" & vbCrLf & _
"BEGIN" & vbCrLf & _
" MultiUse = -1 'True" & vbCrLf & _
"End" & vbCrLf & _
"Attribute VB_Name = """ & VBComponent.Name & """" & vbCrLf & _
"Attribute VB_GlobalNameSpace = False" & vbCrLf & _
"Attribute VB_Creatable = False" & vbCrLf & _
"Attribute VB_PredeclaredId = False" & vbCrLf & _
"Attribute VB_Exposed = False" & vbCrLf
Case 3 ' フォーム
ModuleType = "Forms"
ext = ".frm"
Case 1000 ' Microsoft Excel Objects
ModuleType = "ExcelObjects"
ext = ".bas"
Case Else
ModuleType = "OtherModules"
ext = ".bas"
End Select
Set CodeModule = VBComponent.CodeModule
With CreateObject("Scripting.FileSystemObject")
Dim FileName As String
FileName = FilePath & ModuleType & "\" & VBComponent.Name & ext
' フォルダが存在しない場合は作成します
If Not .FolderExists(FilePath & ModuleType) Then
.CreateFolder FilePath & ModuleType
End If
' ファイルにVBAコードを書き込みます
Dim FileNumber As Integer
FileNumber = FreeFile
Open FileName For Output As FileNumber
Print #FileNumber, header
For i = 1 To CodeModule.CountOfLines
Print #FileNumber, CodeModule.Lines(i, 1)
Next i
Close FileNumber
End With
Next VBComponent
End Sub
' Classモジュールの開放※これを実行するとVBAに梱包されたコードが消えるので注意
Sub VBAクラスモジュール一括開放()
Dim VBComponent As Object
Dim CodeModule As Object
Dim FilePath As String
Dim ModuleType As String
For Each VBComponent In ThisWorkbook.VBProject.VBComponents
Set CodeModule = VBComponent.CodeModule
Select Case VBComponent.Type
Case 1 ' 標準モジュール
Case 2 ' クラスモジュール
Application.VBE.ActiveVBProject.VBComponents.Remove _
Application.VBE.ActiveVBProject.VBComponents(VBComponent.Name)
Case 3 ' フォーム
Case 1000 ' Microsoft Excel Objects
Case Else
End Select
Next VBComponent
End Sub
' ログ出力
Sub LogInfo(ByRef classInstance As Object, ByVal str As String)
Dim log As String
log = TypeName(classInstance)
log = log & "." & str
Debug.Print log
Dim filepath As String
Dim filenumber As Integer
' ファイルパスを設定します(例:C:\vpapplog.log)※ブックファイルと同じ場所にログを出力する。
filepath = ThisWorkbook.Path & "\vbapplog.log"
' ファイルを開いてログを書き込みます
filenumber = FreeFile()
Open filepath For Append As #filenumber
Print #filenumber, log
Close #filenumber
End Sub
クラスモジュールの一括開放について
これはVBAのソースコードが解放されてしまうため操作には十分に気を付けること。バックアップを取っておいてから実施すること。
上記のソースコードでは、クラスモジュールの一括開放のみしか行えない為、モジュールやフォームなどを消したい場合はCase1とCase2の箇所に以下のコードを記載することで対応可能。
Application.VBE.ActiveVBProject.VBComponents.Remove _
Application.VBE.ActiveVBProject.VBComponents(VBComponent.Name)