Salesforceでの動的選択リスト操作: 連動選択リストの完全ガイド


Salesforceでは、連動選択リスト(依存ピックリスト)を設定することで、選択肢の一部を特定の条件に応じて制御できます。この記事では、Apexコードを使用して連動選択リストのデータを取得する方法を詳しく解説します。

コード解説

以下の`getDependentOptions`メソッドは、指定したオブジェクトとフィールドの依存関係を取得し、結果を`Map<String, List<String>>`形式で返します。

コード例

public static Map<String, List<String>> getDependentOptions(String objectName, String controllingField, String dependentField) {
    Map<String, List<String>> dependentPicklistValues = new Map<String, List<String>>();
    
    // グローバルスキーマ記述の取得
    Schema.SObjectType objType = Schema.getGlobalDescribe().get(objectName);
    if (objType == null) return dependentPicklistValues;
    
    // オブジェクトの詳細情報を取得
    Schema.DescribeSObjectResult describeResult = objType.getDescribe();
    Map<String, Schema.SObjectField> fieldMap = describeResult.fields.getMap();
    
    // フィールドが存在しない場合の処理
    if (!fieldMap.containsKey(controllingField) || !fieldMap.containsKey(dependentField)) return dependentPicklistValues;
    
    // 制御フィールドと依存フィールドの記述を取得
    Schema.DescribeFieldResult controllingFieldInfo = fieldMap.get(controllingField).getDescribe();
    Schema.DescribeFieldResult dependentFieldInfo = fieldMap.get(dependentField).getDescribe();
    
    // 制御フィールドと依存フィールドの選択リスト値を取得
    List<Schema.PicklistEntry> controllingValues = controllingFieldInfo.getPicklistValues();
    List<Schema.PicklistEntry> dependentValues = dependentFieldInfo.getPicklistValues();
    
    // 制御フィールドごとの依存フィールド値を処理
    for (Schema.PicklistEntry controllingValue : controllingValues) {
        dependentPicklistValues.put(controllingValue.getLabel(), new List<String>());
        
        for (Schema.PicklistEntry dependentValue : dependentValues) {
            String jsonString = JSON.serialize(dependentValue);
            Map<String, Object> deserializedValue = (Map<String, Object>)JSON.deserializeUntyped(jsonString);
            String validFor = (String)deserializedValue.get('validFor');
            
            Integer controllingIndex = controllingValues.indexOf(controllingValue);
            if (validFor != null && validFor.length() > controllingIndex/8 && (validFor.charAt(controllingIndex/8) & (1 << (7 - Math.mod(controllingIndex, 8)))) != 0) {
                dependentPicklistValues.get(controllingValue.getLabel()).add(dependentValue.getLabel());
            }
        }
    }
    
    return dependentPicklistValues;
}

使用方法

以下は、`Account`オブジェクトのカスタムフィールド`Region__c`と`Zone__c`を使用して連動選択リストのデータを取得する例です。

呼び出し例

Map<String, List<String>> dependentValues = getDependentOptions('Account', 'Region__c', 'Zone__c');

// 結果をデバッグ表示
for (String key : dependentValues.keySet()) {
    System.debug('Parent: ' + key + ', Children: ' + dependentValues.get(key));
}

期待されるデバッグ出力

以下のような形式でデバッグログに表示されます。

Parent: North America, Children: [East Zone, West Zone]
Parent: Europe, Children: [Central Zone, North Zone]
Parent: Asia, Children: [South Zone, East Zone]

コードの動作概要

  1. グローバルスキーマ情報の取得:

    • 指定されたオブジェクト名を使用してスキーマ情報を取得します。
  2. フィールドの存在確認:

    • 制御フィールドと依存フィールドがオブジェクトに存在するかを確認します。
  3. 選択リスト値の取得:

    • 制御フィールドと依存フィールドの選択リスト値をそれぞれ取得します。
  4. 依存関係の計算:

    • `validFor`プロパティを利用して、制御フィールド値ごとの有効な依存フィールド値を判定します。
  5. 結果の構築:

    • 制御フィールド値をキーとし、対応する依存フィールド値をリストに格納したMapを作成します。

応用とエラー処理

  • エラー処理:
    • 無効なオブジェクト名やフィールド名が指定された場合は、適切なエラーログを記録できます。
  • 汎用化:
    • 他のオブジェクトやフィールドにも簡単に適用できます。

まとめ

このメソッドを使用することで、Apexでの連動選択リストの処理が簡単かつ効率的に行えます。`validFor`プロパティを利用したロジックは少し複雑ですが、Salesforceの標準機能と統合して動作するため非常に強力です。

コメント