Data Analytics & BIシリーズの一部
完全ガイドを読むPower BI + Odoo 統合の完全ガイド
Odoo は世界で最も強力なオープンソース ERP プラットフォームの 1 つで、1,200 万人を超えるユーザーがおり、販売、在庫から製造、人事まであらゆるものをカバーする 43 の公式モジュールがあります。 Power BI は、月間アクティブ ユーザー数が 3 億人を超える業界をリードするビジネス インテリジェンス プラットフォームです。しかし、これら 2 つのシステムを接続している組織は驚くほど少なく、膨大な分析価値を残しています。
理由は簡単です。Odoo には独自のレポート機能が組み込まれており、ほとんどの Power BI コンサルタント会社は Microsoft Dynamics、SAP、または Salesforce の統合に重点を置いています。両方のプラットフォームに関する深い専門知識を持つ企業はほとんどありません。 ECOSIRE では、43 を超える Odoo モジュールを構築してデプロイし、Power BI に関する深い専門知識を維持しており、Odoo + Power BI の組み合わせが当社の中核的な専門分野の 1 つとなっています。このガイドには、実際の数十の統合から学んだすべてがまとめられています。
重要なポイント
- Odoo の PostgreSQL データベースは、ネイティブ PostgreSQL コネクタを使用して Power BI Desktop に直接接続でき、すべてのテーブルとフィールドに完全にアクセスできます。
- 分析に最も価値のある 5 つの Odoo テーブルは、sale_order、account_move、stock_picking、hr_employee、mrp_production です。これらを合わせると、経営幹部のレポート ニーズの 80% がカバーされます。
- Power BI の増分更新では、最後の更新以降に変更されたレコードのみをフェッチすることで、Odoo データの読み込み時間を数時間から数分に短縮できます。
- OData エンドポイントと Odoo の外部 API は、データベースに直接アクセスできない場合にクラウドフレンドリーな代替手段を提供します
- Power BI の行レベルのセキュリティは、Odoo の複数企業のアクセス制御をミラーリングできるため、ユーザーは割り当てられた企業のデータのみを参照できるようになります。
- Odoo の PostgreSQL データベースに対するカスタム SQL クエリは、データベース レベルでフィルター、結合、集計できるため、汎用テーブルのインポートよりも 5 ~ 10 倍優れています。
- 適切に設計された Odoo + Power BI の展開により、数十のスプレッドシート レポートが単一の管理された分析プラットフォームに置き換えられます。
Odoo + Power BI が強力な組み合わせである理由
Odoo の組み込みレポートの制限
Odoo には、ピボット ビュー、グラフ ビュー、組み込みダッシュボードなどのいくつかのレポート ツールが付属しています。日常的な操作には、これらで十分です。しかし、いくつかの重要な点でエンタープライズ分析には不十分です。
まず、Odoo のピボット ビューでは、複数のモジュールからのデータを 1 つのビジュアライゼーションに結合できません。売上収益と在庫回転率および製造スループットを 1 つのグラフに重ねることはできません。各モジュールのレポートはサイロ化されています。
第二に、Odoo にはタイムインテリジェンス機能が欠けています。前年比比較、移動平均、累積合計、および期間累計の計算には、カスタム開発または手動のスプレッドシート エクスポートが必要です。
第三に、Odoo には管理されたデータ モデルの概念がありません。 「収益」や「顧客生涯価値」などの指標には共通の定義がありません。すべてのユーザーが独自の解釈を行うため、経営会議で矛盾した数字が生じることになります。
4 番目に、Odoo の視覚化機能は基本的な棒グラフ、折れ線グラフ、円グラフに限定されています。ヒート マップ、散布図、ウォーターフォール チャート、分解ツリー、KPI カードは使用できません。
Power BI で追加されるもの
Power BI は、これらの制限のすべてに対処します。 Odoo の PostgreSQL データベース (または API) に接続し、すべてのモジュールにわたって統一されたセマンティック モデルを作成します。 DAX 数式は、タイム インテリジェンス、統計関数、および複雑なビジネス ロジックを提供します。視覚化ライブラリには 300 を超えるグラフ タイプが含まれています。また、Power BI のガバナンス機能 (ワークスペース、行レベルのセキュリティ、承認、機密ラベル) は、エンタープライズ レベルのデータ管理を提供します。
この組み合わせにより、日常業務における Odoo の卓越した運用と、戦略的意思決定のための Power BI の分析の深さが得られます。運用チームは引き続き Odoo で作業を行います。経営幹部やアナリストは、自動的に更新される Power BI ダッシュボードを入手できます。
接続方法: 直接データベースと API
Power BI を Odoo に接続するには、主に 3 つの方法があります。それぞれには、ホスティング モデルとセキュリティ要件に応じてトレードオフがあります。
方法 1: PostgreSQL への直接接続
これは、オンプレミスまたはセルフホスト型の Odoo 導入に推奨される方法です。 Odoo はすべてのデータを PostgreSQL に保存し、Power BI にはネイティブ PostgreSQL コネクタがあります。
利点:
- 最速のクエリ パフォーマンス (API オーバーヘッドなし)
- カスタム モジュールを含むすべてのテーブルとフィールドへのフル アクセス
- データベースレベルでの結合と集計による複雑な SQL クエリをサポート
- 増分更新を有効にします (日時列が必要です)
- Odoo ライセンスや API レート制限なし
セットアップ手順:
- Power BI Desktop を開き、[データの取得]、[PostgreSQL データベース] の順に選択します。
- Odoo サーバーのホスト名とデータベース名 (通常は Odoo インスタンス名) を入力します。
- 読み取り専用データベース ユーザーを使用します (Odoo 管理者アカウントは使用しないでください)。
- ほとんどのシナリオではインポート モードを選択し、リアルタイム ニーズの場合は DirectQuery を選択します
- テーブル リストを移動するか、カスタム SQL クエリを使用します。
接続文字列パラメータ:
| パラメータ | 代表値 |
|---|---|
| サーバー | your-odoo-server.com:5432 |
| データベース | オドゥープロダクション |
| ユーザー名 | パワービ_読み取り専用 |
| パスワード | (認証情報に保存) |
| SSLモード | 必須 (実稼働用) |
| コマンドタイムアウト | 600 (秒、大規模なクエリの場合) |
PostgreSQL で読み取り専用ユーザーを作成する:
CREATE ROLE powerbi_readonly WITH LOGIN PASSWORD 'secure_password';
GRANT CONNECT ON DATABASE odoo_production TO powerbi_readonly;
GRANT USAGE ON SCHEMA public TO powerbi_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO powerbi_readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO powerbi_readonly;
このアプローチにより、Power BI は運用データベースへの書き込みアクセスなしで、現在および将来のすべてのテーブルを読み取ることができます。
方法 2: Odoo 外部 API (XML-RPC / JSON-RPC)
Odoo は、データの読み取りと書き込みのための完全な API を公開します。 Power BI は、カスタム コネクタまたは Python スクリプトを通じてこれを利用できます。
利点:
- Odoo.sh および Odoo Online で動作します (データベースへの直接アクセスは必要ありません)
- Odoo のアクセス制御ルールと記録ルールを尊重します
- データベースポートを外部に公開する必要はありません
短所:
- データベースへの直接クエリよりも大幅に遅い (大規模なデータセットの場合は 10 ~ 100 倍)
- API レート制限により、大量の抽出が抑制される可能性があります
- カスタム Power Query 関数または中間 ETL ステップが必要です
- ページネーションが複雑さを増す
Odoo の JSON-RPC エンドポイントの場合、一般的な Power Query M 関数は認証を使用して https://your-odoo.com/jsonrpc を呼び出し、結果をページ分割します。これは機能しますが、50,000 を超えるレコードがあるテーブルでは非現実的になります。
方法 3: Odoo コネクタ モジュール経由の OData エンドポイント
いくつかの Odoo コミュニティ モジュールは、Power BI がネイティブに消費できる OData フィードを公開しています。 Power BI の OData コネクタは、すぐに使用できる認証とページネーションをサポートします。
この方法を使用する場合:
- データベースへのアクセスが制限されている Odoo Online / Odoo.sh 展開
- データ内に Odoo のビジネス ロジック (計算フィールド、アクセス ルール) が必要なシナリオ
- 小規模なデータセット (エンティティあたり 100,000 レコード未満)
ほとんどのエンタープライズ展開では、方法 1 (直接 PostgreSQL) を強くお勧めします。パフォーマンスの違いは大きく、SQL クエリの柔軟性によりソースでデータを整形できます。
Power BI に必須の Odoo テーブル
Odoo の PostgreSQL データベースには数百のテーブルが含まれています。効果的な Power BI モデルを構築するには、コア テーブルとその関係を理解することが重要です。以下のテーブルは、エグゼクティブ ダッシュボードの 80% を支えています。
販売モジュールのテーブル
| 表 | 目的 | 主要なフィールド |
|---|---|---|
| 販売_注文 | 販売注文 (ヘッダー) | id、name、partner_id、date_order、amount_total、state、company_id、user_id |
| セール_オーダー_ライン | 販売注文品目 | order_id、product_id、product_uom_qty、price_unit、price_小計、割引 |
| レスパートナー | 顧客とベンダー | id、名前、電子メール、country_id、category_id、customer_rank、supplier_rank |
| 製品_製品 | 製品バリエーション | id、default_code、list_price、standard_price、categ_id、active |
| 製品テンプレート | 製品テンプレート | ID、名前、タイプ、販売OK、購入OK |
主要な関係: sale_order.partner_id は res_partner.id にリンクします。 sale_order_line.product_id は product_product.id にリンクします。 product_product.product_tmpl_id は product_template.id にリンクします。
一般的な販売分析クエリは、これらのテーブルを結合して、非正規化されたファクト テーブルを生成します。
SELECT
so.id AS order_id,
so.name AS order_number,
so.date_order,
so.state,
rp.name AS customer_name,
rp.country_id,
rc.name AS country_name,
sol.product_id,
pt.name AS product_name,
pc.name AS product_category,
sol.product_uom_qty AS quantity,
sol.price_unit,
sol.discount,
sol.price_subtotal AS line_total,
so.amount_total AS order_total,
ru.login AS salesperson
FROM sale_order so
JOIN sale_order_line sol ON sol.order_id = so.id
JOIN res_partner rp ON so.partner_id = rp.id
LEFT JOIN res_country rc ON rp.country_id = rc.id
JOIN product_product pp ON sol.product_id = pp.id
JOIN product_template pt ON pp.product_tmpl_id = pt.id
LEFT JOIN product_category pc ON pt.categ_id = pc.id
LEFT JOIN res_users ru ON so.user_id = ru.id
WHERE so.state IN ('sale', 'done')
ORDER BY so.date_order DESC;
会計モジュールのテーブル
| 表 | 目的 | 主要なフィールド |
|---|---|---|
| アカウントの移動 | 請求書、請求書、仕訳帳 | id、名前、move_type、partner_id、invoice_date、amount_total、state、payment_state |
| アカウント移動ライン | 仕訳帳行 | move_id、account_id、借方、貸方、残高、日付、partner_id |
| アカウント_アカウント | 勘定科目表 | ID、コード、名前、アカウントの種類 |
| アカウントの支払い | 支払い | ID、パートナー ID、金額、日付、州、支払いタイプ |
| アカウントジャーナル | ジャーナル (銀行、販売など) | ID、名前、タイプ、コード |
重要な違い: Odoo では、account_move は請求書 (move_type = 'out_invoice')、仕入先請求書 ('in_invoice')、クレジットノート ('out_refund'、'in_refund')、および仕訳入力 ('entry') を保存します。 Power BI クエリでは常に move_type でフィルターします。
account_move の payment_state フィールドは、請求書が「未払い」、「支払い中」、「支払い済み」、「一部」、または「取り消し」であるかどうかを示します。これは、売掛金の期限切れダッシュボードには不可欠です。
インベントリモジュールテーブル
| 表 | 目的 | 主要なフィールド |
|---|---|---|
| 在庫ピッキング | 配達注文、受領書、社内送金 | id、名前、パートナー ID、予定日、日付完了、状態、選択タイプ ID |
| 在庫移動 | 個々の製品の移動 | ピッキング ID、製品 ID、製品数量、数量、状態、日付 |
| 在庫量 | 現在の手持在庫 | 製品 ID、場所 ID、数量、予約数量 |
| 在庫の場所 | 倉庫、ゾーン、ビン | ID、名前、使用法、location_id (親) |
| 在庫倉庫 | 倉庫の定義 | ID、名前、コード、パートナー ID |
リアルタイム在庫: Stock_quant は常に現在の在庫状態を反映します。過去の在庫分析の場合は、日付フィルターを使用してstock_moveをクエリし、実行残高を計算する必要があります。
マニュファクチャリング モジュール テーブル
| 表 | 目的 | 主要なフィールド |
|---|---|---|
| mrp_production | 製造注文 | ID、名前、製品 ID、製品数量、開始日、終了日、状態 |
| むーむ部品表 | id、product_tmpl_id、product_qty、タイプ | |
| mrp_bom_line | BOM コンポーネント | bom_id、製品 ID、製品数量 |
| mrp_workorder | 作業指示の操作 | Production_id、workcenter_id、期間、状態 |
| mrp_ワークセンター | ワークセンター/機械 | ID、名前、容量、時間効率 |
OEE 計算: 全体的な設備効率は、計画期間と実際の期間を比較し、ダウンタイムの理由を分析し、品質指標を追跡することにより、mrp_workorder レコードから導き出すことができます。
人事テーブル
| 表 | 目的 | 主要なフィールド |
|---|---|---|
| hr_従業員 | 従業員記録 | ID、名前、部門 ID、ジョブ ID、勤務先メールアドレス、アクティブ |
| hr_部門 | 部門 | ID、名前、親 ID、マネージャー ID |
| hr_contract | 雇用契約 | 従業員 ID、賃金、開始日、終了日、州 |
| hr_leave | 休暇申請 | 従業員 ID、休日ステータス ID、開始日、終了日、州 |
| 時間出席 | 出勤/退勤記録 | 従業員 ID、チェックイン、チェックアウト、勤務時間 |
Power BI データ モデルの構築
スタースキーマ設計
Odoo 分析に最も効果的なデータ モデルは、スター スキーマ パターンに従います。ファクト テーブル (販売注文、請求書、在庫移動、製造オーダー) が中心にあります。ディメンション テーブル (製品、顧客、日付、従業員、場所) がそれらを囲みます。
推奨されるファクト テーブル:
- Fact_Sales — sale_order + sale_order_line から (粒度: 注文明細ごとに 1 行)
- Fact_Invoices — account_move + account_move_line から (粒度: 仕訳明細ごとに 1 行)
- Fact_Inventory — Stock_move から (粒度: 在庫移動ごとに 1 行)
- Fact_Production — mrp_production + mrp_workorder から (粒度: 作業指示ごとに 1 行)
- Fact_Attendance — hr_attendance から (粒度: クロックイン/クロックアウトのペアごとに 1 行)
共有寸法テーブル:
- Dim_Date — Power BI で生成されたカレンダー テーブル (タイム インテリジェンスに不可欠)
- Dim_Customer — res_partner から (customer_rank > 0 にフィルタリング)
- Dim_Product — product_product + product_template + product_category から
- Dim_Employee — hr_employee + hr_Department + hr_job から
- Dim_Location — Stock_location + Stock_warehouse から
- Dim_Company — res_company より (複数会社の Odoo デプロイメント用)
日付ディメンションの作成
Odoo には専用の日付ディメンション テーブルがありません。 DAX を使用して Power BI で作成する必要があります。
Dim_Date =
ADDCOLUMNS(
CALENDAR(DATE(2020, 1, 1), DATE(2030, 12, 31)),
"Year", YEAR([Date]),
"Quarter", "Q" & QUARTER([Date]),
"Month", FORMAT([Date], "MMMM"),
"MonthNumber", MONTH([Date]),
"WeekNumber", WEEKNUM([Date]),
"DayOfWeek", FORMAT([Date], "dddd"),
"FiscalYear", IF(MONTH([Date]) >= 4, YEAR([Date]), YEAR([Date]) - 1),
"FiscalQuarter", "FQ" & SWITCH(TRUE(),
MONTH([Date]) >= 10, 3,
MONTH([Date]) >= 7, 2,
MONTH([Date]) >= 4, 1,
4
),
"IsWeekend", IF(WEEKDAY([Date], 2) > 5, TRUE(), FALSE()),
"YearMonth", FORMAT([Date], "YYYY-MM")
)
Power BI でこのテーブルを日付テーブルとしてマークし、各ファクト テーブルの日付列から Dim_Date[Date] へのリレーションシップを作成します。組織に合わせて会計年度の開始月を調整します。
Odoo の複数会社構造への対応
Odoo は、単一のデータベースが複数の法人にサービスを提供する複数企業構成をサポートします。すべてのトランザクション テーブルには company_id 外部キーが含まれます。 Power BI で、res_company から Dim_Company テーブルを作成し、各ファクト テーブルとのリレーションシップを確立します。
行レベルのセキュリティの場合は、Power BI の RLS 機能を使用して、ログインしているユーザーの会社の割り当てに基づいて Dim_Company をフィルター処理します。これは、BI レイヤーにおける Odoo の複数企業のアクセス制御を反映しています。
ダッシュボード レシピ: 販売分析
エグゼクティブセールスダッシュボード
このダッシュボードは、CEO が抱く 5 つの質問に答えます。「今月の収益はいくらですか?」今四半期は順調に進んでいますか?どの製品が勝者となっているのでしょうか?どの販売員がパフォーマンスを行っていますか?私たちの顧客はどこにいるのでしょうか?
作成する対策:
Total Revenue = SUM(Fact_Sales[line_total])
Revenue MTD =
TOTALMTD([Total Revenue], Dim_Date[Date])
Revenue QTD =
TOTALQTD([Total Revenue], Dim_Date[Date])
Revenue YTD =
TOTALYTD([Total Revenue], Dim_Date[Date])
Revenue PY =
CALCULATE([Total Revenue], SAMEPERIODLASTYEAR(Dim_Date[Date]))
Revenue Growth % =
DIVIDE([Total Revenue] - [Revenue PY], [Revenue PY], 0)
Average Order Value =
DIVIDE([Total Revenue], DISTINCTCOUNT(Fact_Sales[order_id]))
Orders Count =
DISTINCTCOUNT(Fact_Sales[order_id])
ビジュアルレイアウト:
- 行 1: 4 つの KPI カード (収益 MTD、収益 QTD、収益 YTD、成長率 %)
- 行 2: 折れ線グラフ (月次収益、今年対前年) および棒グラフ (製品カテゴリ別の収益)
- 行 3: マップ ビジュアル (顧客の国別の収益) とテーブル (収益、注文数、平均取引規模を持つ上位 10 人の営業担当者)
- 行 4: ウォーターフォール チャート (収益ブリッジ: 新規顧客 vs 既存顧客 vs 失われた顧客) およびドーナツ チャート (販売チャネル別の収益)
販売パイプライン分析
Odoo CRM を Sales モジュールと一緒に使用する場合は、crm_lead テーブルを接続してパイプライン ダッシュボードを構築します。
| 表 | 目的 | 主要なフィールド |
|---|---|---|
| crm_lead | 機会と見込み客 | id、名前、partner_id、expected_revenue、確率、stage_id、user_id、date_deadline |
| crm_stage | パイプラインステージ | ID、名前、シーケンス |
パイプライン対策:
Pipeline Value =
SUMX(
FILTER(Fact_Pipeline, Fact_Pipeline[active] = TRUE()),
Fact_Pipeline[expected_revenue] * Fact_Pipeline[probability] / 100
)
Win Rate =
DIVIDE(
CALCULATE(COUNTROWS(Fact_Pipeline), Fact_Pipeline[stage_name] = "Won"),
CALCULATE(COUNTROWS(Fact_Pipeline),
OR(Fact_Pipeline[stage_name] = "Won", Fact_Pipeline[stage_name] = "Lost")
)
)
Average Sales Cycle Days =
AVERAGEX(
FILTER(Fact_Pipeline, Fact_Pipeline[stage_name] = "Won"),
DATEDIFF(Fact_Pipeline[create_date], Fact_Pipeline[date_closed], DAY)
)
ダッシュボードのレシピ: 在庫とサプライ チェーン
在庫健全性ダッシュボード
このダッシュボードは、在庫レベル、回転率、サプライ チェーンのパフォーマンスを監視します。
主な対策:
Inventory Value =
SUMX(Fact_Inventory_Current, Fact_Inventory_Current[quantity] * RELATED(Dim_Product[standard_price]))
Inventory Turnover =
DIVIDE(
[COGS Trailing 12 Months],
[Average Inventory Value]
)
Days of Inventory =
DIVIDE(365, [Inventory Turnover])
Stockout Rate =
DIVIDE(
CALCULATE(COUNTROWS(Dim_Product), Dim_Product[on_hand_qty] <= 0, Dim_Product[active] = TRUE()),
CALCULATE(COUNTROWS(Dim_Product), Dim_Product[active] = TRUE())
)
Reorder Point Items =
CALCULATE(
COUNTROWS(Dim_Product),
FILTER(Dim_Product, Dim_Product[on_hand_qty] <= Dim_Product[reorder_min])
)
ビジュアル:
- KPI カード: 総在庫額、回転率、欠品率、再注文点を下回る品目
- 散布図: 各製品を売上高比率 (X 軸) 対利益率 (Y 軸) でプロットし、収益貢献度によってサイズを調整します --- これは ABC-XYZ 分析のビジュアルです
- 棒グラフ: 在庫金額による上位 20 製品 (動きの遅い在庫に拘束されている資本を特定)
- 表: 現在の在庫、毎日の需要、および推定在庫切れ日を含む再注文ポイント以下の品目
配信パフォーマンス
stock_picking から、予定通りの配達を測定します。
On-Time Delivery Rate =
DIVIDE(
CALCULATE(
COUNTROWS(Fact_Deliveries),
Fact_Deliveries[date_done] <= Fact_Deliveries[scheduled_date]
),
COUNTROWS(Fact_Deliveries)
)
Average Lead Time Days =
AVERAGEX(
Fact_Deliveries,
DATEDIFF(Fact_Deliveries[create_date], Fact_Deliveries[date_done], DAY)
)
ダッシュボードのレシピ: 製造
プロダクション パフォーマンス ダッシュボード
Odoo Manufacturing を実行しているメーカーの場合、mrp_production テーブルと mrp_workorder テーブルは豊富な運用データを提供します。
OEE (総合設備効率) の計算:
Availability =
DIVIDE(
[Actual Production Time],
[Planned Production Time]
)
Performance Rate =
DIVIDE(
[Ideal Cycle Time] * [Total Units Produced],
[Actual Production Time]
)
Quality Rate =
DIVIDE(
[Good Units],
[Total Units Produced]
)
OEE = [Availability] * [Performance Rate] * [Quality Rate]
ビジュアル:
- ゲージ チャート: OEE、可用性、パフォーマンス、品質 (それぞれの目標しきい値: 緑が 85% 以上、黄色が 60 ~ 85%、赤が 60% 以下)
- 折れ線グラフ: 週ごとの OEE 傾向、管理限界あり
- 集合棒グラフ: ワークセンター別の OEE、どの機械がパフォーマンスを下回っているかを明らかにします
- 表: 計画と実際の期間、差異、および不良数量を含む製造オーダー
ワークセンターの利用状況
Utilization Rate =
DIVIDE(
SUM(Fact_WorkOrders[duration_minutes]),
[Available Minutes Per Period]
)
Downtime Hours =
DIVIDE(
[Available Minutes Per Period] - SUM(Fact_WorkOrders[duration_minutes]),
60
)
このダッシュボードは、生産管理者がボトルネックのワークセンターを特定し、スケジュールを最適化するのに役立ちます。 Odoo の計画モジュール データと組み合わせると、いつ最大使用率に達するかを予測する容量計画モデルを構築できます。
ダッシュボードのレシピ: 人事と従業員
従業員分析ダッシュボード
Odoo データから構築された HR ダッシュボードは、ほとんどの HRIS システムが割増価格を請求する洞察を提供します。
従業員数と離職率の測定:
Active Employees =
CALCULATE(
COUNTROWS(Dim_Employee),
Dim_Employee[active] = TRUE()
)
Attrition Rate =
DIVIDE(
CALCULATE(
COUNTROWS(Dim_Employee),
Dim_Employee[departure_date] <> BLANK(),
YEAR(Dim_Employee[departure_date]) = YEAR(TODAY())
),
[Average Headcount],
0
)
Average Tenure Years =
AVERAGEX(
FILTER(Dim_Employee, Dim_Employee[active] = TRUE()),
DATEDIFF(Dim_Employee[contract_start_date], TODAY(), DAY) / 365.25
)
Cost Per Employee =
DIVIDE(
SUM(Fact_Payroll[total_cost]),
[Active Employees]
)
hr_leave からの不勤分析:
Absence Rate =
DIVIDE(
SUM(Fact_Leaves[number_of_days]),
[Working Days In Period] * [Active Employees]
)
Bradford Factor =
SUMX(
Dim_Employee,
VAR AbsenceSpells = CALCULATE(COUNTROWS(Fact_Leaves), Fact_Leaves[state] = "validate")
VAR TotalDays = CALCULATE(SUM(Fact_Leaves[number_of_days]), Fact_Leaves[state] = "validate")
RETURN AbsenceSpells * AbsenceSpells * TotalDays
)
hr_attendance からの勤怠分析:
Average Daily Hours =
AVERAGEX(
VALUES(Dim_Date[Date]),
CALCULATE(SUM(Fact_Attendance[worked_hours]))
)
Overtime Hours =
SUMX(
Fact_Attendance,
IF(Fact_Attendance[worked_hours] > 8, Fact_Attendance[worked_hours] - 8, 0)
)
増分リフレッシュ構成
数百万のレコードを持つ Odoo データベースの場合、完全なデータ更新は現実的ではありません。 Power BI の増分更新機能は、新しいレコードと変更されたレコードのみを読み込むため、更新時間が数時間から数分に短縮されます。
前提条件
- Power BI Pro または Premium ライセンス
- 各テーブルには信頼できる日時列が必要です (Odoo の write_date が理想的です -- レコードが変更されるたびに更新されます)
- データ ソースはクエリ フォールディングをサポートする必要があります (PostgreSQL はサポートします)。
構成手順
ステップ 1: RangeStart パラメーターと RangeEnd パラメーターを作成する
Power Query で、DateTime 型の 2 つのパラメーターを作成します。
- RangeStart: デフォルト値 = 2020 年 1 月 1 日 12:00:00 AM
- RangeEnd: デフォルト値 = 12/31/2030 12:00:00 AM
ステップ 2: パラメータでテーブルをフィルタリングします
ファクト テーブルごとに、Power Query にフィルター ステップを追加します。
= Table.SelectRows(Source, each [write_date] >= RangeStart and [write_date] < RangeEnd)
このフィルターはデータベースに折りたたむ必要があります (生成された SQL に表示されます)。ステップを右クリックし、[ネイティブ クエリの表示] を選択して確認します。
ステップ 3: 増分更新ポリシーを定義する
モデル内のテーブルを右クリックし、「増分更新」を選択して、以下を構成します。
| 設定 | 推奨値 |
|---|---|
| 最後の | に行を格納します。 3年 |
| 最後の | の行を更新します。 7日間 |
| データ変更の検出 | write_date 列 |
| 完了した期間のみをリフレッシュ | 有効 |
この構成では 3 年間の履歴が保存されますが、スケジュールされた更新ごとに過去 7 日間のみが更新されます。 Odoo の write_date 列は、レコードのフィールドが変更されると自動的に更新されるため、信頼性の高い変更検出列になります。
パフォーマンスへの影響
| シナリオ | フルリフレッシュ | 増分更新 |
|---|---|---|
| 100 万件の販売注文明細 | 12分 | 45秒 |
| 500 万件の仕訳 | 38分 | 2分 |
| 1,000 万株の動き | 65分 | 4分 |
特に大量のトランザクション データを生成する製造および在庫データセットの場合、パフォーマンスの向上は劇的です。
上級: 複数の会社と複数の通貨
複数企業の Odoo デプロイメントの処理
多くの Odoo Enterprise 導入環境では、単一のデータベースから複数の法人にサービスを提供しています。すべてのトランザクション レコードには company_id フィールドがあります。 Power BI の場合:
res_companyからDim_Companyテーブルを作成します- 各ファクト テーブルの company_id から Dim_Company への関係を確立します。
- すべてのダッシュボード ページに会社スライサーを追加します
- 行レベルのセキュリティを実装して、各ユーザーが自分の会社のデータのみを参照できるようにする
通貨換算
Odoo は会社の基本通貨で金額を保存します。複数通貨レポートの場合は、res_currency_rate テーブルを結合します。
SELECT
so.id,
so.amount_total AS amount_local,
so.amount_total / COALESCE(
(SELECT rate FROM res_currency_rate
WHERE currency_id = so.currency_id
AND name <= so.date_order::date
ORDER BY name DESC LIMIT 1),
1
) AS amount_usd
FROM sale_order so;
あるいは、Power BI で日次為替レートを使用して Dim_Currency_Rate テーブルを維持し、DAX を使用してレポート時に変換します。このアプローチは、仮定のシナリオ (たとえば、「昨年の為替レートでの収益はどうなるか?」など) に対してより柔軟です。
Odoo Online 向けの OData と REST API の統合
PostgreSQL への直接アクセスが利用できない Odoo Online または Odoo.sh を使用している組織の場合は、代替の接続方法があります。
Odoo の JSON-RPC API の使用
Odoo は、/jsonrpc で JSON-RPC エンドポイント (または /xmlrpc/2 で古い XML-RPC) を公開します。 search_read メソッドを呼び出してデータをフェッチできます。
{
"jsonrpc": "2.0",
"method": "call",
"params": {
"service": "object",
"method": "execute_kw",
"args": [
"your_database",
2,
"your_api_key",
"sale.order",
"search_read",
[[["state", "in", ["sale", "done"]]]],
{"fields": ["name", "partner_id", "date_order", "amount_total", "state"],
"limit": 1000, "offset": 0}
]
}
}
Power BI では、ページネーション ロジックを備えた Web.Contents を使用して、これをカスタム Power Query 関数として実装します。課題はパフォーマンスです。各 API 呼び出しで返されるレコードは最大でも数千件であり、大規模なデータセットの場合は複数回のラウンドトリップが必要です。
コミュニティ OData モジュール
いくつかの Odoo コミュニティ モジュールは OData エンドポイントを追加します。
- Odoo 用 BI コネクタ — 構成可能な OData フィードを公開します
- Odoo-Power BI コネクタ — 共通モジュール用の事前構築されたデータ モデル
これらのモジュールは統合を簡素化しますが、Odoo インスタンスに依存関係を追加します。利便性がコミュニティ モジュールのメンテナンスの負担を上回るかどうかを評価します。
ハイブリッド アプローチ: スケジュールされたデータ エクスポート
実用的な中間点は、Odoo からステージング データベースまたは Azure SQL への夜間のデータ エクスポートをスケジュールすることです。 Odoo のスケジュールされたアクションは、主要なテーブルを CSV にエクスポートするか、API 経由で Azure SQL データベースにデータをプッシュする Python スクリプトを実行します。その後、Power BI は完全なクエリ フォールディング サポートを使用してステージング データベースに接続します。
このアプローチは、Odoo 運用データベースを Power BI クエリに公開せずに、ほぼ毎日のデータの鮮度を維持したい組織に適しています。
実際の KPI の例
ここでは、ECOSIRE クライアントが Odoo を Power BI に接続した後に頻繁に構築する 20 の KPI を部門別に示します。
財務 KPI
- 売上未払い日数 (DSO) — account_move から支払いを回収するまでの平均日数 (請求日と支払日)
- 粗利益率 % — sale_order_line (price_subtotal vs product standard_price) から、収益から COGS を差し引いた値を収益で割った値
- 現金換算サイクル — DSO + 在庫残高日数 - 支払残日数
- 予算と実際の差異 — 予算テーブルが必要です (Odoo の account_budget または手動アップロード)
- 従業員あたりの収益 — 総収益を現役従業員数で割ったもの
販売 KPI
- 顧客獲得コスト — マーケティング費用を獲得した新規顧客で割ったもの (マーケティング費用の手動入力が必要です)
- 顧客生涯価値 — 顧客あたりの平均収益と平均関係期間の積
- 販売サイクルの長さ — 商談の作成から受注までの日数 (crm_lead)
- 見積から注文への換算率 — 確認された注文を見積総額で割ったもの
- 平均割引率 % — sale_order_line 割引フィールドより
オペレーション KPI
- 完璧な注文率 — 注文は正確な文書とともに期限通りに完全に配達されます
- 在庫精度 — 実際の数とシステム数 (stock_quant 調整による)
- サプライヤーのリードタイムの信頼性 — 実際の受領日と発注書の予想日
- 倉庫スペースの利用率 — 占有場所を総場所で割ったもの
- 返品率 — 総売上高に対するクレジットノート/返金の割合
製造業の KPI
- 初回合格歩留まり — 再加工なしで品質検査に合格したユニットを総ユニットで割ったもの
- スケジュール遵守 — 製造オーダーは計画日に完了します
- 材料廃棄物 % — BOM 要件を超えて消費された原材料
- ワークセンターの稼働率 — 実際の生産時間と利用可能な時間
- 平均故障間隔 (MTBF) — 機器が故障するまでの平均稼働時間
これらの各 KPI には、特定のテーブル結合と DAX ロジックが必要です。 ECOSIRE の Power BI 実装サービス には、20 個すべてのメジャーが事前に構築された標準 KPI ライブラリが含まれています。
パフォーマンスの最適化
クエリの折りたたみ
クエリの折りたたみは、Odoo + Power BI の統合にとって最も重要なパフォーマンスの概念です。 Power Query が変換を「折りたたむ」とき、ステップは SQL に変換され、Power BI エンジンではなく PostgreSQL サーバー上で実行されます。
折りたたむ手順:
- Table.SelectRows (WHERE 句)
- Table.SelectColumns (SELECT 特定の列)
- テーブル.ソート(ORDER BY)
- テーブル.グループ (GROUP BY)
- テーブル結合(JOIN)
- Table.FirstN (LIMIT)
折りたたみを壊す手順:
- カスタム M 関数を使用した Table.AddColumn
- テーブルバッファ
- Table.Pivot / Table.Unpivot (ほとんどの場合)
- 折りたたみ不可能な前のステップを参照するステップ
ベスト プラクティス: Power Query の折りたたみに依存するのではなく、カスタム SQL クエリを作成します。これにより、PostgreSQL に送信される SQL を完全に制御できるようになり、折りたたみの不確実性が排除されます。
インポートと DirectQuery
| 係数 | インポートモード | ダイレクトクエリ |
|---|---|---|
| パフォーマンス | 高速 (データはローカルにキャッシュされる) | 遅い (クエリは Odoo DB にライブでヒットします) |
| データの鮮度 | スケジュールされた更新 (最小 30 分) | リアルタイム |
| モデルサイズ | メモリによる制限 (無料 1 GB、プレミアム 10 ~ 100 GB) | サイズ制限なし |
| DAX サポート | フル | 制限あり(一部機能が利用不可) |
| Odoo への影響 | 更新後はなし | レポートの対話ごとに DB にクエリが実行されます。 |
| 推奨事項 | ほとんどのシナリオで使用します。リアルタイムが不可欠な場合にのみ使用してください。 |
ほとんどの Odoo デプロイメントでは、増分更新を伴うインポート モードにより、パフォーマンスと鮮度の最適なバランスが提供されます。 DirectQuery は、30 分前のデータが受け入れられない運用ダッシュボード (たとえば、製造現場のライブ ディスプレイ) 用に予約する必要があります。
複合モデル
Power BI Premium は、Import テーブルと DirectQuery テーブルを組み合わせた複合モデルをサポートしています。これは、次のような Odoo 統合に最適です。
- 大規模な履歴テーブル (販売注文、仕訳入力) は、増分更新を伴うインポート モードを使用します。
- 小さくて急速に変化するテーブル (ライブ在庫のstock_quant) は DirectQuery を使用します。
- 日付ディメンションとその他のディメンションはデュアル ストレージ モードを使用します
一般的な問題のトラブルシューティング
接続エラー
「サーバーに接続できません」 — PostgreSQL が正しいポート (デフォルト 5432) でリッスンしていること、およびファイアウォール ルールが Power BI ゲートウェイまたはデスクトップ IP からの受信接続を許可していることを確認します。クライアント認証ルールについては、listen_addresses については postgresql.conf、pg_hba.conf を確認してください。
「SSL 接続が必要です」 — sslmode=require を接続に追加します。自己署名証明書の場合、CA 証明書をインポートするか、sslmode=allow を設定する必要がある場合があります (運用環境には推奨されません)。
「テーブルに対するアクセス許可が拒否されました」 — Power BI データベース ユーザーには SELECT 権限がありません。 psql で GRANT SELECT ON ALL TABLES IN SCHEMA public TO powerbi_readonly; を実行し、\dp table_name で確認します。
データ品質の問題
重要なフィールドの NULL 値 — Odoo では、多くのフィールドを空白にすることができます。計算エラーを回避するには、SQL クエリで COALESCE を使用するか、DAX で BLANK() を処理します。
レコードの重複 — Odoo の ORM は、編集中に複数のバージョンのレコードを作成することがあります。 active = true でフィルターし、正しい状態フィールドを使用して下書きとキャンセルされたレコードを除外していることを確認します。
タイムゾーンの不一致 — Odoo はタイムスタンプを UTC で保存します。 Power BI は、既定ではローカル タイムゾーンで表示されます。正規化するには、PostgreSQL クエリで AT TIME ZONE を使用するか、Power Query で DateTimeZone.SwitchZone を使用します。
パフォーマンスの問題
遅いリフレッシュ時間 — 増分リフレッシュを有効にします。テーブル全体をインポートする代わりに、カスタム SQL クエリを使用します。非アクティブなレコード、ドラフト文書、および分析ウィンドウを超えた履歴データをフィルターで除外します。
10 秒以上のレポート読み込み時間 — 大きなテーブル (SUMX、多くの行を含む FILTER) を反復する複雑な DAX メジャーがないか確認します。変数を使用して計算の繰り返しを避けます。 SQL ビューでデータを事前に集計することを検討してください。
ゲートウェイ タイムアウト — ゲートウェイ データ ソース構成のコマンド タイムアウトを増やします。デフォルトは 120 秒です。大規模な Odoo データベースの場合は 600 に設定します。
セキュリティに関する考慮事項
データベースのセキュリティ
Odoo 管理データベース ユーザーを使用して Power BI を Odoo に接続しないでください。前に示したように、専用の読み取り専用ユーザーを作成します。次の追加対策を検討してください。
- 行レベルの制限: Power BI がすべてのテーブルにアクセスしたくない場合は、PostgreSQL
CREATE POLICYを使用して読み取り専用ユーザーのアクセスを制限します (たとえば、hr_paylip を除く)。 - 列マスキング: 機密列 (給与、SSN、銀行詳細) を除外するビューを作成し、Power BI にベース テーブルの代わりにビューへのアクセスを許可します。
- 接続の暗号化: 特に Power BI ゲートウェイと Odoo データベースが異なるネットワーク上にある場合は、PostgreSQL 接続には常に SSL を使用します。
- 監査ログ: PostgreSQL
pgauditを有効にして、Power BI ユーザーからのすべてのクエリを追跡します。
Power BI セキュリティ
- Odoo の複数企業アクセス ルールを反映する行レベル セキュリティ (RLS) を Power BI に実装します。
- 財務データまたは人事データを含むデータセットに機密ラベルを使用する
- ワークスペースへのアクセスを承認されたアナリストと消費者に制限する
- データの漏洩を防ぐために、機密レポートのデータ エクスポートを無効にします。
Power BI のセキュリティの詳細については、行レベルのセキュリティの実装 に関するガイドを参照してください。
すべてをまとめる: 実装ロードマップ
フェーズ 1: 基礎 (1 ~ 2 週目)
- Odoo データベースに読み取り専用の PostgreSQL ユーザーを作成します。
- オンプレミス データ ゲートウェイをインストールして構成します (Power BI サービスを使用している場合)
- Power BI Desktop を Odoo データベースに接続します
- 5 つのコア テーブル グループ (販売、会計、在庫、製造、人事) をインポートします。
- 日付ディメンションを構築し、関係を確立する
フェーズ 2: コア ダッシュボード (第 3 ~ 4 週)
- エグゼクティブセールスダッシュボードを構築する (収益、成長、主要製品、パイプライン)
- 財務ダッシュボードを構築する (AR の老朽化、キャッシュ フロー、予算の差異)
- 在庫ダッシュボードを構築する (在庫レベル、売上高、再注文アラート)
- すべてのファクト テーブルの増分更新を構成する
- Power BI サービスに発行し、スケジュールされた更新を設定する
フェーズ 3: 高度な分析 (第 5 ~ 6 週)
- 製造ダッシュボードの構築 (OEE、使用率、生産スケジュール)
- 人事ダッシュボードを構築する (従業員数、人員削減、勤怠、欠勤)
- 複数企業のデータを分離するために行レベルのセキュリティを実装する
- 主要なダッシュボードのモバイルに最適化されたレイアウトを作成する
- 重要な KPI (在庫切れ、請求書の期限切れ、生産の遅延) に対するデータ アラートを設定する
フェーズ 4: ガバナンスと規模 (第 7 ~ 8 週)
- ワークスペースの命名規則とコンテンツ認証を確立する
- セルフサービスレポート作成についてパワーユーザーをトレーニングする
- データモデルと計算ロジックを文書化する
- 使用状況の監視を設定して導入を追跡する
- 追加のデータソースを計画する (マーケティングプラットフォーム、eコマース、IoT)
ECOSIRE の Power BI + Odoo 統合サービス はこのロードマップに従っており、通常は最初のエグゼクティブ ダッシュボードを 2 週間以内に提供します。 Odoo のデータ モデルと Power BI の分析エンジンに関する私たちのチームの二重の専門知識により、初日から正確でパフォーマンスの高い、管理された分析を確実に実現できます。
よくある質問
Power BI を Odoo Online に接続できますか? または自己ホスト型 Odoo のみに接続できますか?
どちらにも接続できますが、方法が異なります。自己ホスト型の Odoo では、より高速かつ柔軟な PostgreSQL への直接アクセスが可能です。 Odoo Online と Odoo.sh はデータベースを直接公開しないため、Odoo の JSON-RPC API、コミュニティ OData コネクタ モジュール、またはステージング データベースへのスケジュールされたデータ エクスポートを使用する必要があります。大規模なデータセットを含む Odoo Online の場合は、50,000 レコードを超えるテーブルの API ベースの抽出が遅いため、ステージング データベースのアプローチをお勧めします。
Power BI は Odoo からのデータをどのくらいの頻度で更新できますか?
Power BI Pro を使用すると、1 日あたり最大 8 回の更新 (3 時間ごと) をスケジュールできます。 Power BI Premium を使用すると、1 日あたり最大 48 回 (30 分ごと) の更新をスケジュールできます。リアルタイム データの場合は、DirectQuery モードを使用しますが、すべてのレポート操作で Odoo データベースに直接クエリが実行されることに注意してください。増分リフレッシュにより、各リフレッシュにかかる時間が短縮され、データベースに過負荷をかけることなく、より頻繁なリフレッシュが実用的になります。
Power BI クエリにより Odoo システムの速度が低下しますか?
インポート モード (推奨) を使用する場合、Power BI クエリは、スケジュールされた更新中 (通常はオフピーク時間帯) にのみ実行されます。 Odoo のパフォーマンスへの影響は最小限です。 DirectQuery を使用する場合、レポートの操作ごとに Odoo データベースに対するライブ クエリが生成され、営業時間中のパフォーマンスに影響を与える可能性があります。軽減策には、リードレプリカの使用、クエリのタイムアウトの構成、インデックスを使用する効率的な SQL クエリの設計などが含まれます。
統合を設定するには SQL の知識が必要ですか?
基本的な SQL の知識は役に立ちますが、厳密に必須ではありません。 Power BI の Power Query インターフェイスを使用すると、テーブルを選択し、フィルターを視覚的に適用できます。ただし、最適なパフォーマンスとデータ品質を得るには、カスタム SQL クエリを強くお勧めします。これらを使用すると、テーブルを事前結合したり、不要なレコードをフィルタリングしたり、データベース レベルでデータを整形したりすることができます。チームに SQL の専門知識が不足している場合は、初期セットアップについて専門家に依頼し、Power BI のビジュアル ツールを使用してレポートを管理することを検討してください。
ECOSIRE の Odoo + Power BI サービスは、一般的な Power BI コンサルティングとどのように異なりますか?
ほとんどの Power BI コンサルティング会社は Power BI の専門知識を持っていますが、Odoo のデータ モデルに関する知識は限られています。彼らは何週間もかけてテーブルのリレーションシップをリバースエンジニアリングし、Odoo 固有の規則 (product_product / product_template の二重構造など) を理解し、どのフィールドが意味があるのかを判断しました。 ECOSIRE は 43 を超える Odoo モジュールを構築および展開し、両方のプラットフォームに関する深い専門知識を維持しています。事前に構築されたデータ モデル、50 以上のメジャーを含む標準 KPI ライブラリ、write_date 列の増分更新などの Odoo 固有の最適化が提供されます。この 2 つの専門知識により、チームが Odoo のデータ モデルを最初から学習する場合と比較して、実装時間が 40 ~ 60 パーセント短縮されます。
執筆者
ECOSIRE Research and Development Team
ECOSIREでエンタープライズグレードのデジタル製品を開発。Odoo統合、eコマース自動化、AI搭載ビジネスソリューションに関するインサイトを共有しています。
関連記事
Power BI AI の機能: Copilot、AutoML、予測分析
自然言語レポート用の Copilot、予測用の AutoML、異常検出、スマート ナラティブなどの Power BI AI 機能をマスターします。ライセンスガイド。
Power BI ダッシュボード開発の完全ガイド
KPI 設計、視覚的なベスト プラクティス、ドリルスルー ページ、ブックマーク、モバイル レイアウト、RLS セキュリティを備えた効果的な Power BI ダッシュボードを構築する方法を学びます。
Power BI データ モデリング: ビジネス インテリジェンスのためのスター スキーマ設計
スター スキーマ設計、ファクト テーブルとディメンション テーブル、DAX メジャー、計算グループ、タイム インテリジェンス、複合モデルを使用した Power BI データ モデリングをマスターします。
Data Analytics & BIのその他の記事
Power BI ダッシュボード開発の完全ガイド
KPI 設計、視覚的なベスト プラクティス、ドリルスルー ページ、ブックマーク、モバイル レイアウト、RLS セキュリティを備えた効果的な Power BI ダッシュボードを構築する方法を学びます。
すべてのビジネス ユーザーが知っておくべき DAX 式
Power BI に不可欠な 20 の DAX 式をマスターします。 CALCULATE、タイムインテリジェンス、RANKX、コンテキスト遷移、イテレータ、実践的なビジネス例。
Power BI Embedded: アプリケーションへの分析の追加
Power BI 分析を SaaS アプリに埋め込みます。認証、マルチテナント RLS、容量サイジング、JavaScript SDK、カスタム テーマ、ファブリックの価格設定について説明します。
Excel から Power BI への移行: ステップバイステップ ガイド
Excel から Power BI への移行に関する完全なガイド。数式の変換、データ モデルの作成、Power Query、検証、廃止をカバーします。
ビジネスにおける AI ROI の測定: 実際に機能するフレームワーク
直接的な節約、生産性の向上、収益への影響、部門全体の戦略的価値をカバーする AI の投資収益率を測定するための実用的なフレームワークです。
財務報告ダッシュボードの構築: KPI、設計、ERP 統合
意思決定を促進する財務報告ダッシュボードを設計します。追跡する KPI、ダッシュボードの設計原則、ERP 統合のベスト プラクティスについて学びます。