計算があわない!日付/時間型を参照する項目を使った日付計算で陥ったワナ

Salesforce
この記事は約6分で読めます。

数式はあっているのに返ってくる値は期待していたものではない…こんなことはありませんか?

もしかして計算式で日付/時間型の項目を参照する数式(日付)項目を計算で使用していませんか?

これにあてはまった方は以下の方法で対処可能かもしれません!

日付型が関連する数式で計算が想定通りに行かない場合
  • 数式(日付)項目にDATEVALUE()を使って日付であることを明確にしましょう!

日付/時間型の項目を参照して数式(日付)項目を作成した場合、その数式(日付)項目は元の日付/時間型の項目の時間部分(hh:mm:ss)の情報をそのまま持ち続けているようです。
例えば、日付/時間型の項目で「2022/02/10 12:34:56」という値を持っているとしましょう。それを参照する数式(日付)項目を作成した結果、画面上には「2022/02/10」と見えますよね。でも実はその後ろに元の参照してきた値の時間部分、つまり「12:34:56」が隠れているということなのです。

そのため、その数式(日付)型の項目を用いて日付計算を実行する場合は、ハッキリと「日付型として扱って計算してくれたまえ!」とSalesforceに示してあげる必要があります。

この記事はこんな人にオススメ
  • 日付型、日付・時間型の項目を使用していて、計算結果が期待通りにならずお困りの方

詳細を見ていきましょう。

スポンサーリンク

数式(日付)型の項目の値を計算に使っていて、計算が思い通りにいかない

ある日付/時間型を参照する数式(日付)型の項目の値を使って計算式を作る…文字だけだと理解しづらいかと思うので具体例を挙げてみます。

まず、日付/時間型の項目を参照する数式項目です。Aというオブジェクトに「会議開始日時」という項目があるとします。「日時」ですから日付/時間型で作成したということにしましょう。

Aというオブジェクトと参照関係にあるBというオブジェクトで「会議日」の情報が欲しいとします。会議の時間までは要らないけど日付が欲しいのです。ということでAオブジェクトの「会議開始時間」項目をとってくるような数式項目を作成します。数式でとってきた結果の値は(日付)型ですね。

さて、会議ではある年会費制のサービスに対する決済について話がなされているそうで、1年の途中から契約した場合、年会費は満額ではなく、決済日から年末までの分で良いのだとか…(いい会社)
この辺の設定は全然理解しなくて良いので、とりあえずこの日付型の項目を使用して何かを計算するのだな…ということだけ理解いただければと思います。

先ほど出てきた「会議日」=「決済日」として、決済日からその年の12/31までの日割り分の年会費を計算したいところです。

というわけで、支払金額をSalesforceの項目にしたいと思います。
必要なのはその年の日数と決済日と年会費ですね。まずは文字でどんな数式になるか考えてみましょう。

決済する年がうるう年でない場合→1年=365日なので、年会費を365で割った後、決済日から12/31までの日数をかける。

決済する年がうるう年だった場合、→1年=366日なので、年会費を366で割った後、決済日から12/31までの日数をかける。

これで計算できそうですね。実際に数式をかいてみましょう。

IF(
  /* うるう年判定 */
  OR(
    MOD( YEAR(決済日), 400 ) = 0,
    AND(
      MOD( YEAR(決済日), 4 ) = 0,
      MOD( YEAR(決済日), 100 ) != 0
    )
  ),
  /* うるう年でない場合の計算 */
  年会費 / 366 * (DATE( YEAR(決済日), 12, 31 ) - (決済日) +1 ),
  /* うるう年の場合の計算 */
  年会費 / 365 * (DATE( YEAR(決済日), 12, 31 ) - (決済日) +1 )
)

「決済日」「年会費」と書いた箇所は本来はSalesforceの項目のAPI参照名が入ります。
DATE( YEAR(決済日), 12, 31 ) – (決済日) +1 で+1としているのは決済日当日分も含めるためですのでさらっと流してください。うるう年の判定数式はSalesforceのヘルプに載っています。

だいだい例のイメージはつかめたでしょうか?実際に上記の数式で項目を作って計算してみます。

決済日は2022/04/16、年会費は36500とします。2022/12/31までは今日を含めると260日で2022年はうるう年ではないですので、返金額は36500 ÷ 365 ×260 = 26000円ですね。

ではSalesforceの数式の結果はどうでしょうか…?

支払額が想定通りにならない…!

25975円になってしまっていますね…計算が合いません。。

なぜ計算が合わないのか!?理由を解説

計算式はあっているのになぜ答えが正しくないのか?ここからは理由をお話していきます。

結論は最初にかいた通り、数式(日付)項目にした際に実は時間の情報も持ってしまっていたからです。

例でいうところの「決済日(日付時間型項目を日付型で参照している)」は見た目は2022/04/16ですが、2022/04/16 15:00 という情報を持っているということです。

そしてこの時間部分が原因で計算に狂いが生じます。試しに時間を変えてみましょう。

時間を変更すると支払額も変化するようだ…


19:00にすると支払額は25958円になりました。

数式で日付型にしていても、参照先が日付/時間型の場合は時間の情報まで持ってきてしまうようです。
そして別の数式(具体例でいうところの「支払額」)でその数式(日付)項目を使って計算をすると時間分の誤差が出てしまうということなのです。

DATEVALUE()関数を使おう

日付型を指定しているのに実は日付/時間の情報を持ってしまっている。。。
どうすれば良いのでしょうか?

対策としてDATEVALUE()関数を用いる方法をご紹介します。

この関数について、Salesforceのヘルプには「日付/時間またはテキストの式に対して日付型の値を返します」と書かれています。この関数を使うことで、日付/時間型の項目値であってもハッキリと!明確に!日付型であることを表せそうです。

実際に書いてみた数式がこちらです。修正するのは「決済日(日付時間型項目を日付型で参照している)」項目の数式です。

修正前

/*会議開始時刻をそのまま参照*/
DateTime__c

修正後

/*会議開始時刻をDATEVALUE()関数を使って日付型であることをハッキリ示す*/
DATEVALUE(DateTime__c)

数式を修正したところで、先ほど例でみたレコードをもう一度見てみましょう。

支払額が想定通りの値になっている

…26000円!正しい値になっていますね。時間を変えてみても値段は正しいようです。

まとめ

今回は数式項目で日付や日付/時間型が絡んだ時に陥ったワナについて書きました。

例が特殊かもしれませんが、数式(日付)型であっても日付/時間の値を参照している場合に時間分の情報を持っているというのは発見でした!

この記事が役に立った、分かりやすかったという方はハートをポチッとお願いします。

このブログではできるだけ分かりやすく、具体例を載せた感じでさまざまな設定方法や構築手順を紹介しています。解説してほしいものがありましたらぜひコメントください。

それでは、ごきげんよう。

コメント