#PowerApps 予定の候補日メーカー V2

2020年3月頃にネタにした [予定の候補日メーカー](https://qiita.com/yamad365/items/ce0fdbbe411dbb26fa00) をバージョンアップしたので 
Microsoft Power Apps Advent Calendar 2022 ＆ 備忘録的なネタとして記録しておく次第。

https://qiita.com/advent-calendar/2022/powerapps

# おことわり
新 Ver をステップバイステップで作成する手順を記載する予定はありません。要点のみ記載となります。

旧 Ver を知りたい方は下記の記事を参照ください。

https://qiita.com/yamad365/items/ce0fdbbe411dbb26fa00

# 動作イメージ
こんな感じです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/PowerApps?src=hash&amp;ref_src=twsrc%5Etfw">#PowerApps</a> 予定の候補日メーカー V2 <a href="https://t.co/k5tupTZ0dY">pic.twitter.com/k5tupTZ0dY</a></p>&mdash; やま (Yama) (@yamad365) <a href="https://twitter.com/yamad365/status/1606078865969131521?ref_src=twsrc%5Etfw">December 23, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 追加された機能
下記の機能を追加しました。

    1. 選択済みの候補日から特定の行を削除可能にした
    2. 選択済みの候補日を常に昇順でソート
    3. 全ての候補を自分の予定表へ「仮の予定」で一括登録
    4. 自分の予定表のみ選択

旧Ver だと1カ所間違えても全クリアしないとダメでした。だって、文字列連結してただけだもの（汗
選択する候補を間違えたり、改めて他人の予定をチェックしたら先約があったり、etc・・・候補日を試行錯誤する際に「1行単位で消せると便利だなぁ」と旧Ver を使っていて思ったので、No.1 の機能はいつか盛り込むつもりでした。

この候補日をコピペしてチャットやメールで「この予定なら調整できまっせ」とするのが主目的なので、日付の昇順で並んでいたほうが便利ですよね。旧Ver は選択した順番にしかならなかったので、日付が前後した際に手動で修正が必要でした。なので、No.2 の機能もついでにいれちゃいました。Sort 関数で1発ですし。

No.3 は、ついにやっちまったなぁー！って機能です。やろうと思えば Power Apps から同席者を指定した会議招集も可能なのですが <del>ちょっとめんどくさいなーってなってｗ</del> 自分の予定に登録するのみにしてあります。うっかり間違った候補でカレンダー反映までしてしまっても、自分の予定だけならナントでもなります。候補の日程をチョイス → Teams 等で「この候補で良い？」(内部調整) → さらなる調整後に社外へ打診、という流れは多いです。そんな流れで同席してほしい他メンバー全て OK とは限りませんので「必要十分でヨシッ！」という判断です。

旧Ver を利用しているなかで他人の予定をこのアプリで1回も確認したことがないので「自分の予定だけで十分じゃん」となりました、というのが No.4 です。

# 機能追加ポイント
追加された各機能の要点を下記にします。ちなみに、旧Ver 同様に［新しい画面］の追加から選択できる「カレンダー」のスクリーンを改造して作っています。

![スクリーンショット 2022-12-17 231545.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/dc184095-e6a1-f78b-8e11-25c0082ab367.png)

## 0. 画面構成
標準で提供されているカレンダースクリーンへ、旧Ver と同じような改造を実施しています。異なっているのは下イメージの (1) と (2) の箇所。それに関連して、(1) の上段にある時間の選択ギャラリー OnSelect プロパティの関数。

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/be817960-b3fb-f132-ffdb-97fa95972899.png)

まず、旧Ver は候補日として選択した時間帯を文字列連携していただけでしたが、新Ver ではコレクションに格納しています。日付、開始、終了 のテーブルデータにしたほうが”プロ開発者ぽい”感じなのは理解しております。元ネタの文字列連結を流用してサクッと実現しようと判断した結果、旧Ver のロジックにチョチョっとコレクションへ格納する処理を追加した程度の仕上がりになっていますｗ

```右端上段のギャラリーコントロール.OnSelect
If(
    isSelecting,
    Patch(
        colSelectedDate,
        Last(colSelectedDate),
        {
            Value: Concatenate( SelectedTxt, Substitute( ThisItem.Value, " ～", "" )
            )
        }
    );
    UpdateContext(
        {
            SelectedTxt: Blank(),
            isSelecting: false
        }
    );
    ,
    UpdateContext(
        {
            SelectedTxt: Concatenate(
                SelectedTxt,
                Substitute(
                    Text( _dateSelected, "[$-ja-JP]mm/dd(ddd)" ), "曜日", "" ),
                " ",
                ThisItem.Value
            ),
            isSelecting: true
        }
    );
    Collect(
        colSelectedDate,
        {Value:SelectedTxt, Date: _dateSelected}
    )
)
```

コレクションの Value が候補として表示する文字列（MM/dd HH:mm ～ HH:mm）で、Date がカレンダーで選択した年月日です。単純に実現したいコトをなるべく最短でほしかったので旧Verのロジックをチョチョっと改造です。（← プロ開発者ぽいデータの持ち方だと「年月日、開始時間、終了時間」というテーブルで綺麗な感じになると思います。たぶん。）

中段の(1)ギャラリーコントロールは、上記で生成されるコレクションをアイテムとして表示しているだけです。右端にある(2)のアイコンは予定表へ登録する画面へ遷移します。Collection に1つも値がない場合は非活性にしておけば事故が防げます。

