はじめに
例えば、データソースとしては、以下のように注文と注文明細を分けて管理し、ID で紐づけ、こちらのデータソースにデータを送信する注文するアプリを作りたいとします。
この場合、案件ごとに注文明細の数が異なるため、入力個数を動的に変更でき、また、注文と注文明細で矛盾が生じないようにデータ登録したいといった要件が考えられます。
今回は、そのような要件を満たす、以下のような画面でデータ登録をする方法について紹介します。
データソースの用意
上述したようなデータソースを作成します。注文テーブルの ID 列と注文明細の注文 ID を紐づけます。
※今回は、アプリ側で矛盾が生じないようにデータ登録をします。Dataverse の時はリレーションシップを設定しても良いかと思います
入力画面の作成
入力画面を段階的に作成していきます。
部品の全体像は以下のような感じです。
今回は体裁を整えるためコンテナベースで作成しています。
ポイントとなるところをもう少し詳しく説明します。
コレクションの作成
[App]
の[OnStart]
にて以下のようなコレクションを作成します。
コレクションに格納する情報は、注文詳細側の列の情報がベースになります。
今回は、以下の 3 つです。
ClearCollect(
colOrderItems,
{
品物: "",
単価: "",
数量: ""
}
)
ヘッダーの作成
こちらのコンテナーにラベルを 3 つ配置します。
[With]
プロパティを Parent.Width/3 にします。
ギャラリーの設定
ギャラリーを追加し、[Items]
プロパティを先ほど作成したコレクションにします。
テキスト入力コントロールを 3 つ、アイコンを一つ追加します。
それぞれのサイズについて、ヘッダーと大体合うようにします。
そして、テキスト入力コントロールの[OnChange]
プロパティを以下のように設定します。
Patch(
colOrderItems,
ThisItem,
{品物: txtItem.Text}
)
※txtItem はテキスト入力コントロールの名前です
また、[Default]
プロパティを以下のようにします。
品物の箇所については、ThisItem.品物 といった感じです。
3 つのテキスト入力コントロールについて、同じように[OnChange]
、[Default]
プロパティを設定していきます。
■単価のテキスト入力コントロールの[OnChange]
Patch(
colOrderItems,
ThisItem,
{単価: txtUnitPrice.Text}
)
■数量のテキスト入力コントロールの[OnChange]
Patch(
colOrderItems,
ThisItem,
{数量: txtQuontity.Text}
)
※[Default]
プロパティについては割愛します
また、プラスのアイコンを配置し、[OnSelect]
プロパティに以下の処理を追加します。
Collect(
colOrderItems,
{
品物: "",
単価: "",
数量: ""
}
);
ギャラリーにゴミ箱アイコンを追加し、[OnSelect]
プロパティに以下の処理を追加します。
Remove(colOrderItems,ThisItem)
データ送信
最後に、送信ボタンを作成し、[OnSelect]
プロパティに以下の処理を追加します。
Set(
gblOrderId,
Patch(
注文,
Defaults(注文),
{
タイトル: TextInput1.Text,
日付: DatePicker1.SelectedDate
}
).ID
);
If(
// エラー判定
!IsEmpty(Errors(注文)),
// エラーメッセージ
Notify(
Concat(
Errors(注文),
Column & ": " & Message
),
NotificationType.Error
),
//注文明細
ForAll(
colOrderItems,
Patch(
注文明細,
Defaults(注文明細),
{
注文ID: Value(gblOrderId),
タイトル: ThisRecord.品物,
単価: Value(ThisRecord.単価),
数量: Value(ThisRecord.数量)
}
)
);
// 成功メッセージ
Notify(
"注文の送信処理が成功しました",
NotificationType.Success
);
ClearCollect(
colOrderItems,
{
品物: "",
単価: "",
数量: ""
}
);
Reset(TextInput1)
);
ポイントは、先に注文テーブルにデータを送信し、そちらの ID 列を変数に格納した上で注文詳細テーブル側にデータを送信するところです。
これにより、注文詳細テーブル側の '注文 ID' が注文テーブル側の該当の注文の ID となります。
実行したところ、問題なくデータの登録が出来ました。
別のアプローチ
書いた後に気づいたのですが、以下のアプローチでも良いと思います。
ポイントは、Gallery1_1.AllItems
を利用することです。この場合、ギャラリーの各行に対して処理をする感じになります。そのため、ギャラリー内の各コントロールの[Text]
プロパティを登録する感じになります。この場合、各コントロールの[Default]
プロパティや[OnChange]
プロパティを設定する必要はないため、手順が少し楽になると思います。
Set(
gblOrderId,
Patch(
注文,
Defaults(注文),
{
タイトル: TextInput1_2.Text,
日付: DatePicker1_2.SelectedDate
}
).ID
);
If(
// エラー判定
!IsEmpty(Errors(注文)),
// エラーメッセージ
Notify(
Concat(
Errors(注文),
Column & ": " & Message
),
NotificationType.Error
),
//注文明細
ForAll(
Gallery1_1.AllItems,
Patch(
注文明細,
Defaults(注文明細),
{
注文ID: Value(gblOrderId),
タイトル: ThisRecord.TextInput2_3.Text,
単価: Value(ThisRecord.TextInput2_4.Text),
数量: Value(ThisRecord.TextInput2_5.Text)
}
)
);
// 成功メッセージ
Notify(
"注文の送信処理が成功しました",
NotificationType.Success
);
ClearCollect(
colOrderItems,
{
品物: "",
単価: "",
数量: ""
}
);
Reset(TextInput1_2)
);
まとめ
今回は、注文テーブルと注文明細テーブルが分かれており、注文明細側の行数が動的な場合における Power Apps 側での注文送信画面を作成する方法について紹介しました。
やや難しいと思いますが、結構需要のあるデータ入力の仕方かと思います。
このような画面で作成したいという方のお役に立てば幸いです。