PowerAppsでオフィス内宅配ロッカーを作ろう

Power Appsを使って、オフィス内で荷物をやり取りする宅配ロッカーのような仕組みを作ります。

情報をやり取りする手紙がメールに置き換わっても、小包のような荷物の配送は依然として大量に存在します。郵便局が扱う手紙が減っても荷物の宅配が増加しているのはその一例です。オフィスの中で荷物を配達するのに、宛先の人のデスクに荷物を置いておくというやり方があります。一方で、最近ではフリーアドレスのようにオフィス内に決まった居場所を持たない働き方が増えています。決まった居場所・デスクのない方へ宛てた荷物を受け渡すための仕組みとして、宅配ロッカーのような仕組みを考えてみましょう。

問題の整理

オフィス内で荷物をやり取りするために必要な機能を宅配ロッカーを参考に考えてみましょう。

  • 荷物を一時的に保管できるスペース(ロッカー)がある。
  • 宛先の人物に、荷物が保管スペースへ納品されたことを知らせる。
  • 宛先の人物に、荷物を回収するように催促する。
  • 宛先の人物が荷物を回収したら、その保管スペースに新たな荷物を設置できるようになる。

他にも、世間の宅配ロッカーには宛先の人物以外が荷物を取り出せないといった機能があります。これは不特定多数の利用者がいる場合に必要ですが、小規模なオフィス内では省略しても問題ないと考えます。また、形状もロッカーである必要はなく、テーブルなどモノを置ける場所に区切りや仕切りを施せば十分です。

また、利用ケースとして、外部から届いた荷物を配送する場合だけでなく、同じオフィスで働く従業員間で荷物をやり取りするケースも想定します。

設計

ソフトウェア

  • 各保管スペース(ロッカー)の情報を管理するSharePointのリスト
  • 各保管スペース(ロッカー)の情報を配達員または利用者が書き換えるためのPower Appsアプリ
  • 利用者に納品通知や回収の催促を送るためのPower Automateフロー

ハードウェア

  • 荷物を一時保管するためのスペース
    広めのデスクをテープ
  • 各保管スペース(ロッカー)に対応するPower Appsアプリを呼び出すためのURLを埋め込んだQRコード
  • 利用方法を案内する掲示物

業務のフロー

荷物の預け入れ

配達員は保管スペースに荷物を設置します。また、配達員は保管スペースに掲示されたQRコードをスマートフォンで読み込むことでPower Appsアプリを起動します。
配達員はアプリを通して、荷物の受取人を選択します。このとき配達員から受取人に対して伝言があれば、伝言を記入します。受取人と伝言を記入してアプリから送信すれば、配達員の手続きは完了です。
Power Appsアプリから送信されたデータはSharePointのリストに格納されます。SharePointのリストを監視しているPower Automateのクラウドフローが受取人に対して通知を送ります。通知には、荷物が届いた旨、どの保管スペースに荷物があるかの情報、配達員が誰かの情報、配達員からの伝言が記載されます。

荷物の受け取り

受取人は保管スペースで荷物を回収します。また、受取人は保管スペースに掲示されたQRコードをスマートフォンで読み込むことでPower Appsアプリを起動します。
受取人はアプリを通して、荷物を回収したことを送信します。
Power Appsアプリから送信されたデータはSharePointのリストに格納されます。SharePointのリストを監視しているPower Automateのクラウドフローが受取人に対して通知を送ります。通知には、荷物を回収したことを確認する旨が記載されます。

荷物回収の催促連絡

未回収の荷物がある場合、カレンダーベースのPower Automateで当該荷物の受取人に通知を送ります。特定の日数(1週間など)を超えて放置されている場合、配達員にも通知を送ります。荷物の放置が通知された場合、配達員は受取人の所属グループ同僚や上司に対して荷物の回収を催促します。


作り方

各保管スペース(ロッカー)の情報を管理するSharePointのリスト

荷物のやり取りに必要な情報を一元的に管理します。

どのロッカー(保管場所)を操作するかをID列で指定します。

