1
/
5

PowerApps~ギャラリーでガントチャート~

Photo by Ed Hardie on Unsplash

こんにちは!開発エンジニアの松田です。PowerPlatformによるローコード開発を続けていて、気づいたら1年が経過していました。

お客様から初めてのご要望

「作業開始日、作業終了日という列を持つレコードを一覧表示したときガントチャートを表示して欲しい。」とのこと。
さらにガントチャートの開始点は「今日の日付」をもとにして欲しいとのことでした。

私にとってはやったことがないどころか今までの案件でもやってる人を見たことがない内容なので、ひとまずガントチャートって何ぞや?というところから考えてみることに、、、

縦軸に作業内容、横軸に時間を並べて、該当する箇所の色を変えれば良い。
複雑そうに見えて、意外といけるかも?と思わせておいて、やっぱりちょっとめんどくさい内容です。
正直ローコードでやるの嫌だなぁ、、、という感想。

とはいえ、やらなければいけないわけで、、

どうやれば実現できるか仕組みを考えてみました。

前提としてお客さんの要望は「ガントチャートに表すのは月単位で良い」ということなので、ギャラリーの上のタイトル列をこのようにしてみました。

//開始月の列はこれでよい
Text(Month(Today())) & "月" //今日の日付から月だけを取り出しています

//2列目以降のタイトルのTextプロパティをこうする
//nは「今日から見て何カ月後か」という任意の値
If(Text(Month(Today())) + n > 12, //もし計算結果が年明けだったら
    (Text(Month(Today())) + n) - 12 & "月", //例:13月 - 12月 = 1月
    Text(Month(Today())) + n & "月" //年明けでなければそのまま表示
)

例えば今日は4月だとして、2カ月後は4 + 2 = 6となるのでそのまま6月と表示されますが、、
9カ月後は4 + 9 = 13となるので13 - 12 = 1月と直してあげないといけないので、このような形になります。
これで出力されるタイトル列が下図のようになります。

続いて中身の方なのですが、今回は「背景色を変える」だけで良いのでギャラリー行のFillプロパティに下記コードを記述します。

//開始月
If(ThisItem.StartDate < Today() && //作業開始日が今日より前(既に開始されている)
    ThisItem.EndDate > Today(), //かつ作業終了日が今日より後(まだ継続中)
    Color.Orange, //trueのとき背景色をオレンジに
    RGBA(0,0,0,0)  //falseのときは背景色なしに
)

//nカ月後(2列目以降)
If(ThisItem.StartDate < DateAdd(Today(), n, TimeUnit.Months ) && //開始日がnカ月後より前
    ThisItem.EndDate > DateAdd(Today(), n, TimeUnit.Months ), //かつ終了日がnカ月後より後
    Color.Orange,
    RGBA(0,0,0,0)
)

これで作業開始日が5月14日で、作業終了日が7月19日というレコードがあった場合、下図のような見た目になります。

この方法だとギャラリー上で直接編集などはできませんが、このレコードの本来の編集フォーム画面から編集したりSharePointリストで直接日付を書き換えた場合にはちゃんと変更が反映される仕組みになっています。(ギャラリー上部に更新ボタンを置いてRefreshしてあげるなどでもOK)

執筆中に新たな問題点が、、

この記事を執筆していて気付いたことなのですが、この方法で実装すると次のような問題があることが判明しました。

今日が4月18日、レコードの作業開始日が5月14日、作業終了日が8月17日だった場合。
さきほどの図と同じように8月が白背景で表示されてしまいます。
理由は明確で、単純にTodayにnカ月足しているだけなので8月18日を基準日として見ているからです。
これだと8月列時点でその作業は「終了している」とみなされてしまうわけです。

ではどうすればよいか?
執筆中に解決策を模索した結果、おそらくこれが良いだろうという結論に至ったコードを掲載しておきます。

//「nカ月後の翌月1日よりも前にスタートしている(nカ月後の月内に開始されている)
//かつ「nカ月後の1日以降に終了予定である(nカ月後の月内に終了予定)
If(ThisItem.StartDate < DateAdd(Date(Year(Today()),Month(Today()),1), (n+1), TimeUnit.Months) &&
    ThisItem.EndDate >= DateAdd(Date(Year(Today()),Month(Today()),1), n, TimeUnit.Months),
    Color.Orange,
    RGBA(0,0,0,0)
)

ちなみになぜ「月末を取得」ではなく、回りくどく「翌月の1日を取得」しているのかというと「翌月1日から1日引く」というコードのところで謎のエラーが発生して解決するのが難しかったからです(小声)

すいません、本記事を投稿した翌日に月末日取得について解決したので備忘録的に記載しておきます。
どうやら私がこの末尾にある「-1」を記述する箇所を間違えていたためにエラーが出ていたようです。
下記のコードで「某月1日の1日前」という引き算によって前月の末日を取得することが可能となります。

Date(Year(Today()),Month(Today()),1) - 1


まとめ

このように日付を扱う際には「いつを基準日としているのか」がかなり重要で、それでいて失念しやすいポイントだと思います。
以前、テストで参画していた現場でも「月末を取得する」という段階が抜けていることで不具合が発生していたことがありました。
当月内という条件でみる場合は開始、終了のどちらを見るのかで月末や月初のどちらを見るべきなのかに注意しましょう。

株式会社シスナビ's job postings
6 Likes
6 Likes

Weekly ranking

Show other rankings
Invitation from 株式会社シスナビ
If this story triggered your interest, have a chat with the team?