Excel VBA 逆引き集 | Excel Add-in化

Excel VBA
スポンサーリンク

ねらい:ブック依存を卒業し、どこでも使える「Excelアドイン(XLAM)」へ

アドイン化は「よく使うVBAを、どのブックでも同じ操作で使えるようにする」ための最短ルートです。機能を共通ライブラリ化し、ボタンやショートカットから呼べるようにすると、配布・更新・運用が劇的に楽になります。ここでは、最小のXLAMテンプレからUDF(関数)、リボン/メニュー、設定・ログ、署名・信頼場所まで、初心者が貼って動かせる形で解説します。

重要ポイントの深掘り

アドインは「開いた瞬間に機能を提供する」常駐モジュールです。だからこそ、開始・終了の枠を備え、公共API(Public Sub/Function)を公開し、ブックに依存しない配列I/Oと前提検証に統一します。更新・互換・セキュリティ(署名/信頼場所)を先に設計しておくと、現場で長く安定運用できます。


XLAMの骨組み:最小テンプレと公開API

アドインの基本構造(標準モジュールとThisWorkbook)

アドイン(XLAM)には「公開する入口(Public Sub)」と「共通枠やユーティリティ」が必要です。ThisWorkbookで起動時のセットアップ、標準モジュールで機能提供、Class/Moduleで補助を構成します。

' ThisWorkbook(アドイン起動時の初期化)
Option Explicit
Private Sub Workbook_Open()
    ' 起動ログや環境設定(必要なら)
    Debug.Print "XLAM loaded: " & ThisWorkbook.Name
End Sub
VB
' ModApp(共通枠)
Option Explicit
Public Sub AppEnter(Optional ByVal status As String = "")
    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Application.DisplayAlerts = False
    Application.Calculation = xlCalculationManual
    If Len(status) > 0 Then Application.StatusBar = status
End Sub
Public Sub AppLeave()
    Application.StatusBar = False
    Application.Calculation = xlCalculationAutomatic
    Application.DisplayAlerts = True
    Application.EnableEvents = True
    Application.ScreenUpdating = True
End Sub
VB
' ModPublicAPI(公開する入口:どのブックでも呼べる)
Option Explicit

Public Sub Run_NormalizeSelection()
    On Error GoTo EH
    AppEnter "Normalize"
    Dim rng As Range
    Set rng = Selection
    If rng Is Nothing Then Err.Raise 900, , "選択範囲がありません"
    Dim arr As Variant: arr = rng.Value

    Dim r As Long, c As Long
    For r = 1 To UBound(arr, 1)
        For c = 1 To UBound(arr, 2)
            arr(r, c) = Trim$(CStr(arr(r, c)))
        Next
    Next

    rng.Value = arr
    AppLeave
    Exit Sub
EH:
    AppLeave
    MsgBox "失敗: " & Err.Description, vbExclamation
End Sub
VB

重要ポイントの深掘り

公開APIは「どのブックでも動く」ことが命です。ActiveWorkbookや特定シート名に依存させず、Selectionや引数で対象を受け取る形にします。開始・終了枠で必ず復帰できる安心を持たせ、エラーはFail Fastで明快に止めます。


UDF(ユーザー定義関数)をアドインから提供する

シート関数として使えるPublic Functionのテンプレ

UDFはどのブックでも関数名で呼べます。副作用を持たず(セルを書かない)、引数だけで結果を返す純粋関数にします。

' ModUdf(アドイン提供の関数)
Option Explicit

Public Function CLEANID(ByVal s As String) As String
    ' 先頭ゼロを残しつつ非数字を除去(例:ID整形)
    Dim i As Long, ch As String, buf As String
    For i = 1 To Len(s)
        ch = Mid$(s, i, 1)
        If ch Like "[0-9]" Then buf = buf & ch
    Next
    CLEANID = buf
End Function

Public Function PASSFLAG(ByVal score As Double, ByVal threshold As Double) As String
    PASSFLAG = IIf(score >= threshold, "○", "×")
