PowerAppsでボタンをselectで呼び出して関数みたいに使おうとしたら痛い目にあった

# はじめに
PowerAppsでは自分で作成した関数が使えません。（自分で定義した関数、と言った方が良いのか。。。）
なので、ボタンに処理をぶち込んで、他のコントロールからselectで呼び出そうとしたら想定と違う動作をした。
ので、ごく単純な処理で再現してみたら、やっぱりできませんでした。
というメモです。

# 更新（2020/5/28）
こういうことでした。

> Select は、後の処理のために対象の OnSelect をキューに入れます。この動作は現在の式の評価が完了した後で行われる場合があります。 Select によって OnSelect がすぐに評価されたり、Select が OnSelect の評価の完了まで待機したりすることはありません。

**[Power Apps の Select 関数](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/functions/function-select)**

# そもそも
Selectでボタン動作を呼び出そうとしても、別の画面のコントロールのOnSelectは呼び出せない。
なので、引数の代わりにグローバル変数にSetしてから、別の画面に `visible=false` にしたボタンをSelectで呼び出す、みたいなことは、そもそもできません。
イマイチつかいにくいです。

> 画面をまたいで Select を使用することはできません。

出典：**[Select 関数](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/functions/function-select)** (MS 数式のリファレンスより)

# 検証
こんな画面を準備
[![Screenshot from Gyazo](https://gyazo.com/266a6b0af703d88a95dca4d774a5f943/raw)](https://gyazo.com/266a6b0af703d88a95dca4d774a5f943)

## 疑似OnVisibleボタン
ここは、本来、画面表示に初期化する想定の処理を入れています。
（`strCheck` という文字列を初期化しています。）

```:疑似OnVisible.Onselect
UpdateContext({strCheck:""})
```

## 関数処理ボタン
この画面で複数回呼び出されるような、共通の処理を関数的に使おうとしている処理の内容です。
（わかりやすいように、単純に文字列への代入としています）

```:関数処理.OnSelect
UpdateContext({strCheck:"Function"})
```

## 関数呼び出しボタン
上記の関数を呼び出した後、別の処理をしようとしています。
想定する動作としては、Selectで関数処理を呼び出した **後に** 別の処理が実施される。ということです。
（わかりやすいように、関数処理の **後に** 同じ変数へ別の値を代入しています。上書きされることを想定しています。）

```:関数呼び出し.OnSelect
Select(関数処理)
;UpdateContext({strCheck:"NextProcedure"})
```

## 処理をベタ書きボタン
比較のために、関数処理で行われる処理を、Selectによる呼び出しでなく、直接書き込んでいます。
（フツーの考え方だと、こうしたくないから「共通的な処理を関数化して呼び出す」ですよね）

```:処理をベタ書き.OnSelect
UpdateContext({strCheck:"Function"})
;UpdateContext({strCheck:"NextProcedure"})
```

確認用のラベルには、各ボタンで代入されたであろう文字列のコンテキスト変数 `strCheck` を表示させています。

```:ラベル.Text
strCheck
```

# 想定する動作

「関数呼び出し」ボタンが押されても、「処理をベタ書き」ボタンが押されても、同じ処理になってくれる。と思うじゃないですか。

## 関数処理ボタン押下時

<img src="https://i.gyazo.com/f7d588d9fa74ec43d00d4ae0ce169b4a.gif" width=20%>

まぁ、当たり前ですよね。
そのボタンの `OnSelect` に strCheckの代入があるのですから。


## 処理をベタ書きボタン押下時

<img src="https://i.gyazo.com/72488dd74a3aeea84dcdb36aeb0e0c82.gif" width=20%>

これも、想定する動作の通りです。
最初の `UpdateContext` で strCheckに"Function"という文字列が代入され、
その後、 `UpdateContext` で strCheckに"NextProcedure"という文字列が代入されるので、
ラベルには、 "NextProcedure" が表示されるはず。実際にそうなっています。


## 関数呼び出しボタン押下時

<img src="https://i.gyazo.com/23225ee5a8e6820a4f613bac4b1a3246.gif" width=20%>

え？
一瞬、ラベルに "NextProcedure" が表示されたように見えますが、その後、 "Function" という表示になってしまいます。
つまり、Select(関数処理) の処理の **後に** UpdateContext({strCheck:"NextProcedure"}) が処理されるわけではない、ということでした。

そのため、当初の目論見であった、「特定の処理をボタンにぶち込んでSelectで呼び出して関数的に利用する」ができませんでした。

やりたかったこととしては、特定のボタンに対して

1. Selectで関数的に呼び出したボタンでとあるコレクションを生成してから
1. 後続の処理で、そのコレクションに対して、別の処理をさせる

ということをしたかったのですが、先行する処理が完了しないまま、後続の処理が行われてしまい、「そんなコレクションねぇぞ」と怒られてしまいました。


# さいごに
えー、なんで？？？
「数式に出現する順序で実行される」んじゃないみたいです。
Selectが完了してから、次の関数を開始してほしいのに。

ちなみに、リファレンスでは、以下のような説明でした。

>**複数のアクション**
>実行するアクションのリストを作成するには、セミコロンを使用します。 たとえば、コンテキスト変数を更新して前の画面に戻るには、次のように指定します。
>`UpdateContext( { x: 1 } ); Back()`
>アクションは、数式に出現する順序で実行されます。 現在の関数が完了しないと、その次の関数は開始されません。 エラーが発生した場合、後続の関数が開始されない場合があります。

出典：[動作の数式＞複数のアクション](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/working-with-formulas-in-depth#more-than-one-action) (MS 数式のリファレンスより)


# 出典
いつもお世話になっております。
https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/formula-reference