1

Is it possible to compare two PickListEntry based on their order value?

For example if we have these values for Opportunity.Stage:

Prospecting
Closed Won

Can we determine if 'Prospecting' comes before or after 'Closed Won'?

0

3 Answers 3

3

You can create a map to efficiently find the values:

// Initialize once
static Map<String, Integer> valueMap = new Map<String, Integer>();
static {
    for(PicklistEntry entry: Opportunity.StageName.getDescribe().getPicklistValues()) {
        valueMap.put(entry.getLabel(), valueMap.size());
    }
}

public static Integer compareStageName(String value1, String value2) {
    return valueMap.get(value1) - valueMap.get(value2);
}

At this point, if value1 is positionally greater than value2, the result will be positive, if less than, negative, and if equal, 0.

You could also make this more generic to support multiple picklist fields without too much effort:

public class PicklistOrder {
    static Map<SObjectField, Map<String, Integer>> 
        values = new Map<SObjectField, Map<String, Integer>>();
    public static Integer compare(SObjectField field, String value1, String value2) {
        if(!values.containsKey(field)) {
            Map<String, Integer> valueMap = new Map<String, Integer>();
            for(PicklistEntry entry: field.getDescribe().getPicklistValues()) {
                valueMap.put(entry.getLabel(), valueMap.size());
            }
            values.put(field, valueMap);
        }
        return values.get(field).get(value1) - values.get(field).get(value2);
    }
}
5
  • 2
    My one question here...Is it guaranteed that getPicklistValues() always returns the values in the order specified in the field configuration?
    – Adrian Larson
    Mar 16, 2017 at 15:32
  • @AdrianLarson The documentation makes no guarantee about the order, but I can't imagine that salesforce would go out of their way to upset the majority of their client base. After all, this method is used to render picklists in Visualforce and Lightning, so if this suddenly broke, I'd imagine almost every major client would be logging cases.
    – sfdcfox
    Mar 16, 2017 at 15:41
  • 1
    For that second example, you might call the outer class PicklistOrder, and then just call the method compare. Then it'd be Integer relativeOrder = PicklistOrder.compare(someField, 'Value 1', 'Value 2');
    – Adrian Larson
    Mar 16, 2017 at 15:43
  • @AdrianLarson I like that. It was more of an intended fragment, but this makes it copy-paste friendly. I've added in the edit.
    – sfdcfox
    Mar 16, 2017 at 15:47
  • we also can init values with Null valueMap = new Map<String, Integer>{Null => -1}; in case if picklist is emtpy Mar 26, 2017 at 18:09
0

Picklist entry doesn't have property describing its position. We can initialize PicklistEntry for field and compare two indexes:

Opportunity opp = new Opportunity(StageName = 'Prospecting');

String v1 = 'Closed Won';
system.debug(v1 + ' > ' + opp.StageName + ' : ' + (v1 > opp.StageName));

Integer index1, index2;
Schema.DescribeFieldResult fieldResult = Opportunity.StageName.getDescribe();
List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();

for( integer i = 0; i < ple.size(); i++){
    system.debug(i + '. ' + ple[i].getLabel());
    if  (v1 == ple[i].getLabel()) {
        index1 = i;
    }
    if  (opp.StageName == ple[i].getLabel()) {
        index2 = i;
    }
}
system.debug(v1 + ' > ' + opp.StageName + ' : ' + (index1 > index2));

Debug:

|DEBUG|Closed Won > Prospecting : false
|DEBUG|0. Prospecting
|DEBUG|8. Closed Won
|DEBUG|Closed Won > Prospecting : true
1
  • 1
    This is terribly inefficient, fwiw, especially if you call this method many times.
    – sfdcfox
    Mar 16, 2017 at 15:18
0

Here is an example of validation similar to what we use to control Stage progression:

(ABS( 
CASE( StageName , 
"Prospecting",1, 
"Qualification",2, 
"Needs Analysis",3, 
"Value Proposition",4, 
"Id. Decision Makers",5, 
"Perception Analysis",6, 
"Proposal/Price Quote",7, 
"Negotiation/Review",8, 
9) 
- 
CASE(PRIORVALUE(StageName) , 
"Prospecting",1, 
"Qualification",2, 
"Needs Analysis",3, 
"Value Proposition",4, 
"Id. Decision Makers",5, 
"Perception Analysis",6, 
"Proposal/Price Quote",7, 
"Negotiation/Review",8, 
9) 
) * 
CASE( StageName , 
"Closed Won",0, 
"Closed Lost",0,
1) 
> 1) 

It's not letting the users to skip stages (with exception for "Closed Won", "Closed Lost"), and also to move stage backwards, but only to the neighboring picklist value.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .