フロー：リストビューレコードにフローを使用する方法


元の記事 : [Flows: How to use Flows for List View Records](https://www.accidentalcodersf.com/2020/07/use-flows-from-list-views-salesforce.html)

このブログでは、リストビューからSalesforceフローを使用および呼び出す方法を紹介します。一括更新、一括削除、挿入などの複数のレコードに対してアクションを実行するために、選択したレコードをリストビューからフローに渡す方法を説明します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/4fa7966d-4afa-d107-38e8-97367b20a44c.png)


**この記事の主なポイント：**
1.リストビューからフローに選択したレコードを渡す
2.フローを使用して、リストビューから一度に複数のレコードに対してアクションを実行する

# リストビューからフローへのレコードの受け渡し

フローは、使用法と機能の点で非常に用途が広くなっています。リストビューボタンのようにリストビューのフローを使用して、選択したレコードに対してアクションを実行できるかどうかを常に考えていました。そして今、私は私たちができることを知っています。

しかし、一度はキャッチがあります。少しのVisualforceとApexなしではこれを達成することはできません。ただし、ほんの少しです。これには、非常に基本的なVisualforceページと非常に単純なコントローラーが必要です。コーディングがあなたのものでなくても、これは非常に理解しやすく、簡単に複製して使用することができます。

アイデアは、リストビュー用の新しいリストビューボタンを作成し、そのリストビューボタン内でVisualforceを使用することです。このVisualforceは基本的に、リストビューから選択したレコードを取得するのに役立ち、これらのレコードはフローに直接渡されます。フローでレコードを選択したら、それらのレコードを使用できますが、自動化を作成する必要があります。かなりかっこいいですね！

# シナリオ：リストビューからのSalesforceフローのトリガー/起動

**ユースケースの例**

ユーザーは、ケースリストビュー（要件に応じて任意のリストビュー）からケースを選択して、更新（クローズ）できるようにする必要があります。また、選択したケースの件名には、最後にテキストを追加する必要があります。この追加テキストは「DuplicateClosed 」である必要があります。 
基本的に、これは手動のケースアーカイブと考えてください。ユーザーは、自動化されたリストビュー内からバルクケースを閉じることができます。

ユーザーがケースリストビューからいくつかのケースを選択します->ユーザーがリストビューのボタンをクリックします->選択したケースは自動的に閉じられます->ケースの件名には「重複して閉じられました」が追加されます 注意：特定のユースケースでは、この記事のフロー開発に関連するいくつかのベストプラクティスを見落としている可能性があります。実際のシナリオやプロジェクトでは、必ずこれらに従ってください。以下のいくつかの本当に重要なものをチェックしてください

# ソリューションと設計

前にも言ったように、これは3つのアイテムを使用することで実現されます。

1. Visualforceページとコントローラー：選択したケースレコードとそのフィールド値（必要なフィールド）を取得し、フローに渡します。
2.リストビューボタン： これはリストビューにあり、Visualforceページのプレースホルダーになります。このボタンをクリックすると、Visualforceページが呼び出され、次にFlowが呼び出されて自動化が実行されます。
3.画面フロー/自動フロー：選択によって異なります。ただし、この例ではスクリーンフローを使用しました。


# 1.Visualforceページとコントローラー：選択したレコードのリスト（IDだけでなく）をフローに送信します。

この例では、CaseObjectを使用しています。したがって、オブジェクトCaseの標準コントローラーと基本的にApexコントローラーである1つの拡張クラスを使用して非常に基本的なVisualforceページを作成します。コードはシンプルで、選択したオブジェクトで名前を変更するだけで他のオブジェクトに再利用できます。詳細については、以下のコードを確認してください。

VisualforceのApexControllerは、フローに送信する必要がある選択されたケースレコードのすべてのフィールドをクエリするために使用されます。この場合、これらのフィールドはケースIDとケースサブジェクトです。このケースレコードのリスト（IDだけでなく）をフローに直接送信します。

