【入門編】【上級者】PowerPointの「アドイン(.ppam)」として実装し、ファイル保存時に社内Web API(REST API)を叩いて「文書管理番号」を自動取得・プロパティに埋め込んで保存するエンタープライズマクロ – PowerPoint VBA解析バイブル

スポンサーリンク

こんにちは!チーフアーキテクトの私です。
普段は大規模な業務システムの自動化や、数千人規模のOfficeマクロ基盤の設計・構築を手がけています。

さて、マクロの記録から抜け出し、日々の退屈な作業をVBAで自動化できるようになったあなた。今、こんな壁にぶ当たっていませんか?

*「ローカルで作った資料を、いちいち社内の文書管理システムに手動で登録するのが面倒……」*
*「ファイル保存のタイミングで、勝手にサーバーと通信して管理番号をもらってこられないものか?」*

──お任せください。今回は、PowerPoint VBAを単なる「お絵描きツール」から「エンタープライズな業務システムの一部」へと昇華させる極限のテクニックを授けます。

テーマは「PowerPointアドイン(.ppam)として実装し、ファイル保存時に社内REST APIを叩いて文書管理番号を自動取得・プロパティに埋め込んで保存するシステム」です。

ここをクリアすれば、あなたはもうただのVBAユーザーではありません。立派な「エンタープライズ・オートメーション・エンジニア」です。さあ、一緒に深淵の世界へ足を踏み入れましょう!

なぜ「アドイン(.ppam)」×「REST API連携」なのか?

一般的にVBAを書くときは、特定のプレゼンテーションファイル(`.pptm`)の中にコードを閉じ込めがちです。しかし、全社展開するシステムにおいて、個別のファイルにマクロを埋め込むのは悪夢の始まりです。バージョンアップのたびにファイルを配り直す必要がありますからね。

そこで登場するのがPowerPointアドイン(`.ppam`)です。
アドインとして背後で常駐させることで、ユーザーがどのファイルを開いていても、保存の瞬間をフックして自動的にサーバー通信を行わせることができます。

さらに、`MSXML2.ServerXMLHTTP` オブジェクトを使用すれば、サードパーティ製のライブラリや追加のインストールなしで、VBAから直接社内Web API(REST API)を叩くことが可能です。

全体像:システムが動く仕組み

ファイル保存時に以下のドラマが裏側で瞬時に展開されます。

1. 保存イベントの検知: ユーザーが「上書き保存」または「名前を付けて保存」を実行。
2. APIリクエスト: アドインが起動し、社内文書管理APIへ非同期(または同期)でPOSTリクエスト送信。
3. 管理番号の採番: サーバー側で一意の文書管理番号(例: `DOC-2023-9999`)を発行して返却。
4. プロパティ埋め込み: 取得した番号をPowerPointの「組み込みプロパティ」または「カスタムドキュメントプロパティ」に書き込む。
5. 保存完了: 番号が刻印された状態で、安全にファイルが保存される。

実装ステップ 1:イベントを監視するクラスの準備

PowerPointのアドインで「保存の瞬間」を捉えるには、アプリケーションレベルのイベントをフックする必要があります。

まずは、標準モジュールではなくクラスモジュールを挿入し、名前を `CAppEvents` に変更してください。

' =================================================================
' クラスモジュール: CAppEvents
' 目的: PowerPoint全体のアプリケーションイベントを監視する
' =================================================================
Option Explicit

' WithEventsキーワードを使い、PowerPointのAppイベントを捕捉できるようにします
Public WithEvents App As PowerPoint.Application

' 「名前を付けて保存」または「上書き保存」の直前に走るイベント
Private Sub App_PresentationBeforeSave(ByVal Pres As Presentation, Cancel As Boolean)
    On Error GoTo ErrorHandler
    レジストリ通信とプロパティ付与のメイン処理 Pres
    Exit Sub