End Function
VB

重要ポイントの深掘り

UDFは「速さ」と「副作用ゼロ」が基本です。ApplicationオブジェクトへのアクセスやファイルI/Oは避け、計算だけに専念します。引数検証(IsNumeric/IsDate)は親切ですが、エラーを返す場合は CVErr(xlErrValue) などのExcelエラー値も選択肢です。


リボン・メニューから呼べるようにする(初心者はメニュー型から)

旧コマンドバーでボタンを追加する(最短・作業量少)

Ribbon XMLが難しければ、CommandBarsで「アドイン」メニューにボタンを追加できます。起動時に登録し、終了時に削除する形にします。

' ModMenu(起動時にボタン追加)
Option Explicit
Private mButton As CommandBarButton

Public Sub RegisterMenu()
    On Error Resume Next
    Dim bar As CommandBar
    Set bar = Application.CommandBars("Cell")
    If mButton Is Nothing Then
        Set mButton = bar.Controls.Add(Type:=msoControlButton, Temporary:=True)
        mButton.Caption = "Normalize(XLAM)"
        mButton.OnAction = "Run_NormalizeSelection"
    End If
    On Error GoTo 0
End Sub

Public Sub UnregisterMenu()
    On Error Resume Next
    If Not mButton Is Nothing Then mButton.Delete
    Set mButton = Nothing
    On Error GoTo 0
End Sub
VB
' ThisWorkbook(アドインの起動・終了フック)
Option Explicit
Private Sub Workbook_Open()
    RegisterMenu
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    UnregisterMenu
End Sub
VB

重要ポイントの深掘り

CommandBarsは「右クリックメニュー」などに簡単にボタンを足せます。RibbonXより導入が手軽で、配布直後から誰でも使えます。後からRibbonXに移行する場合は、同じ公開API(OnAction先)を使い回せるようにしておけば移行コストが下がります。


RibbonXで本格UIにする(必要に応じて)

customUI(Ribbon XML)を追加し、コールバックをVBAに結びつける

XMLは「Office RibbonX Editor」などでブックに追加します。コールバック名はPublic Subで用意し、IDを結びます。

<!-- customUI14.xml の例(Book内に追加) -->
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
  <ribbon>
    <tabs>
      <tab id="tabAddin" label="XLAMツール">
        <group id="grpNormalize" label="整形">
          <button id="btnNormalize" label="Normalize" onAction="Run_NormalizeSelection"/>
        </group>
      </tab>
    </tabs>
  </ribbon>
</customUI>

重要ポイントの深掘り

RibbonXは「見た目を綺麗に、機能をグループ化」できます。コールバックはPublic Sub名で指定し、アドインに存在する必要があります。XMLは別編集ツールで追加するのが一般的です。まずはメニュー型で運用し、必要性が出たらRibbonXへ移行するのが負担が少ない道筋です。


設定・ログ・バージョン管理をアドイン内に持つ

設定はConfigシートに外出し、鍵で読む

' ModConfig(XLAM内のConfigシートを読む)
Option Explicit
Private Function ConfigSheet() As Worksheet
    Set ConfigSheet = ThisWorkbook.Worksheets("Config")
End Function

Public Function GetConfigString(ByVal key As String) As String
    Dim ws As Worksheet: Set ws = ConfigSheet()
    Dim last As Long: last = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    Dim r As Long
    For r = 2 To last
        If StrComp(CStr(ws.Cells(r, "A").Value), key, vbTextCompare) = 0 Then
            GetConfigString = Trim$(CStr(ws.Cells(r, "B").Value))
            Exit Function
        End If
    Next
    Err.Raise 900, , "Configキーが見つかりません: " & key
End Function
VB

ログはLogシートへ時刻・アクション・詳細で記録

