ブックに標準モジュールを挿入したり、複数ブックのコードを一括で書き換えるなど、
マクロの作成や更新を自動化したいということもあります。
この時に使用する基本コード集を汎用関数としてまとめましたので、
参考にするなり、中身を読まずに使うなり、ご自由にお持ち帰りください。
汎用関数の使用例
例えば個人用マクロブックの汎用関数モジュールをActiveWorkbookにコピーする場合は、以下のように汎用関数をCallしてください。
If Isモジュールが存在する("Ut_汎用関数", ActiveWorkbook) = False Then Call モジュールをコピーする(ActiveWorkbook _ , Workbooks("PERSONAL.XLSB"), "Ut_汎用関数") End If
主に「ブック/モジュール名/ソースコード」を引数として動くように作ってあります。
なお、VBAからVBEを操作するにはひとつセキュリティ設定を切る必要があり、
「開発」⇒「マクロのセキュリティ」⇒
「VBA プロジェクト オブジェクト モデルへのアクセスを信頼する」
にチェックを入れることで以下の関数群が使用可能になります。
セキュリティに関することなので、このセキュリティの詳しい説明と、
各汎用関数のご使用は、自己責任でお願いいたします。
コード・モジュールを操作する汎用関数集
モジュールの存在判定
' モジュールが存在するか判定 Function Isモジュールが存在する(判定モジュール名 As String, wb指定ブック As Workbook) As Boolean On Error Resume Next Isモジュールが存在する = wb指定ブック.VBProject.VBComponents(判定モジュール名).Name = 判定モジュール名 End Function ' 標準モジュールがあるか判定 Function Is標準モジュールが存在する(wb指定ブック As Workbook) As Boolean With wb指定ブック.VBProject Dim モジュール As Object For Each モジュール In .VBComponents If モジュール.Type = 1 Then Is標準モジュールが存在する = True Exit Function End If Next End With End Function ' クラスモジュールがあるか判定 Function Isクラスモジュールが存在する(wb指定ブック As Workbook) As Boolean With wb指定ブック.VBProject Dim モジュール As Object For Each モジュール In .VBComponents If モジュール.Type = 2 Then Isクラスモジュールが存在する = True Exit Function End If Next End With End Function ' フォームモジュールがあるか判定 Function Isフォームモジュールが存在する(wb指定ブック As Workbook) As Boolean With wb指定ブック.VBProject Dim モジュール As Object For Each モジュール In .VBComponents If モジュール.Type = 3 Then Isフォームモジュールが存在する = True Exit Function End If Next End With End Function
モジュールの挿入・コピー・削除・名称変更
' モジュールの挿入 Sub 標準モジュールを挿入する(wb挿入ブック As Workbook, モジュール名 As String) wb挿入ブック.VBProject.VBComponents.Add(1).Name = モジュール名 End Sub ' モジュールのコピー Sub モジュールをコピーする(wbコピー先ブック As Workbook, wbコピー元ブック As Workbook, モジュール名 As String) With wbコピー元ブック.VBProject.VBComponents(モジュール名) wbコピー先ブック.VBProject.VBComponents.Add(.Type).Name = モジュール名 Call wbコピー先ブック.VBProject.VBComponents(モジュール名).CodeModule.AddFromString _ (.CodeModule.Lines(3, .CodeModule.CountOfLines)) End With End Sub ' モジュールがなければコピーする Sub モジュールがなければコピーする(wbコピー先ブック As Workbook, wbコピー元ブック As Workbook, モジュール名 As String) If Isモジュールが存在する(モジュール名, wbコピー先ブック) = False Then Call モジュールをコピーする(wbコピー先ブック, wbコピー元ブック, モジュール名) End If End Sub ' モジュールの削除 Sub モジュールを削除する(削除モジュール名 As String, wb指定ブック As Workbook) With wb指定ブック.VBProject ' モジュールの解放はマクロ終了まで反映されない場合があるため、 ' 同名モジュールの再作成に影響が出ないよう、モジュール名を変更してから削除する Dim i As Long Do ' 重複の無いよう連番を付与 If Isモジュールが存在する("削除中モジュール" & i, wb指定ブック) = False Then .VBComponents(削除モジュール名).Name = "削除中モジュール" & i ' 解放されずに残る場合があるので、一応すべてコメントアウトしておく Call モジュールをコメントアウトする(wb指定ブック, "削除中モジュール" & i) Exit Do End If i = i + 1 Loop ' モジュールを開放 Call .VBComponents.Remove(.VBComponents("削除中モジュール" & i)) End With End Sub ' モジュール名の変更 Sub モジュール名を変更する(wb指定ブック As Workbook, 元モジュール名 As String, 変更モジュール名 As String) wb指定ブック.VBProject.VBComponents(元モジュール名).Name = 変更モジュール名 End Sub ' シートモジュール名の設定 Sub シートモジュール名を設定する(ws指定シート As Worksheet, モジュール名 As String) ws指定シート.Parent.VBProject.VBComponents(ws指定シート.CodeName).Name = モジュール名 End Sub
ソースコードの挿入・コピー
' コードの挿入 Sub コードを最後尾に挿入する(挿入コード As String, Optional wb指定ブック As Workbook, Optional 指定モジュール名 As String) ' 連続実行時に引数を省略できるようStatic変数に直前の引数を記憶 Static Staticwb挿入ブック As Workbook Static Static挿入モジュール名 As String If Not wb指定ブック Is Nothing Then Set Staticwb挿入ブック = wb指定ブック If 指定モジュール名 <> "" Then: Static挿入モジュール名 = 指定モジュール名 With Staticwb挿入ブック.VBProject.VBComponents(Static挿入モジュール名).CodeModule .InsertLines .CountOfLines + 1, 挿入コード End With End Sub ' コードのコピー Sub コードを別モジュールの最後尾にコピーする(wbコピー先ブック As Workbook, コピー先モジュール名 As String _ , wbコピー元ブック As Workbook, コピー元モジュール名 As String _ , Optional コピー第1行 As Long = 3, Optional コピー最終行 As Long = -1) With wbコピー元ブック.VBProject.VBComponents(コピー元モジュール名).CodeModule ' ◇ 省略時はモジュール内のすべてのコードをコピー If コピー最終行 = -1 Then コピー最終行 = .CountOfLines ' コードをコピーして挿入 Call コードを最後尾に挿入する(.Lines(コピー第1行, コピー最終行), wbコピー先ブック, コピー先モジュール名) End With End Sub
ソースコードの置換
' モジュール内コードの置換 Sub モジュール内のコードを置換する(検索テキスト As String, 置換テキスト As String _ , wb指定ブック As Workbook, モジュール名 As String) With wb指定ブック.VBProject.VBComponents(モジュール名).CodeModule Dim i As Long For i = 1 To .CountOfLines Call .ReplaceLine(i, Replace(.Lines(i, 1), 検索テキスト, 置換テキスト)) Next End With End Sub ' ブック内コードの置換 Sub ブック内の全モジュールのコードを置換する(検索テキスト As String, 置換テキスト As String, wb指定ブック As Workbook) ' △ 指定ブックのモジュールを走査 Dim 更新モジュール As Variant For Each 更新モジュール In wb指定ブック.VBProject.VBComponents Dim 更新モジュール名 As String: 更新モジュール名 = 更新モジュール.Name Call モジュール内のコードを置換する(検索テキスト, 置換テキスト, wb指定ブック, 更新モジュール名) Next ' ▽ 指定ブックのモジュールを走査 End Sub
コメントアウト・アンコメント
' モジュールのコメントアウト Sub モジュールをコメントアウトする(wb指定ブック As Workbook, モジュール名 As String) With wb指定ブック.VBProject.VBComponents(モジュール名).CodeModule Dim i As Long For i = 1 To .CountOfLines Call .ReplaceLine(i, "'" & .Lines(i, 1)) Next End With End Sub ' コメントアウトの復元 Sub モジュールのコメントアウトを解除する(wb指定ブック As Workbook, モジュール名 As String) With wb指定ブック.VBProject.VBComponents(モジュール名).CodeModule Dim i As Long For i = 1 To .CountOfLines If Left(.Lines(i, 1), 1) = "'" Then Call .ReplaceLine(i, Mid(.Lines(i, 1), 2)) End If Next End With End Sub
ライブラリ(Scripting Runtimeなど)の自動参照
' Scripting Runtimeの参照設定 Sub ScriptingRuntimeを参照設定する(wb指定ブック As Workbook) On Error Resume Next wb指定ブック.VBProject.References.AddFromGuid _ GUID:="{420B2830-E718-11CF-893D-00A0C9054228}", _ Major:=1, Minor:=0 On Error GoTo 0 End Sub
以上です。
VBEをVBAから操作する場合は、
WorkbooksオブジェクトのVBProjectプロパティを主に使用します。
各メソッド・プロパティの動きは割愛しますので、
必要に応じてMS公式ドキュメントなどで調べてください。