关于Salesforce存在至于项目的选择List的取值问题

 

概要:

我们在做项目的时候,经常会遇到一个问题:

一个选择List字段的可选项被另一个选择List制约,这种情况如何在后台取得这两者的对应关系。

 

原文在这里(侵删):

Apexで連動項目の選択肢を取得する方法 - Qiita

Apexで連動項目の選択肢を取得する方法(改善版) - Qiita

之前第一个博文看不懂,看了第二个之后才明白大概原理。

所以才有了这篇随笔:

 

·Example.apxc
public class Example {
    private static String INITIAL_VALUE = '';
    // 選択リストで選択された値が格納される変数
    public SomeObject objectInstance {get; set;}

    public List<SelectOption> DependentPickListOptions{
        get{
            List<SelectOption> options = new List<SelectOption>();

            // 選択リストの一番上にデフォルトの選択値を設定
            options.add(new SelectOption(INITIAL_VALUE, '-- なし --'));

            // 制御項目ctrlPicklistが選択されている時に連動項目depPicklistで選べる選択肢を取得する。
            if( this.objectInstance.ctrlPicklist != null || this.objectInstance.ctrlPicklist != INITIAL_VALUE ){
                List<DepPickListCtrl.TPicklistEntry> tPicklistEntries = 
                    DepPickListCtrl.GetDependentOptions('SomeObject','ctrlPicklist','depPicklist').get(this.objectInstance.ctrlPicklist);

                for( DepPickListCtrl.TPicklistEntry e : tPicklistEntries ){
                    options.add(new SelectOption(e.value, e.label));
                }
            }
            return options;
        }
    }

    // コンストラクタ
    public Example(){
        this.objectInstance = new SomeObject();
    }     
}

这个部分,相信大部分人都能查看文档弄清楚。

最关键的下面这个方法(GetDependentOptions):DepPickListCtrl.apxc

/* Reference
 * Great thanks to Neel
 * http://titancronus.com/blog/2014/05/01/salesforce-acquiring-dependent-picklists-in-apex/
 */