これは非常に重要です 。フローにケースレコードを送信しています。ケースIDだけではありません。
GET Elementを使用せずに、フローで直接使用/検出できるのは、コントローラーで照会するフィールドの値のみです。基本的に、必要なすべてのフィールドを含むケースレコードのリストをフローに直接送信します。このようにして、GET要素を使用してこれらのレコードを再度クエリし、レコードのフィールド値を取得する必要はありません。
それ以外の場合、ケースIDのみをフローに送信し、フィールド値を含むケースレコード全体を送信しなかった場合、フローでGET要素を使用して、これらのケースIDからすべてのフィールドをフェッチする必要があります。また、複数のケースレコードが選択される可能性があるため、GET要素はループで使用されます。これは、知事の制限に達する可能性があるため、常に回避可能です。

Visualforceから任意のフローを直接呼び出して、その変数に値を渡すことができます（フロー変数は入力値を受け入れることができ、タイプはRecordである必要があります）。これについては、この記事の後半で説明します。


**重要：**

フロー名と入力変数は、Visualforceページで提供するものと同じである必要があります。
コードをチェックアウトします。また、このコードを他のオブジェクトにも使用するには、Caseではなく選択したオブジェクトからオブジェクト名を変更することを忘れないでください。シンプルでわかりやすいです。 

これがApexコントローラーコードです。繰り返しになりますが、フローに必須/送信するすべてのフィールドをクエリすることを忘れないでください。 

```
public with sharing class ListViewController {

    /**This is the list which will be passed to Visualforce Page and in turn passed to Flow from Visualforce**/
    public List < Case > LstSelectedCases {
        get;
        set;
    }
    
    public ListViewController(ApexPages.StandardSetController listcontroller) {
      
        Set < Id > casesSelectedIds = new set < Id > ();
        LstSelectedCases = new List <case >();
            
        for (Case c: (Case[]) listcontroller.getSelected()) {
            casesSelectedIds.add(c.id);
        }
        
        /**Querying on the Selected records and fetching fields which are required in Flow **/
        LstSelectedCases = [select Id,Subject from case where id in: casesSelectedIds];
    }
}
```

これがVisualForceページコードです。パラメータinterviewnameで指定された名前のフローが必要であり、ページで使用するようにフローに一致する変数が必要であることを忘れないでください。
重要な注意：ページとコントローラーを作成する前に、空白/空のフローを作成し、フローにレコードタイプの変数も作成してください。フローを保存してアクティブ化します。Visualforceでフロー名と入力変数名を使用する必要があるため、このページを作成する前に存在する必要があります。この記事の後半で、この入力変数を作成する方法を示しました。このページとコントローラーを作成する前に、それを確認してください。 

```
<apex:page standardController="Case" recordSetVar="Cs" extensions="ListViewController" lightningStylesheets="True">
    
   <!--This is how we call the Flow with a input paramater. Here CasesSelectedRecs is the input variable of the Flow-->
   <flow:interview name="CaseListView">
        <apex:param name="CasesSelectedRecs" value="{!LstSelectedCases}" />
    </flow:interview>
    
</apex:page>
```

VFおよびコントローラーコードによると、この場合、フロー名は「CaseListView」であり、Visualforceから選択されたケースレコードを受け入れるフローの入力変数は「CasesSelectedRecs」という名前です。この変数を作成する方法については、この記事の後半で説明します。 また、この変数には、「 LstSelectedCases
」という名前の変数を介して、コントローラーから選択されたケースレコードのリストが割り当てられます。より明確にするために、コードをもう一度チェックアウトしてください。

ListViewControllerTestクラス：これは、実稼働 環境の要件の基本およびサンプルのテストクラスです。組織やシナリオに応じて変更が必要な場合があります。私のシナリオでは、正常に機能しますが、組織で微調整する必要がある場合があります。

```
@istest（）
public class ListViewControllerTest
{
	private static testmethod void ListViewControllerTest（）
	{ case obj = new case（Subject ='Test'、Origin ='Web'）; objを挿入します。
		
		



		list <case> selected = new list <case>（）; selected.add（obj）;
		

		PageReference pageRef = Page.CaseListView;
	

		Test.setCurrentPage（pageRef）;

		pageRef.getParameters（）。put（'Id'、String.valueOf（obj.Id））; ApexPages.StandardSetController sc = new ApexPages.StandardSetController（selected）; ListViewController l = new ListViewController（sc）;
		
		

	}

}
```

