mcpField
P
power-bi-dax

power-bi-dax

github.com/julianobarbosaデータ・データベース1471 回インストール2 日前に更新
リポジトリ

power-bi-dax について

power-bi-dax は、接続済みの Power BI モデルに対して DAX クエリを実行・検証するスキルです。メジャー作成、モデルデータの確認、クエリで起きやすい問題も扱います。

主な機能

  1. 01コマンドライン、ファイル、標準入力から DAX を実行
  2. 02DAX クエリの検証
  3. 03DAX によるメジャー作成
  4. 04テーブル、列、データの確認
  5. 05数式エンジンキャッシュの消去

活用シーン

  1. 01接続済みモデルに対する DAX クエリのテスト
  2. 02売上や時系列分析用メジャーの作成
  3. 03モデル構造の確認とテーブルデータのプレビュー

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/julianobarbosa/claude-code-skills --skill power-bi-dax

インストール後、Claude Code で/power-bi-daxを入力して読み込まれたか確認します。

詳細

Power BI DAX スキル

接続された Power BI モデルに対して DAX クエリを実行し、検証します。

前提条件

pipx install pbi-cli-tool
pbi-cli skills install
pbi connect

クエリの実行

# Inline query
pbi dax execute "EVALUATE TOPN(10, Sales)"

# From file
pbi dax execute --file query.dax

# From stdin (piping)
cat query.dax | pbi dax execute -
echo "EVALUATE Sales" | pbi dax execute -

# With options
pbi dax execute "EVALUATE Sales" --max-rows 100
pbi dax execute "EVALUATE Sales" --timeout 300       # Custom timeout (seconds)

# JSON output for scripting
pbi --json dax execute "EVALUATE Sales"

CLI での DAX 式の制限事項

DAX を -e 引数として渡すと、シェルによって改行が 1 行にまとめられます。SUM(Sales[Amount]) のような単純な式は問題なく動作しますが、VAR/RETURN を使用した複数行の DAX は、DAX パーサーがこれらのキーワード間の改行を必要とするため、エラーになります。

これが重要な理由: VAR x = [Total Sales] VAR y = [Sales PY] RETURN DIVIDE(x - y, y) のようなメジャーは、ステートメントの区切りがない連続した 1 行としてエンジンに認識されるため、構文エラーになります。

回避策(いずれかを選択):

# Option 1: Pipe from stdin (recommended for measures)
echo 'VAR TotalSales = SUM(Sales[Amount])
VAR TotalCost = SUM(Sales[Cost])
RETURN TotalSales - TotalCost' | pbi measure create "Profit" -e - -t Sales

# Option 2: Write to a .dax file and use --file (for queries)
echo 'EVALUATE
ROW("Result",
    VAR x = SUM(Sales[Amount])
    RETURN x
)' > query.dax
pbi dax execute --file query.dax

単一行での代替方法(可能な場合はこちらを推奨):

単純な比率/成長率のメジャーでは、VAR/RETURN の代わりにインラインパターンを使用してください。

# Instead of: VAR x = SUM(...) / VAR y = SUM(...) / RETURN DIVIDE(x, y)
# Use inline DIVIDE -- it handles division-by-zero gracefully (returns BLANK):
pbi measure create "Margin %" \
  -e "DIVIDE(SUM(Sales[Amount]) - SUM(Sales[Cost]), SUM(Sales[Amount]))" \
  -t Sales --format-string "0.0%"

# Instead of: VAR current = [Total Sales] / VAR prev = [Sales PY] / RETURN DIVIDE(...)
# Reference measures directly in DIVIDE:
pbi measure create "YoY %" \
  -e "DIVIDE([Total Sales] - [PY Sales], [PY Sales])" \
  -t Sales --format-string "0.0%"

クエリの検証

pbi dax validate "EVALUATE Sales"
pbi dax validate --file query.dax

キャッシュ管理

pbi dax clear-cache    # Clear the formula engine cache

DAX によるメジャーの作成

# Simple aggregation
pbi measure create "Total Sales" -e "SUM(Sales[Amount])" -t Sales

# Time intelligence
pbi measure create "YTD Sales" -e "TOTALYTD(SUM(Sales[Amount]), Calendar[Date])" -t Sales

# Previous year comparison
pbi measure create "PY Sales" -e "CALCULATE([Total Sales], SAMEPERIODLASTYEAR(Calendar[Date]))" -t Sales

# Year-over-year change
pbi measure create "YoY %" -e "DIVIDE([Total Sales] - [PY Sales], [PY Sales])" -t Sales --format-string "0.0%"

