フロー内で作成したレコードのIdを使って子レコードも紐づけてコピーする

# 結論
画面フローだけで「親子レコードの複製」を実現する最短手順は、
1. 割当 で元レコードを丸ごとコピー & Id を Null 化
1. レコードの作成要素 の“レコード変数から”で 作成
1. 返ってきた CloneContact.Id を子レコードの 上司Id に流し込む
これにより、新フィールドが追加されてもフロー改修ゼロが実現。子レコードはループ＋レコードコレクション変数で一括作成すれば OK。
コードも拡張パッケージも不要で、組織フィールドが増えても自動追従するため、保守コストを最小化できる。

# 背景
「どの取引先責任者をコピーしますか?」と聞かれ、１人の取引先責任者Aを選択。
「取引先責任者Aには取引先責任者a1、a2、a3が紐づいています。併せてコピーしますか?」
と聞かれ、「はい」を選ぶと、コピー開始。A’及びA’に紐づいたa1’a2’a3’というレコードが作成。

という画面フローを実現したいというご相談がありました。
恐らく通常はコードを書いている優秀な方なのかと思いますが、フロー内で作成したレコードのIdを取得することに困っていたようです。
この手順は確かに分かりづらいので、良い記事があれば教えて差し上げたいと探してみましたが、なかなか見当たりません。
何故だろうか？と考えたところ、確かに私もメンバーに対して説明するときには口頭だと伝わらないので毎回webMTGしていたことに気が付きました。
そこでパッケージを用意し、ご自身で触っていただくのがよいかと考えてこの記事とパッケージを作成しました。
↓未管理パッケージURL
https://login.salesforce.com/packaging/installPackage.apexp?p0=04tWU0000008COz

# 構築内容
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/c1430019-7e51-4d83-8f98-42f332348380.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/0602fe79-7e46-4bb2-a76c-4ab2e6046c12.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/30b00c1e-03ab-4ddc-b382-88f53091b739.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/b2617bd1-ce49-480c-8283-3c4114ac7af9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/a215f5a7-1e2e-46a1-bab9-0a31bffb2e92.png)


## フロー全景
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/42f95ac4-9478-4651-bf66-4f9d9e5f4383.png)

## 事前準備
### 使用するオブジェクトと項目
* 取引先
    * Id
* 取引先責任者
    * Id
    * 氏名
    * 上司Id
    * 説明

標準項目だけにしています。
また、項目が増えてもキーにする項目が変わらなければメンテナンス不要にすることを目指しています。

### フローで最初に作成しておく変数
* レコード単一変数
    * recordId
        * レコード型（Account）
    * var_CloneContact
        * レコード型（Contact）
    * var_CloneChildContact
        * レコード型（Contact）
* レコードコレクション変数
    * vars_CloneChildContacts
        * レコード型（Contact）


## フロー内容解説
1. get_OriginContats
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/9700fde0-e7a7-42de-aab1-d7237a8cfd8a.png)
    1. 取引先のレコードページのIdから現在存在する取引先責任者を取得しています。
1. sc01
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/dde67870-15a7-4e5a-a981-bc7fd73dd3c5.png)
    1. この画面でコピーする取引先責任者を選択します

1. set_CloneContact
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/ebd64b6d-99f9-474e-baef-44efa24c0571.png)
    1. ここが一番重要です。レコード変数var_CloneContactに画面で選択したレコードの情報を割り当てます。この際に**レコード変数の各項目選択に進みたくなるUIではありますが、これを無視して別の領域をクリック**してください。※次の画像まで変数を設定したら別領域をクリック。これにより画面で選択したコピー元レコードの値すべてが変数に割当たります。
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/5bb3c207-169c-4cd7-ae5a-36b7c4129dc9.png)
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/ea4eed11-88c7-494d-9e2f-1bc74ed65423.png)
    1. 次の行で変数の取引先責任者Idを空にします。また、今回はテスト用のため、説明項目にはクローンであると明記させています。実際の構築では適宜修正してください。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/68464b13-9271-4896-b585-b97d0b7593ae.png)
1. create_CloneContact
    1. 変数を基にレコードを作成します。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/c3fb2cb4-8b6f-4b62-a4d7-ead10592b97e.png)

1. sc02
    1. レコード作成後の変数内容を確認する画面です。ここでレコード変数にIdが入っていれば、レコードが作成され、レコードIdが変数に割り当てられたことが確認できます。構築でのわかりやすさの為に作っていますが、実運用では不要だと思います。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/3ef1c596-f984-4385-a00a-c4d13116e457.png)

1. get_OriginChildContacts
    1. コピー元となった取引先責任者の子レコードを取得します。今回のシナリオでは部下も含めてコピーする、と仮定し、上司項目の値がコピー元のレコードIdと一致することにしました。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/1ba40bd5-a50e-4b74-a07d-ad8fb3e3e4e6.png)

1. sc03
    1. 取得した部下の取引先責任者一覧の取引先責任者達を画面に表示します。この画面も実際の運用では不要ですが処理状況の確認の為に入れています。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/bceac0ca-0ec1-4b0e-b81b-f8d2c35d2890.png)

1. loop_originChildContacts
    1. 取得した部下の取引先責任者一覧でループを開始します。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/f8ae013a-6301-46ef-b906-aa9410adafe0.png)

1. set_CloneChildContact
    1. 先と同様にレコード変数の項目までは進まずに、変数に対して現在ループ中の取引先責任者情報を割り当てます。
    1. 変わる部分は上司Idの部分です。ここではcreate_CloneContactで作成する際に使用した変数の値を用います。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/49b88f13-d047-4491-8045-5c09d3391536.png)

1. add_CloneChildContacts
    1. レコード変数をレコードコレクション変数に追加します。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/8333f3c7-02a9-49be-a277-4487f1713da4.png)


1. create_CloneChildContacts
    1. レコードコレクション変数の内容で作成します。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/e89a5636-d79a-4fbc-8dac-80dfca78c48a.png)

1. sc04
    1. 作成確認画面です。ここも実運用では不要ですので、動作確認が出来た後は削除いただいて構いません。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017914/455620b8-c2db-465e-8e27-aeefb47e428d.png)



# 別案
極力作らないことを正しいと考えています。
優秀なAppExchangeがあるので通常はこちらを推奨します。
https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3A00000G12chUAB

# まとめ
1. 割当要素 の項目指定無しでの「=」演算子は“全フィールドコピー”を意味する。ここで Id = Null を忘れない。
1. レコードの作成要素 で「レコード変数からすべての値を取得」を選ぶと、ReadOnly フィールドを自動除外して Insert。
1. レコードの作成 後は同じレコード変数に 新しい Id が返る。この Id を子レコードの外部参照に流用できる。
1. 子レコードは Loop → 1 件ずつ 割当 → コレクションに追加 → 一括 レコードさくせ が最もシンプル。
1. フィールド追加やレイアウト変更があっても、フロー側はメンテ不要。大規模オブジェクトでも安全に運用できる。

※あくまで構築のヒントの為のサンプルです。自己責任でお願いします。