
はじめに
Salesforceは、独自開発言語「Apex」を使用した開発を行う場面が多いです。
Apexとは、Salesforce独自のオブジェクト指向プログラミング言語であり、世界中で使用されているプログラミング言語「Java」とよく似ているという特徴があります。Salesforceにおける開発手法の中でもかなりカスタマイズ性が高く、複雑なロジックをつくりたい、大規模なデータを扱いたいなどの場面で活躍します。
一方で、Salesforceには宣言的開発機能*が充実しており、その代表的なものが「フロー」です。最近、Salesforceはフローに力を入れているようで、様々なアップデートがされているおかげでApexでの実装が不要になる場面が増えるなど、どんどん便利になってきています。
そのような背景のもと、私自身がApexを使用した開発でコレクション変数の並び替え(ソート)を実装したい場面がありました。その実装方法について調査をしたところ、Apexとフローでは標準で用意されているソート機能に違いがあることがわかりました。そこで本記事では、Apexとフローの標準で用意されているソート機能について、仕様や実装方法を解説していきます。
*どのような結果になるのか、宣言するように開発すること。コードを書かずともクリックベースでアプリケーションの定義をマウスで行い、最小限の専門知識で開発が可能。
Apexにおけるソート
まずは、Apexにおけるコレクション変数に対するソート機能を見ていきます。
Apexにはsortメソッドが用意されており、昇順で並び替えができます。シンプルなコレクション変数に対して昇順で並び替えたい場合は、sortメソッドで充分だと言えます。
しかし、sObject型のコレクション変数の並び替えをしたい場合では、使い勝手が悪いです。sObjectの並び替えは以下の順に評価され、並び替えられます。
Salesforceヘルプ sObject のデフォルトの並び替え順
- sObject 型の表示ラベル。
たとえば、Account sObject は Contact の前になります。- Name 項目 (該当する場合)。
たとえば、リストに A と B という名前の 2 つの取引先がある場合、取引先 A が取引先 B よりも前になります。- 標準項目。ID 項目と Name 項目を除き、アルファベット順で最初の項目から使用されます。
たとえば、2 つの取引先が同じ名前の場合、並び替えに使用される最初の標準項目は AccountNumber です。- カスタム項目。アルファベット順で最初の項目から使用されます。
たとえば、2 つの取引先の名前と標準項目が同じで、FieldA と FieldB という 2 つのカスタム項目がある場合、並び替えでは FieldA の値が最初に使用されます。
カスタムオブジェクト「売上(Uriage__c)」を例として、ソート結果を見ていきます。
List<Uriage__c> recordList = [SELECT Name, Amount__c, Staff__c FROM Uriage__c];
recordList.sort();
for(Uriage__c uriage : recordList){
:
}
Apexにおけるソートのサンプルコード
ソートを実行すると、上記のルールのうち、「2.Name項目」が該当し、優先してName項目の昇順でソートされます(表1参照)。
表1:「売上(Uriage__c)」のレコードのソート実行結果(1)
Name | 金額(Amount__c) | 担当者(Staff__c) |
---|---|---|
売上001 | 30,000 | Bさん |
売上002 | 20,000 | Aさん |
売上003 | 10,000 | Cさん |
売上004 | 10,000 | Aさん |
Apexにおけるソートでは、上記のルールが適用されるため、表1のようなレコードを金額や担当者でソートしたい場合、そのための処理を自身で実装する必要があります。
フローにおけるソート
次に、フローにおけるコレクション変数に対するソート機能を見ていきます。
フローでは、コレクション変数をソートするための機能が用意されており、「コレクション並び替え」によって、ソートを実行することができます。
Salesforceヘルプ フロー要素: コレクション並び替え

図1:フロー要素「コレクション並び替え」の実装例
フローにおけるソートでは、ソートの対象にName項目以外の項目を指定することができ、更に昇順か降順か、空の文字列やnull値の扱いまで設定することができます。
並び替えオプションの追加上限は3つまでであることに注意です。4つ以上の項目でソートしたい場合はApexで処理を実装する必要があります。
表2:「売上(Uriage__c)」のレコードのソート実行結果(2)
Name | 金額(Amount__c) | 担当者(Staff__c) |
---|---|---|
売上004 | 10,000 | Aさん |
売上003 | 10,000 | Cさん |
売上002 | 20,000 | Aさん |
売上001 | 30,000 | Bさん |
実行結果(表2参照)からわかるように、Apexでは別途実装が必要だった「金額」や「担当者」での並び替えが標準の機能で実装可能です。
Apexからフローを呼び出す
ご紹介した内容を踏まえ、オブジェクトのデータ並び替えについて、Apexとフローを比較してみました。
表3:オブジェクトのデータ並び替えに関するApexとフローの特徴一覧
Apex | フロー | |
---|---|---|
Name項目で並び替え | sortメソッドで標準的に並び替え | 標準機能で可能 |
Name項目以外で並び替え | sortメソッドでは不可 ただし実装すれば可能 | 標準機能で可能 |
降順で並び替え | sortメソッドでは不可 ただし実装すれば可能 | 標準機能で可能 |
並び替え対象の項目制限 | 実装すれば制限なし | 3つまで |
テストクラスの作成 | 必要 | 不要 |
表3からわかるように、sObject型コレクション変数を並び替える場合、Apexよりもフローのほうが標準機能が充実しています。
状況によってはApexでソート処理を実装する必要がありますが、ソートしたい項目が3つ以下の場合は、Apexからフローを関数のように呼び出すことで、より簡単に実装することができます。
フローの作成
まずは、フロー側でApexからコレクション変数を入力、出力できるように設定しておきます。

