Power BIのDAXで「A circular dependency was detected」が出たら、最後に追加した式だけでなく、エラーに並ぶ計算列・measure・計算table・relationshipの依存を追います。見えている式に相互参照がなくても、measure呼出やcontext transitionを通して依存が広がる場合があります。式を作る順番や列の表示順を変えるだけで、計算上の循環がなくなるとは限りません。
この記事は、原因の範囲を小さくして依存を切り分ける手順です。実際のPBIX、DAX engine、service refresh、外部編集toolは操作していません。依存図と数値は架空例で、修正式を実modelで検証した報告ではありません。変更は検証用の複製で行い、元の計算とmodel定義を保存してください。
目次
エラーが出る時点と変更差分を残す
列追加時、relationship作成時、Desktop更新時、service更新時のどこで失敗するかを記録します。対象model、Desktop版、storage mode、直前に変えた式や関係、エラーに出るobject名を揃えます。資格情報や容量のエラーと混ぜず、まず計算依存の問題かを確認します。
表は横にスクロールできます
| 直前の変更 | 最初に追うもの | まだしないこと |
|---|---|---|
| 計算列を追加 | 参照列と呼出measure | 全列の一括削除 |
| measureを変更 | そのmeasureを呼ぶ計算列・table | エラーの列だけをrename |
| 計算tableを作成 | 元table・集計・relationship | 関係を無差別に無効化 |
| 更新時だけ失敗 | 同じmodelの版と更新差分 | 認証を作り直して解決扱い |
式を一つ戻して保存・更新できるなら、原因候補を絞る情報になります。ただし「戻すと通る」だけでは、その式のどの依存が循環を作ったかまでは分かりません。
直接の依存を矢印で書く
「Aの計算にBが必要」をA→Bとして並べます。object名はtable名も含め、列とmeasureを区別します。名前が同じでも別objectの場合があり、式の短い参照だけで判断しないようにします。
架空の設計で、販売金額列を「基礎金額+調整額」、調整額列を「販売金額×率」と定義すると、販売金額→調整額→販売金額へ戻ります。どちらを先に確定するかが決まらない設計です。Power BIでこの二式を作成できたという意味ではありません。
循環する設計案:
販売金額 → 調整額 → 販売金額
別の要件が確認できた場合の設計案:
調整額 → 基礎金額・率
販売金額 → 基礎金額・調整額
二つ目は調整額が基礎金額に対する率である場合だけの例です。実際に税込総額や割引後総額を基準にする業務なら、別の数式設計が必要です。循環を消すために、意味の違う基礎値へ勝手に置き換えません。
計算列・measure・計算tableの役割を分ける
Microsoftの計算列資料(新しいタブで開く)は、計算列が行ごとの値を計算し、他の計算列やmeasureにも基づけることを説明しています。参照を一段ずつたどり、列の式だけで探索を止めないことが大切です。
計算列は行に持たせる分類や値、measureはreportのfilter contextに応じた集計など、必要な使い方が違います。「列をmeasureへ変えれば必ず直る」という対処はしません。slicer、relationship、並べ替え、行単位の出力で列が必要なのかを確認し、計算の置き場所を選びます。
表は横にスクロールできます
| 必要な結果 | 見直す方向 | 再確認する影響 |
|---|---|---|
| 各行で固定する分類 | 元データ・変換工程・計算列 | 更新時点と分類条件 |
| 選択期間で変わる合計 | measureの設計 | filterと合計行 |
| 独立した対応table | 元データとrelationship | keyの一意性・未対応行 |
| 計算結果を再び入力に使用 | 元の業務数式 | 循環しない定義があるか |
CALCULATEやmeasure呼出を展開して考える
CALCULATE公式資料(新しいタブで開く)は、row contextからfilter contextへの変換と、row context内でmodel measureを使う場合の自動的なcontext transitionを説明しています。式に直接書かれた列名だけで依存の全範囲を判断しないようにします。
問題の計算列からmeasureを呼んでいたら、その定義を開き、CALCULATE、iterator、参照table、関連する列を記録します。検証用の複製で、呼出を単純な元列の式へ一時的に替えた場合と比較し、依存が広がる入口を絞ります。この比較用の式を、元の意味を確認せず最終式にしません。
ALLEXCEPTやREMOVEFILTERSを足して通った場合も、計算対象や分母が変わる可能性があります。残すべきkeyやfilterを定義し、一意性を確認してから採否を判断します。すべてのfilterを外してエラーを消すことは、正しい計算の証明ではありません。
計算tableとrelationshipを含む循環を分ける
計算tableが元tableを参照し、その結果と元tableの関係を作る場合は、式とrelationshipの両方を確認します。relationshipを一時的に外す比較は、依存箇所を調べるための検証です。reportのfilter伝播が変わるため、エラーが消えたことだけで本番modelの最終解決にしません。
Power BIの公式更新トラブル資料(新しいタブで開く)には、CALCULATETABLE内でSUMMARIZECOLUMNSを使う計算tableの循環依存という、特定条件の案内があります。該当する式・更新時の症状なら、その節のfilterとblank rowの扱いを確認します。
同資料には、複数計算tableの変更を一つのtransactionで適用する必要がある場合も記載されています。これを全DAXの共通修正とせず、該当条件を整理し、採用tool・backup・確認方法を含めてmodel管理者と扱います。問題が特定できていない段階で外部toolを導入したり、本番の全tableを書き換えたりしません。
エラー消失後に計算結果を検算する
修正は一つずつ記録し、元の式、変更理由、切れた依存、必要な関係を残します。検証用modelで計算・更新が通った後、既知の少数行、空白、key重複、関連先がない行、reportの代表的なfilterで結果を比べます。合計が一致しても行別の誤りが相殺される場合があるため、行単位と集計を分けます。
表は横にスクロールできます
| 確認 | 合格条件 | 不合格なら |
|---|---|---|
| 依存 | 自分に戻る経路を説明できる形で除去 | 探索した依存図へ戻る |
| 行の結果 | 業務定義から計算した期待値と一致 | 基礎値・条件を再確認 |
| 集計 | filter別・合計の意味が維持される | contextの変更を点検 |
| model更新 | 対象環境と対象版で確認 | Desktopだけの結果と区別 |
依存を切るために不要になった比較用式や一時的な関係変更は、採用した差分と分けて元へ戻します。戻すと再び循環する場合は、最終解決が比較用変更に依存していたということです。完了記録には、解消した経路、検算した条件、未確認の更新環境を残し、実測していない成功を補わないようにします。
