Salesforceフロー:変換要素と「次に含まれる」演算子で関連レコードを一括取得する
#Salesforce #フロー #変換要素 #関連レコード #一括取得
目次
- 1. 変換要素とは
- 1.1 変換要素を使うメリット
- 2. 「次に含まれる」演算子とは
- 2.1 「次に含まれる」を使うメリット
- 2.2 なぜ「ループ内のデータ操作」を避けるべきなのか
- 3. 2つを組み合わせると何ができるか
- 4. 具体例:完了予定日が今日以前の未クローズ商談に関連する取引先責任者を取得する
- 4.1 Step 1:完了予定日が今日以前の未クローズ商談を取得する
- 4.2 Step 2:変換要素で AccountId コレクションを作る
- 4.3 Step 3:「次に含まれる」で取引先責任者を取得する
- 5. 従来の作り方との比較
- 6. このパターンの考え方
- 7. 注意点
- 7.1 0件の場合は分岐する
- 7.2 空のIDを含めない
- 7.3 重複IDを考慮する
- 8. まとめ
Salesforceフローで複数レコードを扱うとき、よくある課題のひとつが関連レコードの取得です。
たとえば、
・「完了予定日が今日以前の未クローズ商談」に紐づく取引先を起点に、その各取引先に所属する取引先責任者をまとめて取得したい
という要件があったとします。
このとき、商談を1件ずつループし、その中で取引先責任者を取得する構成にしてしまうと、対象件数が増えたときにレコード取得の回数が増えてしまいます。
そこで使えるのが、フローの変換要素と「次に含まれる」演算子です。この記事では、まずそれぞれの特徴とメリットを整理し、その後で2つを組み合わせた具体的な活用例を紹介します。
– 変換要素でレコードコレクションからIDコレクションを作る考え方
– 「次に含まれる」演算子で関連レコードを一括取得する方法
– ループ内のレコード取得を避ける設計のメリット
– 商談に関連する取引先責任者をまとめて取得する具体例
変換要素とは
変換要素は、フロー内のデータを別の形に変換するための要素です。たとえばレコードコレクションから特定の項目だけを取り出して、別のコレクションを作ることができます。
今回のようなケースでは、商談レコードコレクションから AccountId だけを取り出し、取引先IDのコレクションを作るために使えます。
商談レコードコレクション取得
↓
Opportunity.AccountId だけを抽出
↓
取引先IDのテキストコレクション


従来であれば、こうした処理はループと割り当てで実装することが多かったと思います。
商談をループ
↓
現在の商談.AccountId をテキストコレクションに追加
↓
次の商談へ

変換要素を使うメリット
変換要素はいくつかの機能を持っていますが、今回の大きなメリットは、コレクションの形を変えるためだけのループを減らせることです。
変換要素を使うと、「レコードの集合」から「検索条件に使う値の集合」へ変換できます。今回の例では、商談レコードコレクションをそのまま後続処理に渡すのではなく、AccountId だけのテキストコレクションに変換しています。
商談レコードコレクションそのものには、Id、Name、Amount、CloseDate、AccountId など、さまざまな項目が含まれています。しかし、後続処理で必要なのが AccountId だけであれば、商談レコード全体を持ち回る必要はありません。
- ループ要素を減らせる
- 割り当て要素を減らせる
- フローの見た目がシンプルになる
- レコードコレクションから必要な項目だけを抜き出せる
- 後続処理に渡しやすい形へ変換できる
- 「何のために値を取り出しているか」が分かりやすくなる
特に重要なのは、フローの意図が読み取りやすくなることです。ループと割り当てで実装している場合、あとから見た人は「このループは何のため?」「この割り当てでは何を集めている?」と読み解く必要があります。
一方、変換要素を使えば、「商談コレクションから AccountId コレクションを作る」という目的を要素単位で表現できます。つまり変換要素は、単に要素数を減らすだけでなく、フローを読みやすく保つための要素としても有効です。
「次に含まれる」演算子とは
「次に含まれる」は値がコレクション内に含まれるかを判定する演算子です。
レコード取得要素で使うと、SOQL の IN 句のように、複数の値に一致するレコードをまとめて取得できます。
なお、フローにはこの系統の演算子として、「次に含まれる」と「次に含まれない」があります。
・次に含まれる
指定した値が、コレクション内に含まれているレコードを取得する
・次に含まれない
指定した値が、コレクション内に含まれていないレコードを取得する
SOQL の考え方に置き換えると、「次に含まれる」は IN 句、「次に含まれない」は NOT IN 句に近いイメージです。
今回の記事では、完了予定日が今日以前の未クローズ商談に関連する取引先責任者を取得したいため、取引先責任者の AccountId が、商談から抽出した取引先 ID コレクションに「次に含まれる」条件を使います。
Contact.AccountId 次に含まれる 取引先IDコレクション

