タイム インテリジェンス 関数は見えるようにして確認するとよいのではなかろうか。

先般の Power BI 勉強会 \#16 で質問が上がっていたのだけどあまり時間が取れなかったので、改めてこんな感じで勉強するとよいですよって話。質問の内容としては、

> SAMEPERIODLASTYEAR と PREVIOUSYEAR どう違うの？

まぁ、別の関数ですし、得られる結果は異なりますよね。異なることはわかっているけどどうなの？って感じだったかな。違いを覚えないと使うことはできないから、当たって砕けろだけじゃなくて、どのように理解しやすくするか。特にタイム インテリジェンス関数は似た感じのもの多い気がするし。

# まずはリファレンスをきちんと読む

- [タイム インテリジェンス関数 (DAX) - DAX | Microsoft Docs](https://docs.microsoft.com/ja-jp/dax/time-intelligence-functions-dax)
- [DAX Guide](https://dax.guide/)

支援はあるけれども、さっぱりわからんですよね。なので、リファレンスはきちんと読んだ方がいい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/cd5df6ff-5495-5a2b-b91f-db2216a20fe8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/bd8090dd-5ca4-fdf8-0806-50bfa79224b2.png)

例えば、[SAMEPERIODLASTYEAR 関数 (DAX) - DAX | Microsoft Docs](https://docs.microsoft.com/ja-jp/dax/sameperiodlastyear-function-dax)

> 現在のコンテキストで、指定された dates 列の日付から 1 年前にシフトした日付の列を含むテーブルを返します。

読んでも、うーん🤔ってこともあるでしょう。目に見える形だ確認したほうがよいよね。でも、リファレンスがまったく意味がないということではなく、とても重要な記述があるのでお見逃しなく。
## パラメータ－
タイム インテリジェンス関数ですから "日付列" が重要です。構文にある Dates は 日付テーブルの 日付列を指定することがほとんどなのではないかと。

```text:DAX構文
SAMEPERIODLASTYEAR( <dates> )
```

ちなみに、SAMEPERIODLASTYEAR は

```text:DAX-DATEADD
DATEADD( <Dates>, -1, YEAR )
```
です。

## 戻り値
戻り値の型にはいくつかあるのだけど、多くの場合、**列をひとつだけ持つテーブル** で その値は 日付。なかには、**列 / 行 ともにひとつだけのテーブル** や **スカラ値** が戻るものもある。このあたりはよーく確認してください。
ただ、DAX では 1 行1 列のテーブルは暗黙の変換でスカラ値としてくれるのは便利ではあるけれども、なぜうまくいくのかぐらいは確認しておいた方がよいのでしょう。暗黙の変換をあてにしない記述は大事なことだと思うのです。

# 見えるようにして確認するとよい
例に挙げるタイム インテリジェンス 関数は 日付の範囲を戻す感じだから 範囲の両端と行数を メジャー でしたたて、マトリクス や テーブルに配置してみる感じで。

```text:SAMEPERIODLASTYEAR
SPLY = 
VAR DateFilter = SAMEPERIODLASTYEAR( 'Dates'[Date] )
VAR ResultValue =
    CONCATENATEX(
        CALCULATETABLE(
            {
                MIN( 'Dates'[Date] ),
                MAX( 'Dates'[Date] ),
                FORMAT( COUNTROWS( 'Dates' ), "0" )
            },
            DateFilter
        ),
        [Value], " - "
    )
VAR Result =
    IF(
        NOT ISEMPTY( DateFilter ),
        ResultValue
    )
RETURN
    Result
```

```text:PREVIOUSYEAR
PY = 
VAR DateFilter = PREVIOUSYEAR( 'Dates'[Date] )
VAR ResultValue =
    CONCATENATEX(
        CALCULATETABLE(
            {
                MIN( 'Dates'[Date] ),
                MAX( 'Dates'[Date] ),
                FORMAT( COUNTROWS( 'Dates' ), "0" )
            },
            DateFilter
        ),
        [Value], " - "
    )
VAR Result =
    IF(
        NOT ISEMPTY( DateFilter ),
        ResultValue
    )
RETURN
    Result
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/11fbea08-8e15-9ef1-7fac-f09cd02c96fd.png)

カレント行の日付の範囲から得られる結果(ここでは日付のセット)の違いの整理はつけられそう。なので具体的な結果もこんな感じになる。

```text
受注額 (SPLY) = 
CALCULATE(
    [受注額],
    SAMEPERIODLASTYEAR( 'Dates'[Date] )
)
```

```text
受注額 (PY) = 
CALCULATE(
    [受注額],
    PREVIOUSYEAR( 'Dates'[Date] )
)
```
いわゆる未来の日付についてなにも手当てしてないから別途実装のこと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/34a40d79-90a1-d48a-11b0-54b1285405da.png)

# 思ったこと🙄
4、5 年前 こんなことやってたなぁと思いだした。読むだけ聞くだけではダメなんですね。試さないと。

# その他
- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Power BI Desktop を使い始めるには](http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981)
- [Excel で Power Query を使い始めるには](http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9)