power-bi-dax について
power-bi-dax は、接続済みの Power BI モデルに対して DAX クエリを実行・検証するスキルです。メジャー作成、モデルデータの確認、クエリで起きやすい問題も扱います。
主な機能
- 01コマンドライン、ファイル、標準入力から DAX を実行
- 02DAX クエリの検証
- 03DAX によるメジャー作成
- 04テーブル、列、データの確認
- 05数式エンジンキャッシュの消去
活用シーン
- 01接続済みモデルに対する DAX クエリのテスト
- 02売上や時系列分析用メジャーの作成
- 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でフィルターします。
コメント
Markdown 対応