進行状況の追跡を始めよう
Trailhead のホーム
Trailhead のホーム

高度な数式を使用してレベルアップ

学習の目的

この単元を完了すると、次のことができるようになります。
  • 複雑な使用事例に対応する高度な数式を実装する。
  • 整然として理解しやすい数式を記述する。

高度な数式

このモジュールでは、たくさんの複雑な数式を見てきました。けれども、ビジネス上の問題を取り上げ、数式を利用して解決を図ることは必ずしも容易なことではありません。この単元では、数式を概念から実践に移すためのヒントをいくつかご紹介します。

書き出す

数式を使用することを思い付いたら、高度な数式エディタを開く前に、日常的な言葉で検討します。まずその目標を自問し、ありふれた言葉で説明します。

この例は、Salesforce Trailblazer Community で取り上げられたものです。ここでの目標は、システム管理者以外の誰かが商談を「不成立」とマークする場合は、不成立の理由の記入を必須にすることです。

この例では、すでに [Loss Reason (不成立の理由)] というカスタム選択リスト項目が設定され、商談の不成立の正当な理由が事前入力されているものとします。誰であっても理由を記入しなければレコードを保存できないようにするという目標を達成するために、ここでは入力規則数式を使用します。

この数式の目的をわかりやすく言うと、次のようになります。

システム管理者以外の誰かが商談の [フェーズ] を「不成立」に変更し、かつ [Loss Reason (不成立の理由)] が空白の場合は、エラーを表示する。

数式を書き出したら、このモジュール全体で使用されている関数に対応するキーワード、つまり「and (かつ/および)」「or (または)」「if (もし/場合)」を探します。これらの関数は、より大規模でより複雑な数式を構築するビルディングブロックです。使用事例のこれらの言葉を認識することは、高度な数式の実装に役立ちます。

ユーザがシステム管理者でないことをチェックするには、レコードに編集を行うプロファイルを表す差し込み項目 $Profile.Name を挿入します。StageName が更新されているかどうかをチェックするには、ISCHANGED() を使用します。項目の現在の値が以前の値と異なる場合は、ISCHANGED() が true を返します。

残りの要件は、ISPICKVAL() でチェックできます。ISPICKVAL() についての詳細は、「数式での選択リストの使用」を参照してください。

  1. [設定] で、[クイック検索] ボックスを使用して [オブジェクトマネージャ] を検索します。
  2. [商談] | [入力規則] をクリックします。
  3. [新規] をクリックします。
  4. [ルール名] に、「Loss Reason Required (不成立の理由 (必須))」と入力します。
  5. [エラー条件数式] に、次の数式を入力します。
    AND(
      $Profile.Name <> "System Administrator",
      ISCHANGED(StageName),
      ISPICKVAL(StageName, "Closed Lost"),
      ISPICKVAL(Loss_Reason__c, "")
    )
  6. [エラーメッセージ] に、「Opportunities can’t be marked Closed Lost without providing a Loss Reason (不成立の理由を記入しない限り、商談を「不成立」とマークすることはできません)」と入力します。
  7. エラー表示場所には、[項目][Loss Reason (不成立の理由)] を選択します。
  8. [保存] をクリックします。

これで、システム管理者以外のユーザが商談を「不成立」とマークするたびに、エラーメッセージが表示されます。

整然としたスペースおよび書式の使用

数式に適切なスペースや書式を設定すると読みやすくなり、理解しやすくなります。テキスト数式の説明で、国、収益、ソースに基づいてリードに動的に評価を割り当てる数式を記述しました。