' ModLog(アドイン共通ログ)
Option Explicit
Public Sub LogInfo(ByVal action As String, ByVal detail As String)
    Dim ws As Worksheet
    On Error Resume Next
    Set ws = ThisWorkbook.Worksheets("Log")
    If ws Is Nothing Then Set ws = ThisWorkbook.Worksheets.Add: ws.Name = "Log"
    On Error GoTo 0
    Dim r As Long: r = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
    ws.Cells(r, 1).Value = Format(Now, "yyyy-mm-dd HH:NN:SS")
    ws.Cells(r, 2).Value = action
    ws.Cells(r, 3).Value = detail
End Sub
VB

重要ポイントの深掘り

アドイン内にConfigとLogを持てば、どのブックから呼んでも「同じ設定・同じ記録」が使えます。現場での調整はConfigに集約し、コードの再配布を減らします。バージョン番号をConfigに持たせ、起動時にログへ出すと配布確認が容易です。


配布・導入・更新の手順と安全策

導入手順(XLAMの作成と登録)

  • XLAMに保存: 元の開発ブックを「名前を付けて保存」で「Excel アドイン(.xlam)」形式にする。
  • アドイン登録: Excelの「オプション > アドイン > 設定」でXLAMにチェックを入れる。
  • 信頼済み場所: 共有配布なら「信頼できる場所」にXLAMを置くと、マクロ警告が減る。

更新のコツ(後方互換と署名)

  • 公開APIの互換: Public Sub/Functionのシグネチャ(引数)を変えずに内部実装を更新する。
  • デジタル署名: 可能なら自己署名/企業署名でVBAプロジェクトに署名し、配布先で信頼設定。
  • バージョン管理: ConfigにVersionを持ち、Workbook_Openでログに吐くと「どれが入っているか」が一目で分かる。

重要ポイントの深掘り

配布の事故は「信頼場所・署名・互換性」を押さえると激減します。後方互換を守るほど、ユーザー側の更新作業が軽くなります。アドインの起動はExcel全体に影響するため、例外時でも復帰する設計(開始・終了枠)を標準化します。


例題シナリオ:よく使う整形・UDF・CSV出力をアドイン化

操作の流れと確認ポイント

  • Normalize: 任意のブックで範囲を選択し、右クリックメニューの「Normalize(XLAM)」を押す。トリム整形が反映される。
  • UDF: 任意のブックのセルで =CLEANID(A2)=PASSFLAG(D2,70) を使用。関数が期待通り動く。
  • ログ: アドインのLogシートに操作履歴が残る。起動時にVersionが記録される。
  • 設定: Configでしきい値を変え、PASSFLAGの既定値を差し替えるなど、コードに触れず運用変更できる。

重要ポイントの深掘り

「どのブックでも同じ操作で使えること」を確認してください。選択依存機能はSelection、関数はセル計算、I/Oは配列で統一すると、アドインの“持ち運び性”が担保されます。ログ・設定が内蔵されていると、配布後の運用が静かに回ります。


トラブル対策と落とし穴回避(深掘り)

競合や二重登録

アドイン複数が同じメニューに同名ボタンを足すと競合します。IDやキャプションをユニークにし、起動時に「既に登録済みか」を確認して二重追加を避けます。

ActiveWorkbook依存

アドイン側でActiveWorkbook前提のコードを書くと、別ブック操作時に誤動作します。対象は引数で受け取る(Selection、Range、Path)か、明示的にApplication.ActiveWindowから取り出します。

UDFの副作用

UDF内でApplicationやセルを書き換えると再計算ループやエラーの原因になります。UDFは純粋な計算関数に徹します。I/OはPublic Subから呼ぶ設計に分離します。


まとめ:XLAMは「共通枠+公開API+UDF+UI登録」で完成する

アドイン化の鍵は、ブック非依存で動く公共の入口(Public Sub/Function)、開始・終了枠、配列I/O、設定・ログ、そして簡単に押せるUI(メニュー/リボン)。この型に沿えば、初心者でも「貼って動く」、運用側でも「更新が楽」、現場でも「壊れない」アドインになります。

タイトルとURLをコピーしました