おはようございます、こんにちは、こんばんは。先日は学習アプリ作成会にご参加いただきありがとうございました。今回もレポートとして記事を投稿いたします。分かりにくかった点は以下の動画#5をご覧ください。
また、記事に誤りがあった場合は、優しくご指摘いただけますと幸いです。なお、この記事は筆者が一方的に書いているものなので、文責はkuro.が負うものです。ご理解いただけますと幸いです。
動画#5
120分ほどある動画を編集するのって大変なんですよね…。10分ですら大変なのですが、今回もお忙しい中…。チャンネル登録、高評価で応援よろしくお願いします!
学習アプリ作成会で使用した関数は、ようさんのチャンネルで『関数解説シリーズ』としてリリースされています。チャンネル登録、高評価よろしくお願いします!
前回の復習(#4)
復習に関しては動画を視聴していただくか、当ブログの『Power Platform学習アプリ作成会#4』をお読みいただければと思います。Akiraさんのチャンネルは高評価と登録をよろしくお願いします(※新型コロナウィルスはただの風邪ではないです)
今回(#5)の目指すところ
成績登録画面にひと工夫を施し、新たなスクリーン(ViewScreen)を作成します。このViewScreenは、学習履歴や成績を日付ごとに管理する目的で使用します。
画面の幅を誤答数に合わせる
…と、その前に、成績登録を終えたらすぐに次の問題に取り組めるように修正していきます。こちらに関しては btnRegister(成績登録ボタン)のOnSelectプロパティに「問題作成」で使用したコードとcolAnswerのレコード削除のコードをコピペで追記するだけです。
必ずPatch関数(成績登録コード)よりも下に書くことだけ気を付けます。基本的に「書いた順番に動作する」を心得ておきましょう。
Mod関数
ギャラリー・テンプレート(誤答の「列の数」)とギャラリー(galWrongAnswer)の高さが合うように画面幅を修正していきます(比較画像参照)
ところが、Power Appsには画面幅を調節するための関数がありません。いくつか関数を組み合わせるなどし、少し工夫してやる必要があります。
ここでは、ギャラリー・テンプレートが2列で折り返されている点に着目しました。Mod関数の登場です。Mod関数とは、わり算で出た「余り」を返す関数です。まずは、以下の表をご覧ください。
式 | 商 | 余 | Mod関数 | 戻り値(剰余) |
10÷3= | 3 | 1 | Mod (10,3) | 1 |
12÷3= | 4 | 0 | Mod (12,3) | 0 |
今回、このMod関数を使ってやりたいのは「誤答数を2で割った時の余り」と「ギャラリーテンプレートの高さ」を掛けた値が「ギャラリーのHeightプロパティの値」になるようにすることです。以下のコードと表をご覧ください。
なお、ギャラリー・テンプレートの高さに合わせてギャラリー(galWrongAnswer)の高さを調節するので、galWrongAnswer の Heightプロパティに以下のコードを書きます。
Self.TemplateHeight * If(
Mod(
CountRows(Self.AllItems),
2
) = 0,
CountRows(Self.AllItems) / 2,
(CountRows(Self.AllItems) + 1) / 2
)
誤答の数 | Mod(n,2) | 戻り値 | 結果 | 行数(高さ) |
10 | Mod(10,2) | 0 | 10/2 | 5 |
9 | Mod(9,2) | 1 | (9+1)/2 | 5 |
8 | Mod(8,2) | 0 | 8/2 | 4 |
7 | Mod(7,2) | 1 | (7+1)/2 | 4 |
6 | Mod(6,2) | 0 | 6/2 | 3 |
4 | Mod(4,2) | 0 | 2 | 2 |
2 | Mod(2,2) | 0 | 1 | 1 |
苦労の跡が見られますが、このように書くことで先の「新画面」のような結果が得られました。数学というのは偉大です。今回の「最おもしろポイント」でしょうね。
余談:可読性について考える
ちょっとがんばったコードでしたが、Akiraさんの採点は80点(意外と高得点)でした。「動いているから100点」というフォローはいただいたものの、残り20点が気になるところです。
少し余談にはなりますが、アプリ開発をする上で大切な「可読性」について盛り上がったので備忘録としてまとめておきます。この時間、みんなでワイワイ話せて楽しかったですね…。
「可読性」と言っても、作り手の癖や趣味嗜好の問題も絡んでくるので「どれだけ単純に書けるか」に重きを置く人もいれば「動けばいい」と考える人もいます。
自分の意見としては、どちらか一方に偏ることがなければ良いのではないかな、と思っています。単純に書くことに注力し過ぎて制作に時間をかけてしまったり、単純に書いてしまったが故に他の人が理解できなかったりしてはなりませんし、一方で、変数やWith文を多用したり、コードが複雑化したりしてしまえば、起動時(実行時)の動作が重くなるでしょうし、バグが発生した時や機能を追加する時なんかにも困ってしまいます。
現時点での自分の力量では「とりあえず動けばいい」で精一杯ではあるのですが、作り続けていく内に色々な引き出しが増えてくるように思います。この「動けばいい」という考え方でずっといるのではなく「再現性」や「可読性」に優れたコードを意識して書くように心がけ、日々の学習(開発)に取り組むようにしたいものです。
色んなアイディアを頂戴したので、メモとして書き留めておきます。
(If(
Mod(
CountRows(Self.AllItems),
2
) = 0,
0,
1
)
+ CountRows(Self.AllItems)
)
/ 2 * Self.TemplateHeight
Self.TemplateHeight * (CountRows(Self.AllItems) + Mod(CountRows(Self.AllItems),2)) /2
訂正(2022.09.05)
アプリを後追いで作ってて気づいたのですが、先週Mod関数のところで最終的に入力されていた式だと奇数の時におかしな表示になります。
今「Mod(CountRows(Self.AllItems),2)+CountRows(Self.AllItems)/2*Self.TemplateHeight」で設定されていますが、
「(Mod(CountRows(Self.AllItems),2)+CountRows(Self.AllItems))/2*Self.TemplateHeight」のようにModの前から「/2」の前まで括弧で括らないと駄目ですね。
とのことでした。考え方は四則計算と同じですね。
学習履歴を確認できるようにする
ここからは次回(9月10日)に向けた話になって行きます。スクショ画面と一緒に振り返ります。
Calendar関数
まずは「ドロップダウンリスト」を作成し、Itemsプロパティに Calendar.MonthLong() と入力します。ドロップダウンリストの項目は Itemsプロパティはブラケット(コイツ→ [ ] )で囲って [1, 2, 3] のようにして作ることができますが、これを使えば1月から12月までを書く必要がなくなります。
なお、日本語の環境であればCalendar.MonthShort() と入力しても同様の結果になります。英語の環境であれば January なら Jan. の値が返って来ます。短縮形ということですね。Calendar関数に関してはDocsに分かりやすくまとめられています。
Distinct関数
データソースの中から登録日時だけを表示させたいのですが、重複するレコード、つまり、同じ日付は表示させたくありません。その時に使用するのがDistinct関数です。
ところが、これでも同じ日付が “Result” 列に格納されています(※2023年3月7日より、ResultではなくValueで返ってくるようになりました:詳細)。どうやら、登録された日付だけでなく時間も反映されているようです。これは修正が必要となりました(#6で解決します)
なお、隣に書かれてある「7」の数字は、そのDistinct関数の戻り値である “Result“ “Value” をMonth関数でフィルタリングしたものとなっています。次回に必要となっておくのでDocsを眺めるなどして整理しておくことに致します。
User関数
現在、SharePointリストにはアプリを使用している人たち全てのデータが保存されています。他人の成績を覗き見するわけにもいかないので、ここから自分のデータのみを抽出しなければなりません。そこでUser関数の登場です。
Filter(
English_Result,
User().Email = 登録者.Email,
galDate.Selected.Result = 登録日時
)
ここでのポイントは User().Email = 登録者.Email と書かれている点です。User().FullName と書いてしまうと、SharePointリストに登録されている名前がファースト・ネーム(姓)なので、上手く抽出できないためです。※ Office 365 はラスト・ネーム(名)
尚且つ、右側の日付リストから選択されたもので抽出されるように galDate.Selected.Result = 登録日時 というコードもFilter関数の第2引数として書きます。これで準備は完了です。
次回(#6)に向けて
上の方法で成績画面を作るよりも、もっと視覚的に分かりやすくする方法を教えていただきます。具体的には、Power Apps内に用意されたコントロールを使わないで、自分でカレンダーを作る方法を学びます。
自作カレンダーのメリットは「成績画面が使いやすくなる」の一点に尽きます。一般的には「自作カレンダーは難しい」と言われていますが、Akiraさんの方法は、変数を使用することもなく(原理さえわかれば)意外と簡単なコードで作ることができるようです。
次回は9月10日(土)の開催です。PAD勉強会が15時より開催なので、次回の学習アプリ作成会は通常よりも1時間早い13時開催となります。ご注意ください。