はじめに
2021年2月18日日の発表でカスタム関数の作成機能をプレビューでの公開を開始した。といった旨の記事が公開されました。
この発表によると、これまでは、 OnSelect
のイベントのみ実行可能でしたが、今回のアップデートで OnChange
イベントを実行できるようになったと記載されています。
例えば、クエリや関数を作成して、それにパラメータを渡すことで内部で計算させて結果を出力させるという関数のようなものを独自に作成できるようになったようですね。
とはいえなにやら制限はあるっぽい?ですが私の英語力と知識が足りないので、なにを伝えたいのかよくわからないですね。。。
such as output properties must be pure without side effects
"出力プロパティは副作用のない純粋なものでなければならない"
と直訳するとなるのですかね?どういうことだ??
なおこの機能はPreview 機能のため、今後更に機能追加が行われていく一方これまで使えていた機能が使えなくなる。仕様変更が行われる。などの可能性があるためご注意ください。
カスタム関数を作成できるようにする
カスタム関数の作成機能は現段階ではPreview 機能なため、設定により対象機能を有効化してあげる必要があります。
ファイル > 設定 > 詳細設定 > 実験的な機能 より、"拡張コンポーネントのプロパティ"を"オン"にします。
これでカスタム関数作成の準備ができました!
カスタム関数を作成してみる
今回は Enhanced component properties に記載されている例に倣ってカスタム関数を作成していこうと思います。
動作プロパティ
"コンポーネント"より、"新しいコンポーネント"を選択して、コンポーネントを作成します。
記事のように、"日付の選択"と"ラベル"を2つずつ作成します。
これから作成するカスタム関数では、"日付の選択が変更されると、通知を行う"といったものを作成するようです。
"Component1"を選択して、"新しいカスタム プロパティ"より、カスタムプロパティを定義します。
今回設定した項目は以下項目です。
表示名:OnChange
説明:Notify when User Change DataPicker
プロパティの型:動作
設定したら、"作成"を行います。
先ほど作成した"日付の選択"を2つ選択し、 OnChange
にて以下のように設定します。
OnChange
Component1.OnChange()
ここで記載した、 OnChange()
は先ほどカスタムプロパティで設定した名前となります。
では実際に作成したカスタム関数の動作確認を行ってみましょう。
画面に戻り、"カスタム"より先ほど作成した Component1
を追加します。
追加した Component1
の OnChange
プロパティに Notify()
関数を設定します。
Component1_1.OnChange
Notify("You have changed date.")
それでは日付を変更してみましょう。
日付を変更してみると、先ほど設定した通知が画面上部に表示されたかと思います。
Great! Easy so far.
すごい!今のところ簡単だそうです。
プロパティパラメータ
続いて OnChange
の際にパラメータを渡してみます。
先ほど作成したコンポーネントに戻り、カスタムプロパティの編集画面を表示します。
先ほど作成したカスタムプロパティの右側(画像だと"テキスト")を選択すると表示できます。
"新しいパラメーター"を選択して、カスタム関数にパラメータ(引数)を定義します。
今回設定した項目は以下項目です。
パラメータ名:Begin
説明:a parameter
データ型:日時
作成を行うと、作成したパラメータが追加されます。
同様の手順でパラメータ名:End のパラメータも作成しましょう。
保存を行ったら、"日付の選択"を2つ選択して OnChange
プロパティを編集して、呼び出している OnChange
関数に先ほど作成したパラメータを渡すように設定します。
OnChange
Component1.OnChange(DatePicker1.SelectedDate, DatePicker1_1.SelectedDate)
画面に戻り、作成したパラメータを通知で表示するように設定します。
Component1_1.OnChange
Notify("You have changed date. Begin is " & Begin & ", End is " & End)
先ほど、 Component1_1
の OnChange
に設定したはずの関数が消えているかと思いますが、これはバグで修正予定だそうです。
Note that because we added the parameters to the event, the formula’s value in the app will have returned to its default and our earlier customization will have been lost. This is a bug that we will fix soon (sorry, we’re still experimental).
設定を行い、実際に動作させてみると、選択した日付が表示されたかと思います。
純粋関数
最後に、入力プロパティと出力プロパティを利用してみます。
Power Apps ではExcel のRANDBETWEEN 関数 という、指定された範囲内の整数の乱数を返すような関数は提供されていません。
今回はこのRANDBETWEEN 関数をカスタム関数で作成してみます。
新規で MathUtils
というコンポーネントを作成して、 RandBetween
というカスタムプロパティを定義します。
今回設定した項目は以下項目です。
表示名:RandBetween
説明:RandBetween
プロパティの型:出力
データ型:数値
続いてパラメータを2つ作成します。
作成するパラメータは数値型の Bottom
と Top
です。
これらは必須パラメータとしたいので、"必須"にチェックを入れます。
MathUtils
を選択し、設定項目を確認してみると、先ほど作成したカスタム関数を確認することができます。
RandBetween
に以下式を記載します。
MathUtils.RandBetween
If( Top >= Bottom, Round(Rand() * (Top - Bottom) + Bottom, 0), Blank() )
簡単に式の解説を記載しておきます。
まず、前提として作成する乱数の範囲は 最大値 >= 最小値
となっている必要があるので Top >= Bottom
で判定を行っています。
Round 関数 は、簡単にいうと指定した桁数になるように四捨五入を行う関数です。
Rand 関数 は、0 以上 1 未満の疑似乱数を返す関数です。
Rand() * X
とすると、0~X までの値が返ってくることになりますね。
このX が最大値である Top
です。
また、最低値は0ではなく Bottom
で設定された値としたいです。
なので Bottom
の数値を加算するわけですが、これでは Top + Bottom
の数値が最大返ってきます。
これでは想定通りの動作にならないので、 Top - Bottom
を行っているというわけです。
以上でカスタム関数の作成は完了したので、画面に追加してカスタム関数の動作確認を行ってみます。
画面に先ほど作成した、 MathUtils
コンポーネントを追加し、 Bottom
と Top
を設定するためのスライダー、 RandBetween
関数の出力結果を表示するためのラベル、また、それらがなにを表すのかを記載したラベルを追加します。
RandBetween
関数の出力結果を表示するためのラベルには以下のように設定し、 RandBetween
関数を呼び出すようにします。
Text
MathUtils_1.RandBetween(Slider1.Value, Slider1_1.Value)
スライダーの値を変更してみると、Bottom ~ Top までの間でランダムな数値が返されることが確認できるかと思います。
おわりに
発表されたブログの日本語訳と簡単な解説の補足だけになってしまいましたが、以上でカスタム関数の作成の紹介は終わりです。
これを利用すれば、よく使うような式を関数化して使いまわすようにしたり、開発を行う際に関数作成チームと画面作成チームという所謂フロントとエンドに分かれての開発が可能になってくるかもですね。
ただ、ブログでも記載されている通り、いくつか問題があるようです。
- RandBetween is a pure function – it does its work based purely on its input parameters. It can’t read state in the app, such as global variables or data sources.
- RandBetween is a data flow property. It cannot change state within the component or the app.
- The component had to be instanced. It is a UX component that has to be placed on the screen, where in fact MathUtils has no UI at all. It would be better if RandBetween was simply a function in a MathUtils namespace and not object oriented.
- RandBetween は純粋な関数です。 グローバル変数やデータソースなど、アプリ内の状態を読み取ることはできません。
- RandBetween はデータフローのプロパティです。 コンポーネントやアプリ内の状態を変更することはできません。
- コンポーネントがインスタンス化されている必要があります。 これは画面上に配置しなければならないUXコンポーネントであり、実際にはMathUtils にはUI が全くありません。 RandBetween は、オブジェクト指向ではなく、単にMathUtils の名前空間にある関数であれば良いと思います。
We are actively working to build on this foundation, to make this all cleaner, and address the limitations.
私たちは、この基盤上に構築を行い、これをすべてクリーンにして、制限に対処するために積極的に取り組んでいます。
もし利用していく中で、意見などがありましたら、Power Apps community forum で投げてみましょう。