【Power Apps】コードをスッキリ読みやすく！ 一時変数 With関数 の使い方

## With関数とは？:pushpin:
`With関数` とは関数内で数式を **`一時的に変数に置き換え`** データの参照回数を減らしたり
コードを読みやすくさせるための関数です。

## Set関数とUpdateContext関数との違いは？
変数設定の関数は Set関数 と UpdateContext関数 もありますが
それぞれ参照できる範囲が違います。
With関数 は有効範囲がコントロール内と一番小さいです。

ですが、With関数はテキストコントロールなどの非動作プロパティでも宣言が可能です。
どういうことかはこのあとの使い方でご説明します。

使いこなすことができればコードの整理や、変数種類の削減など非常に便利になるのでぜひ覚えてみてください！

| 関数 | 使用できる画面 | 有効範囲 |　非動作プロパティでの宣言 |
|:-:|:-:|:-:|:-:|
|  Set |  アプリ内 |  大 | 不可 |
| UpdateContext  |  画面内 | 中  | 不可 |
|  With | コントロール内  | 小  | 可能 |

## 基本的な構文
With関数の基本的な書き方は以下になります。
`{}` 内はSet関数やUpdateContext関数と同様に変数名と格納したい値を宣言します。
`式` で宣言した変数を使用します。

```ruby:書き方
With( {変数名: 値}, 式 )
```

## 使い方
**Textコントロールで使用**
テキストラベルをプロパティに以下を入力します。

```ruby:点数が80以上なら合格、79以下なら不合格を表示
With(
    {点数: 85},
    If(点数 >= 80,"合格","不合格")
)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/b8c43d55-3ccb-4b85-a33d-6c4248256127.png)


`点数` という変数に 85 の値を設定しています。
判定は `true` にあたるので **`合格`** が値に表示されます。

では、点数の値を60に変更してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/bd1d37bc-383b-4792-9843-ab70273fcb4c.png)

判定は `false` になるので **`不合格`** が表示されました。

ちなみにこのテキストラベルで Set関数 を使用するとどうなるか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/9f0cc6d8-103d-44cf-8058-150f2524b277.png)

エラーになりました。
このように非動作プロパティでは Set関数 や UpdateContext関数 のような
動作プロパティは設定することができませんが With関数 では非動作プロパティでも
設定を行うことが可能なので非常に利便性が高いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/d06498d2-13ff-4f25-b27b-394064a88eb7.png)


**レコードを格納してみる**
以下のような `社員名簿テーブル` があります。
ユーザーの名前が `田中 太郎` だと仮定して、アプリを開いた時に
自身の情報がテキストラベルに表示されるように設定してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/097ad3e8-6d77-42ce-a2a9-13e040a48f1d.png)

以下のように内容がほぼ同じ LookUp関数 を2回使用してデータを呼び出しています。
この LookUp関数 で引っ張ってくるレコードを With関数 で一時的に保存してみましょう。

【With関数を使わない場合】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/1b7d3090-ffa9-42c9-a7cf-d61c5ee7c461.png)

【With関数を使った場合】

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/2f0b7857-8803-41e6-a8b1-75751dec9f9a.png)


```ruby:ユーザー情報(レコード)を一時変数に格納
With(
    {
        ユーザー情報: LookUp(
            社員名簿テーブル,
            フルネーム = Userinf
        )
    },
    ユーザー情報.フルネーム & "：" & ユーザー情報.部署
)
```

**`ユーザー情報`** という変数名に LookUp関数 で呼び出したレコードを一時格納します。
二つ目の引数の式で **`ユーザー情報`** という変数(レコード)を使用してフルネームと部署名を表示させることができました。
この関数を使用することでデータを呼び出す回数を1回に減らすことができました。

今回の例は簡易的な表示なので、そこまでデータ接続の時間に影響することはありませんが、このデータの呼び出す量が膨大になればなるほど時間の短縮を行うことが可能です。

**ボタンの OnSelect に設定してみる**
With関数 はネスト(入れ子)が可能なのでボタンを押した時に Set関数 に変数を設定する関数を記入してみましょう。
先ほどテキストラベルに表示させていた `ユーザー情報.フルネーム & "：" & ユーザー情報.部署` 
をそのまま Set関数 に入れて変数に置き換えてみましょう。

```ruby:OnSelect (一時取得で格納したデータをグローバル変数に格納)
Set(
    FullName,
    With(
        {
            ユーザー情報: LookUp(
                社員名簿テーブル,
                フルネーム = Userinf
            )
        },
        ユーザー情報.フルネーム & "：" & ユーザー情報.部署
    )
)
```

【OnSelect 実行結果】
`FullName` というグローバル変数に With関数で取得したデータを使用して値を表示させることができました。
このように With関数 他の関数とあわせてネストすることが可能です。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/f97db365-3834-4865-80a8-bb1b08c5767c.png)




## With関数のメリット
:bulb: **コードがスッキリと読みやすくなる**
　➡ 一時変数を定義できるため、繰り返し使う計算やデータ参照を整理できる。

:bulb: **アプリのパフォーマンスが向上する**
　➡ 関数の中だけで有効なため、不要なデータ取得を防げる。
　➡ データソースへのアクセス回数を減らせる ので、動作が速くなる。

:bulb: **余計な変数を増やさなくて済む**
　➡ Set関数 や UpdateContext関数 とは異なり、With関数 の変数は一時的なものなので
　 　他の画面や関数に影響を与えない。

## With関数のデメリット
:zap: **変数を使用できる箇所が限定される**
　➡ With関数 はその関数の中でしか使えないため、画面をまたいで使いたい場合には
　　 Set関数 や UpdateContext関数 の方が適している。

:zap: **データの保存は一時的**
　➡ 一時的な計算やデータ取得には向いているが、データの保存や更新には向いていない。

:zap: **ネストしすぎると可読性が下がる**
　➡ With関数 はネスト(入れ子)が可能ですが、あまりにもネストしすぎると
　　 逆にコードが読みづらくなり可読性が下がってしまうため注意しましょう。

## まとめ
With関数は適切に使えばコードをシンプルにし、パフォーマンスを向上させる強力なツールです！
使い慣れるまではネストの方法だったりと大変かもしれませんが、一度覚えてしまうと強力な味方になります！
ぜひ活用してみてください:clap::clap: