PowerAppsのギャラリーでカレンダー表示をする方法(Sequence関数、Date関数)
PowerAppsのギャラリーでSequence関数とDate関数を使って一か月分のデータをカレンダー上に簡単に表示するやり方を紹介してます。
(動画時間:12:15)
Udemy.comでオンラインコースを運営しています。
マイクロソフトPowerApps 中級編【SharePointで、実務で使える業務アプリの作り方:勤怠管理アプリ編】
⇒ 半額になる「ディスカウントリンクページ」へ
年月を選んでその月の稼働記録をカレンダーで表示する。
こんにちは、リーンシグマブラックベルトのマイク根上です。
業務改善コンサルをしています。
今日はこの動画リクエストからです。

「月単位で社員の稼働を一目で表示をさせたいと考えています。
午前午後で業務が違う人も多いのでそれもわかればというイメージです。」
伊藤さん、動画リクエストありがとうございました。
多くの業務を月単位でやりますので、
その毎日の業務の予定や結果を1ヶ月分表示させたい事は多々ありますよね。
しかしPowerAppsの既定ではカレンダーコントロールがないので、
複数のギャラリーを使って自作するしかありません。
ご要望により、複数の作業員の毎日、午前と午後の作業場所と
各労働時間を表示する画面を作りました。
先ずは完成した動きを見てみましょう。

最初にプルダウンで年月を表示して
ユーザーは表示させたい月を選びます。
すると選択した月の月初から月末までの日付を表示します。
各日の作業者名が横に並び、
彼らの午前と午後の作業場所と労働時間を表示させています。
午前と午後で二段にして見易くしている事にご留意下さい。
人数が多い日でも内部ギャラリーを横にスクロールすれば全て表示されます。
今回準備したデータソースの構造を確認する。
次に元データのテーブルの構造を確認しましょう。
今回はサンプルデータをコレクションで用意しましたが、
外部データソースでもこの後の数式の書き方は同じになります。
最近のPowerAppsでは画面左隅の変数アイコンから、
変数やコレクションを簡単に見えて便利になりました。
そして、「ビューテーブル」からそれらの中身の詳細も見えます。

下図が今回の元データの構造で
作業者一人に付き一日で午前と午後の二行のレコードになります。

年月を選択するドロップダウンの作り方。
それではこのギャラリーをどの様に作っているか見てみましょう。
それにはSequence関数とDate関数がキーとなります。
それらの関数を上手く使う事でカレンダーを
簡単に作成する事ができるのです。
まず最初の年月を選択するドロップダウンの選択肢ですが、
年の変わり目とかで上手く出すのに結構苦労します。
その「Items」属性を見ると下記の様に
こんな短い式でできてしまい、
ここでもSequence関数とDate関数を使っています。
年月を選択するドロップダウンの「Items」属性
=AddColumns(
Sequence(8),
”年月”,
Text(
Date(
Year(Today()),
Month(Today())-Value+1,
1
),
”yyyy-mm”
)
)
Sequence関数の使い方
上記コード内にSequence(8)とありますが、
その結果を見ると、1から8までの連番が入った、
列名が「Value」の一列でできたテーブルを作成してくれます。

因みに、第二引数に数字を入れると
始めの数字を変えられますし、
また第三引数に数字を入れると
連番の間隔を変えられます。
だから何?と思われますが、
結果がテーブル型になるのを利用して、
AddColumns関数と一緒に使って、
今回の様に自由に規則性のある選択肢を作ったり、
ギャラリーをカレンダー表示にできるのです。
ここではSequence関数で1から8の入ったテーブルを作成して、
AddColumns関数で新しく「年月」の列を作っています。
Date関数の使い方
AddColumns関数の第三引数に、
Text関数の内側でDate関数を使っています。
その部分を下に再掲しています。
Date関数の引数の構造を数式バーの上で確認すると
「Date(年, 月, 日)」です。
Date(
Year(Today()),
Month(Today())-Value+1,
1
)
その3つの引数に数値型の値を入れて日付を作成できます。
ここでは第一引数の「年」として、
Year関数とToday関数を使って、
今年の値、「2023」が入ります。
第二引数の「月」ですが、
Month関数を使って今月の数値から
「-Value+1」を入れています。
ちょっと分かり難いですね。
この第二引数の結果だけで、新たに列を作ってみます。
下図がそれで、作った「第二引数」の列を見て頂いて、
Month関数とToday関数で今月の5となり、
そこからValue列の各値で引いて1を足した値が入ります。

そしてDate関数の第三引数に単に「1」を入れています。
Date関数全体で新しい列を作ってみます。
それが下図内の「全体」列で、
これで毎月の一日の日付を作る事ができるのです。

下図がスクロールダウンした部分で、そこで分かる様に
Date関数の便利な点は引数に0やマイナスの数値を入れたら
年が変わってもちゃんとその対象の月になってくれるのです。
後でお見せしますが、この特性を使って
月末の日付もちゃんと取得する事ができます。

Date関数の結果をText関数で
年四文字、月二文字だけの書式(yyyy-mm)に変えているのです。
これで過去8か月分の年月の選択肢を作成できます。
Text(
[Date関数の結果],
”yyyy-mm”
)
Date関数だけで簡単に月末を求める方法
次が今日のテーマのカレンダーの作成です。
それをギャラリーで作ります。
下にスクロールするので「空の垂直ギャラリー」を使っています。
このギャラリー内には一枚のテキストラベルで日付だけを表示して、
もう一つのギャラリーを入れ子にしてその他の情報を表示させています。

