効率的な社員管理システムの構築：PowerAppsで複数データベースの情報を一元管理する方法

# 記事について

本記事は、PowerAppsでDataverseの二つのテーブルの情報を紐付けて操作する方法について説明します。

具体的には、Employee（社員）とAddress（住所）の情報を紐づけて閲覧・編集するアプリを作る手順を解説していきます。

# そもそもPowerApps,Dataverseとは何か
PowerAppsとはMicrosoftが作ったノーコードツールで、
コードを一切書かずにスマホやタブレット端末向けのアプリを作成するためのツールです

https://powerapps.microsoft.com/ja-jp/

DataverseとはPowerAppsやPowerAutomateと簡単に連携できるMicrosoftのデータベースの一種です。詳しい説明は以下の公式ページを見てください。

https://learn.microsoft.com/ja-jp/power-apps/maker/data-platform/data-platform-intro

# どんな問題を解決できるか
DataverseとPowerAppsで社員管理アプリを作ったが、社員の情報を一つのテーブルじゃなくてセキュリティや権限、グループ化などの理由で複数のテーブルで分散管理したい！けどそれを表示したり編集したりする方法がわからない！そんなあなたに本記事がおすすめです！

# 対象読者
- これからPowerAppsでアプリを作ってみたい方
- PowerAppsで単一データベースでごちゃごちゃに管理するのではなく、概念ごとに細分化させた複数のデータベースで管理したい方

# 完成イメージ

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641616/7ae2893c-2119-84d3-5ae7-aef83a251b39.png" width="300">

上の図ではEmployeeテーブルを利用して自動で作成された社員の詳細画面にAddressテーブルのデータを表示させるようにしています

以下のような流れで作業を進めます

- 作業1. データベースを作る
- 作業2. PowerAppsのキャンバスアプリを自動で生成する
- 作業3. キャンバスアプリの詳細画面にほかのデータベースの情報を表示する
- 作業4. 編集ボタンを配置し、他のデータベースの情報を編集できるようにする

# 作業1. データベースで作る
今回使うデータベースはPowerAppsと連携がしやすいMicrosoft推奨のDataverseで
社員の情報全般を管理しているEmployeeテーブル
今回はPowerAppsと連携しやすいMicrosoft推奨のDataverseをデータベースとして使用します。
また、作るテーブルは二種類あり
1. Employeeテーブル：個人情報（住所を除いた）、所属、メールアドレス等の列が作られている
1. Addressテーブル：社員IDとそのIDに結び付けるための住所の情報が格納されています。

どんなデータを入れるかは皆さんの自由です。

:::note warn
今回のやり方としては共通している社員IDを使うので、AddressテーブルのaddressIDはオートナンバー（自動でナンバリング）にするのではなく、１行テキストにして、Employeeテーブルにある社員IDと対応させる必要がある

今回の目的としてはiとoで社内か社外かの区別をするために利用している。

例：
- Employeeテーブルの社員ID→000003
- AddressテーブルのID→i000003
- 社外テーブルの社員ID→000001
- AddressテーブルのID→o000001
:::

__手順：__
1. PowerAppのページを開いて、サイドバーにあるテーブル（Dataverseをクリック）
1. 上のほうにある「+新しいテーブル」をクリックし新しいテーブルを作成。（既存のデータを使いたい場合は外部データによる新しいテーブルを選んで、作成する）
1. 必要に応じて列を追加して、その中に適当にデータを追加していく
1. 同じような方法で今度は住所用のデータテーブルを作成
1. 最後にaddressテーブルと連携させる必要があるので、社員テーブルにて、列の追加をクリックし、データの種類を「検索」にして、addressのデータテーブルを選ぶ

# 作業2. PowerAppsのキャンバスアプリを自動で生成する
今回のアプリのベースは社員データテーブルがベースなので、社員データテーブルを自動生成のデータとして選ぶ

__手順：__
1. PowerAppのページを開いて、「+作成」をクリック
1. アプリを作成する選択肢の中からDataverseを選択
1. 先ほど作ったデータベースを格納している接続を選択
1. 先ほど作った社員管理データベースを選択
1. 右下にある「接続」ボタンをクリック

これだけで一覧画面と詳細画面、および編集画面とそれらを操作するための基本的な機能が備わったアプリが簡単に出来上がる
これはすごいですね

具体的なやり方（公式）

https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/data-platform-create-app?tabs=home-new-look

