2017.05.23

関連オブジェクトの項目で検索するApex拡張

  • このエントリーをはてなブックマークに追加
  • follow us in feedly

取引先の検索画面を作ったが、取引先の項目だけでなく取引先責任者の電話番号や商談名など子のレコードの情報でも検索したい、というような要望としてよく頂いていますが、ガバナー制限や他様々な技術的な要因で残念ながらSkyVisualEditorの検索テンプレートでは関連項目を検索条件として指定できません。

以前こちらのブログでもふれたように、検索対象としたい関連オブジェクトを主オブジェクトにすることである程度実現できますが、データの編集が出来ないなどいくつか機能的な制限もあります。

それに対して、今回は色々前提条件や運用上の注意点がありますので全てのケースに対応できるわけではありませんが、少々の設定とApexクラス拡張を作成することで実装する少し高度なカスタマイズについてご紹介したいと思います。例として、取引先に所属する取引先責任者の名前で検索できる、取引先の検索画面を作成していきます。

まずは下準備として、主オブジェクトに検索用のフェイク項目を作成します。詳細については後述としますが、この項目は値を入力されない、検索対象の値と重複することがないなどを考慮し、運用する必要があります。

次に、SkyVisualEditorで検索画面を作成します。検索項目として先ほど作成した項目を選択しますが、ここで重要なポイントとして該当項目を「デフォルト演算子-次の文字と一致しない」「演算子を表示しない」として設定します。これによって拡張用として利用しやすい、「フォーム内に存在しますがどのような条件とも一致しない項目」の出来上がりです。

ここまでの設定で、以下のような画面が出来ます。

設定に関する下準備としては以上になりますが、Apexクラス拡張に入る前にいくつかコードをわかりやすくするための工夫をしておきます。

SVEではコンポーネントのIDがそのまま生成されたコード内の変数名になりますので、コードのメンテナンス性を高めるためにプログラミングする前にIDをデフォルトの自動的に振られたものから意味のある名称に変更することをおすすめしています。ここでは検索するための項目と、テーブルを変数として利用したいのでそれぞれに分かりやすい名前を設定します。

  • [検索項目のID] ComponentXX → contactNameSearch
  • [テーブルのID] ComponentXX → resultTable

全ての準備が整ったので、後はApexクラス拡張の作成するのみとなります。Apexクラス拡張の説明などは以前このブログでも紹介したので、詳しく知りたい方はこちらの記事を御覧ください。Apexクラス拡張を使ってSkyVisualEditorを強化しよう

global with sharing class ContactSearchExtender extends SkyEditor2.Extender{

    private ContactSearch sveController;
    
    public ContactSearchExtender(ContactSearch extension){
        sveController = extension;
    }
    
    private MyQueryListener  myListner;
    
    public override void init(){
            myListner = new MyQueryListener();  
            svecontroller.QueryMap.get('resultTable'). addListener(myListner);
    }
    /**
    * 検索処理の直前に呼び出されるメソッドです。ここで検索フォームに配置した拡張用の検索項目の値をMyQueryListener に渡すことで最新の入力値で検索します。
    */
    public override void preSearch(){
        if(String.isBlank(sveController.contactNameSearch_val.SkyEditor2__Text__c)){
            myListner.setMyWhereClause(null);
        }else{
            String sWhere = 'Id in ( select accountid from contact where name Like \'%' + sveController.contactNameSearch_val.SkyEditor2__Text__c + '%\')';
            myListner.setMyWhereClause(sWhere);
        }
    }
    /**
    * QueryListenerはSVEの検索処理を拡張するためのインターフェースです。これを実装することで追加のクエリーを発行することが出来ます。
    */
    public class MyQueryListener implements SkyEditor2.QueryListener{
        private string myWhereClause;
        public void setMyWhereClause(String s){
            myWhereClause = s;
        }

        public void apply(skyEditor2.Query query){
                if(String.isNotBlank(myWhereClause)){
                    query.addWhereIfNotFirst('AND');
                    query.addWhere(myWhereClause);
                }
        }
    }
}

以上が今回作成したApexクラス拡張です。とてもブログで説明しきれるようなボリュームではありませんので、コードの細かい説明やExtenderのインターフェース、作法などについては割愛しますが、全体の流れとしてはこうなります:

  1. QueryListenerインターフェースを実装し、検索画面に対し追加の検索条件をセット出来るようにする
  2. preSearchメソッド内で検索フォームの入力値を取得
  3. 同メソッド内でサブクエリーを作成し、追加の検索条件を付加した上で検索を行う

作成したApexクラス拡張を検索ページに組み込んで実行した画面はこうなります。見事に取引先責任者に「田中」さんが所属している取引先を検索できました!(...内部処理の拡張ですので見た目はまるで変わりませんが)

冒頭でもあったように、このカスタマイズは組織の設定や運用、データ件数などの事前の設計が必要になります。また、既存の仕組みとの共存のため演算子をフォームで指定することが出来ませんので、どの案件でも使えるような汎用的なものではありません。しかしSkyVisualEditorを使って画面を作成する時に、あと少し!という場面でこのようにApexクラス拡張で解決出来ることもあるとご理解できればと思います。

今回は簡単な例として子オブジェクトのname項目での検索を実装しましたが、他の項目やデータ型、あるいは数式などを利用した複数条件での検索などアイデアやカスタマイズ次第で色々と応用出来ますので、ぜひお試しください。

1 件

関連する記事