はじめに
Power Apps では、何かの予約をする業務を効率化するアプリを作成することが可能です。
以下は備品の予約の例ですが、まず、データソースとして、備品および備品の予約をする SharePoint リストを作成します。
そして、上記データソースをベースに、備品の予約をするアプリを作成します。
このようなアプリを作成する際、予約が重複しないようにしたいといった相談をいただくことがあります。
例えば、複数の人が同じ時間帯にアプリを開いており、予約したい時間帯について予約がないと判断して予約したものの、実はアプリを開いている間に他の人が予約をした際にダブルブッキングになってしまうという懸念があります。
簡単な対策として、例えば、予約のデータを定期的に Refresh して最新のデータを参照出来るようにすることが考えられますが、あまり頻繁にやりすぎるとちょっと効率が悪いため、別のアプローチが必要と考えます。
そのため、今回は、そのような要件に対するアプローチについて紹介いたします。
Power Apps のみで実装する場合
Power Apps で実装する場合は、送信 (つまり予約) ボタンを押した際に、その備品、期間で予約データがないか最終確認し、データが無ければ予約をするといった処理にします。
以下、処理の例です。予約したい日時の開始と終了と既存のデータの開始と終了を比較し、条件に一致する (予約が重複する) データを取得します。取得結果が空の場合は重複する予約がないと判断しています。データを登録する部分は割愛しています。
いつも思いますが、日時の比較部分が少し複雑ですね。私もいつも悩みます笑。
If(
IsBlank(
LookUp(
EquipmentReservations,
EquipmentID = Value(EquipmentID_DataCard1.Update) && StartDateTime_DataCard1.Update < EndDateTime && EndDateTime_DataCard1.Update > StartDateTime
)
),
Notify(
"予約可能です。",
NotificationType.Success
);
SubmitForm(frmReservationDatails),
Notify(
"予約できません。",
NotificationType.Error
)
);
テストしてみます。10 時から 17 時まで既存の予約があります。以下のような結果となる想定です。
9 時から 10 時のため、連続していますが予約は可能です。
9 時から 11 時のため、終了が 10 時過ぎているため予約出来ません。
開始も終了も 10 時から 17 時の間のため予約出来ません。
開始が 17 時より前のため予約出来ません。
開始が 17 時からのため、連続していますが予約可能です。
上手く動作しているようです。こちらの方法により、予約前に最終チェックすることで、基本的には、よほどのことがなければ、予約の重複は回避できると思います。
※強いて言えば、最終チェックして、予約をするまでの数ミリ秒以下の間に別の人が予約した場合、予約が重複する可能性がありますが、可能性は極めて低いと考えます。
Power Automate で実装する場合
同じようなことを Power Apps から Power Automate をキックして実現します。
ポイントは、以下のように、コンカレンシー制御をオンにして 1 にします。これにより、仮に他の人がほぼ同時に予約をしても、順番にフローが実行されるため、予約処理の排他制御が出来ます。
基本的には上述の Power Apps 側の実装でも問題ないとは思いますが、こちらの方がより厳密に予約の重複を防ぐことが可能です。
試しに以下のようなアプリ、フローを作成してみます。
複数のユーザーでフローを実行してみます。片方は実行中、片方は待ちとなっています。期待通りです。
それでは、こちらの設定を行った上で、Power Apps と同様に、予約しようとしている時間帯にデータが存在するか判断し、Power Apps に予約可否の応答をします。
こちら複雑ですが、以下のような感じになると思います。SharePoint 上に予約しようとしている時間帯と重複する予約があればデータを返すようフィルターをします。
(EquipmentID eq @{int(triggerBody()['text_2'])}) and ('@{triggerBody()['text_3']}' lt EndDateTime) and ('@{triggerBody()['text_4']}' gt StartDateTime)
取得したデータの件数が 0 件の場合、つまり重複する予約がない場合に予約をするようにして Power Apps に応答を返します。
取得したデータの件数は、length
関数の結果を元に判断します。
length(outputs('複数の項目の取得')?['body/value'])
上記 Power Automate のフローを呼ぶ Power Apps 側の処理のイメージは以下のような感じです。
Set(
gblReturn,
備品予約テストフロー.Run(
Title_DataCard1.Update,
Description_DataCard1.Update,
EquipmentID_DataCard1.Update,
Text(
DateAdd(
StartDateTime_DataCard1.Update,
TimeZoneOffset(),
TimeUnit.Minutes
),
"yyyy-mm-ddThh:mm:ssZ"
),
Text(
DateAdd(
EndDateTime_DataCard1.Update,
TimeZoneOffset(),
TimeUnit.Minutes
),
"yyyy-mm-ddThh:mm:ssZ"
)
)
);
If(
gblReturn.予約結果 = "0",
Notify(
"予約成功です。",
NotificationType.Success
),
Notify(
"重複する予約があるため予約できませんでした。",
NotificationType.Error
)
);
全部のパターンは書きませんが、Power Apps のときと同じテスト結果になりました。
まとめ
今回は、Power Apps で予約系アプリを作成する際の重複排除についてアプローチを紹介しました。
予約系のアプリを作成したいといった相談をいただくことは多いため、参考にしていただけると幸いです。