列名列名(内部)列の型目的
タイトルTitle一行テキスト人の目で見てわかりやすい各保管スペース(ロッカー)の名前を示します。
SharePointのリストで自動生成されるタイトル列を使用します。
IDID数値各保管スペース(ロッカー)と紐づけます。
SharePointのリストで自動生成されるID列を使用します。
受取人Receiver個人荷物の宛先(受取人)をユーザーで指定します。
荷物ありhasItemはい/いいえ荷物が設置されているか否かを示します。荷物がある場合は「はい」、荷物がない場合は「いいえ」です。
配達人PostedBy個人荷物を各保管スペースに設置したユーザーを指定します。
荷主Sender一行テキスト組織外部から荷物を発送した荷主の社名や名前を示します。荷物を各保管スペースに設置したユーザーではありません。
伝言message一行テキスト配達員から受取人への伝言を示します。
更新日時Modified日付最後に情報が更新された日時を示します。
SharePointのリストで自動生成されるModified列を使用します。

SharePointのリストで作ったイメージが次の図です。


各保管スペース(ロッカー)の情報を配達員または利用者が書き換えるためのPower Appsアプリ

SharePointのリストに対して、PowerAppsの編集フォームコントロールによる編集操作を行います。荷物があるかないかをhasItem列で判別し、hasItem列が「はい」の場合は荷物の回収動作、hasItem列が「いいえ」の場合は荷物の預け入れ動作を行います。

荷物の預け入れ動作 hasItem列が「いいえ」の場合

預け入れ動作用のスクリーンを表示します。

荷物を設置しようとする対象のロッカー名およびIDを表示します。

入力欄として、宛先人のユーザー選択を必須とします。必須でない項目として、荷主の名前と宛先人への伝言を入力できるテキストボックスを用意します。
この入力欄に対して「登録」ボタンを用意し、SubmitFormで入力欄の情報をリストに登録します。また、リストのhasItem列を「はい」に変更します。

荷物の回収動作 hasItem列が「はい」の場合

荷物の回収動作用のスクリーンを表示します。

荷物を設置しようとする対象のロッカー名およびIDを表示します。また、その時点で設定されている荷物の宛先ユーザー名、荷主の名前、宛先人への伝言、更新日時、荷扱人を表示します。

入力欄として、「荷物回収」ボタンだけを表示します。このボタンが押されたとき、リストのhasItem列を「いいえ」に変更します。


利用者に納品通知や回収の催促を送るためのPower Automateフロー

リストの変更があったときに動作するフローと、定時で動作するフローの2つを作ります。前者は荷物の預け入れと回収に関する通知、後者は回収の催促に使用します。

荷物の預け入れと回収に関する通知

「自動化されたクラウドフロー」をSharePointの「アイテムが作成または変更されたとき」トリガーで実行します。

トリガーからは、アイテムが変更された後の最新の情報がフローに渡されます。
リストのhasItem列が「はい」のときは荷物が預けられたことを意味します。このとき受取人に対して荷物が届いたので回収するように連絡します。また、荷物を預けたユーザー(配達人)には入力を受け付けた旨を通知します。
リストのhasItem列が「いいえ」のときは荷物が回収されたことを意味します。このとき受取人には入力が受け付けられたことを通知します。また、配達人には荷物が回収されたことを通知します。

回収の催促

「スケジュール済みクラウドフロー」を1日ごとに実行します。

宅配ロッカーリストをSharePointコネクタ複数の項目の取得ですべてのロッカーのデータを取得します。取得したデータに対して、Apply to eachで個々のロッカーごとのレコードを取り出します。ここでhasItem列がはいであれば荷物があることになりますから、hasItem列の値を条件に代入します。条件で比較するときに注意が必要なのが、hasItemと比較する対象は式エディタでtrueと入力するという点です。ベタ書きで「はい」や「true」と書いても一致判定してくれません。
hasItemtrueのときだけ、Teamsのチャットまたはチャネルでメッセージを投稿するアクションを使って、受取人にメッセージを送ります。


アプリ作成の詳細

道具

各保管スペース(ロッカー)の情報を配達員または利用者が書き換えるためのPower Appsアプリの作成詳細

画面遷移

アプリが読み込む情報によってユーザーに求める動作が変わります。そこで、まずは画面遷移の構成を考えます。