## 1. 選択済みの候補から1行削除する
候補を表示するギャラリーコントロール、右端の(×)アイコンをクリックしたらコレクションから該当アイテムを削除（ [Remove](https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-remove-removeif?WT.mc_id=BA-MVP-5004053#remove-function) ）すれば1行単位で削除できますね。コレをするためだけにコレクションを利用した、と言っても過言ではありません。

なお、ギャラリーコントロールにラベルを置いただけであっても、ドラッグで範囲選択してコピー＆ペーストできます。Edge ではギャラリー内のアイテムに追加しているバツアイコンはスペース（” ”）ぽく処理されます。
※ Edge でのみ試しています。その他ブラウザーは試してない(;^ω^)

![スクリーンショット 2022-12-17 233813.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/1a0be943-ef4e-82e1-9bec-d61dfad018c5.png)

なお、iPhone で試してたら範囲選択してコピーするとアイコンが「項目１」みたいな内容でクリップボードに保持されるぽいです。当方はブラウザーでの利用を目的に作成しているので、全く問題無いと判断。むしろ、間違えても 1行だけ消せる、というメリットのが大きいです。Power Apps でもクリップボードへデータ渡せる関数ができてほしいなぁーってこういう時に思いますね。（でも、すぐに欲しかったのを忘れちゃう汗）

## 2. 選択済みの候補を常に昇順でソート
コレクションの Value で [Sort](https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-sort?WT.mc_id=BA-MVP-5004053) してあげれば OK です。


## 3. 予定表へ「仮の予定」で一括登録
子画面でも実装できますが、同席者も含めた招待へ今後（＝気分がのったら）VerUp するかもしれないな、と思ったので別スクリーンにしました。

![スクリーンショット 2022-12-17 234902.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/d31a9c55-6e9b-aaff-3603-d8bdc47d007c.png)

左側にあるギャラリーコントロールは前画面のコピペですね。アイコンの位置が変わっているのは”うっかり候補を消しちゃった”がないような配置にしているからです。詳しく(？)は下記の記事を参照ください。

https://qiita.com/yamad365/items/7d370bcdf029b8b99593

件名は予定を登録する際に必須にしたいため、何かしら文字列が入って無いと予定反映するボタンをクリックできないようにしてあります。予定反映するボタンに、Exchange の予定表へ反映する処理を書けば完成です。単体の予定を Power Apps から作成する手順は下記の記事を参照ください。

https://qiita.com/yamad365/items/fc8e7f76771570aba660

「Office 365 Outlook」コネクターの「イベントの作成 (V4)」を利用します。

https://learn.microsoft.com/ja-jp/connectors/office365/?WT.mc_id=BA-MVP-5004053#%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90-(v4)

[ForAll](https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-forall?WT.mc_id=BA-MVP-5004053) 関数を利用して、候補日が詰まったコレクションから 1つずつ要素をとりだして、上記のイベント作成アクションを実行すれば OK です。皆さん、是非ここは各自で工夫して頑張ってみてください（つまり、動いている関数を明記する気は無い）。
冒頭で”プロ開発者ぽいデータの持ち方”にしてあると [Split](https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-split?WT.mc_id=BA-MVP-5004053) 使わなくて済むんですけどねー。繰り返しになっちゃいますが、美しいロジックを組むコトよりも「少しでも早く目的を達成する道具が欲しかった」のです。

## 4. 自分の予定に限定する
まず、カレンダーのドロップダウン Default プロパティを”予定表”（自分の予定表）に設定し、DisplayMode を View にしました。これで選択できない状態になります。ただ、この設定だけではカレンダースクリーンで標準搭載されている予定表を取得する処理が発動しません。

Screen の OnVisible プロパティで予定表のドロップダウンを [Select](https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-select?WT.mc_id=BA-MVP-5004053) 関数で強制選択します。
(´ω`)。○○（旧Ver を作った頃は、Select みたいな便利な関数は無かったなぁ…）

https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-select?WT.mc_id=BA-MVP-5004053

これで自分の予定が画面描画時に取得されるようになります。なぜ、その動きになるか？をジックリ解析してみると非常に多くの学びが得られると思いますので、興味がある方は是非チャレンジを！（つまり、ココも詳細を説明する気は以下略）

# 結び
旧Ver でも必要十分な機能だったのです。が、自分で暫く使ってみて「〇〇がｘｘなってると、もっと便利なんじゃない？」と感じてきた箇所を一気に改善してみました。フィードバック＆改善のループですね。独り PDCA を回してみた、ってトコでしょうか。旧Ver を作ってから年単位の時間をおいてから改造しています。時間を長めに置いた結果、旧Ver 作成当時では存在しなかった関数・機能が増えており『昔できなかったコトが今できる！』というのも実感できました。1年以上前に作成した昔のアプリ、時間がある時に見直して再作成や新しい便利な関数や機能で VerUp するのも良さそうですねー。

旧Ver を改造するのではなく、ド新規で再作成してもサクッと欲しいアプリを作れました。昨今、Power Platform 単体では実現が難しい CI/CD 等をプロ開発者とコラボレーションする等々、数年前ではできなかったコトが数多く実現できるようになっています。それは素晴らしいコトだと思いますが、やはり「欲しいアプリ・機能が自分でサクッと作れる」というスピード感や手軽さが本質で重要で Power Platform のステキなポイントだな、と改めて実感しました。自分で試して、自分で欲しいアプリ・仕組みが作れる。ホント、素晴らしい！

それでは、皆さま、素晴らしい Power Platform Life を！
メリークリスマスッ！！🎅