【Salesforce】祝日にリマインドが飛ぶのを防ぐ!フローで作る「営業日」判定ロジック完全ガイド

Keisuke Hisamitsu

Rewa Tech

技術コラム

システム開発

はじめに:その通知、せっかくの祝日に飛んでいませんか?

「担当者を割り当ててから2日後にSlackでリマインドを送りたい」 そんな要件、Salesforce管理者なら一度は耳にしたことがあるはずです。しかし、標準機能の「スケジュール済みパス」だけで設定すると、せっかくの祝日にSlackが鳴り響くことになります。

ゴールデンウィークの真っ最中、山登りを楽しんでいる最中に「商談の対応が遅れています!」とリマインドが届く……。これではユーザーのやる気を削ぐだけでなく、システムへの信頼も失ってしまいます。休日はしっかり休み、営業日に最高のパフォーマンスを出す。そんな当たり前を実現するために、フローで「営業日」を判定するロジックをマスターしましょう。

なぜ日本の祝日判定は「自動化」が難しいのか

Salesforceの標準機能だけで完結できない最大の理由は、日本の祝日が「固定ではない」ことにあります。

内閣府の「国民の祝日について」で定義されているルールを改めて見てみましょう。日本の祝日が、いかに複雑かがわかります。

  • 振替休日:「国民の祝日が日曜日に当たるときは、その日後においてその日に最も近い『国民の祝日』でない日を休日とする」という動的なルール。
  • 国民の休日:前日と翌日が「国民の祝日」である平日は、休日になる。
  • ハッピーマンデー:特定週の月曜日に移動する祝日。

これらをすべてフローの数式で網羅するのは現実的ではありません。

解決策:休日(Holiday)オブジェクトへの「単体登録」

Salesforce標準の「休日(Holiday)」オブジェクトを活用しましょう。あえて「毎年1回、管理者が翌年分を『繰り返しなし』のレコードとして一括登録する」運用を推奨します。内閣府の公表データに基づき登録するこの「少しのアナログ」が、フローのロジックをシンプルにし、法改正にも柔軟に対応できる保守戦略になります。

【詳細手順】Holidayオブジェクトへの「単体登録」方法

「休日」の設定は、通常のオブジェクトマネージャーではなく、Salesforceの「設定」メニュー内にあります。

  1. Salesforce画面右上の「歯車アイコン」から [設定] をクリック
  2. クイック検索ボックスに 「休日」 と入力し、[会社情報] > [休日] を選択
  3. [新規] ボタンをクリック
  4. 以下の項目を入力
    • 休日名:任意の名前(例:元日、成人の日)
    • 日付:祝日の日付を入力
    • 時間:終日チェックをON
  5. 重要:下部の「繰り返しの設定」は チェックを入れずに空欄のまま にします
  6. [保存] をクリック

実装するフローの全体像

具体的な手順に入る前に、これから作成する仕組みの全体像を確認しておきましょう。今回は、役割の異なる2つのフローを組み合わせて「営業日判定」を実現します。

フロー名 種類 役割
①商談アサイン日更新フロー レコードトリガー 担当者が決まった瞬間に、その「日付」をレコードに記録します。
②営業日判定&通知フロー スケジュールトリガー 毎日定刻に起動し、「今日から2営業日前」の日付を計算。対象レコードを抽出してSlack通知を送ります。

処理の流れ

  1. [準備] 祝日データをHolidayオブジェクトに登録しておく
  2. [起点] フロー①:商談の担当者が変わったら、「アサイン日」を記録する
  3. [判定] フロー②:毎日定刻に起動し、土日・祝日をスキップしながら「2営業日前」を逆算する
  4. [実行] フロー②:逆算した日付と「アサイン日」が一致する放置商談を見つけて通知する

この「2段構え」の構成を頭に入れておくと、各ステップの作業の意味がスムーズに理解できるようになります。

フロー①:担当者の「アサイン日」を記録する

営業日を正確に計算するためには、まず「いつ担当者が決まったのか」という正確なスタート地点(基準日)をデータとして持っておく必要があります。

Salesforceの標準機能では「担当者が変更された履歴」は追えますが、フローで計算に利用するには専用の日付項目があった方が圧倒的に便利です。まずは、担当者が変わった瞬間にその日付を記録する簡単な仕掛けを作ります。

事前準備