1つの取引先IDに一致する取引先責任者を取得するのではなく、複数の取引先IDに一致する取引先責任者をまとめて取得できる、ということです。
「次に含まれる」を使うメリット
「次に含まれる」演算子の大きなメリットは、関連レコードを一括で取得できることです。
もし「次に含まれる」を使わない場合、次のような構成になりがちです。
商談レコードコレクション取得
↓
商談をループ
↓
ループ内で、その商談の取引先に紐づく取引先責任者を取得
この構成は分かりやすく見えますが、商談の件数が増えるほど、レコード取得要素の実行回数も増えてしまいます。
一方、「次に含まれる」を使えば、次のようにできます。
取引先IDコレクションを用意
↓
Contact.AccountId 次に含まれる 取引先IDコレクション
↓
取引先責任者を一括取得
- 複数の値を条件にできる
- 関連レコードをまとめて取得できる
- レコード取得要素の実行回数を減らせる
- ループ内のレコード取得を避けやすくなる
- SOQLのIN句に近い考え方でフローを設計できる
なぜ「ループ内のデータ操作」を避けるべきなのか
ここで言う「ループを使わない」は、すべてのループを否定しているわけではありません。問題になりやすいのは、ループの中で[レコードを取得][レコードを作成][レコードを更新][レコードを削除]など、データベースにアクセスする要素を繰り返し実行する構成です。
たとえば、商談を1000件取得して、そのループ内で取引先責任者を取得すると、取引先責任者のレコード取得が最大1000回実行される可能性があります。対象件数が増えるほど処理回数も増えるため、ガバナ制限やパフォーマンス面で不利になります。
一方、取引先IDを先にコレクション化し、「次に含まれる」で取引先責任者をまとめて取得すれば、取引先責任者の取得は1回で済みます。
・避けたい構成例:
商談1000件 → ループ内で取引先責任者を取得 →[レコードを取得]要素が最大1000回実行される
・改善構成:
商談1000件 → AccountIdコレクション化 → 取引先責任者の取得は1回
ガバナ制限に強くなる:Salesforceでは、1回のトランザクション内で実行できるSOQLクエリ数やDML実行回数などにガバナ制限があります。ループ内で[レコードを取得]や[レコードを更新]などを繰り返すと、対象件数に比例してSOQLやDMLの実行回数が増え、制限に達しやすくなります。
処理性能が安定しやすい:ループ内でレコード取得を繰り返す構成は、件数が少ないときは問題が見えにくいですが、件数が増えると処理時間が伸びやすくなります。一括取得にすると、件数増加に対して設計が安定しやすくなります。
フローの意図が明確になる:「まず対象をまとめて取得し、必要なIDを集め、関連レコードをまとめて取得する」という流れは、後から見ても処理の目的が分かりやすくなります。
後続処理も一括処理にしやすい:関連レコードをまとめて取得しておくと、通知・更新・メール送信などの後続処理も、コレクション単位で考えやすくなります。
つまり、ループを減らすこと自体が目的ではありません。目的は、フローを「1件ずつ処理する形」ではなく、「まとめて取得し、まとめて処理する形」に近づけることです。変換要素と「次に含まれる」は、そのための有効な組み合わせです。
2つを組み合わせると何ができるか
変換要素と「次に含まれる」は、それぞれ単体でも便利です。ただし、関連レコードを一括取得する場面では、組み合わせることで真価を発揮します。
| 要素・演算子 | 役割 |
|---|---|
| 変換要素 | レコードコレクションから、検索条件に使いたい項目だけを抜き出す |
| 次に含まれる | 抜き出した値のコレクションを使って、関連レコードを一括取得する |
レコードコレクション
↓
変換要素
↓
次に含まれる
↓
関連レコードを一括取得
今回の例では、次のようになります。
商談レコードコレクション取得
↓
変換要素で Opportunity.AccountId だけを抽出
↓
Contact.AccountId 次に含まれる 取引先IDコレクション
↓
取引先責任者を一括取得
ここでポイントになるのは、「次に含まれる」にはレコードコレクションをそのまま渡すのではなく、比較対象となる項目だけのコレクションを渡すという点です。
Salesforce の ID 項目は、フロー上ではテキスト型の値として扱えます。そのため、変換要素の変換先はテキストコレクションにします。
できない例:
Contact.AccountId 次に含まれる 商談レコードコレクション
できる例:
Contact.AccountId 次に含まれる AccountIdテキストコレクション
具体例:完了予定日が今日以前の未クローズ商談に関連する取引先責任者を取得する
フロー全体像