PowerAppsのアプリ起動時に表示する画面は、ツリービュー>画面>AppのStartScreenで設定できます。If関数を使って、アプリが読み込むデータに基づいて適切な画面を表示できるように設定します。

荷物がすでにロッカーに存在する場合は、荷物の回収動作をします。荷物がない場合は、荷物の預け入れ動作をします。これらはSharePointのリスト宅配ロッカーにある情報を読み込めばhasItem列の値で判定できます。
SharePointのリスト宅配ロッカーのID列の値をロッカー番号として使いクエリパラメータLockerID=#の形で与える場合、表示すべき画面の分岐は次のようになります。hasItem列がはいTrueの場合は荷物の回収動作いいえFalseの場合は荷物の預け入れ動作という名前の画面からアプリがスタートします

If(LookUp(宅配ロッカー,ID=Param("LockerID")).hasItem,
   荷物の回収動作,
   荷物の預け入れ動作
)

ここでもう一つ考えたいのが、エラー処理です。SharePointのリスト宅配ロッカーのデータがないLockerIDを指定されたり、そもそもLockerIDの値が与えられていない場合、アプリは正しい処理をできません。そのような場合、早めにユーザーへ警告したほうがよいでしょう。そこで、IsBlankOrError関数を使って、SharePointのリスト宅配ロッカーのデータを見つける動作を正常に行えなかった場合に失敗画面へ遷移するようにしておきます。

If(IsBlankOrError(LookUp(宅配ロッカー,ID=Param("LockerID"))),
    失敗画面, 
    If(LookUp(宅配ロッカー,ID=Param("LockerID")).hasItem,
        荷物の回収動作,
        荷物の預け入れ動作
    )
)

これでアプリ起動時の画面遷移ができました。ほかに後で出てくるデータ送信が成功したときのための成功画面も作っておくとよいでしょう。

荷物を預け入れる動作画面をつくる

まずは、荷物がない場合つまりhasItemが「いいえ」のときを考えます。これは新しく荷物を設置して、受取人に連絡する業務フローです。

「編集フォーム」コントロールを用意します。これをForm1と呼びます。Form1のデータは、SharePointのリストで作成した「宅配ロッカー」リストを使用します。Form1のプロパティ>データはDataSourceが「宅配ロッカー」、DefaultModeがFormMode.Editです。ここで編集対象のロッカー番号を指定して、指定したアイテムだけを編集したいと考えます。テキスト入力コントロールを挿入し、名称を「ロッカー番号入力」とします。ロッカー番号入力にロッカー番号を記入して、ロッカー番号がIDと一致するアイテムを編集対象とするには、Itemを以下のように書きます。
LookUp(宅配ロッカー,ID=Value(ロッカー番号入力.Text))
LookUp関数はデータテーブルから1個のレコードを抽出する関数です。第1引数はデータソース(リスト)の名前、第2引数は条件式です。ロッカー番号入力.Textでロッカー番号入力コントロールに記入された文字列を読み取ります。IDは数値なのでロッカー番号入力.Textを数値変換するようにValue関数にかけます。

ユーザーに手作業をさせると、必ずどこかで間違いが生じます。いまロッカー番号を手入力するような形で作りましたが、アプリ起動時のURLから自動的にロッカー番号を設定できるようにしましょう。画面遷移のパートで書いたように、Param関数を使ってURLから文字列を取り出すことができます。FormのItemを次のように記述すれば、Param関数から直接ロッカー番号LockerIDを読み出すことができます。

LookUp(宅配ロッカー,ID=Value(Param("LockerID")))

続いて、フォームで編集する項目を変えてみましょう。
Form1のプロパティ>フィールド>フィールドの編集で、編集対象とする項目を編集できるようにましょう。ここでは、Title, Receiver, hasItem, Sender, message, PostedByを編集対象に加えます。

まず、hasItemはユーザーが値を入れるのではなく状態に応じて「はい/いいえ」が適切に変化するようにします。いまは荷物がないとこりに荷物を設置する場合を考えているので、操作をしたあたはhasItemが「はい」になるようにします。
ツリービューからhasItem_DataCard1のプロパティを開き、詳細設定Defaulttrueにします。trueは「はい」を意味します。逆にfalseは「いいえ」です。また、ユーザーが操作できないないように非表示します。同じく詳細設定Visiblefalseに設定します。

