blog
ブログ

ApexでのsObjectソートとNULLの制御

こんにちは!
Apexでオブジェクトのリストを扱う上では欠かせないソート。
デフォルトでは以下4つの順でソートされることはご存知でしょうし、
それ以外のルールでソートしたいときはComparableインターフェースを使用する、
ということも詳しい皆さんのことですから重々承知でしょう。

(4つのソート順)

  • sObject型の表示ラベル
  • Name項目
  • 標準項目(アルファベット順)
  • カスタム項目(アルファベット順)
しかし、公式のドキュメントではカスタム並び替え順は単一のキーでしか対応していません。
これは大変もどかしい。
膨大なデータを扱うときはキー1つでは同じ値が出てきたときに困る!
第2キーを使いたい!
そんなあなたのために、今回はcompareToメソッドで第2キーまでのソートに対応する方法をご紹介しましょう。

単一キーでのソート

さてここで1つおさらい。単一キーでのソートは大変シンプル。
以下のようなコードでさっくり実現できます。
今回は取引先を従業員数の昇順でソートしてみましょう。

public class SingleKeySortController {
    public List targetAccList{get;set;}
    public Boolean isDesc{get;set;}
    
    public SingleKeySortController(){
        isDesc = false;
        //取引先を取得
        List accList = new List();
        accList = [SELECT Id, Name, Sic, NumberOfEmployees FROM Account]; 
        //対象をソート
        targetAccList = new List();
        for(Account ac : accList){
            targetAccList.add(new AccDto(ac, isDesc));
        }
        targetAccList.sort();
    }
    
    /**
     * ソート用クラス
     */
  public class AccDto implements Comparable{
        public Account acc{get;set;}
        private Integer sortFactor;
    
        //昇順降順を判定
    public AccDto(Account ac, Boolean isDesc){
      acc = ac;
            sortFactor = 1;
            if(isDesc){
                sortFactor = -1;
            }
    }
    
        //ソートを実行
    public Integer compareTo(Object compareTo) {
      AccDto thisDto = (AccDto)compareTo;
      //nullを含まない場合
      if(this.acc.NumberOfEmployees == thisDto.acc.NumberOfEmployees){
        return 0;
      }else if(this.acc.NumberOfEmployees > thisDto.acc.NumberOfEmployees){
        return sortFactor;
      }
      return sortFactor*-1;
    }
  }
}
結果は以下の通り。

従業員数は昇順なのに産業コードは降順でソートされていますね。
どうせなら産業コードも昇順にしたいところです。

複数キーでのソート

さてさて漸くの本題、第2キーを使用したソートです。
と言っても上記の単一キーソートのcompareToメソッドに少し手を加えてやるだけ。実に簡単です。

    //ソートを実行
   public Integer compareTo(Object compareTo) {
      AccDto thisDto = (AccDto)compareTo;
      //nullを含む場合
      if(this.acc.NumberOfEmployees == null && thisDto.acc.NumberOfEmployees == null){
        if(this.acc.Sic > thisDto.acc.Sic){
          return sortFactor;
        }
        if(this.acc.Sic  thisDto.acc.Sic){
          return sortFactor;
        }
        if(this.acc.Sic  thisDto.acc.NumberOfEmployees){
        return sortFactor;
      }
      return sortFactor*-1;
    }
結果は以下の通り

しれっとnullを考慮しているのでnullを含めた従業員数の昇順、
従業員数が同数の場合は産業コードの昇順になっています。スゴイ!

もうひと手間

今回は第2キーまでを利用したsObjectリストのソートを紹介しましたが、
これは応用すればNULLS LASTやNULLS FIRSTの制御、複数オブジェクトのリストソートなども可能です。
それを書くにはこの記事は余りにも狭すぎるのでまたの機会に……

では、オタッシャデー!
contact

ご相談・ご質問等ございましたら、お気軽にお問い合わせください。

翻訳

SFA/CRMに蓄積されている情報を活用する方法ガイド