ここからは、具体的なフロー例です。要件は次の通りです。
完了予定日が今日以前の未クローズ商談に関連する取引先責任者をまとめて取得したい
想定する処理は次の流れです。
完了予定日が今日以前の未クローズ商談一覧
↓
商談に紐づく取引先IDを集める
↓
その取引先に所属する取引先責任者を取得する
Step 1:完了予定日が今日以前の未クローズ商談を取得する
レコード取得「完了予定日が今日以前の未クローズ商談一覧」

オブジェクト:
商談(Opportunity)
条件:
CloseDate 以下 今日を表す日付リソース
IsClosed 次の値と一致 false
AccountId Null false
保存方法:
すべてのレコード
ここでは、完了予定日が今日以前で、まだ完了していない商談を対象にしています。
Step 2:変換要素で AccountId コレクションを作る
変換要素で Opportunity.AccountId をコレクション化

変換元:
完了予定日が今日以前の未クローズ商談コレクション
変換先:
変換要素の出力として、取引先IDのテキストコレクション指定
マッピング:
Opportunity.AccountId → 取引先IDテキストコレクション
これにより、商談レコードコレクションを、取引先IDだけのコレクションに変換できます。
Step 3:「次に含まれる」で取引先責任者を取得する
Contact.AccountId に「次に含まれる」を指定

オブジェクト:
取引先責任者(Contact)
条件:
AccountId 次に含まれる 取引先IDコレクション
保存方法:
すべてのレコード
これで、完了予定日が今日以前の未クローズ商談に関連する取引先に所属する取引先責任者を、まとめて取得できます。
従来の作り方との比較
従来のループ構成

従来の作り方では、IDコレクションを作るためにループを使うことが多かったと思います。
商談を取得
↓
商談をループ
↓
現在の商談.AccountId をテキストコレクションに追加
↓
ループ終了後、取引先責任者を取得
この方法でも、ループ内で取引先責任者を取得しなければ問題ありません。ただし変換要素を使うと、IDコレクション作成用のループを減らせます。
商談を取得
↓
変換要素で AccountId コレクションを作成
↓
取引先責任者を取得
なお、ループと割り当てでIDコレクションを作る構成自体が常に誤りというわけではありません。問題になりやすいのは、ループ内で[レコードを取得]を繰り返す構成です。変換要素を使うと、ID抽出のためのループも減らせるため、より読みやすい構成にできます。
「次に含まれる」演算子を使わない場合、次のようにループ内でレコード取得を行う構成になってしまうことがあります。
商談を取得
↓
商談をループ
↓
ループ内で取引先責任者を取得
【NG例】「ループ内で取引先責任者を取得する構成」