よく使われる DAX パターン

モデルデータの確認
# List all tables
pbi dax execute "EVALUATE INFO.TABLES()"

# List columns in a table
pbi dax execute "EVALUATE INFO.COLUMNS()"

# Preview table data
pbi dax execute "EVALUATE TOPN(10, Sales)"

# Count rows
pbi dax execute "EVALUATE ROW(\"Count\", COUNTROWS(Sales))"
集計
# Basic sum
pbi dax execute "EVALUATE ROW(\"Total\", SUM(Sales[Amount]))"

# Group by with aggregation
pbi dax execute "EVALUATE SUMMARIZECOLUMNS(Products[Category], \"Total\", SUM(Sales[Amount]))"

# Multiple aggregations
pbi dax execute "
EVALUATE
SUMMARIZECOLUMNS(
    Products[Category],
    \"Total Sales\", SUM(Sales[Amount]),
    \"Avg Price\", AVERAGE(Sales[UnitPrice]),
    \"Count\", COUNTROWS(Sales)
)
"
フィルター処理
# CALCULATE with filter
pbi dax execute "
EVALUATE
ROW(\"Online Sales\", CALCULATE(SUM(Sales[Amount]), Sales[Channel] = \"Online\"))
"

# FILTER with complex condition
pbi dax execute "
EVALUATE
FILTER(
    SUMMARIZECOLUMNS(Products[Name], \"Total\", SUM(Sales[Amount])),
    [Total] > 1000
)
"
時系列分析
# Year-to-date
pbi dax execute "
EVALUATE
ROW(\"YTD\", TOTALYTD(SUM(Sales[Amount]), Calendar[Date]))
"

# Rolling 12 months
pbi dax execute "
EVALUATE
ROW(\"R12\", CALCULATE(
    SUM(Sales[Amount]),
    DATESINPERIOD(Calendar[Date], MAX(Calendar[Date]), -12, MONTH)
))
"
ランキング
# Top products by sales
pbi dax execute "
EVALUATE
TOPN(
    10,
    ADDCOLUMNS(
        VALUES(Products[Name]),
        \"Total\", CALCULATE(SUM(Sales[Amount]))
    ),
    [Total], DESC
)
"

パフォーマンスに関するヒント

  • 開発中は --max-rows を使用して結果セットを制限します
  • ベンチマークの前に pbi dax clear-cache を実行します
  • グループ化には SUMMARIZE よりも SUMMARIZECOLUMNS を優先します
  • ネストした FILTER の代わりに、単純なフィルターを指定した CALCULATE を使用します
  • 集計で十分な場合は、大きなテーブルでイテレーター(SUMX、FILTER)を使わないようにします

注意点

  • -e では VAR/RETURN の改行が失われます: シェルによって改行がスペースにまとめられますが、DAX パーサーはステートメントの区切りとして改行を必要とします。VAR x = ... VAR y = ... RETURN ... を 1 行で記述すると、有用な位置情報のない「構文エラー」が発生します。標準入力からパイプするか、--file を使用してください。
  • CALCULATE(SUM(x), ALL(table)) と ALLEXCEPT と ALLSELECTED: 3 つとももっともらしい数値を返しますが、正しいのは 1 つだけです。ALL はそのテーブル上のすべてのフィルターを解除し、ALLEXCEPT は指定した列のみを保持し、ALLSELECTED は外側のフィルターを尊重します。誤った選択をすると、気づかないまま合計が間違います。
  • SUMMARIZECOLUMNS は、すべてのメジャーが BLANK の行を除外します: 出力に「カテゴリがない」場合、多くはデータの欠落ではなく、このフィルターが原因です。その行を表示する必要がある場合は、メジャーを COALESCE(measure, 0) で囲みます。
  • DIVIDE([a], [b]) はゼロ除算時に 0 ではなく BLANK を返します: BLANK は後続のグラフに引き継がれ、ゼロではなく空白として表示されます。ゼロにする場合は、DIVIDE([a], [b], 0) のように第 3 引数を明示します。
  • pbi dax clear-cache がクリアするのはフォーミュラエンジンのキャッシュだけです: ストレージエンジンのキャッシュは残ります。実際のコールドクエリのベンチマークを行うには、Desktop を再起動するか接続し直してください。そうしないと、繰り返し実行した際の速度が実態よりも大幅に速く見えます。
  • INFO.TABLES() は非表示のテーブルも返します: 計算グループ、自動日付階層、翻訳テーブルもユーザーテーブルとともに表示されます。レポート作成者に見えるものだけを取得するには、[IsHidden] = FALSE でフィルターします。

コメント