# 2.リストビューボタン

VFとコントローラーの使用が完了したので、リストビュータイプのケースオブジェクトに新しいボタンを作成する必要があります。Visualforceページをコンテンツソースとして使用します。
ボタンに「アーカイブケース」という名前を付けました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/fc754d28-1193-3785-aa01-4676686116ff.png)


# 3.フロー

の設計フローは、この要件のすべての前に作成されます。フロー名は「CaseListView」です。 重要：画面タイプフローを作成しています。ただし、自動起動されたフローを使用して、visualforceからデータを直接送信することもできます。要件に応じて、それはあなた次第です。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/85f1e05e-a812-1a9b-c07f-e86a621dc656.png)


それでは、アクションに飛び込んで、このフローを作成しましょう。フローには5つの要素と2つの主要な変数があります。

**1.入力変数**：Visualforceから選択されたケースのリストを受け入れます。
まず、type、Record、DatatypeCaseの新しい入力変数を作成します。
この変数は複数のレコードを保持できます。 また、この変数は 、フローの外部から渡された値を受け取ることができるように、入力可能としてマークされます。

この場合、この変数（CasesSelectedRecs）の値は、上記のVisualforceコードに示されているようにVisualforceページから渡されます。


**2.更新する必要のあるケースを保持するためのタイプRecord（MultipleValues）の変数。 **
この変数は、上記の変数に似ています。ただし、ケースレコードを更新するために使用されます。これもCase型であり、複数の値を保持することもできます。この中で値がどのように割り当てられるかは、フローの後半で説明します。


**3.ケースが選択されたかどうかを確認するための決定要素。**
フローから始めるために、ボタンをクリックする前に、ユーザーがリストビューからケースを選択したかどうかを確認する決定要素を最初に作成します。これは、Visualforce（ CasesSelectedRecs ）から値を受け取る入力変数 がNullであるかどうかを確認することで実行できます。 nullでない場合にのみ、プロセスはさらに処理します。


**4.これらのケースでループする要素をループします。**
ユーザーがケースを選択した場合は、ループ要素を使用して、選択したケースレコードを反復処理します。ビジュアルフォースページから選択されたケースを受け取っ た入力変数「CasesSelectedRecs 」をループします。

Summer'20のリリース後は、ループ反復変数を作成する必要はありません。自動的に作成されます。

以下のステップ5の後、割り当てに沿ったこのビデオをチェックアウトします。

**5.要件に従って新しいステータス値とサブジェクト値を割り当てるための割り当て要素。**
ここで、選択したケースレコードを1つずつループし、ループしたすべてのケースのケースステータスをクローズとして割り当てます。 また、要件に応じて、各ケースの件名の最後に 文字列値「DuplicateClosed 」を追加します。
以前にApexクラスのSOQLクエリでSubjectをクエリしなかった場合、ここでは使用できなかったことを覚えておいてください。


**6.ループからの個々のケースレコードをステップ2の変数を更新するケースに追加するための割り当て要素。**
これは、ループされている現在のケースレコードを新しく作成された変数に追加して、更新されたすべてのケース値を格納するために使用されます。 したがって、基本的に、ループのすべての反復で、更新されたケースレコードをこの新しいレコード変数に追加します。これは、後でケースを更新するために使用されます。


**7.要素を更新して、ケースを更新し、更新された値を持つ変数を更新します（ステップ2）。**
ループが終了したら、update要素を使用してレコードを更新します。

ループからケースを追加するために作成されたケース更新リスト変数を更新するだけです。


完了です。 ケースリストビューにリストビューボタンを追加します。これは、検索レイアウトを使用して実行できます。 https://trailblazers.salesforce.com/answers?id=90630000000grS1AAIデモビデオの下のチェックアウトと実際のフローを参照してください。