次に、受取人Receiverを工夫します。
表示がReceiverだと英語がわからない人に通じないので、受取人と表示されるようにします。ReceiverのDataCardでDisplayNameを”受取人”にしておけば、ほかの部分も連動して変わります。

Receiverはリストに「個人」型を設定したので、PowerAppsのForm1でも対応するUser型のデータを扱います。いまReceiver_DataCard1の下にDataCardValue2がある状態を考えると、DataCardValue2には選択されているユーザーのDisplayNameが表示されます。したがって、DataCardValue2で選択されているユーザーUserはDataCardValue2.Selectedで参照できます。たとえばDataCardValue2.Selected.Emailとすれば、選択されているユーザーのメールアドレスを取得できます。これを応用して、選択されているユーザーの姓だけを取り出すことができます。
Office365ユーザー.UserProfileV2(DataCardValue2.Selected.Email).surname
DataCardKey2詳細設定Textを以下のようにすることで、「受取人: 佐藤様」のような表示にできます。
"受取人: "&Office365ユーザー.UserProfileV2(DataCardValue2.Selected.Email).surname&"様"
ちなみに、このように表示項目に関数を仕込む場合は、関数がエラーを吐く場合に備えてIsBlankOrError関数でエラー処理を組み込んでおくと良いです。

PostedByもアプリを開いたユーザーが指定すればいいだけなので、同様にVisibleをfalseにしておきます。次にDefaultをアクセスしているユーザーにしたいのですが、これが一筋縄に行きません。Power AppsからSharePointのリストに送信するデータの形式をSharePointのリストの個人型に合わせるため、フォームで送信する値を工夫する必要があります。解決方法はリンク先を参照してください。工夫が必要になる原因はPowerAppsとSharePointのリストでデータ形式が不一致を起こすためです。なんのためのローコードか。

アプリを開いているユーザーを指定する最小の設定では、PostedBy_DataCard1 > DataCardValueのDefaultSelectedItemsを以下のように記述します。

{
 Claims: "i:0#.f|membership|" & Lower(User().Email),
 DisplayName: User().FullName
}

最後に送信ボタンを設置しましょう。
「ボタン」コントロールを挿入します。詳細設定のデータ>Textには「荷物を登録」のような文言を記入します。このボタンで重要なのはアクション>OnSelectにフォーム送信アクションを設定することです。
SubmitForm(Form1)
Form1の内容がSharePointのリストに送信されます。

フォームの送信に成功したことがユーザーわかるようにするため、「正常に完了しました」とだけ表示する画面に遷移させます。フォーム送信時に画面を遷移させるには、Form1のプロパティ詳細設定のOnSuccessに以下のように記述します。ここで遷移先のスクリーン名を成功画面としています。
Navigate(成功画面)
一方で、OnFailureはfalseのままでよいです。入力必須の項目が未入力の場合に警告を表示するような動作はFormの方で勝手にやってくれるので。

成功画面は予め1枚のスクリーンとして作っておきます。PowerAppsの編集画面左上にある「新しい画面」から「成功」を選ぶとそれらしい画面が生成されます。

ここまででフォームの編集ができるようになりました。
次に考えたいのが、前のデータ残っている場合です。

ここで想定しているSharePointのリストのデータ設計では、ロッカー番号に1対1でレコードがあります。これのレコードを書き換え続けます。したがって、荷物を受け取り済みにしても、前の荷物の情報が残ります。こうしておくと、前の荷物に関するトラブルが生じたときに直前回の情報がすぐに手に入るのでトラブル解決に便利です。
一方で、新しく荷物を預け入れたいのに、編集フォームで前の荷物の情報が出てきてしまうと困ります。誤った情報の登録にもつながります。そこで、SharePointのリストから読み取った情報の一部を消してPower Apps上で表示します。

Receiver_DataCard1の詳細設定>データ>DefaultBlank関数を入れることで、入力フォームの値が入っていない状態にできます。入力フォームがBlankだとSubmitformが動作しないので、意図しない受取人を設定するミスを予防できます。

