Mark Hammer's blog

SalesforceやTrailheadに関する情報を投稿しているブログです。

行動の被招集者をまとめたテキスト項目を作りたい

要件

行動には、「被招集者」という標準項目があります。

f:id:mark-hammer:20200801223946p:plain
行動レコード画面

「被招集者」項目には同じ行動に参加予定のユーザを追加しています。

さて、行動と被招集者をレポート表示する場合、標準レポートタイプの「被招集者が関連する行動」だと、以下のように被招集者の人数分の行ができてしまいます。

f:id:mark-hammer:20200801224206p:plain
「被招集者が関連する行動」レポートタイプの表示

こんな表示はいやだ、下記キャプチャのように行動ごとに被招集者のユーザを一覧できる項目を作ってくれ、というのが今回の要件となります。

f:id:mark-hammer:20200801224431p:plain
期待するレポート表示

具体的な要件

  • 「被招集者」項目に表示されているユーザの氏名をまとめてテキスト項目「同行者」にカンマ区切りで設定してほしい。同行者の並び順は任意とする。
  • 「被招集者」項目に行動任命先ユーザ以外の値を設定していない場合は「被招集者が関連する行動」レポートタイプのレポートには表示されないので、「同行者」項目もそれに合わせ空白とする。
  • 「被招集者」項目にはユーザの他にリード、取引先責任者、リソースも設定できるが、今回はユーザ以外のものは「同行者」項目に反映しない。

「被招集者」項目の内容はどうやって保存されるのか

Salesforce標準オブジェクトの中でも、ToDo、行動は特殊なオブジェクトです。
以下のオブジェクトER図を見てもそれが分かります。(出典元)

f:id:mark-hammer:20200801225237p:plain
ToDo・行動オブジェクトER図

このうち、「被招集者」項目のデータはEventRelationオブジェクトに保存されています。
例えば、ある行動にユーザ、取引先責任者、リード、リソースを保存した場合、以下のように保存されます。

EventId RelationId 備考
00U112222233333AAA 005aaBBBBBcccccZZZ 被招集者のユーザ
00U112222233333AAA 003bbCCCCCdddddYYY 被招集者の取引先責任者
00U112222233333AAA 00QccDDDDDeeeeeXXX 被招集者のリード
00U112222233333AAA 023ddEEEEEfffffWWW 被招集者のリソース

ここで問題は、【「被招集者が関連する行動」レポートタイプのレポートには任命先ユーザも表示されるが、EventRelationオブジェクトには任命先ユーザは入っていない】ことです。
行動を作成すると、「被招集者」項目にはデフォルトで任命先ユーザが入りますが、この任命先ユーザはEventRelationオブジェクトには存在しないのです。

実現方法

以上を踏まえ、要件に合う仕組みを考えると、以下となりました。

  • 要件実現にはEventRelationオブジェクトのデータを取得する必要があるが、プロセスビルダーでは取れないのでフローの利用が必須。
  • フロー処理内容は以下のようにする。
    • 作成/編集された行動オブジェクトのレコードIDに紐づくEventRelationオブジェクトのデータを全て取得する
    • 取得したデータからユーザのデータだけ取り出し、ユーザ氏名を変数に代入する。
    • EventRelationオブジェクトのデータにユーザのデータが1つ以上あった場合は、任命先ユーザ氏名も追加して「同行者」項目を更新する。
    • EventRelationオブジェクトのデータにユーザのデータがない場合は、「同行者」項目を空白で更新する。

作成したフロー

全体図

f:id:mark-hammer:20200801231024p:plain
フロー全体図

EventRelationオブジェクトデータ取得処理部分

f:id:mark-hammer:20200801231617p:plain

当初は「EventRelationオブジェクトのデータからユーザだけ取り出す」処理は、以下の通り最初のレコード取得要素で処理しようと考えていました。

f:id:mark-hammer:20200801231801p:plain

しかし、「ID項目は【次の文字列で始まる(starts with)】は使用不可」というエラーが出て、この方法は不可となりました。*1

f:id:mark-hammer:20200801231922p:plain

最終的に、ここでの条件は「行動レコードIDに紐づくEventRelationオブジェクトのデータを全て取得する」だけにしました。

f:id:mark-hammer:20200801232325p:plain
修正後の条件

EventRelationオブジェクトデータからユーザ情報抽出処理部分

f:id:mark-hammer:20200801232529p:plain

一部文字被りがありますが、ここでの処理は以下です。

  • 前の処理で取り出したRelationIdが005以外から始まる場合はループ要素に戻す。
  • RelationIdが005から始まる場合はユーザオブジェクトから名前(Name)を取り出し、変数に保存する。
  • RelationIdが005から始まるレコードが複数存在する場合は、名前をカンマ区切りでつなぎ合わせる。

ユーザオブジェクトからのレコード取得要素を入れている場合は、RelationIdが複数オブジェクトのレコードを受け入れる仕様のため、RelationId.Name という取り出し方ができないためです。*2

ユーザ情報抽出後処理部分

f:id:mark-hammer:20200801233420p:plain

ここでの処理は、以下となります。

  • 前の処理で名前保存用変数が空白の場合は、「任命先以外に被招集者となったユーザが存在しない」ため、「同行者」項目を空白で更新する。
  • 名前保存用変数が空白ではない場合は、任命先ユーザの名前も追加し、「同行者」項目を変数の内容で更新する。

ToDoの場合は任命先にキューも設定できるため、「任命先がユーザか否か」の決定要素も必要ですが、行動は現状キューが使えないため、決定要素は外しました。

終わりに

改めて、どのオブジェクトレコードも項目値に設定できる項目を持つToDo、行動に対する自動処理を考えるのが難しいことを学びました。
標準オブジェクトのER図も把握した上でデータの取得方法を考えるのはなかなか大変でした。

Trailheadではない、独自の要件からフローを作ったのは今回が初ですが、Flow Builderになってかなり機能拡張され、直感的にわかりやすくなったと思います。
ただ、要素を組み合わせることによる自由度の高さと、複雑さどちらも備える機能のため、使いどころは考えたいと思います。

*1:プロセスビルダーだと「行動の関連先が003から始まる(取引先責任者)」を条件にできますが、フローだとダメなんですね

*2:ループ内にレコード取得要素を入れるのはガバナ制限を考えるとよくないというヒントも表示されましたが、やむなしとしました