【PowerApps Tip's】開発言語経験者の多くが陥る最初の罠と回避方法

Power Apps へ初めてアプローチした時、罠にかかったような気持ちになった経験をされた方いませんか？
C#やJavaなどの他開発言語でアプリを作成した経験があると陥りやすい”罠”があるんですよ。プログラミングに自信があればあるほど、ハマりやすい罠かもしれません。今回は、その罠の正体と回避方法について解説してみたいと思います。
あるいは、ボタンクリックでイベントを発生させるようにアーキテクチャーを組みなおす手引き、としても案内できるかもしれません。何を言っているか？は最後まで読んでいただければ伝わるかと思います。

# はじめに
SharePoint Online のリストから自動生成するアプリを使って説明していきます。この自動生成されるアプリ、かなりナレッジ詰まってるので動作とロジックを解析してみると勉強になりますよ。
## 説明に利用するデータソースとアプリ
SharePoint Online のサイトに、以下のようなカスタムリストを作成しておきました。
![01-List.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/bcf51ab7-444e-94bf-b2c8-0f1e5f556db3.png)
タイトルと、通貨の列があるだけのリストです。そのカスタムリスト画面から[Power Apps] → [アプリの作成] を利用して Power Apps のアプリを自動生成しています。
![02-MakeApps.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/3f92d5b0-1b62-2eab-ab82-1d2a48f266f1.png)

【参考URL】[Powe rApps で SharePoint リストからキャンバス アプリを作成する](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/app-from-sharepoint)

# 他開発言語経験者が陥りがちな罠
前述の手順で準備したような、SharePoint Online のカスタムリストから生成した Power Apps のアプリについて、アクションが発生する箇所（例えば、画面遷移する、リロードする等）を１つずつ解析したことある方、どれぐらい存在するんでしょうかね？
自動生成される画面の1枚目（1つ目のScreen）ですが、Power Apps の実装経験がない方がみたら、下記イメージのように思うんではないかな、と考えています。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/5ae82694-15f2-0885-e874-03f69bccdad4.png)

1. 「検索アイテム」のテキストボックスへ文字列を入力させて
2. 虫眼鏡アイコンをクリックしたら上記No.1の文字列を利用して検索クエリを生成
3. 検索クエリの発行結果をもとに、一覧であるギャラリーを更新

C#やJava等で開発を経験したことがある方であれば、上記のような発想を自然とするかと思います。
はい、残念。その発想では、Powe rApps のアプリは動きません。しかも、上記のようなロジックを記載してもエラーになりません。エラーにはならないのですが、動作しません。期待した動作をしない、と言ったほうが正確でしょうか。

![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/6d2dbdd0-d5c7-fd19-0d76-3780c449832a.png)

Power Apps はC#やJava等の開発言語で実装するアプリとは「方向が逆」で考える必要があるのです。

# Power Apps における考え方
「方向が逆」とは？いったいどういうコトでしょうか？

まず、虫眼鏡アイコンの[OnSelect]イベントを確認してください。検索クエリなどは見当たらないと思います。そもそも、このアプリは検索ボックスに文字列を入力した瞬間にギャラリーで検索が実行されます。

つまり、ギャラリー側に秘密がありそうですよね？

説明用に準備したアプリのギャラリーコントロール、その[Items]プロパティを確認してみましょう。なお[Items]プロパティは、ギャラリーに表示されるべき要素を指定する場所になります。何やら関数がズラズラと書かれています。

![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/93b81bab-6d8f-87e6-0b4c-a800fcc64c0f.png)

``` BrowseGallery.Items
SortByColumns(
    Filter(
        List01,
        StartsWith(
            Title,
            TextSearchBox1_1.Text
        )
    ),
    "Title",
    If(
        SortDescending1,
        Descending,
        Ascending
    )
)
```
Filter関数と、StartsWith関数を利用してList01から検索を実施していますね。さらに、その外側でソート処理が記載されています。このように、Power Appsは**「効果を得たい側から、効果を与える側を参照する」**仕組みで考える必要があります。

【参考URL】
　[Power Apps の Filter、Search、および LookUp 関数](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/functions/function-filter-lookup)
　[Power Apps の EndsWith 関数と StartsWith 関数](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/functions/function-startswith)