図2:Apexから呼び出すフローの種類
Apexから呼び出すフローの種類は「自動起動フロー(トリガーなし)」を選択します。
次に、引数となるコレクション変数を作成します。

図3:引数となるフローのリソース
以下3点のチェックボックスにチェックを入れることに注意してください。
- 複数の値を許可(コレクション)
- 入力で使用可能
- 出力で使用可能
最後に、先程ご紹介した「コレクション並び替え」をフローに配置し、任意の設定をします。

図4:コレクション並び替えの設定
今回は、担当者(Staff__c)、金額(Amount__c)の優先度で昇順で並び替えるように設定しました。
Apexの作成
Apexからフローを呼び出すには、Flow.Interviewクラスのstartメソッドを使用します。
List<Uriage__c> recordList = [SELECT Name, Amount__c, Staff__c FROM Uriage__c];
// recordList.sort();
Map<String, Object> flowInput = new Map<String, Object>(); // フロー引数Map定義
flowInput.put('argRecords', recordList ); // フロー引数をput
Flow.Interview.SampleFlow myFlow = new Flow.Interview.SampleFlow( flowInput );
myFlow.start();
for(Uriage__c manhour :(List<Uriage__c>)myFlow.getVariableValue('argRecords')){
:
}
Apexからフローを呼び出しコレクション変数をソートするサンプルコード
5,6行目では、フローへ渡す引数を用意しています。
フローへ渡す引数はMapを使用し、keyに変数のAPI参照名、valueに値をputします。今回は、図3で作成した変数のAPI参照名をkeyにputしています。引数が複数ある場合、複数のkey, valueをputすればOKです。
8,9行目では、Flow.Interviewクラスをインスタンス化し、startメソッドを使用してフローを起動しています。
8行目の「SampleFlow」は起動したいフローのAPI参照名です。引数に5,6行目で作成したMap変数を渡します。
11行目では、getVariableValueメソッドを使用して、フローの実行結果である出力変数を受け取っています。
引数には、図3で作成した変数のAPI参照名を使用します。
実行結果
上記で作成したApexを実行すると、フローが関数のように呼び出され、コレクション変数である「recordList」に対してName項目以外でのソートをすることができます。
表4:「売上(Uriage__c)」のレコードのソート実行結果(3)
Name | 金額(Amount__c) | 担当者(Staff__c) |
---|---|---|
売上004 | 10,000 | Aさん |
売上002 | 20,000 | Aさん |
売上001 | 30,000 | Bさん |
売上003 | 10,000 | Cさん |
実行結果(表3参照)からわかるように、図4で設定した担当者(Staff__c)、金額(Amount__c)の優先度で昇順に並び替えられています。
最後に
データの並び替えについてApexとフローの仕様や実装方法を紹介しました。
sObject型コレクション変数を並び替える場合、フローの方が標準機能が充実していることは意外だったのではないでしょうか。
sObject型コレクション変数に対して複数回並び替えたい場面においては、ORDER BYを含んだSOQLクエリを実行する回数を削減できますので、ガバナ制限への対策にもなるでしょう。
もちろんApexのみで実装していくことも不可能ではないですが、フローでの開発はテストクラスの作成が不要であったり、バージョン管理が容易であったりなど、利点も多くありますのでApex、フロー両方のメリットを理解した上で開発手段を選択していくことが重要だといえます。
また、後半でご紹介したApexからフローを呼び出す方法についても参考になるかと思います。
今後もフローの機能拡充に期待したいですね!
投稿者プロフィール

-
主にSalesforceを使用した開発を担当しており、Salesforce歴は3年程です。
フローを使ったローコードでの実装や、Apexを使用したバックエンドの構築を担当しております。最近では、Lightning Web Componentや、第2世代管理パッケージの開発にも携わっております。
保有資格:Salesforce認定platformデベロッパー
最新の投稿
Salesforce2024.05.22【Salesforce】Apexとフローで異なる!オブジェクトのデータ並び替え(ソート)実装方法を徹底解説
Salesforce2023.11.22【Salesforce】Apexで実装しよう!Basic認証を使用したコールアウトの紹介【サンプルコード付き】
Salesforce2023.05.23【Salesforce】セキュリティトークンを使用して、DataSpider Cloudのグローバルリソースに接続設定を作成する
Salesforce2022.12.13【Salesforce】フローでループを使う際の厄介なエラー「Number of Iterations Exceeded」をプラットフォームイベントトリガフローで回避する