[Power BI] DAX Debugger in Tabular Editor 3

Tablular Editor 3 のデバッグ機能について、丁寧な説明の動画がありますが、ちょっとわかりにくいので記事にしてみました。

※ソース元

https://youtu.be/m4g9BxcUf4U


　Daniel Otykier (@DOtykier) は、デンマークを拠点とするコンサルティング会社 Kapacity A/S のプリンシパル・アーキテクトです。２０１６年に Tabular Editor　の開発を始めました。

　Reid Havens (@HavensBI) は、Havens Consulting Inc.の創設者であり、MVP(Microsoft Most Valued Professional)です。組織開発とビジネス分析の修士号を取得し、ワシントン大学や他の大学でビジネスインテリジェンス、レポート作成、データビジュアライゼーションのコースを教え、世界中の企業向けのトレーニングカリキュラムの開発や大学レベルのカリキュラムの開発も行っています。

# DAXのデバッグとは
- DAXは２つの異なる方法で使用される関数型言語です
    - Analysis Service の tabular model の**クエリ言語**
    - Analysis Service の tabular model でビジネスロジックを定義するための**データ定義言語(DDL)**

- DAXと従来のプログラミング言語との違い
    - エントリーポイントを示す特定のコードがありません
    - Analysis Serviceは「ランタイム」エンジンです
        - DAXクエリを入力し、データ結果の出力を得るブラックボックスです
    - 関数型言語であり、制御構造やアプリケーションの状態を持ちません

- DAXをデバッグする方法
    - DAXパーサーを活用することでDAX式のツリーにステップダウンできます
    - DAXパーサーは、**評価コンテキスト**（行／フィルター）に関する情報を提供します
    - 途中で適切なDAXクエリを生成して評価し、変数と部分式の結果を取得します

# Tabular EditorでDAXをデバッグ
**DAXデバッガは２つの方法で呼び出すことができます**

1. **ピボットグリッド**のデータセルから呼び出す
　フィルターコンテキストは、ピボットグリッドに適用されている現在のフィルターと、行／列スライサーとして使用されるフィールドから推測されます。

2. **DAXクエリ**の結果セルから呼び出す（いくつかの制限が適用されます）
　フィルターコンテキストは、現在の結果行から決定可能である必要があります。

**Tabular Editor 3の制限事項**
- DAXクエリでは、クエリスコープ／暗黙的なメジャーを使用できません
- 特定のDAX関数は完全にサポートされていません
- メジャー以外の計算テーブル／計算列／計算グループの式は現在サポートされていません

# TE3 DAX デバッガ機能
- コール・ツリー・ビュー(Call Tree view)
    - 評価対象のDAX式の階層ビューを表示します
    - 式ツリーを移動することができます
    - 関数呼び出し、行コンテキスト、およびコンテンツ繊維に関する情報を表示します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/c92aa1d6-1f85-4c5b-ae00-cfc38e9da698.png)

- 評価コンテキスト・ビュー(Evaluation Context)
    - 現在のフィルター／行コンテキストに関する情報を表示します
    - 行コンテキスト内の行間を移動できます
    - 「外部」フィルターを切り替えられます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/6d900e00-c09b-4d4e-20eb-8ee74b2e32bd.png)

- ウォッチ・ビュー(Watch view)
    - 現在の評価コンテキスト内で任意のDAX式を入力及び評価できます
    - 変数、行コンテキスト列、スカラー、テーブル式をサポート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/234c90f9-ead4-f1f7-2b26-301d49888b91.png)

- ローカル・ビュー(Locals view)
    - 変数、サブ式、および現在のノードの結果をセルツリービューに表示します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/90eeea0d-80d8-650f-0c0f-8aefd2134724.png)

# Tabular Editor 3のDAXデバッグ
**TE3 DAX デバッガは、セマンティック（意味的）デバッガです**
- Analysis Serviceエンジンは、DAXデバッガのようにコードを物理的に走査することはありません。実際には、さまざまな最適化が行われるため、多くの部分式がAnalysis Serviceによって評価されることはありません。
- DAXデバッガは、複雑なDAXコードの理解と分解を容易にするために、中間的な結果に踏み込んで評価するためのツールに過ぎません。

**やるべきこと、やってはいけないこと:**
- **やるべきこと**：DAXデバッガを不正確な計算結果や予期しない結果を調査するために使用すること
- **やるべきこと**：DAXデバッガをDAXの概念を理解するための学習ツールとして使用すること
- **やってはいけないこと**：DAXデバッガをDAXのパフォーマンスを最適化するために使用してはいけません
- **やってはいけないこと**：DAXデバッガをAnalysis Serviceで生成された論理／物理クエリプランを推論するために使用してはいけません

# DAXデバッガ・デモ 1

フィルターの理解:

