【Power Apps】名前付き計算式(App.Formulas)とコンポーネント

Power Appsでロジックのカプセル化を行うことができる機能である、名前付き計算式とコンポーネントについて解説します。

ロジックのカプセル化で保守性とコードの可読性を向上させましょう。

登壇資料1：[Power Appsの変数・コンポーネント (気ままに勉強会 #83)](https://www.docswell.com/s/pplog/5Q864V-variablecomponent)
登壇資料2：[App.OnStartとApp.Formulasの使い分け (ビリビリ☆Power Apps 同好会 登壇大会＃1)](https://www.docswell.com/s/pplog/Z24XLV-onstartvsformulasbiribiri)

## 変数・コントロールの出力値との使い分け

[以前書いた記事](https://powerplatformnikki.com/variabletypes/)で作成した表の再掲です。
それぞれのスコープや用途を理解して使い分けましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/c05e0988-ef4a-c9c0-8d08-9e44b93e79d8.png)

## コンポーネントと名前付き計算式の使い分け
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/033f4358-fe90-dd77-7f69-7d5513a83769.png)

### アプリ個別でロジックをカプセル化したい場合は名前付き計算式
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/2faf58c8-ee6e-9012-ac12-7c6de716fb56.png)

(イメージ)右下の黒丸のようにアプリ個別の複雑な要件には名前付き計算式

アプリ個別の特殊な要件やデータソースに依存しているようなロジックのカプセル化には名前付き計算式が向いています。

逆に組織単位で共通部品として持っておくべきような汎用的なロジックは、管理のしやすさという面でもコンポーネントの方が向いています。

### コントロール単位で再利用したい場合はコンポーネント

名前付き計算式はロジックのみでコントロールなどの画面要素を持ちません。

そのためコントロールのまとまりとして再利用が必要な(カプセル化したい)場合はコンポーネントを利用します。

### データ型

入力・出力で扱えるデータ型が異なりますが、現時点ではコンポーネントの方が使えるデータ型が多いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/cee509da-826e-cc9a-7a5c-3de9838970a0.png)
ユーザー定義関数

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/046f4950-6e49-e50b-2add-83faab344f6c.png)
コンポーネント(入力)

## ロジックのカプセル化を行う機能のうち、引数ありは現時点(2024/5/6)では試験段階の機能

現時点では引数ありの名前付き計算式(=ユーザー定義関数)・コンポーネントどちらの機能も引数ありの関数作成機能が試験段階の機能であるためご注意ください。

### 拡張コンポーネントの有効化手順

有効化したいアプリの設定をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/593c3786-b7c6-ec0c-34ab-f52adbb33d3a.png)

近日公開の機能を選択して、拡張コンポーネントのプロパティをオンにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/da5533eb-7678-d5c5-2a77-e45591f0f2c4.png)

### ユーザー定義関数(UDF)の有効化手順

ユーザー定義関数は以下の手順で有効化します。

まずは新しい分析エンジンを有効化します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/b65a3b44-86d4-dabd-e811-7ac74f1e5650.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/41a2175a-3b70-11df-b2ca-b7b0405d41e3.png)

その後ユーザー定義関数を有効にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/d09109ab-c7cd-8330-f363-79db35e1d5c6.png)

## 名前付き計算式(App.Formulas)　

Appオブジェクトにあるアプリ全体で再利用できる式を定義できるプロパティです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/68d5098e-3aee-15ae-5cf3-9fba7ec1a283.png)

こちらは変数ではなく数式(関数)なので、使用するたびに最新化されます。そのため、値に要求される情報鮮度によって変数とFormulasを使い分ける必要があります。

その他の変数同様定義や用途を変数タブから確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/e242d2f4-80b0-2ac7-408d-2f1f187013c2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/01731f60-7070-2656-edc5-f7b039442df9.png)
一時的に値を確認するときはボタンのOnSelectが便利です。
また、現在の値をApp.Formulasプロパティではプレビューで確認することはできません。

### App.OnStartで定義していた定数の代替
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/3f391c4f-bd63-cf14-a94f-3213018c54b0.png)

名前付き計算式はApp.OnStartで定義していた定数の代替手段としての利用が推奨されていますが、グローバル変数と違い動的(常に値が最新)であるため完全な代替手段にはなりません。

App.OnStartは廃止予定みたいですが、以下の記事で検証したところデータソースを都度参照するような定数はApp.OnStartで宣言した方がパフォーマンスよさそうです。

https://powerplatformnikki.com/formulasvsonstart

### 複数の箇所で利用したり、複雑な数式は名前付き計算式を使用する

コントロールの出力値とは複数の箇所で利用したり、複雑な数式であるかで使い分けるといいと思います。

複数箇所での利用という観点では、他画面のコントロールを参照するとパフォーマンスが落ちる場合があります。ケースにもよりますが、ユーザー定義関数の使用を検討しましょう。

[ヒントとベスト プラクティスを使用して、キャンバス アプリのパフォーマンスを向上させる - Power Apps | Microsoft Learn](https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/performance-tips#%E7%94%BB%E9%9D%A2%E9%96%93%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%AB%E4%BE%9D%E5%AD%98%E3%82%92%E5%9B%9E%E9%81%BF%E3%81%99%E3%82%8B)

また複雑な数式という観点では、名前付き計算式に複雑な数式を書いておいてそれを参照することで、数式の可読性が向上します。

### (プレビュー機能) ユーザー定義関数(UDF)

前述の通り現時点(2024/5/6)では試験段階の機能となっています。

通常Formulasでは一行目のように引数なしの数式しか作成できませんが、この機能を有効化することで二行目のように入力と出力をもつ関数を作成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/f91c2edb-2295-1180-b322-183cc43a900e.png)
引数なし(GA済み)と引数あり(試験段階)の数式は共存可

関数を作成するための構文は以下。通常のFormulasと同様文末の;を忘れないようにしましょう。

```
<関数名>(<引数名>:<引数の型>):<関数の型> = <数式>;
IsWeekDay(date:Date):Boolean = Not(Weekday(date) in [1, 7]);
```

引数ありの数式を作成できるようになることで、コントロールの出力値を入力することなどが可能になるためより汎用性の高い数式が作成できるようになります。

```
If(
    IsWeekDay(DatePickerCanvas1.SelectedDate),
    "平日です",
    "休日です"
)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/c66a6774-e299-8e56-df92-1d81fae221d9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/0a0173c0-e0af-c062-642e-d490ac4d31db.png)

## コンポーネント

コンポーネントについては以下の記事をご覧ください。

https://powerplatformnikki.com/componentproperties

## 参考・元記事

https://koruneko.hatenablog.com/entry/2024/01/22/075820#google_vignette

https://koruneko.hatenablog.com/entry/2024/02/07/021145

https://powerplatformnikki.com/udfcomponent/