これは、商談件数が増えるほどレコード取得回数が増えるため、避けたい構成です。
今回のパターンでは商談をまとめて取得し、AccountIdをまとめて抽出し、取引先責任者をまとめて取得できます。
このパターンの考え方
ここまでの考え方は、「ある条件に合う起点レコードを取得し、そこから参照先IDを抜き出して、関連レコードをまとめて取得する」場面で応用できます。
親または中間レコードをまとめて取得
↓
変換要素で参照先IDだけを抽出
↓
次に含まれるで関連レコードをまとめて取得
●パターン例
| やりたいこと | 起点 | 変換要素で作るコレクション | 次に含まれるで取得 |
|---|---|---|---|
| ①期限切れケースに関連する取引先責任者を取得したい | 期限切れケース | ケース.AccountId を抽出 | 取引先責任者.AccountId ~ 次に含まれる ~ AccountIdコレクション |
| ②更新対象の契約に関連する取引先責任者を取得したい | 更新対象の契約 | 契約.AccountId を抽出 | 取引先責任者.AccountId ~ 次に含まれる ~ AccountIdコレクション |
| ③対象商談商品に関連する価格表エントリを取得したい | 対象商談商品 | 商談商品.PricebookEntryId を抽出 | 価格表エントリ.Id ~ 次に含まれる ~ PricebookEntryIdコレクション |
ポイントは、後続のレコード取得で条件に使いたい値だけを、先にコレクション化しておくことです。
注意点
0件の場合は分岐する
最初の商談取得結果が0件の場合、後続の変換や取引先責任者取得は不要です。商談取得後に判断要素を入れておくと、フローの意図が分かりやすくなります。
空のIDを含めない
今回の例では、最初の商談取得条件に AccountId Null false を入れ、AccountId が空の商談を対象外にしています。
同様に、後続処理で条件に使うID項目が空になり得る場合は、起点レコードの取得条件で除外しておくとフローの意図が分かりやすくなります。
重複IDを考慮する
複数の商談が同じ取引先に紐づいている場合、取引先IDコレクションに同じIDが複数含まれる可能性があります。取引先責任者を取得するだけであれば問題になりにくいですが、後続処理でIDコレクション自体を使う場合は、重複の扱いを考えておく必要があります。
まとめ
変換要素と「次に含まれる」演算子は、それぞれ役割が異なります。
・変換要素:
レコードコレクションから必要な項目だけを抜き出し、後続処理に渡しやすいコレクションを作る
・次に含まれる:
コレクションを条件にして、関連レコードを一括取得する
この2つを組み合わせることで、次のようなフローを作れます。
商談をまとめて取得
↓
変換要素で AccountId コレクションを作成
↓
Contact.AccountId 次に含まれる AccountIdコレクション
↓
取引先責任者をまとめて取得
関連レコードを取得する場面では、まず「起点レコードから必要なIDを取り出せないか」「そのIDコレクションを使って 次に含まれる で取得できないか」を考えると、ループに頼らない設計にしやすくなります。
<Salesforce>
弊社ではSalesforceをはじめとするさまざまな無料オンラインセミナーを実施しています!
>>セミナー一覧はこちら
また、弊社ではSalesforceの導入支援のサポートも行っています。ぜひお気軽にお問い合わせください。
>>Salesforceについての詳細はこちら
>>Salesforceの導入支援実績はこちらからご覧いただけます!
医療業界に特化した営業支援、顧客管理(SFA/CRM)のコンサルティングも提供しております。こちらもぜひお気軽にお問い合わせください。
>>顧客管理(SFA/CRM)のコンサルティングの詳細はこちら


