こんにちは、あんこ先生です。
指定したレコード数ごとに、ギャラリーを分割表示させたくありませんか?
例えば、レコード数の制限を設けページ分割するとスクロールが無くなり移動が楽になります。
また、PowerAppsでの印刷は、画面に表示されているものしか含まれません。
そこで、今回は「アプリの操作を楽にしたい」、「すべてのレコードを印刷したい」といった悩みを解決する方法を紹介します。
この記事を読めば、ギャラリーに指定したレコード数ずつ表示させる仕組みや記述方法を理解できますよ。
- スクロールから解放される
- 印刷されないレコードを回避できる
- ページ単位に集計できる
[ad1]
ギャラリーを分割表示する仕組み
どのように動作するかは動画で確認してみてください。
機能要件
10レコードずつ表示します。
ページを増やすボタンを押すと次の10レコードを表示します。
また、ページを減らすボタンを押すと前の10レコードを表示します。
もちろん0を下回ったり、総レコード数を超えたりしないよう制御します。
サンプルデータについて
今回は、サンプルとして商品の入出荷記録を用意して解説します。
レコード数は200件で、それを10レコードずつ、20ページに分割して表示させます。

では実際にこの機能を作ってみましょう。
なお、分割前のテーブルは可視化するためにギャラリーコントロール(Galleryxx)で表示させています。
また、あとから表示レコード数を変更できるよう、テキスト入力コントロール(TextInput01)に入力しておきます。
[ad1]分割表示のための変数と計算

総ページ数を取得する
まず何ページ必要なのかを計算します。
これは次の式で求めます。
RoundUp(CountRows(Galleryxx.AllItems)/Value(TextInput01.Text),0)
CountRows関数でテーブルの総レコード数を求めて、それを表示レコード数で割っています。
余りの処理をするため、RoundUp関数で繰り上げています。
現在のページ数を変数に落とし込む
ページ数は都度変化するため、変数_cntで管理します。
AppのOnStartかScreenのOnVisibleで次を記述しておきます。
Set(_cnt,0)
比較演算子に<=や=>ではなく<と>を使うため、初期値は0としました。
あとは表示レコード数に変数_cntをかけて1を足せば表示開始レコードがわかります。
8ページ目なら、10×8+1=81 となります。
あとはこれらの数値を使ってギャラリーのデータソースを切り替えていくだけです。
[ad1]ギャラリーのデータソース指定

実際に表示するレコードを抽出する
先ほどの変数_cntを使って、ギャラリーのデータソースを変化させます。
GalleryのItemsに次を記述します。
FirstN(
LastN(_T入出荷,CountRows(Galleryxx.AllItems)-Value(TextInput01.Text)*_cnt),
Value(TextInput01.Text)
)
このコードの仕組みは次の通りです。
- 総レコード数から表示レコード数×ページ数を引きます。
- 次に最後からその値のレコード分のテーブルを作成します。
- そして先頭から表示レコード数分を抜き取ります。
文章では分かりにくいので、8ページ目を例に挙げた図を確認してください。
変数_cntを増減させる
ページ数を管理する変数の値を増減させるには、再度宣言しなおします。
具体的には、増減させたいアイコンのOnSelectに次をそれぞれ記述します。
//前回の値に1増やす
Set(_cnt,_cnt+1)
//前回の値から1減らす
Set(_cnt,_cnt-1)
変数_cntの値が変わるたびにギャラリーのデータソースも切り替わります。
細かい制御

ただ、この状態では変数_cntが0を下回ったり、総ページ数を超えることができてしまいます。
そのため、上限下限の範囲内に収まるよう次の記述を加えます。
増減させたいアイコンのOnSelectに次をそれぞれ記述します。
//上限を超えないように1ずつ増やす
If(_cnt+1<CountRows(Galleryxx.AllItems)/Value(TextInput01.Text),
Set(_cnt,_cnt+1)
)
//0を下回らないように1ずつ減らす
If(_cnt>0,
Set(_cnt,_cnt-1)
)
これでページ数を範囲内に収めることができます。
画像のように範囲外に出るときは、そもそも押せないようにすることもできます。
その場合、減少させるアイコンのDisplayModeに次を記述してみましょう。
//変数が0より大きければ編集、そうでなければ無効モードに切り替える
If(_cnt>0,
DisplayMode.Edit,
DisplayMode.Disabled
)
補足事項

今回は、あとから表示レコード数を変更できるようにしています。
そのため、変更時はページ数をクリアしないと正しく処理が行えません。
図では表示レコード数を10件から20件に変えた結果、ページ数が上限を超えてしまっています。
これを回避するため、テキスト入力コントロール(TextInput01)のOnChangeにSet(_cnt,0)を加えておくとページ数がリセットされて安心です。
[ad1]分割した全ページを印刷する方法
複数ページの場合、印刷の都度増減させるのは手間です。
そこで印刷するたびに、変数を増加させるようにします。
具体的には、印刷用アイコンのOnSelectに次の記述を加えれば、全ページを印刷するまで印刷スクリーンにとどまることができます。
Print();
If(_cnt=RoundUp(CountRows(Galleryxx.AllItems)/TextInput01.Text,0),
Navigate(Screen_Top, ScreenTransition.Fade),
Set(_cnt,_cnt+1)
)
印刷後、現在のページが総ページ数と等しいか判定します。
等しければ別スクリーンに移動し、そうでなければページ数を更新して印刷スクリーンに留まります。

Printループは許可されていないようで、エラーとしてはじかれます。
めんどうですが、都度印刷ボタンを押す必要があります。
まとめ
今回は表示レコード数を指定して、ギャラリーコントロールを分割する方法を紹介しました。
そのため、具体的な手順は理解いただけたと思います。
この仕組みを使えば、紹介した特定件数単位の分割表示や印刷ページの分割ができます。
もう少し手を加えれば、写真を5枚ずつ表示させるといったこともできますね。
ぜひ色々と試してみてください。
いつも参考にさせていただいております。
このアプリでどのコントロール、どのプロパティに上記式をセットしているかお教えいただけないでしょうか
質問ありがとうございます。
全体的にコントロールとプロパティを追記しましたのでご確認ください。
ご対応いただきありがとうございます。
無事?理解でき自分でも作ることが出来ました!
可能でしたら追加で質問させて下さい。
分割対象のテーブルがもともと希望する列の並び順になっておらず、今回教えていただいた手順で分割した後にソート処理を行うと分割したページ単位でのソートとなってしまいます。
いったん希望する列でソートした状態を入力として分割する方法がございましたらお教えいただけると幸いです。
アプリができたようで何よりです。
元テーブルを例えば日付順にソートしてから指定件数ごと表示したいってことですよね。
それであれば記述はそのまま、テーブル部分にSortを追加すればできますよ。
FirstN(
LastN(Sort(_T入出荷,列名,並び),CountRows(Galleryxx.AllItems)-Value(TextInput01.Text)*_cnt),
Value(TextInput01.Text)
)
あと、いまはIndex関数があるのでFirstN等を使わなくても簡単に指定できるようになっちゃいました。
勉強させて頂いています。
以前のご質問にて、どこにそれぞれを
入力されるか反映していただいています。
そんな中、私の理解不足で本当に申し訳ないのですが、一番初めの→RoundUp(CountRows(Galleryxx.AllItems)/Value(TextInput01.Text),0)
こちらの部分は、どこに設定となりますでしょうか。勉強不足で申し訳ありません。色々試してみたのですが、どうすることもできず、、、
ご連絡させて頂きました。
一番初めのコードはこういう計算式で求めていますよっていう例示であり、実際に記述しません。
GalleryのItemsやIconのOnSelectなどで利用されています。
このような回答でよろしいでしょうか?
お恥ずかしい質問をしてしまい、
申し訳ありません。理解致しました。
丁寧にご返信頂きまして、
ありがとうございました。