ErrorHandler:
    MsgBox "文書管理番号の取得に失敗しました。" & vbCrLf & _
           "エラー内容: " & Err.Description, vbCritical, "API連携エラー"
    ' 必要に応じて Cancel = True にして保存を強制キャンセルすることも可能です
End Sub

実装ステップ 2:API通信とプロパティ埋め込みの核心部

次に、標準モジュールを挿入し、名前を `MainsModule` にします。ここが今回のアーキテクチャの心臓部です。

' =================================================================
' 標準モジュール: MainsModule
' 目的: REST APIとの通信、およびドキュメントプロパティへの書き込み
' =================================================================
Option Explicit

' イベントを管理するためのグローバル変数
Public GlobalEvents As New CAppEvents

' アドイン有効時に最初に呼ばれるプロシージャ(自動実行)
Sub Auto_Open()
    ' アプリケーションオブジェクトをクラスに紐付け、監視を開始する
    Set GlobalEvents.App = Application
    MsgBox "文書管理システム連携アドインが正常にロードされました。", vbInformation, "エンタープライズ連携"
End Sub

' メインのビジネスロジック
Sub レジストリ通信とプロパティ付与のメイン処理(ByVal targetPres As Presentation)
    
    ' 既に管理番号が埋め込まれている場合は二重発行を防ぐためスキップ
    On Error Resume Next
    Dim existingId As String
    existingId = targetPres.CustomDocumentProperties("DocumentControlID").Value
    On Error GoTo 0
    
    If existingId <> "" Then
        ' 既に付与済みなら何もしない
        Exit Sub
    End If

    ' 1. REST APIのエンドポイント(社内環境に合わせて変更してください)
    Dim apiUrl As String
    apiUrl = "https://api.internal.company.co.jp/v1/documents/issue-id"

    ' 2. MSXML2.ServerXMLHTTPを用いたHTTP通信の構築
    Dim http As Object
    Set http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
    
    ' ペイロード(JSON形式でメタデータを送信)
    Dim payload As String
    payload = "{""author"":""" & Application.UserName & """," & _
              """fileName"":""" & targetPres.Name & """}"

    ' 通信の初期化 (POSTメソッド、同期通信)
    http.Open "POST", apiUrl, False
    http.setRequestHeader "Content-Type", "application/json"
    http.setRequestHeader "Authorization", "Bearer YOUR_API_ACCESS_TOKEN_HERE" ' 必要に応じて認証トークン
    
    ' リクエスト送信
    http.send payload

    ' 3. レスポンスのハンドリング
    If http.Status = 200 Then
        ' 簡易的なJSONパース(本来はVBA用JSONパーサーを推奨しますが、今回は擬似的に文字列抽出)
        Dim responseText As String
        responseText = http.responseText
        
        ' 例: レスポンスが {"documentId":"DOC-2023-8888"} であると仮定した簡易抽出
        Dim docId As String
        docId = ExtractJsonValue(responseText, "documentId")
        
        If docId <> "" Then
            ' 4. PowerPointの「カスタムドキュメントプロパティ」に埋め込む
            targetPres.CustomDocumentProperties.Add _
                Name:="DocumentControlID", _
                LinkToContent:=False, _
                Type:=msoPropertyTypeString, _
                Value:=docId
                
            ' スライドの右上などに視覚的にスタンプとして押すことも可能(高度な演出)
            Call StampIdOnSlide(targetPres, docId)
            
            MsgBox "文書管理番号 [" & docId & "] を正常に取得し、ファイルに紐付けました。", vbInformation, "API連携成功"
        Else
            Err.Raise 1000, , "APIからの応答パースに失敗しました。"
        End If
    Else
        Err.Raise http.Status, , "サーバーエラー: " & http.statusText & " (Response: " & http.responseText & ")"
    End If
End Sub