IF(AND(AnnualRevenue > 1000000, CONTAINS(CASE(Country,
"United States", "US", "America", "US", "USA", "US", "US", "US",
"NA"), "US")), IF(ISPICKVAL(LeadSource, "Partner Referral"),
"Hot", IF(OR(ISPICKVAL (LeadSource, "Purchased List"),
ISPICKVAL(LeadSource, "Web")), "Warm”, "Cold")), "Cold")

次の数式は構文的には正しいものの、これが何をするのか、どのような論理になっているのかを知ることはほぼ不可能です。数式ではスペースや改行は関係ないため、スペースを使って簡単に読みやすくすることができます。次も同じ数式ですが、インデントや改行によって整然としています。

IF(
  AND(AnnualRevenue > 1000000,
  CONTAINS(CASE(Country, "United States", "US", "America",
    "US", "USA", "US", "US", "US", "NA"), "US")),
  IF(
    ISPICKVAL(LeadSource, "Partner Referral"), "Hot",
    IF(
      OR(
        ISPICKVAL(LeadSource, "Purchased List"),
        ISPICKVAL(LeadSource, "Web")
      ), "Warm”, "Cold"
    )
  ), "Cold"
)

数式の書式に絶対的なルールはありませんが、論理ステートメントをネストするたびにインデントとスペースを 2 つ使用することをお勧めします。インデントを適切かつ一貫して使用すると、どの関数を処理しているのかがすぐわかり、括弧の過不足を回避できます。

論理ステートメントを読みやすくするもう 1 つの方法は、関数の代わりに論理演算子を使用することです。AND() の代わりに &&、あるいは OR() の代わりに || を使用すると、数式を見た人が論理フローに従いやすくなります。以下も同じ数式ですが、AND()OR() の代わりに &&|| が使用されています。

IF(
  AnnualRevenue > 1000000 &&
  CONTAINS(CASE(Country, "United States", "US", "America", "US", 
    "USA", "US", "US", "US", "NA"), "US"),
  IF(
    ISPICKVAL(LeadSource, "Partner Referral"), "Hot",
    IF(
      ISPICKVAL(LeadSource, "PurchasedList") ||
      ISPICKVAL(LeadSource, "Web"),
      "Warm", "Cold"
    )
  ), "Cold"
)

簡潔にする

複雑な数式を記述しているときに、ネストされた論理ステートメントや他の項目への参照で立ち行かなくなることが少なくありません。概して、最もシンプルな数式がベストな数式です。

次の入力規則数式は、商談の完了予定日が当月ではない場合に true を返します。
OR (
CloseDate < DATE( YEAR(TODAY()), MONTH(TODAY()), 1), 
IF (
AND (
MONTH (TODAY() ) =1, 
CloseDate > DATE( YEAR(TODAY() ), MONTH(TODAY() ), 31)),
true, 
IF (
AND (
MONTH (TODAY() ) =2, 
CloseDate > DATE( YEAR(TODAY() ), MONTH(TODAY() ), 28)), 
true,
IF (
AND (
MONTH (TODAY() ) =3, 
CloseDate > DATE( YEAR(TODAY() ), MONTH(TODAY() ), 31)), 
true,
IF (
AND (
MONTH (TODAY() ) =4, 
CloseDate > DATE( YEAR(TODAY() ), MONTH(TODAY() ), 30)),
true,
IF (
AND (
MONTH (TODAY() ) =5, 
CloseDate > DATE( YEAR(TODAY() ), MONTH(TODAY() ), 31)),
true, 
IF (
AND (
MONTH (TODAY() ) =6, 
CloseDate > DATE( YEAR(TODAY() ), MONTH(TODAY() ), 30)),
true,
IF (
AND (
MONTH (TODAY() ) =7, 
CloseDate > DATE( YEAR(TODAY() ), MONTH(TODAY() ), 31)),
true,
IF (
AND (
MONTH (TODAY() ) =8, 
CloseDate > DATE( YEAR(TODAY() ), MONTH(TODAY() ), 31)),
true,
IF (
AND (
MONTH (TODAY() ) =9, 
CloseDate > DATE( YEAR(TODAY() ), MONTH(TODAY() ), 30)),
true,
IF (
AND (
MONTH (TODAY() ) =10, 
CloseDate > DATE( YEAR(TODAY() ), MONTH(TODAY() ), 31)),
true,
IF (
AND (
MONTH (TODAY() ) =11, 
CloseDate > DATE( YEAR(TODAY() ), MONTH(TODAY() ), 30)),
true,
IF (
AND (
MONTH (TODAY() ) =12, 
CloseDate > DATE( YEAR(TODAY() ), MONTH(TODAY() ), 31)),
true, false
)))))))))))))
この複雑なチェックは、完了予定日が当月の初日より前か、当月の最終日より後かを判断します。けれども実際のところ、日は関係ありません。完了予定日の年月が当月の年月と同じであれば、同じ月になります。そのため、数式を次のとおり記述し直しました。
NOT( 
  AND( 
    MONTH( CloseDate ) = MONTH( TODAY() ), 
    YEAR( CloseDate ) = YEAR( TODAY() ) 
  ) 
)
この新バージョンははるかに読みやすく、当初の数式が 3,000 字を超えていたのに対し、わずか 200 字にコンパイルされます。数式が必要以上に複雑と思えるときは、おそらくそのとおりでしょう。簡潔にするために、別の角度から問題に取り組んでみてください。