public class DepPickListCtrl {
    public static Map<String,List<DepPickListCtrl.TPicklistEntry>> GetDependentOptions(String pObjName, String pControllingFieldName, String pDependentFieldName){
        Map<String,List<DepPickListCtrl.TPicklistEntry>> objResults = new Map<String,List<DepPickListCtrl.TPicklistEntry>>();
        //get the string to sobject global map
        // 拿到Schema命名空间的描述
  Map<String,Schema.SObjectType> objGlobalMap = Schema.getGlobalDescribe(); if (!objGlobalMap.containsKey(pObjName)) return objResults; //get the type being dealt with Schema.SObjectType pType = objGlobalMap.get(pObjName); Map<String, Schema.SObjectField> objFieldMap = pType.getDescribe().fields.getMap(); //verify field names if (!objFieldMap.containsKey(pControllingFieldName) || !objFieldMap.containsKey(pDependentFieldName)) return objResults; //get the control values // 拿到控制的选择List选项对应关系
List<Schema.PicklistEntry> ctrl_ple = objFieldMap.get(pControllingFieldName).getDescribe().getPicklistValues(); //get the dependent values // 拿到被控制的List选项对应关系
List<Schema.PicklistEntry> dep_ple = objFieldMap.get(pDependentFieldName).getDescribe().getPicklistValues(); //iterate through the values and get the ones valid for the controlling field name // 这个Validfor我实在不知道是干嘛的。官方文档上也没找打,但是这个值很重要
DepPickListCtrl.DependentValidFor dvf=new DepPickListCtrl.DependentValidFor(); //set up the results for(Integer pControllingIndex=0; pControllingIndex<ctrl_ple.size(); pControllingIndex++){ //get the pointer to the entry Schema.PicklistEntry ctrl_entry = ctrl_ple[pControllingIndex]; //get the label String pControllingLabel = ctrl_entry.getLabel(); //create the entry with the label objResults.put(pControllingLabel,new List<DepPickListCtrl.TPicklistEntry>()); } //cater for null and empty objResults.put('',new List<DepPickListCtrl.TPicklistEntry>()); objResults.put(null,new List<DepPickListCtrl.TPicklistEntry>()); //check the dependent values for(Integer pDependentIndex=0; pDependentIndex<dep_ple.size(); pDependentIndex++){ //get the pointer to the dependent index Schema.PicklistEntry dep_entry = dep_ple[pDependentIndex]; //get the valid for
// 不转换成Json,你是拿不到validfor这个值的 String pEntryStructure = JSON.serialize(dep_entry); DepPickListCtrl.TPicklistEntry objDepPLE = (DepPickListCtrl.TPicklistEntry)JSON.deserialize(pEntryStructure, DepPickListCtrl.TPicklistEntry.class); //if valid for is empty, skip if (objDepPLE.validFor==null || objDepPLE.validFor==''){ continue; } //iterate through the controlling values
// 【getControlIndexes】这个方法就是取得被控制选择List选项的Index的方法
// 实现原理看在下面 for(Integer idx : dvf.getControlIndexes(objDepPLE.validFor)){ //get the label String pControllingValue = ctrl_ple[idx].getValue(); objResults.get(pControllingValue).add(objDepPLE); } } return objResults; } public class TPicklistEntry{ public string active {get;set;} public string defaultValue {get;set;} public string label {get;set;} public string value {get;set;} public string validFor {get;set;} public TPicklistEntry(){ } } private class DependentValidFor { private Map<String,Set<Integer>> mapValidForIndexes=new Map<String,Set<Integer>>(); public Set<Integer> getControlIndexes(String validFor){ if(mapValidForIndexes.containsKey(validFor)) return mapValidForIndexes.get(validFor); // 将validfor从Base64转化成16进制格式
// 对,也就是说,validfor是Base64格式的数据
// 而官方只提供了转化成16进制格式的方法(convertToHex),这样才将validfor变为可读数据
String hex=EncodingUtil.convertToHex(EncodingUtil.base64Decode(validFor)); Set<Integer> result=new Set<Integer>(); // 循环遍历16进制数的每一位
for(Integer i=0; i<hex.length(); i++){ String b=hex.substring(i, i+1); Integer off=i*4;
// 每一位都当成二进制数据 switch on b { //0123(index) when '0'{ //0000 }
// 第一次循环时i=0
// 当0010的时候,意味着被控制选择List的选项的Index2的选项是可选的 // 当0100的时候,意味着被控制选择List的选项的Index3的选项是可选的
// 。。。。

// 也就是说决定那个Index的选项可选不是看值的大小,
// 而是看值的位置,1处在那个位置上,index几就是可选项。
// 因为每一个16进制数可以表示n~n+4(index),
// 所以当i+1时,index就是从n+4开始的,
// 例子: i=0时,“f” → 0,1,2,3
// 例子: i=1时, “f” → 4,5,6,7
// 所以off每次都要*4
when '1'{ //0001 result.add(off+3); }
when '2'{ //0010 result.add(off+2); } when '3'{ //0011 result.add(off+2); result.add(off+3); } when '4'{ //0100 result.add(off+1); } when '5'{ //0101 result.add(off+1); result.add(off+3); } when '6'{ //0110 result.add(off+1); result.add(off+2); } when '7'{ //0111 result.add(off+1); result.add(off+2); result.add(off+3); } when '8'{ //1000 result.add(off+0); } when '9'{ //1001 result.add(off+0); result.add(off+3); } when 'a'{ //1010 result.add(off+0); result.add(off+2); } when 'b'{ //1011 result.add(off+0); result.add(off+2); result.add(off+3); } when 'c'{ //1100 result.add(off+0); result.add(off+1); } when 'd'{ //1101 result.add(off+0); result.add(off+1); result.add(off+3); } when 'e'{ //1110 result.add(off+0); result.add(off+1); result.add(off+2); } when 'f'{ //1111 result.add(off+0); result.add(off+1); result.add(off+2); result.add(off+3); } } } mapValidForIndexes.put(validFor,result); return result; } } }

  

 

 

DepPickListCtrl.apxc
 
/* Reference
 * Great thanks to Neel
 * http://titancronus.com/blog/2014/05/01/salesforce-acquiring-dependent-picklists-in-apex/
 */

public class DepPickListCtrl {
    public static Map<String,List<DepPickListCtrl.TPicklistEntry>> GetDependentOptions(String pObjName, String pControllingFieldName, String pDependentFieldName){
        Map<String,List<DepPickListCtrl.TPicklistEntry>> objResults = new Map<String,List<DepPickListCtrl.TPicklistEntry>>();
        //get the string to sobject global map
        Map<String,Schema.SObjectType> objGlobalMap = Schema.getGlobalDescribe();
        if (!objGlobalMap.containsKey(pObjName))
            return objResults;
        //get the type being dealt with
        Schema.SObjectType pType = objGlobalMap.get(pObjName);
        Map<String, Schema.SObjectField> objFieldMap = pType.getDescribe().fields.getMap();
        //verify field names
        if (!objFieldMap.containsKey(pControllingFieldName) || !objFieldMap.containsKey(pDependentFieldName))
            return objResults;     
        //get the control values   
        List<Schema.PicklistEntry> ctrl_ple = objFieldMap.get(pControllingFieldName).getDescribe().getPicklistValues();
        //get the dependent values
        List<Schema.PicklistEntry> dep_ple = objFieldMap.get(pDependentFieldName).getDescribe().getPicklistValues();
        //iterate through the values and get the ones valid for the controlling field name
        DepPickListCtrl.DependentValidFor dvf=new DepPickListCtrl.DependentValidFor();

        //set up the results
        for(Integer pControllingIndex=0; pControllingIndex<ctrl_ple.size(); pControllingIndex++){          
            //get the pointer to the entry
            Schema.PicklistEntry ctrl_entry = ctrl_ple[pControllingIndex];
            //get the label
            String pControllingLabel = ctrl_entry.getLabel();
            //create the entry with the label
            objResults.put(pControllingLabel,new List<DepPickListCtrl.TPicklistEntry>());
        }
        //cater for null and empty
        objResults.put('',new List<DepPickListCtrl.TPicklistEntry>());
        objResults.put(null,new List<DepPickListCtrl.TPicklistEntry>());
        //check the dependent values
        for(Integer pDependentIndex=0; pDependentIndex<dep_ple.size(); pDependentIndex++){          
            //get the pointer to the dependent index
            Schema.PicklistEntry dep_entry = dep_ple[pDependentIndex];
            //get the valid for
            String pEntryStructure = JSON.serialize(dep_entry);                
            DepPickListCtrl.TPicklistEntry objDepPLE = (DepPickListCtrl.TPicklistEntry)JSON.deserialize(pEntryStructure, DepPickListCtrl.TPicklistEntry.class);
            //if valid for is empty, skip
            if (objDepPLE.validFor==null || objDepPLE.validFor==''){
                continue;
            }
            //iterate through the controlling values
            for(Integer idx : dvf.getControlIndexes(objDepPLE.validFor)){
                //get the label
                String pControllingValue = ctrl_ple[idx].getValue();
                objResults.get(pControllingValue).add(objDepPLE);
            }
        } 
        return objResults;
    }
    public class TPicklistEntry{
        public string active {get;set;}
        public string defaultValue {get;set;}
        public string label {get;set;}
        public string value {get;set;}
        public string validFor {get;set;}
        public TPicklistEntry(){
        }
    }
    private class DependentValidFor {
        private Map<String,Set<Integer>> mapValidForIndexes=new Map<String,Set<Integer>>();
        public Set<Integer> getControlIndexes(String validFor){
            if(mapValidForIndexes.containsKey(validFor))
                return mapValidForIndexes.get(validFor);
            String hex=EncodingUtil.convertToHex(EncodingUtil.base64Decode(validFor));
            Set<Integer> result=new Set<Integer>();
            for(Integer i=0; i<hex.length(); i++){
                String b=hex.substring(i, i+1);
                Integer off=i*4;
                switch on b {   //0123(index)
                    when '0'{   //0000
                    }
                    when '1'{   //0001
                        result.add(off+3);
                    }
                    when '2'{   //0010
                        result.add(off+2);
                    }
                    when '3'{   //0011
                        result.add(off+2);
                        result.add(off+3);
                    }
                    when '4'{   //0100
                        result.add(off+1);
                    }
                    when '5'{   //0101
                        result.add(off+1);
                        result.add(off+3);
                    }
                    when '6'{   //0110
                        result.add(off+1);
                        result.add(off+2);
                    }
                    when '7'{   //0111
                        result.add(off+1);
                        result.add(off+2);
                        result.add(off+3);
                    }
                    when '8'{   //1000
                        result.add(off+0);
                    }
                    when '9'{   //1001
                        result.add(off+0);
                        result.add(off+3);
                    }
                    when 'a'{   //1010
                        result.add(off+0);
                        result.add(off+2);
                    }
                    when 'b'{   //1011
                        result.add(off+0);
                        result.add(off+2);
                        result.add(off+3);
                    }
                    when 'c'{   //1100
                        result.add(off+0);
                        result.add(off+1);
                    }
                    when 'd'{   //1101
                        result.add(off+0);
                        result.add(off+1);
                        result.add(off+3);
                    }
                    when 'e'{   //1110
                        result.add(off+0);
                        result.add(off+1);
                        result.add(off+2);
                    }
                    when 'f'{   //1111
                        result.add(off+0);
                        result.add(off+1);
                        result.add(off+2);
                        result.add(off+3);
                    }
                }
            }
            mapValidForIndexes.put(validFor,result);
            return result;
        }
    }
}

posted on 2021-07-01 10:26  、文君  阅读(162)  评论(0编辑  收藏  举报

导航