' 簡易JSONパース用ヘルパー関数(実務では専用ライブラリ推奨)
Private Function ExtractJsonValue(json As String, key As String) As String
    Dim p1 As Long, p2 As Long
    p1 = InStr(json, """" & key & """")
    If p1 = 0 Then Exit Function
    p1 = InStr(p1, json, ":")
    p1 = InStr(p1, json, """") + 1
    p2 = InStr(p1, json, """")
    ExtractJsonValue = Mid(json, p1, p2 - p1)
End Function

' おまけ:取得した管理番号をスライド上の目立つ位置にテキストボックスとして描画する演出
Private Sub StampIdOnSlide(Pres As Presentation, docId As String)
    Dim sld As Slide
    Set sld = Pres.Slides(1) ' 表紙スライド
    
    Dim shp As Shape
    Set shp = sld.Shapes.AddTextbox(msoTextOrientationHorizontal, 30, 30, 300, 30)
    shp.TextFrame.TextRange.Text = "管理ID: " & docId
    shp.TextFrame.TextRange.Font.Size = 10
    shp.TextFrame.TextRange.Font.Color.RGB = RGB(128, 128, 128)
End Sub

実装ステップ 3:PowerPointアドイン(.ppam)として保存する

コードが書けたら、いよいよこれを「全社共通のアドイン」へと仕立て上げます。手順は極めてシンプルです。

1. 通常のプレゼンテーションウィンドウで、先ほどのコードをすべて記述します。
2. キーボードの `F12`(名前を付けて保存)を押します。
3. ファイルの種類から 「PowerPoint アドイン (*.ppam)」 を選択します。
*(※この瞬間、保存先が自動的にOfficeアドインのデフォルトフォルダに切り替わります。大体は `%APPDATA%\Microsoft\AddIns` です)*
4. 適当な名前(例: `CorpDocumentManager.ppam`)で保存します。

アドインの有効化

1. PowerPointを新しく起動し、「ファイル」>「オプション」>「アドイン」を開きます。
2. 下部にある「管理」コンボボックスで 「PowerPoint アドイン」 を選択し、[設定] ボタンを押します。
3. [追加] ボタンを押し、先ほど保存した `CorpDocumentManager.ppam` を選択します。
4. チェックが入っていることを確認し、[閉じる] を押します。

これで完了です!今後はあなたが作るどのプレゼンテーションファイルであっても、保存ボタンを押した瞬間に背景でAPIが叩かれ、文書管理番号が刻み込まれるようになります。

陥りやすい罠とプロの回避術

現場でこのシステムを運用する際、必ず直面する「罠」と、その回避術を先回りしてお伝えしておきます。

1. ネットワーク切断時の挙動(オフライン問題)

  • 罠: 出張先や新幹線の中など、社内APIに接続できない環境で「上書き保存」をすると、`http.send` でVBAが強制終了し、ファイルが保存できなくなる。
  • 極限の知見: 本番運用では、必ず `On Error Resume Next` でエラーをキャッチし、通信タイムアウト(`http.setTimeouts` の設定)を短く(例: 2秒)設定すること。さらに、オフライン時はローカル用の仮番号(`TEMP-xxxx`)を発行して保存を継続させ、次回オンライン時に同期する「キューイング機構」を設計レベルで組み込むべきです。

2. セキュリティソフト・プロキシの壁

  • 罠: `MSXML2.ServerXMLHTTP` は、企業の厳重なプロキシ環境やSSL/TLSの証明書検証でブロックされることがある。
  • 極限の知見: 社内インフラチームと事前に協議し、APIのエンドポイントを例外リストに登録してもらうか、WinINet APIを直接叩くラッパー設計を検討してください。

まとめ:ここをクリアすれば、PowerPoint VBAは「武器」になる

いかがでしょうか?
今回は、単なるマクロの域を超え、「社内システムと連携するエンタープライズ・アドイン」の構築方法を解説しました。

ここをクリアしたあなたなら、もはや「VBAの初学者」ではありません。PowerPointを業務基幹システムのフロントエンドとして自在に操る、立派な自動化エンジニアです。

ぜひ自分の環境でこのコードを組み立て、社内の同僚をあっと言わせるようなスマートな自動化を実現してみてください。あなたのエンジニアライフの飛躍を、心から応援しています!

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