商談オブジェクトにカスタム項目 『担当者アサイン日』日付型)(OwnerAssignedDate__c) (を作成しておきます。

フロー設定:レコードトリガーフロー

  • オブジェクト:商談
  • トリガー:レコードが作成または更新された
  • 条件:担当者(OwnerId)が変更された、かつ 担当者(OwnerId)がユーザーである (IDが005ではじまる)
  • 最適化:高速項目更新
  • 更新内容:担当者アサイン日OwnerAssignedDate__cに現在日 (実行中のフローインタビュー$Flow.CurrentDate)を割り当てる

フロー②:「2営業日前」にアサインされた放置商談を特定し、通知する

基準日が用意できたら、いよいよ本丸の「営業日判定」に入ります。

このステップでは、毎日決まった時間に起動するスケジュールトリガーフローを使用します。このフローの最大の役割は、「今日から遡って、土日と祝日を除いた『2日前』は具体的に何月何日か?」を特定することです。その日付を導き出した後、ステップ1で記録したアサイン日と照らし合わせることで、放置されている商談を正確に抽出します。

1. 判定に使うリソース

  • 2営業日前を保持するための日付変数(var_TargetDate)
    初期値は現在日 (実行中のフローインタビュー $Flow.CurrentDate)を設定します。
  • 2営業日前をカウントするための数値変数(var_BusinessDayCounter)
    初期値は0を設定します。
  • 土日判定のBoolean数式(for_IsWeekend)
    判定対象の日付が土日かどうかを True/False で返します。

OR( 
  MOD({!var_TargetDate} - DATE(1900, 1, 7), 7) = 0, /* 日曜日 */
  MOD({!var_TargetDate} - DATE(1900, 1, 7), 7) = 6 /* 土曜日 */ 
)

※ DATE(1900, 1, 7) は基準となる日曜日です。

  • Slack通知メッセージ用のテキストテンプレート (tt_SlackNotificationBody)<例文>商談対応リマインド 2営業日前にアサインされた以下の商談が「未着手」のままです。
    至急、内容を確認して初動対応をお願いします!

    • 商談名: {!loop_Opportunities.Name}
    • アサイン日: {!loop_Opportunities.OwnerAssignedDate__c}
    • リンク: Salesforceで開く

2. フローの要素構成

1. 開始(Start)

  • タイプ:スケジュールトリガーフロー
  • 条件:オブジェクトを選択せずに「なし」で設定(※日付計算を先に行うため)

2. レコード取得:『祝日レコードの取得』 (get_HolidayRecords)

  • オブジェクト:休日(Holiday)
  • 条件:ActivityDate(日付) 次の値以下:$Flow.CurrentDate(今日)
  • 保存:すべてのレコードを保存(※過去分を含めて取得し、遡り計算に使用します)

3. 決定:『ループ継続判定(2日未満か)』(dec_CheckCounter)

ここから日付計算のループが始まります。

  • 結果(はい):var_BusinessDayCounter次の値未満:2
    → 次の「4」へ接続
  • 結果(いいえ/デフォルト):(2日分の遡りが完了)
    → 「9」のレコード取得へ接続

4. 割り当て:『日付を1日戻す』(asg_SubtractOneDay)

  • var_TargetDate(日付変数) 次の値を減算:1

5. 決定:『土日判定』(dec_IsWeekend)

  • 結果(土日):数式 for_IsWeekendTrue
    → 「3」の継続判定へ戻る(カウントを増やさずやり直し)
  • 結果(平日):次の「6」へ接続

6. コレクション検索条件:『祝日レコードの抽出』 (fil_CheckHoliday)

  • コレクション:get_HolidayRecordsから取得したリスト
  • 条件:ActivityDate次の値と一致する:var_TargetDate

7. 決定:『祝日判定』 (dec_IsHoliday)

  • 結果(祝日):fil_CheckHoliday(フィルタ結果の数) 次の値より大きい:0
    → 「3」の継続判定へ戻る(祝日なのでカウントせずやり直し)
  • 結果(営業日):
    → 「8」へ

8. 割り当て:『営業日数カウントアップ』 (asg_BusinessDayCounterAddOne)

  • var_BusinessDayCounter1を加算。その後、「3」の継続判定へ戻る

9. レコード取得:『滞留商談レコードの取得』 (get_Opportunities)

  • オブジェクト:商談 (Opportunity)
  • 条件:OwnerAssignedDate__c(担当者アサイン日) 次の値と一致する:var_TargetDate
    • StageName(フェーズ) 次の値と一致する:未着手(※組織のフェーズ名に合わせてください)
  • 保存:すべてのレコードを保存

10. ループ:『商談レコードのループ』 (loop_Opportunities)

  • 取得した商談コレクションを1件ずつ処理します。

11. アクション:『Slackに投稿』 (act_PostToSlack)

  • 担当者への通知メッセージ(tt_SlackNotificationBody)を送信します。
  • ループの終わりを「9」に戻します。

終わりに:未来の通知にもこのロジックを応用

今回ご紹介した「営業日を遡る(カウントダウン)」ロジックは、日付を加算する「カウントアップ」に変えるだけで、未来の事前通知にも応用可能です。

例えば、「契約終了の30営業日前」を正確に算出し、解約防止の交渉を開始するためのリマインドを送るといった運用も同じ構造で実現できます。期限が過ぎてから焦るのではなく、営業日を味方につけて一歩先を行く自動化を構築しましょう。

Salesforceの標準機能に「営業日」という概念を持たせるこの一工夫が、現場のユーザーにとって本当に意味のある通知体験を生み出します。内閣府のサイトをチェックして祝日を登録したら、さっそくフローを構築してみましょう。

それ、サンブリッジなら実現できます!
Salesforceで解決するビジネス課題

【ダウンロード資料】Salesforce導入・開発を検討されているお客様必見
数あるSalesforceベンダー企業のなかから、サンブリッジが選ばれる理由はなぜか。課題別にどんなソリューションがあるのかといった観点で、実際にサンブリッジが対応した事例やご利用企業様からの評価などをご紹介します。(全16ページ)

関連記事