Azure Blob Storageに請求書PDFをアップロードするだけで、Azure Document Intelligence(旧Form Recognizer)のカスタム抽出モデルが自動解析し、結果をSharePoint上のExcelテーブルへ追記していく――この一連の自動化は、Power Automate中心でも、Azure Functions中心でも実現できます。
実現したいゴールを「3つの流れ」に分解する
請求書自動集約を安定稼働させるためには、まず処理を次の3つに分けて考えると設計がブレません。
- 検知:Blobに新しい請求書が来たことをどう検知するか
- 抽出:Document Intelligenceのカスタムモデルで必要項目をどう取り出すか
- 集約:SharePoint上のExcel「テーブル」へどう書き込むか(重複・エラーも含めて)
おすすめの構成パターン(結論)
| パターン | 向いているケース | 主な構成 | 注意点 |
|---|---|---|---|
| Power Automate中心(最短で動かす) | まずは業務で使える形にしたい/運用をノーコード寄りにしたい | Blobトリガー → Document Intelligence(コネクタ) → Excel Online(Business)で追記 | Excelの同時更新・ロック、スロットリング対策が必要 |
| Power Automate + HTTP(コネクタが見つからない/柔軟にしたい) | コネクタが環境に出ない/API版の挙動を細かく制御したい | Blobトリガー → HTTPでDocument Intelligence REST → JSON整形 → Excel追記 | 非同期APIのポーリング設計(Do until)が必要 |
| Azure Functions中心(大量処理・堅牢性重視) | 請求書が多い/監視・リトライ・冪等性をきっちりやりたい | Blobイベント → Functions → Document Intelligence REST → GraphでExcel追記 | Graph認証、運用監視、例外系の設計が増える |
最初に決めておくと「後で詰まらない」設計ポイント
Excelは「テーブル」を前提に設計する
Power AutomateでExcelに追記する場合、基本は「シート」ではなくExcelのテーブルに行を追加します。Excel Online(Business)コネクタには「Add a row into a table(テーブルに行を追加)」があり、書き込み先はテーブル単位で指定します。
おすすめの列設計(後から運用が楽になります)。
| 列名(例) | 型(Excel表示) | 用途 | ポイント |
|---|---|---|---|
| InvoiceId | 文字列 | 請求書番号 | 重複判定のキー候補 |
| InvoiceDate | 日付 | 請求日 | 整形はフロー側で行う |
| DueDate | 日付 | 支払期限 | 未記載の請求書もあるので空欄許容 |
| VendorName | 文字列 | 取引先名 | 表記ゆれ対策で別列に正規化名を置くのも有効 |
| Currency | 文字列 | 通貨 | JPY/USD等 |
| TotalAmount | 数値 | 合計金額 | 数値変換(float等)して格納 |
| BlobPath | 文字列 | 元PDFの場所 | 監査・再処理の起点になる |
| BlobETag | 文字列 | Blobのバージョン識別 | 同名上書き・再処理判定に効く |
| ExtractedAt | 日時 | 抽出実行日時 | 運用監視に便利 |
| ConfidenceTotal | 数値 | 抽出の信頼度 | 低信頼は人手確認フローへ回す |
Blob側の「置き方」が運用を左右する
Power AutomateのAzure Blob Storageコネクタのトリガー「When a blob is added or modified (properties only) (V2)」は、ルート配下の追加/更新を検知し、まずはメタデータのみを返します。ファイル本体を扱うには別アクションで「Get file content」相当の取得が必要です。また、サブフォルダ配下の追加/更新ではトリガーが発火しない点は現場でハマりやすいので、請求書は原則コンテナー直下に置く運用が無難です。
さらに、同コネクタには既知の制約として、古い(非V2の)トリガーが遅延する可能性があること、Power Platformからはストレージのファイアウォール配下ストレージに頼らない方がよいこと等が明記されています。閉域が必須なら、Power Automateを前面に置かず、Azure側(Functions/Logic Apps/Event Grid)で受けてから処理する設計に寄せるのが安全です。
Power Automate中心で作る手順(ノーコード寄りの最短ルート)
Blob追加をトリガーにする
- Power Automateで「自動化したクラウドフロー」を作成
- トリガーにAzure Blob Storageの「When a blob is added or modified (properties only) (V2)」を選択
- Storage account / Container(請求書コンテナー)を指定
このトリガーはメタデータのみを返すため、次のアクションでBlob本文(PDFのバイナリ)を取得する流れになります。
ファイル内容を取得する
トリガーの出力(Path/Idなど)を使って、「Get blob content (V2)」などのファイル取得アクションでPDFを取得します。ここで得られた「File content」を次の解析に渡します。
Document Intelligenceで解析する(Azureのカスタムモデルを再利用)
すでにAzure Document Intelligence Studioで「請求書向けカスタム抽出モデル」を作成済みなら、Power AutomateからそのモデルID(モデル名)を指定して呼び出すのが最短です。
方法は大きく2つあります。
- Azure AI Document Intelligence(form recognizer)コネクタを使う(扱いやすい)
- HTTPアクションでREST APIを直接呼ぶ(柔軟・確実)
コネクタを使う場合
Microsoftの「Azure AI Document Intelligence (form recognizer)」コネクタは、事前学習済みモデルだけでなくカスタムモデルも対象にでき、「Analyze Document for Prebuilt or Custom models (v4.x API)」アクションではmodelIdを指定して解析できます。
認証方式は環境・ガバナンスに合わせて選びます。コネクタ側でAPIキー認証に加えて、Microsoft Entra ID統合など複数方式が案内されています(鍵運用を避けたい場合はEntra ID統合が有力)。
AI Builderを使う場合(Power Platform側のドキュメント処理)
Power Automate上でAI Builderのドキュメント処理モデルを使う場合、以前の「Extract information from documents」アクションは、現在は「Process documents」に名称変更されています。AI Builder側のモデルを選んで、トリガーで得た「File Content」を渡すだけで、抽出値と信頼度(confidence)を動的コンテンツとして利用できます。
ただし、今回の前提は「Azure Document Intelligence Studioでカスタムモデルを作成済み」なので、最初はAzure側モデルをそのまま呼ぶほうが手戻りが少ないケースが一般的です(作り直す判断基準は後述)。
抽出結果を整形する(Excelに入る形に変換する)
Document Intelligenceの結果は、フィールドごとに型(date / number / currency 等)を持ち、正規化された値として返ることがあります。例えば通貨は「amount」や「currencySymbol」のような形で表現されることがあり、Excelに書き込むときは「金額(数値)」と「通貨(文字列)」に分けておくと集計が楽です。
Power Automate側では次のようなアクションが使いやすいです。
- Parse JSON:解析結果JSONを扱いやすくする
- Compose:列ごとの値を組み立てる
- 変数:InvoiceIdなどキーを保持して後段の重複判定に使う
マッピング例(フィールド名はあなたのカスタムモデルの定義に合わせて読み替えてください)。
| Document Intelligence側(例) | Excel列(例) | 整形の考え方 |
|---|---|---|
| InvoiceId(valueString) | InvoiceId | 前後空白を除去、ハイフン表記ゆれを正規化 |
| InvoiceDate(valueDate) | InvoiceDate | Excel側の表示形式に合わせて日付へ |
| InvoiceTotal(valueCurrency.amount) | TotalAmount | 数値だけを格納(通貨記号は別列へ) |
| InvoiceTotal(valueCurrency.currencySymbol) | Currency | 「¥」「$」等をISO通貨コードへ寄せる(任意) |
| VendorName(valueString) | VendorName | 全角/半角、株式会社/(株)の統一など |
| confidence(例:重要項目の最小値) | ConfidenceTotal | 閾値未満は「要確認」扱いにする |
SharePoint上のExcelテーブルへ書き込む
SharePointドキュメントライブラリに「請求書一覧.xlsx」を置き、あらかじめテーブル(例:Invoices)を作っておきます。Power AutomateではExcel Online(Business)コネクタの「Add a row into a table」を使い、LocationをSharePointサイト、Document Library、File、Tableを指定して行を追加します。
ここで重要なのがExcelの同時更新です。Excel Online(Business)コネクタは、他のクライアント(Excel Desktop/Excel Web/別フロー等)との同時書き込みを推奨しておらず、ロックや整合性問題の原因になります。運用では「集計用Excelは基本触らない」「閲覧用は別ブックにする」などルールを決めると安定します。
重複登録を防ぐ(必須の運用設計)
Blobの「追加/変更」トリガーは、同一ファイルの更新やメタデータ更新でも再実行される可能性があります。重複登録を防ぐには、少なくとも次のどれかを入れてください。
- Excel側にユニークキー列(例:InvoiceId + VendorName + InvoiceDate)を作り、追加前に「List rows present in a table」で存在チェック
- BlobのETagを記録して、同じETagなら処理済みと判定
- Blobメタデータにprocessedフラグを付ける(Power Automateで更新できる場合)
Excelコネクタは「List rows present in a table」がデフォルトで256行までなど制約があるため、規模が増えると存在チェックにPaginationや別ストア(SharePoint List/Dataverse等)が必要になります。
エラー時の運用(再処理・人手確認へ回す)
請求書はフォーマットゆれがあるため、抽出が完全一致する前提で作ると運用が破綻しがちです。おすすめは「失敗・低信頼を貯める場所」を作り、例外を人が処理できるようにすることです。
- 解析に失敗したPDFはBlobの
/errorコンテナーへ移動(またはフォルダ移動) - 抽出JSONをBlobやSharePointに保存して監査できるようにする
- Confidenceが閾値未満なら「要確認」列にフラグを立て、Teams通知
Excel Online(Business)はスロットリング(429)や、更新反映が遅れるケースがあり得るため、リトライと待機(Delay)を前提にフローを組むと安定します。
Power AutomateからAzure Document Intelligenceのカスタムモデルを呼び出す方法
方法A:公式コネクタで「modelId」を指定して呼ぶ
コネクタでの最短手順は次の通りです。
- Power Automateで「Azure AI Document Intelligence (form recognizer)」コネクタの接続を作成(Endpoint + キー、またはEntra ID統合など)
- アクションに「Analyze Document for Prebuilt or Custom models (v4.x API)」を追加
- modelIdにカスタムモデル名(Studioで公開したモデル名)を入力(カスタムmodelId形式の説明あり)
- 入力に「Document/Image File Content」を渡す(Blobから取得したPDFバイナリ)
- 戻り値のdocuments/fieldsから必要項目を取り出す
コネクタ経由だと、Document Intelligenceの「非同期処理のポーリング」を意識せずに済むことが多く、業務フローには適しています。
方法B:HTTPでREST APIを直接叩く(コネクタが出ない/制御したい場合)
Document Intelligenceの解析は基本的に非同期で、解析開始リクエストを送ると、結果取得用URLがOperation-Locationヘッダーで返ってきます。完了までそのURLをポーリングして結果を取得します。
Power Automateでの実装イメージ(ノウハウ)
- HTTP(POST)で解析開始 → ヘッダーからOperation-Locationを取り出す
- Do untilでHTTP(GET)を繰り返し、statusがsucceededになるまで待つ(1〜数秒間隔)
- 完了したJSONからfieldsを取り出してExcelへ
この方式は「APIバージョンを固定したい」「特定のヘッダーやパラメータを付けたい」「コネクタの不具合を回避したい」場合に強力です。反面、運用時はポーリング回数・タイムアウト・リトライの設計が必須になります。
Power Platform側にモデルを作り直すべきか?判断基準
結論として、すでにAzure Document Intelligence Studioでカスタムモデルを作っているなら、まずはそれを再利用して自動化するのが合理的です。一方で、次の条件に強く当てはまるなら、AI Builderのドキュメント処理モデルに寄せて再構築する価値があります。
| 判断軸 | Azure Document Intelligenceを継続 | AI Builderへ寄せる |
|---|---|---|
| 運用担当 | IT/開発チームが運用できる | 業務部門がノーコードで回したい |
| 統制(ガバナンス) | Azureリソース/キー/Entra ID運用が可能 | Power Platform環境内で完結させたい |
| 改善サイクル | Studioで学習・公開、API連携で更新 | Power Platform側で学習〜利用まで一気通貫 |
| フローの作りやすさ | コネクタ or HTTPで柔軟 | 「Process documents」アクションで簡単 |
「請求書抽出モデルがすでに精度良く動いている」「Azureでのモデル管理が確立している」なら、Power Platformに作り直すより、集約先(Excel/Dataverse等)と運用設計に力を使うほうが成果が出やすいです。
Azure Functionsを使う構成(大量処理・厳密運用向け)
構成イメージ
Azure Functionsを使う場合は、Power Automateよりも「処理の確実性・監視・再処理」に軸足を置けます。典型構成は次の通りです。
- Blobの作成/更新をトリガーにFunctionsを起動(Blob triggerやEvent Grid)
- FunctionsからDocument Intelligence REST APIで解析開始
- Operation-Locationをポーリングして結果取得(非同期)
- 整形してMicrosoft GraphでSharePoint上のExcelテーブルへ行追加
Blob triggerは「新規または更新されたBlobを検知して関数を開始し、Blob内容を入力として渡す」仕組みです。低遅延が必要ならイベントベース実装が推奨されます。
冪等性(同じファイルを二重に処理しない)を作り込みやすい
Azure FunctionsのBlob triggerでは、ランタイムが「同じ新規/更新Blobに対して関数が複数回呼ばれないようにする」仕組み(blob receipts)を持ちます。これに加えて、ETag/メタデータ/別テーブルで処理済み管理を組み合わせると、請求書処理の冪等性を堅牢にできます。
Document Intelligence REST API呼び出しの要点
Document IntelligenceのAnalyzeは非同期で、開始時にOperation-Locationが返るため、Functions側では以下を必ず実装します。
- 解析開始(POST)
- Operation-Locationを保持
- 完了までポーリング(GET)
- statusがsucceeded以外(failed等)のときはエラーとして扱い、再試行や隔離へ
この非同期性はDocument Intelligenceの仕様として明記されています。
Excel書き込みはMicrosoft Graphが最も制御しやすい
SharePoint上のExcelへ大量に書き込む場合、Power AutomateのExcelコネクタより、Graphで「テーブルに複数行をまとめて追加」する設計が有利になる場面があります。GraphのCreate TableRowは、複数行を一度に追加でき、1行ずつ追加するよりパフォーマンス面で推奨される旨が記載されています。また、504が返ることがあり、その場合はリトライが適切とされています。
Excel REST APIは、OneDrive for BusinessだけでなくSharePointサイト上のブックも対象にでき、Drive APIの識別子(drive/item)を使ってアクセスします。
Graphでの書き込みは、次のような観点で設計すると実運用に耐えます。
- セッション:まとめて書く処理はセッション(workbook-session-id)利用で効率化しやすい
- バッチ投入:数十〜数百行をまとめて追加(実際の最適値は検証)
- リトライ戦略:504/429などを想定して指数バックオフ
- 監査列:BlobPath/ETag/ExtractedAtを必ず残す
認証と秘密情報(Key/Token)をどう扱うか
Functions構成では「鍵をどこに置くか」が重要です。おすすめは次の考え方です。
- Document Intelligence:キー認証を使うならKey Vaultに保管、Functionsは参照のみ
- Graph:FunctionsのマネージドIDを使い、最小権限でアクセス(可能ならアプリ権限の範囲を絞る)
Power Automate側でDocument Intelligenceコネクタを使う場合も、Entra ID統合のようにキー管理を避ける選択肢が用意されています。
よくあるつまずきと、最初から入れておく対策
Blobトリガーが動かない/遅い
- サブフォルダに入れていないか(トリガーはサブフォルダでは発火しない)
- トリガーがDEPRECATEDの方になっていないか(V2へ)
- ストレージアカウントにファイアウォール制約があり、Power Platformから安定アクセスできない構成になっていないか
Excelに追記できない/重い/二重登録される
- Excelがロックされている(Excel Online(Business)はロック・同時更新に弱い)
- スロットリング(429)が出るので、Delayやリトライを組む
- 更新反映が最大30秒程度遅れることがある前提で、直後の参照ロジックを組む
- ファイルサイズが大きすぎる(Excel Online(Business)のサポート上限がある)
「抽出はできるが、業務で使える集計にならない」
請求書の自動抽出は、解析精度だけでなく「集計の使いやすさ」で評価が決まります。次の工夫は効果が出やすいです。
- 金額は数値列に統一(通貨記号・カンマを残さない)
- 日付は日付列に統一(文字列のままだと月次集計が面倒)
- 重要項目だけConfidenceで検品(請求書番号・合計金額など)
- 行明細(品目)を扱うなら別テーブル(ヘッダ情報と1:Nになるため)
まとめ:まずはPower Automateで動かし、必要ならFunctionsへ拡張する
「Blobに請求書PDFが追加されたら自動抽出し、SharePoint上のExcelテーブルに集約する」仕組みは、Power Automate中心でも実現できます。ポイントは、コネクタでカスタムモデル(modelId)を呼べること、Excelの制約(ロック・同時更新・スロットリング)を前提に運用設計を入れることです。
処理量が増えたり、閉域ネットワークや厳密な監査・再処理が必要になった段階で、Azure Functions + REST + Graphへ寄せると、冪等性・監視・性能の面で伸ばしやすくなります。まずは「最短で回る」形を作り、例外処理と重複防止を足しながら、業務に馴染む集計Excelへ育てていくのが成功パターンです。

コメント