关于Salesforce存在至于项目的选择List的取值问题
概要:
我们在做项目的时候,经常会遇到一个问题:
一个选择List字段的可选项被另一个选择List制约,这种情况如何在后台取得这两者的对应关系。
原文在这里(侵删):
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;
}
}
}
/* 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;
}
}
}
关于Salesforce存在至于项目的选择List的取值问题的更多相关文章
- pycharm新建项目时选择virtualenv的说明
虚拟环境及venv和virtualenv介绍:https://www.cnblogs.com/mind18/p/13877170.html pip介绍:https://www.cnblogs.com/ ...
- git的使用学习笔记3---关于项目分支创建克隆拉取推送
一.创建项目 1.打开官网 2.填写相关内容 查看新创建的项目 3.选择方式 4.在git上新建文件夹 1)克隆: mkdir workspace 将代码克隆到本地,取本地配置的.ssh的文件 git ...
- jQuery取得select选择的文本与值
jquery获取select选择的文本与值获取select :获取select 选中的 text :$("#ddlregtype").find("option:selec ...
- springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序
springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序 http://www.360doc.com/content/14/03 ...
- Android项目,从web上取下汉字,中文部分乱码
Android项目,从web上取下汉字,中文部分乱码. 常见问题,搜索一下,网上有很多办法解决.如果还没有试过这个办法,可以尝试一下. BufferedReader in = new Buffered ...
- [荐] jQuery取得select选择的文本与值
csdn:http://blog.csdn.net/tiemufeng1122/article/details/44154571 jquery获取select选择的文本与值获取select :获取se ...
- Salesforce中所有常用类型字段的取值与赋值
Salesforce中所有常用字段类型的定义以及如何用代码进行取值和赋值: Field Type的定义: http://www.salesforce.com/us/developer/docs/api ...
- Xamarin.iOS项目提示error MSB3174:”TargetFrameworkVersion”的值无效
Xamarin.iOS项目提示error MSB3174:”TargetFrameworkVersion”的值无效 错误信息:MSBulid\14.0\bin\Microsoft.Common.Cur ...
- jquery获取select选择的文本与值
jquery获取select选择的文本与值获取select :获取select 选中的 text : $("#ddlregtype").find("option:s ...
- bootstrap select 多选的用法,取值和赋值(取消默认选择第一个的对勾)
h5自带的select标签可以实现按住ctrl键多选的功能,但是样式及其难看. bootstrap select是很好用的前端插件 首先引入bootstrap和bootstrap-select的c ...
随机推荐
- JZOJ 5947.初音未来(miku)
题目大意 维护一个数列 \(a_n\),\(m\) 次操作,每次对区间 \([l..r]\) 进行升序排序 求最后询问区间 \([L..R]\),输出 \(a_L,a_{L+1},···,a_{R}\ ...
- 如何基于IM即时通讯SDK从零开发仿微信聊天交友功能
IM即时通讯技术的发展 IM即时通讯(Instant Messaging)是一种基于互联网的即时交流消息的业务. 实时聊天交互功能是市面上主流APP的重要功能之一,人们所熟悉的就是微信,QQ的聊天消息 ...
- EMBARK研究: 依那西普治疗早期nr-axSpA达48周的临床和MRI疗效
关键词: 放射学阴性中轴型SpA; TNF拮抗剂; 磁共振影像 EMBARK研究48周结果: 依那西普治疗早期放射学阴性中轴型SpA患者的临床与MRI疗效 电邮发布日期:2016年1月25日 文献: ...
- axSpA患者新发炎症更容易发生在既往发生过炎症的区域
axSpA患者新发炎症更容易发生在既往发生过炎症的区域 EULAR2015; PresentID: SAT0240 NEW INFLAMMATORY LESIONS IN AXIAL SPONDYLO ...
- Error in created hook: "TypeError: Cannot read properties of undefined (reading 'get')"
写Vue 的时候常遇到的错误之一就是XXXXXX未定义,然后来一个undefined这种问题一般都是创建钩子出错:无法读取未定义的 xxx 属性. 此错误一般多出现在 created() 中, Vue ...
- 如何在 JavaScript 中使用媒体查询
前言 说起媒体查询想必大家最先想到的都是CSS中@media,没错,这是我们最常用的媒体查询方法,主要用来为我们的网站做适配处理. 比如: h1 { font-size: 2rem; color: g ...
- YML
一.YML语法 1.约定 k: v 表示键值对关系,冒号后面必须有一个空格 使用空格的缩进表示层级关系,空格数目不重要,只要是左对齐的一列数据,都是同一个层级的 大小写敏感 缩进时不允许使用Tab键, ...
- day12_内部类&API
1.参数传递 1.1 类名作为形参和返回值 类名--方法形参 方法的形参是类名,需要的是该类的对象:实际传递的是该对象的地址值 类名--返回值 方法的返回值是类名,返回的是该类的对象: ...
- Day 23 23.2.1:微信公众平台案例
微信公众平台案例 注意:接下来将的内容,请忽视具体网站,重点专注逆向的分析思路! 接下来就是爬什么网站,什么数据,什么形式都统统不重要!重点是分析思路 微信公众平台案例 url:https://mp. ...
- 回归分析 3.X 多元线性回归
多元线性回归模型 参数估计 模型表示 我们先将模型 \[y_{i}=\beta_{0}+\beta_{1} x_{i 1}+\cdots+\beta_{p} x_{i k}+\epsilon_{i}, ...