こんにちは、あんこ先生です。
親子関係のSharePointリストをギャラリーで表示したくありませんか?
例えば、次のような処理です。
- 顧客からの注文とその明細を表示したい。
- レンタル会員とその貸出リストを表示したい。
- 部門ごとの機材一覧を表示したい。
このような処理ができれば、作れるアプリの幅も広がりますよね。
しかし、参照方法が複雑になるため、狙った表示ができないことがあります。
そこで今回は、親子関係のリストをギャラリーで思い通りに表現する方法について解説します。
これであなたも入れ子マスターですね!
ギャラリーがよくわからない人はコチラの記事もどうぞ。
Contents
親子関係とは
専門用語で、依存リレーションシップといいます。
ふたつ以上のテーブルがあり、複数のテーブルが親であるテーブルに依存している関係です。
受注システムで例えると、注文テーブルと明細テーブルがこの関係になります。
親である注文がないと、子となる明細は存在しない、子の存在が親に依存しているわけです。
具体的には、親テーブルの主キーが子テーブルの主キー含まれている状態です。
親子関係のSharePointリスト
上図では、親が注文テーブル、子が明細テーブルです。
今回のサンプルでは、それぞれSharePointリストに登録しています。
テーブルの中身を確認すると、親の主キーであるOrderNoを複数の子が所持していることがわかります。
これでふたつのリストを紐づければ、どの注文でどの商品をいくつ受注したかがわかります。
注文の全貌が見えてきますね。
ギャラリーで親子関係を表現する
ギャラリーを使って親子関係を表現するには、ギャラリーの入れ子を使います。
具体的には、親となるギャラリーのテンプレートにもうひとつギャラリーを設置します。
そして親子を紐づかせるキーで抽出したテーブルを指定します。
子となるギャラリーの数に制限はありませんが、入れ子は2階層までで孫は表現できません。
また、入れ子は多重処理されるため、全体的に重くなります。
サンプルのER図
リストの関係性がわかるER図を作成してみました。
実務に寄せるため、以後、顧客マスタと商品マスタを追加した4つのリストで解説します。
親ギャラリーの作成
はじめに、親である注文テーブルを表示するギャラリーを作成します。
注文テーブルは、注文をいつ、だれから受けたのかがわかる最低限のデータを格納しています。
項目は上図のとおり、注文番号と注文日、そして顧客IDの3つです。
実際に親ギャラリーへ表示させる情報は、注文番号と注文日、顧客名と合計金額の4つです。
顧客IDを使って顧客マスタを参照させれば、顧客名と住所がわかります。
合計金額は後述します。
まずは3つの情報をギャラリーに表示させてみましょう。
//親ギャラリーのItems
注文テーブル
注文テーブルの内容を表示する
注文テーブルにある情報でそのまま使えるのは注文番号と注文日です。
ここは普通にThisItemで指定すれば表示されます。
//注文番号
ThisItem.OrderNo
//注文日
ThisItem.Date
顧客マスタを参照する
次に顧客名を表示させますが、注文テーブルは顧客名を持っていません。
そこで、注文テーブルが持つ顧客IDを使って顧客マスタから顧客名を持ってきます。
自身以外のデータソースを参照するには、LookUp関数を使います。
顧客マスタの顧客IDと比較させることで、レコードごとにIDと一致する顧客名を持ってきます。
LookUp(顧客マスタ,CId=ThisItem.CId,CName)
このやり方でも問題ありませんが、レコード数が増えてくると通信回数が増加します。
そこで、あらかじめ親ギャラリーのデータソースである注文テーブルに顧客名列を追加する方法をとります。
データソースに項目列を追加するには、AddColumns関数を使います。
ギャラリーのItemsに使うことで、項目列を追加できます。
AddColumns(注文テーブル As Par,
"CName",LookUp(顧客マスタ,CId=Par.CId,CName)
)
これで親ギャラリーのデータソースが下図のようになります。
あとは注文番号などと同じようにThisItemで顧客名も指定できるようになります。
//顧客名
ThisItem.CName
合計金額を計算する
合計金額を求めるには、商品マスタから単価を、明細テーブルから商品ごとの数量が必要です。
そのため、まず注文番号で絞った注文テーブルに、AddColumns関数で単価列を追加します。
それをSum関数に与えて、単価✖数量の結果を総和します。
With関数は読みやすくするために使用しているので、直接記述しても問題ありません。
頭に¥マークや3桁ごとにカンマを入れるため、少しごちゃごちゃしています。
//合計金額
With({Total:Sum(AddColumns(Filter(明細テーブル,OrderNo=ThisItem.OrderNo) As Par,
"Price",LookUp(商品マスタ,PId=Par.PId,Price)),Price*Value)},
"合計│¥"&Text(Total,"#,#")
)
これで、合計金額も表示されましたね。
子ギャラリーの作成
次に、子である明細テーブルを表示するギャラリーを作成します。
明細テーブルは、注文番号と何をいくつ注文されたのかがわかるデータを格納しています。
項目は上図のとおり、注文番号と商品ID、そして数量の3つです。
実際に子ギャラリーへ表示させる情報は、商品名と単価、数量と合計金額の4つです。
では、それぞれ表示させてみましょう。
子ギャラリーを作成する
親と紐づいたテーブルを表示するだけなら、親のキーで抽出するだけです。
Filter(明細テーブル,OrderNo=ThisItem.OrderNo)
商品マスタを参照する
まず、商品名と単価を表示させますが、明細テーブルはそれらを持っていません。
そこで、明細テーブルが持つ商品IDを使って商品マスタから情報を持ってきます。
子は親と比べ量が多いので、LookUp関数ではなくAddColumns関数で商品名と単価列を追加しておきます。
AddColumns(
Filter(明細テーブル,OrderNo=ThisItem.OrderNo) As Chi,
"PName",LookUp(商品マスタ,PId=Chi.PId,PName),
"Price",LookUp(商品マスタ,PId=Chi.PId,Price)
)
これで子ギャラリーのデータソースが下図のようになります。
あとは注文番号などと同じようにThisItemで顧客名も指定できるようになります。
//商品名
ThisItem.PName
//単価
ThisItem.Price
明細テーブルの内容を表示する
明細テーブルにある情報でそのまま使えるのは、数量のみです。
ここは普通にThisItemで指定すれば表示されます。
//数量
ThisItem.Value
合計金額を計算する
合計金額を求めるには、単価と数量が必要です。
すでにその情報は用意してあるので単純にSum関数で算出するだけです。
頭に¥マークや3桁ごとにカンマを入れるため、少しごちゃごちゃしています。
"¥"&Text(ThisItem.Price*ThisItem.Value,"#,#")
以上で完成です。
親子ギャラリーの参照
ThisItemで親の値(サンプルなら注文テーブル)を参照する範囲は、親ギャラリーのテンプレートに含まれるコントロールです。
これは、子ギャラリー本体も含みます。
しかし、子ギャラリーのテンプレートに含まれるコントロールは、子の値(明細テーブル)を参照します。
親から子の値を参照する場合は、子とおなじデータソースを指定するか、ギャラリーのAllItemを使います。
//親から子の先頭レコードにある商品名を参照
First(galDetail.AllItems).PName
逆に子から親の値を参照する場合は、親とおなじデータソースを指定するしかありません
子から親ギャラリーのAllItemは参照できません。
今回は親子関係のリストとギャラリーを使って、参照や計算する方法を解説しました。
ギャラリーから他リストの参照、自身の値を使った計算ができましたね。
これができれば、ずいぶん思い通りにデータを操作できるようになると思います。
アクセスなどのデータベースで表現するようなことも容易にできるので、実際に作成して理解を深めてみましょう!
予告│親子関係リストで親または子のレコードを追加・修正・削除する方法
はじめまして。
あんこ先生の記事にはいつも大変助けられておりありがたい限りです。
SharePointのドキュメントフォルダに関する親子関係について質問させてください。
PowerAppsでSPOの”ドキュメント”フォルダ(正確にはShared Documents/img/)に保存されているイメージの
ID列と名前(*)列をコレクションに格納したいのですが、これがなかなかうまくいきません。
*)Titleなのか名前なのかタイトルなのか統一して欲しいw
ドキュメントフォルダに格納されたイメージはサムネイルという入れ子構造になっているためなのか?
この辺の構造について情報が少なく、あんこ先生なら・・・と思い質問させていただきました。
何かヒントとなるような助言でもいただければ非常に助かります!
はじめまして、ご質問ありがとうございます。
SharePoint全般あまり精通しておらず、お力になれそうにありません。
(リストの方であれば少しはわかるんですが…)
大抵入れ子構造になっているので.Valueというテーブルをあれやこれやしてレコードを特定できればいけるかもしれません。
もしくはTwitterで質問してみると識者から回答があるかもです。
情報ありがとうございます。
本ページの内容を見よう見まねで作って練習してみました。
もしよかったら教えてほしいのですが。
親ギャラリーのデータソースには、以下のコマンドを設定すればいいのかと思っているのですが、うまくいきません。
何かアドバイスいただけると助かります。
AddColumns(注文テーブル As Par,
“CName”,LookUp(顧客マスタ,CId=Par.CId,CName)
);
With({Total:Sum(AddColumns(Filter(明細テーブル,OrderNo=ThisItem.OrderNo) As Par,
“Price”,LookUp(商品マスタ,PId=Par.PId,Price)),Price*Value)},
“合計│¥”&Text(Total,”#,#”)
)
よろしくお願いいたします。
ご質問ありがとうございます。
親ギャラリーのItemsは
AddColumns(注文テーブル As Par,
"CName",LookUp(顧客マスタ,CId=Par.CId,CName)
)
です。
後半のこの部分は親ギャラリーに追加したラベルコントロールのTextに張り付けちゃってください。
//合計金額
With({Total:Sum(AddColumns(Filter(明細テーブル,OrderNo=ThisItem.OrderNo) As Par,
"Price",LookUp(商品マスタ,PId=Par.PId,Price)),Price*Value)},
"合計│¥"&Text(Total,"#,#")
)
気持ちブログ本文も加筆しました。