それでは最初のギャラリーの「Items」属性の式を見ましょう。
最初のギャラリーの「Items」属性
=With(
{年月:Dropdown1.Selected.年月},
With(
{
月初:Date(Left(年月,4),Right(年月,2),1),
月末:Date(Left(年月,4),Right(年月,2)+1,0)
},
AddColumns(
Sequence(Day(月末)),
”日付2″,
月初 + Value – 1
)
)
)
まず、With関数を使って
さっきのドロップダウンで選択された年月を
一時的変数「年月」に入れています。
この値は何度も使うので短い分かり易い変数に入れた方が可読性が上がります。
そしてもう一つのWith関数を使って、
その変数「年月」の値とDate関数を使って選択年月の
月初の日と、月末の日を
それぞれ変数「月初」と「月末」に入れています。
選択された年月の書式(yyyy-mm)から
最初の4文字を取ると年になり、
最後の2文字を取るとその月になり、
それらをDate関数の第一、第二引数に入れて、
第三引数に「1」を入れる事で月初の日を取得できます。
また月末を求めるのに第二引数で
さっきの「月」の数値に1を足す事で翌月になりますよね。
そして第三引数で「1」を入れたら翌月の一日を求められますが、
「0」を入れる事でその一日前の今月の月末を取得できるのです。
月末は月によって28日や30、31日とありますが、
この式で簡単に正確に月末の日を求める事ができます。
Sequence関数とAddColumns関数を使ってカレンダー表示をする。
そして二つ目のWith関数の第二引数で
実際にギャラリーに表示させる式を入れます。(下コード参照)
ここでまたSequence関数とAddColumns関数を使って
カレンダー表示ができるのです。
AddColumns(
Sequence(Day(月末)),
”日付2″,
月初 + Value – 1
)
Sequence関数の引数に「Day(月末)」を入れていて、
1から選択年月の月の日数分だけの連番を作成します。
この列名は「Value」になるのをご留意下さい。
そしてAddColumns関数で新しい列名「日付2」の列を作成しています。
それは変数「月初」の日に「Value」列の各値を足して、
1を引いて選択月の毎日の日付を「日付2」列に入れているのです。
そして内部の日付のテキストラベルの「Text」属性に
「ThisItem.日付2」で毎日の日付が入いるのが分かります。
曜日を一文字で表示した見易い日付の表示の仕方
日付だけでも良いですが、曜日も出た方がユーザーには親切ですよね。
そこで次の式に変更すると、日付に曜日が入って簡潔に見易くなります。
例)2023年5月2日 ⇒ 5/2 (火)
内部の日付のラベルの「Text」属性
=Text(
ThisItem.日付2,
”m/d”
) & Substitute(
Text(
ThisItem.日付2,
” (ddd)”
),
”曜日”,
””
)
最初のText関数の第二引数に「”m/d”」を入れる事で
日付を簡潔にして、半角「&」記号で次の文字列と繋げています。
また同じ様にText関数を使ってその第二引数に「”(ddd)”」を指定する事で
その日の曜日を表示して、それを両括弧で挟んでいます。
しかしそれだけだと全ての行に「曜日」が入っていてくどいですよ。
そこでSubstitute関数を入れて、
「曜日」を二つのダブルクォーテーションの空白と置き換えています。
つまり「曜日」を削除して見易くしているのです。
内部ギャラリーを使って各日の稼働記録の情報を表示する。
次に内部ギャラリーで詳しい稼働記録情報を表示させます。
作業者が多い時でも右にスクロールして見える様に
「空の水平ギャラリー」を使っています。
その「Items」属性に次の数式を入れています。
内部のギャラリーの「Items」属性
=GroupBy(
Filter(
稼働記録,
日付=ThisItem.日付2
),
”作業者”,
”その他”
)
よく考えたら最初のギャラリーではデータソースは
Sequence関数だけで、全く稼働記録データと無縁でした。
この内部ギャラリーで初めてコレクション「稼働記録」から
そのデータを持ってきています。
まず内側のFilter関数で同じ日付である事を条件に絞込みをしています。
この「ThisItem.日付2」は最初のギャラリーで作った各行の日付です。
同じ作業者のデータが一日に午前と午後で二つありました。
それを上下に表示させるためにGroupBy関数で「作業者」列でまとめていて、
それ以外の列を全て新たなサブテーブルの「その他」に入れています。
もしこのGroupBy関数を使わないと
同じ作業者名が横に二回出てきてしまいます。
そしてこの内部ギャラリーのテンプレートに
テキストラベルを3枚追加していて、
一番上の「Text」属性に「ThisItem.作業者」で作業者名を表示しています。
二番目のラベルのText」属性の数式はこれです。
内部の二枚目のラベルの「Text」属性
=”午前:” & LookUp(
ThisItem.その他,
時間帯=”午前”,
作業場所
) & ” ” & LookUp(
ThisItem.その他,
時間帯=”午前”,開始時間
) & “~” & LookUp(
ThisItem.その他,
時間帯=”午前”,
終了時間
)
もう一度ソースデータを見ましょう。

さっきの数式でやっている事は
各作業者の各日の「時間帯」列の値が「午前」の
「作業場所」、「開始時間」、「終了時間」の各データを
LookUp関数で取得して、半角の「”」と「&」記号を使って
ユーザーに読み易い様に加工して表示しているのです。
ここでの注意点はLookUp関数のソースデータを
さっきのGroupBy関数で作ったサブテーブルの
「ThisItem.その他」にしている事です。
次の午後のテキストラベルを見ると、
午前と同じ様な数式で、
ただ「午前」の文字を「午後」にして、
各ユーザーの午後の作業情報を表示しているのです。
カレンダー内で違うデータを表示したい時は、
基データを変えるだけで今回の手法のまま
色んな場面で使えますのでぜひマスターしてみて下さい。
「こちらの記事も読まれてます。」