受取人はBlank関数を使えばいいのですが、荷主Sender, 伝言messageはこの方法が使えません。Sender, messageは入力必須でない項目なので、値がBlank()でもSubmitformできます。値がBlankのままSharePointのリストに送信された項目は、前の値が更新されずに残ります。受取人Receiverは入力必須なのでSubmitformが動かずこのようにはなりません。そこで、Sender, messageは明示的に空の文字列を与えてやる必要があります。Blank()の代わりに“”と書きます。

荷物を回収する動作画面をつくる

次に、荷物がない場合つまりhasItemが「はい」のときを考えます。荷物を回収する動作画面では、荷物の受取人をユーザーとして想定します。また、想定する動作は荷物を回収するのみです。

荷物を預け入れる動作の画面とほとんど同じように作れます。こういうときはツリービュー>荷物の預け入れ動作の三点ボタンから「画面の複製」を行うと楽です。各アイテムの名前の末尾に_1が付与されて画面ごとに名前が異なるように調整されることに注意して下さい。

ツリービューからhasItem_DataCard1_1のプロパティを開き、詳細設定Defaultfalseにします。falseは「いいえ」を意味します。

この画面でユーザーに期待するのは荷物の回収だけです。そこで、既存のデータを書き換えられないようにしておきます。
編集フォームコントロール自体に、動作を編集・新規投稿・ビュー(閲覧のみ)に設定できます。しかし、編集フォームコントロール全体の設定で動作モードをビューに設定してしまうと、SubmitFormでSharePointのリストを書き換える動作も封じられます。そこで、画面に表示されている各入力欄の設定を表示のみに書き換えます。
ツリービューを見るとForm配下の末端にDataCardValueという名前の付いた入力系コントロールがあります。これが入力欄です。これの詳細設定の一番下の方にDisplayModeというプロパティがあります。これをDisplayMode.Viewに設定すると、動作時に表示のみになります。


配布の準備

作成したアプリを業務で使えるようにしましょう。

「共有」から公開を行うと、Web リンクに次のようなURLが表示されます。これが作成したアプリへアクセスするためのURLです。
https://apps.powerapps.com/play/example?tenantId=example

今回作成したアプリは、URLからロッカー番号を指定できるようにしました。前述のURLの末尾に&でLockerID=#をつなぎます。#にはロッカー番号を入れます。

例:ロッカー番号51のとき
https://apps.powerapps.com/play/example?tenantId=example&LockerID=51

このURLをQRコードのして印刷し、ロッカーの現場に表示しておけば、利用者はスマホでQRコードを読み込むだけでアプリにアクセスできます。URLからQRコードを作るにはqrqrなどを使います。


本アプリの作成を通じて業務の自動化を体験するワークショップを開催する場合の進め方例

1回目
小包、郵便をオフィス内で分配する業務フローを書き出してみる。
業務フローの中で困っていること、面倒なこと、間違いが起こりやすいことを探す。
消費者として使用した宅配ロッカーの経験を基に、宅配ロッカーの業務フローを書き出してみる。
これらを踏まえて、最終的なワークフローを書く。

2回目
SharePointのリストにデータを格納する方法を考える。
まずExcelにデータを入れて、手作業ですべての操作をすることを考える。
どんな列にどんなデータが入ればいいかを考える。
業務フローをカバーできるExcelができたら、これを基にSharePointのリストを作成する。

3回目
SharePointのリストに対して、PowerAppsからデータを操作できるようにする。
PowerAppsの勉強の導入になるので時間をかけて、リード役が画面を見せながら説明する。

4回目
SharePointのリストに対して、Power Automateで連絡のフローを作成する。
「自動化されたクラウドフロー」を「SharePointのアイテムが作成または変更されたとき」トリガーで実行する。

5回目
サービス展開に必要な資料を作成する。
ユーザーへの説明書はもちろん施策の狙いをまとめた資料を作成する。
ユーザーへの説明書はできるだけ具体的でわかりやすくする。ユーザーの支持を得るため。
施策の狙いをまとめた資料は、現場の切なる問題の提示とともにDXのような今時でいい感じの雰囲気をちりばめる。このような活動に肯定的な感触を持ってもらい、今後も自由に活動しやすくするため。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください