和風スパゲティのレシピ

日本語でコーディングするExcelVBA

コードやモジュールをVBAで操作する基本コード集

ブックに標準モジュールを挿入したり、複数ブックのコードを一括で書き換えるなど、
マクロの作成や更新を自動化したいということもあります。

この時に使用する基本コード集を汎用関数としてまとめましたので、
参考にするなり、中身を読まずに使うなり、ご自由にお持ち帰りください。

汎用関数の使用例

例えば個人用マクロブックの汎用関数モジュールを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 コピー第1As 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公式ドキュメントなどで調べてください。