「効果を与える側から処理をする」のではないのです。これが『方向が逆』の理由です。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/04a838ac-bdc0-f7f4-91ff-a7734d429777.png)

Power Apps でコントロールの連動や、何かの操作結果をもとに画面の項目を変更するなどの対象を実施する際は、基本的に大きく2つの手段があります。
1つ目は前述どおり「効果を与える側を参照する」方法。
2つ目は「変数を利用する」方法になります。

# 変数を利用した方法／虫眼鏡アイコン押下で検索
「変数を利用する」方法の例として、今のアプリを「虫眼鏡アイコンを押下したら検索する」という仕様に改造してみたいと思います。

1. 虫眼鏡アイコン押下時に検索用文字列を変数へ格納
虫眼鏡アイコンを選択 → [OnSelect]アクションを下記へ変更。

    ```SearchIcon.OnSelect
UpdateContext({SearchText: TextSearchBox1_1.Text})
    ```
これで、虫眼鏡アイコンを押下した際に”SearchText”変数へ検索用文字列が格納されるようになりました。
![07-変数経由.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/27c6a13b-7c75-a44c-700b-ded4ff7e5d46.png)
2. ギャラリーの検索処理
続けて、検索用文字列を格納した変数でギャラリーコントロールのItemsを検索するよう改造します。
今まで検索用テキストボックスを参照していた箇所を、先ほどの変数に置き換えればよいです。しかし、それだけではチョッと利用者に優しくない。なので、変数に何も入ってない場合（＝Blank）の際は、全てのデータを表示するようにしています。
ここらへんは下記の処理を改造してみるとわかると思いますので、是非手を動かして検証してみてください。

``` BrowseGallery.Items
SortByColumns(
    If(
        IsBlank(SearchText),
        List01,
        Filter(
            List01,
            StartsWith(
                Title,
                SearchText //TextSearchBox1.Text
            )
        )
    ),
    "Title",
    If(
        SortDescending1,
        Descending,
        Ascending
    )
)
```

![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/c83a09a6-c19c-28ee-fe3d-fb10a93de3d3.png)

## 変数を利用した場合の動作イメージ
実際の動作イメージは以下のようになります。虫眼鏡アイコン画像をクリックするまで検索が発動しなくなっていますね。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/PowerApps?src=hash&amp;ref_src=twsrc%5Etfw">#PowerApps</a> SPO自動生成アプリを少し改造する。 <a href="https://t.co/zcmfNdEFPB">pic.twitter.com/zcmfNdEFPB</a></p>&mdash; やま (@yamad365) <a href="https://twitter.com/yamad365/status/1150362983677059073?ref_src=twsrc%5Etfw">2019年7月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 「リアクティブ」
解説したような『値の関係性を記述してプログラミングする』ことを**『リアクティブ』**と呼称するそうです。もし、この説明を実施される際は「リアクティブって言うんだけども～」という感じでドヤ顔しましょうｗ
[@saikou9901](https://twitter.com/saikou9901) さん、ご教示ありがとうございます！！

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">そうそう。こういうのをカッコイイ単語で「リアクティブ」っていうんですよね。<br>そして、リアクティブの代表がExcel。 <a href="https://t.co/R5U7ZrJS5J">https://t.co/R5U7ZrJS5J</a></p>&mdash; Koji Saiki (@saikou9901) <a href="https://twitter.com/saikou9901/status/1149338516540706817?ref_src=twsrc%5Etfw">2019年7月11日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# まとめ
- PoweApps は 従来の開発言語と効果を得る方向が逆
- **「効果を得たい側から、効果を与える側を参照する」**仕組みで考える必要がある
    - 方法１：効果を与えるコントロールを、効果を得たい側から参照する
    - 方法２：変数を利用して実現する
- Power Apps の実装方式はカッコよく言うと「リアクティブ」

当方もいまだにハマるコトがあります。Power Apps 初めて触る方に、必ず説明する内容なんですけどね(;^ω^)
それほどまでに簡単にハマっちゃう罠ですので、皆様もお気をつけください。もし、実行したけど期待した動作をしていない場合「処理の向き」にも気を付けてみると改善が得られるかもしれませんね。

それでは、皆さま。素晴らしい Power Platform Life を！