```text:DemoMeasures
2012 Sales v1 := CALCULATE([Sales Amount], FILTER(Calendar, Calendar[Year] = 2012))
2012 Sales v2 := CALCULATE([Sales Amount], Calendar[Year] = 2012)
2012 Sales v3 := CALCULATE([Sales Amount], KEPPFILTERS(Calendar[Year] = 2012))
```
　このメジャーは、以下のように働きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/ddf147aa-c798-045f-0ada-cf17fdb78c1b.png)
　Tablular Editor 3 でメジャーの動きを見てみます。まず、Power BI Desktopのパフォーマンスアナライザを使って、クエリを取り出します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/8b53632e-6693-c54c-b14c-68e8bf23ef0d.png)
　Tabular Editor 3のDAX Queryに貼り付けて実行してみます。（実行はF5キーでもOK)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/e667b0a7-1fa3-943f-63ee-27136806cf02.png)
　アイコンを使う場合は、これです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/c7903b97-6643-27bb-3c01-94b4ab6efb90.png)
　表示されたテーブルの中のセルを選び、Debugを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/e45cef3b-05c0-6c3f-da40-d89802443791.png)
　デバッグ画面として、DAX debugger, Locals, Watch, Evaluation Context, Call Treeのビューが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/bfee4fb5-6a42-720b-5a5d-b070a1085c4c.png)
　Evaluation Contextには、現在のコンテキスト情報が表示されており、チェックボックスのチェックを外す事ができます。
　Call Treeには、メジャーで実行される関数が細分されて表示されており、それぞれをクリックするとDAX debuggerの表示がハイライトされ、Localsに値が表示されます。また、変数を使っている場合は、それぞれの変数の値を表示することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/21672352-3fdc-63e2-5e97-e6768e5bbae3.png)
　以下のような操作を行うこともできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/6810e2b8-b29a-4972-dcab-6e0315683cb8.png)
　Locals viewに表示されるテーブルタイプでカッコで囲まれている部分は、行と列の数です。以下は３６５行１３列のテーブルを表しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/d61de6ed-6a11-42d3-1158-a4f9263a3b6e.png)
 このテーブルの値を見たい場合、Watch viewに使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/ce89c629-e81c-c510-c593-b11fd29634d8.png)

　１つ新しくメジャーを作成してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/6c8a24ed-6c6e-f4f1-4c7e-5dc9a00c6978.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/03c78b8e-2de4-f458-6480-3b76a5ef4303.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/fc1d9e11-b923-71a6-097a-a897ffa999ea.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/a6d3a7b8-388f-9474-888d-dbe062ed98ca.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/1753d5b3-7237-ec7b-af4b-4ca55535e7a1.png)

# DAXデバッガ・デモ 2
日付型の動作:

 Tablular Editor 3 で Pivot Grid を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/b5b8069e-dbb4-a1cb-2b4b-ae8309457a70.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/b4c074df-0637-7cff-e58f-18136ebd77ad.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/a4393ba2-0050-c7ee-f520-efc70521a63d.png)
　日付がどのように使われているかを確認するために、Watch viewに以下のようなExpressionを入力してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/10336812-19b4-f23f-cdd8-0094af42bcb6.png)
　Tableタイプを確認したい場合は、Valueの虫眼鏡をクリックして表示させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/bcbf120a-4c81-960c-6f11-7fb2fbcdba81.png)

# DAXデバッガ・デモ 3
制御フローの検証:

```
IF(
    ISFILTERD('Measure Slicer'[Measure Selector]),
    SWITCH(
        SELECTEDVALUE( 'Measure Slicer'[Measure Selector] ),
        "Sales Amount", [Sales Amount],
        "Gross Amount", [Gross Amount],
        "Discount Amount", [Discount Amount],
        "Please select only one measure'
    ),
    "Please select a measure on [Measure Selector]"
)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/0b6efb67-3e8a-8fd6-9d46-232a7fef95b7.png)
　Step In (F11) を使って評価を進めると、除外されたコードには消し線が入ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/8a887013-d9a7-1262-bd40-b71a23c5ee90.png)

# DAXデバッガ・デモ 4
行コンテキストの働きを見ます。
以下のようなPivot Gridで、Cell phonesのSales Amount Totalを右クリックしてDebug this valueを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/2c8217d9-9132-8bc7-1ea8-bebfe1642a16.png)
F11を何度か押して、以下の部分がマーカー表示になったとき、Evaluation ContextのウィンドウにRow contextの状態が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/9355987e-1dba-6735-91bc-1dfb08d9bcb8.png)
Call Treeウィンドウには、以下のようにSalesがイテレータされていることが表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/e73c8a16-1896-6a0a-2ef5-27a03c3741d6.png)
Rowの下の数字ををクリックすると、数字が入力できるようになります。その数字を変化させると、選択されている行が変わり、LocalあるいはWatchウインドウに表示されている値が変化します。
虫眼鏡マークをクリックすると現在のコンテキストで選択されているデータが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/55a06d4b-9362-49de-219b-a1d3a31a660c.png)

以下のようなDAX Queryを実行し、値をデバッグします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/1bb0db1c-2722-1b26-758d-7b4328cde8f2.png)
以下のようなコンテキストが発生していることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/c0301658-2d0a-0c0e-8d61-ee977e8a6ef5.png)