有没有办法使用apex检索记录类型的Salesforce选项列表值?

时间:2017-07-18 20:22:35

标签: salesforce apex

我需要收集有关每种记录类型可用的选项列表值的信息。我知道这可以使用describeLayout或readMetadata API来实现。但是当我尝试为大型自定义对象收集此信息时,会发生麻烦。 SalesForce API返回一个记录类型,其中包含所有可用的选项列表值。

<recordTypeMappings>
    <name>Record1</name>
    <picklistsForRecordType>
        <picklistName>Picklist1</picklistName>
        <picklistValues>
            ...
        </picklistValues>
    </picklistsForRecordType>
    <picklistsForRecordType>
        <picklistName>Picklist2</picklistName>
        <picklistValues>
            ...
        </picklistValues>
    </picklistsForRecordType>
</recordTypeMappings>
<recordTypeMappings>
    <name>Record2</name>
    <picklistsForRecordType>
        <picklistName>Picklist1</picklistName>
        <picklistValues>
            ...
        </picklistValues>
    </picklistsForRecordType>
    <picklistsForRecordType>
        <picklistName>Picklist2</picklistName>
        <picklistValues>
            ...
        </picklistValues>
    </picklistsForRecordType>
</recordTypeMappings>

这意味着如果我有一个大对象(包括200个选项列表和100个记录类型),我将获得200 * 100 = 20,000个选项列表记录。它使API响应非常大,高达80MB。这是非常低效的,如果所有记录类型的选项列表值保持不变,它们仍会在API响应中包含在每个记录中。

我们的想法是获取唯一的选项列表值集,然后只包含记录ID,因此每个记录类型都不会复制相同的选项列表。

<recordTypeMappings>
    <name>Record1, Record2</name>
    <picklistsForRecordType>
        <picklistName>Picklist1</picklistName>
        <picklistValues>
            ...Values which are the same for Record1 and Record2...
        </picklistValues>
    </picklistsForRecordType>
    <picklistsForRecordType>
        <picklistName>Picklist2</picklistName>
        <picklistValues>
            ...Values which are the same for Record1 and Record2...
        </picklistValues>
    </picklistsForRecordType>
</recordTypeMappings>

这会减少响应大小。有没有办法在Apex中做到这一点?我在API中搜索,但找不到合适的东西。 Apex似乎是一个更好的解决方案,因为所有处理都将在Salesforce端进行。

感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

要过滤掉重复项并仅获取唯一值,请尝试在a Set中捕获一组选项列表值。例如,这里有一个函数,它接受一个字段列表(在这种情况下它是一个选项列表字段列表)并返回一组唯一的选项列表值。

// Given a list of picklist fields, return a set of unique picklist values
 Set<Schema.PicklistEntry> getUniquePickListValues(List<Schema.DescribeFieldResult> pickListFields) {

     Set<Schema.PicklistEntry> uniquePicklistValues = Set<Schema.PicklistEntry>();

     for(Schema.DescribeFieldResult pickList : pickListFields){

        List<Schema.PicklistEntry> pickListValues = pickList.getDescribe().getPicklistValues();

        for(Schema.PicklistEntry entry : pickListValues){

            uniquePicklistValues.add(entry);

        }

     }

     return uniquePicklistValues;

   }

我知道使用嵌套循环是低效的,但我不知道是否有更好的方法将对象列表合并到一个Set中。

希望这会有所帮助。

答案 1 :(得分:0)

如果您想根据记录类型检索选项列表值,请在此处查看我的解决方案, https://salesforce.stackexchange.com/questions/103837/how-do-i-get-the-intersection-of-recordtype-and-picklist-values-inside-apex/202519#202519

它使用REST API调用,但响应类似于getdescribe结果和记录类型信息。

答案 2 :(得分:0)

以下是性能和数量问题的解决方法。

挑战在于收集具有大量记录类型和选项列表的所有大型自定义对象记录类型的可用选项列表值。 首先,我没有找到任何方法直接在Apex中做到这一点,我使用了API调用。

当我们通过describeSObject调用(https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_calls_describesobject.htm)收到自定义对象描述时,我们获得所有选项列表值和记录类型值。我们没有得到的是每种记录类型可用的特定选项列表值。为此,我们需要执行describeLayout请求(https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_calls_describelayout.htm)。使用来自describeSObject的信息,我们可能会尝试预测describeLayout响应的大小。

例如,如果我们有500个选项列表值和20个记录类型,则describeLayout的总响应将具有最多500 * 20 = 10,000个选项列表值(因为describeLayout返回可用于每个记录类型的所有选项列表值)。然后我们需要估计XML响应的大小,因为Salesforce API的响应限制为5mb。在检查响应后,我发现要匹配5mb的限制,我们需要满足每个describeLayout请求少于30,000个选项列表值的要求。

解决方案是将这个大型调用分成几个较小的记录类型,因此我们检索几个记录类型的所有选项列表值,然后重复其他记录类型。

最多需要24个API请求才能从SalesForce API检索70MB数据,由于响应大小限制,这是不可能通过一次API调用实现的。