# 作業3. キャンバスアプリの詳細画面にほかのデータベースの情報を表示する
この作業では詳細画面に異なるテーブルのデータを表示させるようにします。
自動で作成された詳細画面にはデフォルトでIDと作られた日しか入っていません。
必要に応じてフィールドを画面上に追加します。

__手順：__
1. 編集画面を開き
1. フォームをクリック
1. 右のサイドバーにある「プロパティ」を選択
1. 「フィールドの編集」をクリック
1. フィールドの追加をクリック
1. 作業1で作ったaddressテーブルと連携しているフィールドを追加（他のフィールドは必要に応じて）

今回の記事の必要最低限として以下の画像のようになる

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641616/8412e946-8287-7c2c-0e37-71fafdaf906a.png" width="300">

## デフォルトで用意されてきたここまでの操作で作ったものを目的に合わせてカスタマイズします

今回は社員ID000003を例として使用する
まず現状連携しているデータのプライマリー列であるAddressIDの値が表示されている。
今回これは必要ないので一旦削除
赤いバツ印のエラー表示が出てくるので、該当する波線の部分を削除

次に、情報を表示させるためにテキストラベルをサイドバーの挿入から探し出して、Addressの部分にドラックアンドドロップ
そのままでは被ってしまうのでカードの高さを調節、さっきドラックアンドドロップしたテキストラベルのTextを編集
参照先のデータを表示させたいだけなので、Textに対して、以下の式を使います。

```プラットフォームの名前:Power Platform,Power Apps
"国："&LookUp(address, AddressID = "i"&ThisItem.EmployeeNumber).country
```

__式の説明：__
- `"国："`：ただ単に「国：」これをテキストとして表示しているだけ
- &：特に何もしない、前後と式をつなげ合わせる役割を果たしている
- LookUp(address, AddressID = "i"&ThisItem.EmployeeNumber).country：これは、address テーブルから、AddressID 列が "i" で始まり、かつその後にフォームに結びついている社員データのIDと一致する行を探し、その行の country 列の値を取得しています。具体的には、Japanが取り出されて表示される

LookUp関数とその使い方に関してはこちらの公式ページか、他のサイトを参考にしてください。

https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-filter-lookup

そして、このように異なるテーブルの値を表示できるようになります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641616/ac43e27a-be90-3b9d-da23-1923379f25b2.png" width="300">

同じように繰り返していくと

![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641616/06470eef-dee7-9af4-c586-bdca6e13376a.jpeg)

このように社員の詳細画面上に対応しているaddressテーブルのデータを表示することが出来るようになります(四角の中は著者の個人情報が含まれているため隠しています)

# 作業4. 編集ボタンを配置し、他のデータベースの情報を編集できるようにする

__手順：__
1. キャンバスアプリの編集画面にボタンを追加する
1. 新規作成と編集を行うための編集フォームを含んだAddressEditという名前の新しい画面を作成する
1. 他のデータベースの情報を編集できるようにする
1. 間違いが起こらないように編集不可を追加する

## キャンバスアプリの編集画面にボタンを追加する

addressテーブルの編集画面に遷移するための準備をするにはいくつか知っておかなければいけないことがあります。
1. 詳細画面ではボタンを押しても反応しない
1. 社員データの編集フォームではできるかもしれないが、addressデータを編集するのは困難（やり方知ってる方いたらご教授願いたい）
1. ボタンを押して、何も情報を持っていなかったら何も表示されないし、編集もできないので、Set関数を使いaddressデータのプライマリ列の値を保持する必要がある

__手順：__
1. 編集画面に移動し、addressフィールドを詳細画面と同じように追加する
1. フィールドの中にあるデータカードは今回において不要なので削除
1. 丸い×のエラー表示が表示されると思うのですが、エラー個所を削除すれば消えます。
1. 次に、挿入からボタンを見つけ出しaddressのフィールドにドラックアンドドロップ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641616/9398b2fd-abaf-f816-cccf-adea97176ac1.png)


## 新規作成と編集を行うための編集フォームを含んだAddressEditという名前の新しい画面を作成する

1. 左側にあるサイドバーのツリービューを開き新しい画面を選択
1. テンプレートの中にあるフォームを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641616/af72f8bb-be78-7a96-b350-fa221155b4da.png)

そうすればこの様な画面が作られるはず

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641616/0b3238f6-be4a-5337-d071-f732bc3a6dd2.png" width="300">

この状態ではまだデータと連携できていないので、連携させる必要があります。
__手順：__
1. フォーム部分をクリックし、右のサイドバーのプロパティからデータソースのドロップダウンをクリック
1. 連携させたいデータをクリック

そうすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641616/1454f14a-17a0-15a2-2b78-439084d40dd1.png)
このような画面が出来上がります。

次に

作業3と同様必要なフィールドを追加します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641616/e5126a17-4cfc-3e60-d109-7d12271e1c28.jpeg" width="300">

これでaddressテーブルのデータの新規追加兼編集用のフォームの画面を作り終わった。

4で追加したボタンのOnSelectに新しい画面への画面遷移を行う式を追加する

```プラットフォームの名前:Power Platform,Power Apps
Set(EmployeeNumberForEdit,"i"&ThisItem.EmployeeNumber);
If(
    IsEmpty(Filter(address,AddressID="i"&ThisItem.EmployeeNumber)),
    NewForm(Form10);
    Navigate(EditAddress,ScreenTransition.None),
    Navigate(EditAddress,ScreenTransition.None)
)
```

__式の説明：__

Set(EmployeeNumberForEdit,"i"&ThisItem.EmployeeNumber);：EmployeeNumberForEditという変数に iと社員IDをつなげた文字を代入し、遷移先で使用する。

If(
    IsEmpty(Filter(address,AddressID="i"&ThisItem.EmployeeNumber)),
    NewForm(Form10);
    Navigate(EditAddress,ScreenTransition.None),
    Navigate(EditAddress,ScreenTransition.None)
)

これはもしすでにaddressデータに iと現在見ている社員IDが含まれているデータが存在していなかったら、新たなForm10を作成し、画面遷移を行う
もし存在していたら
そのまま画面遷移を行うという処理を行っている。

これでAddressを編集する画面への遷移の準備ができた。

しかし、これだけでは新規作成をしているのか、もともとあるデータを編集しているのかわからないので

addressフィールドのボタンのTextに対して以下の式

```プラットフォームの名前:Power Platform,Power Apps
If(
    IsEmpty(Filter(address,AddressID="i"&ThisItem.EmployeeNumber)),
    "追加",
    "編集"
)
```
__式の説明：__
もしaddressテーブルの中に iと現在見ている社員IDが含まれているデータが存在していなかったら、
“追加”が文字として表示され
そうでなかったら、
“編集”が文字として表示されるようになる。

これでボタンは正常に動くようになります

## 他のデータベースの情報を編集できるようにする

見た目は作ったので完成しているが、これではまだ機能しない

### 該当するデータに連携させる

フォームのitemに以下の式を使う
```プラットフォームの名前:Power Platform,Power Apps
LookUp(address,AddressID=EmployeeNumberForEdit)
```
__式の説明：__
フォームの参照先をaddressテーブルにあるAddressIDがEmployeeNumberForEdit変数と一致するデータに指定する。

### Submitボタンを機能させる
これに関しては画面を作成した時点で、自動で式が作成されていました。

### デフォルトでaddressIDを入力済みの状態にして、編集不可にする

addressIDのフィールドの中にある「テキスト入力」のdefaultに以下の式を使用する

```プラットフォームの名前:Power Platform,Power Apps
If(
    EditForm2.Mode = 1,
    EmployeeNumberForEdit,
    Parent.Default
)
```
__式の説明：__

EditForm2.Modeには、Edit、New、Viewの三つのあり、1はNew、つまり新規モードを意味していて、
もしEditForm2が新規作成だったらEmployeeNumberForEditの値を代入
もし違う場合は
Parent.Defaultを代入するようにしている。

変に編集して保存先を間違えることを避けるためにAddressIDのDisplayModeをDisplayMode.Disabledにする。

最後にフォームのOnSuccessにback関数を追加すれば、Submitが成功した際に、一つ前の画面に戻るようになります。

最終的にはこんな画面が出来上がります
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641616/896db3b3-b381-5bde-c459-5bf56cd8eaca.png" width="300">

# 結論
本記事では、PowerAppsとDataverseを使用して社員テーブルの詳細画面にAddressテーブルの情報を表示させそれを編集する仕組みを作りました。この方法を用いることで、一つの社員テーブルに雑多な種類のデータを管理するのではなく、管理するデータを細分化し、その新規追加と編集を可能にしました。

最後に、本記事がPowerAppsを使用したアプリケーション開発の参考になれば幸いです。