Find your content:

Search form

You are here

Refer to Record Type ID in Formula without Hard-coding

 
Share

I'm building a Custom List Button in a Dev Environment, and I'd like it to work with no changes when deployed to Production even though all IDs will change.

The list button (which will be displayed in a related list) allows users to create a new related object, but specifies a specific Record Type, and pre-fills the new object with data from the current record.

It looks like this:

{!URLFOR( $Action.Contact.NewContact , null, [CF00NJ0000000QIX7=Contact.Id, RecordType="012J00000004NGB"])}

The problem is that this RecordType ID will change with deployment. I'll always know it's name, though. Is there any way to use that?

Update: Also, won't the custom field ID change also (CF00NJ0000000QIX7 above) -- what do I do about that?


Attribution to: Benj

Possible Suggestion/Solution #1

Yes. You can query the RecordType object in your controller and then reference that property in your VF page.

Here's an example using the Account object:

Id recTypeId = [
     Select Id 
     From RecordType 
     Where SObjectType ='Account' 
       And Name = 'Your Record Type Name' Limit 1
][0].Id;

Attribution to: Peter Knolle

Possible Suggestion/Solution #2

You can use custom setting for this. Keep the record type Id in custom setting and use that in your button code, it will look something like this "{!$Setup.CustomSettingAPI_c.RecordTypeId_c}"


Attribution to: Forceguru

Possible Suggestion/Solution #3

Great question!

For the sake of anyone who's doing this in Visualforce (which, Benj, I recognize you're not), here's what I would do: get a reference to the record type Id in Apex using a method similar to this: (note that I am returning a Map keyed by RecordType DeveloperName, NOT Name, because Name can always be changed/overridden in Production org, whereas DeveloperName does not change. This is an especially important best practice when developing managed packages.

// Returns a map of active, user-available RecordType IDs for a given SObjectType,
// keyed by each RecordType's unique, unchanging DeveloperName 
global static Map<String, Id> GetRecordTypeIdsByDeveloperName(
    Schema.SObjectType token
) {
    // Build a map of RecordTypeIds keyed by DeveloperName
    Map<String, Id> mapRecordTypes = new Map<String, Id>();

    // Get the Describe Result
    Schema.DescribeSObjectResult obj = token.getDescribe();

    // Obtain ALL Active Record Types for the given SObjectType token
    // (We will filter out the Record Types that are unavailable
    // to the Running User using Schema information)
    String soql = 
        'SELECT Id, Name, DeveloperName '
        + 'FROM RecordType '
        + 'WHERE SObjectType = \'' + String.escapeSingleQuotes(obj.getName()) + '\' '
        + 'AND IsActive = TRUE';
    List<SObject> results;
    try {
        results = Database.query(soql);
    } catch (Exception ex) {
        results = new List<SObject>();
    }

    // Obtain the RecordTypeInfos for this SObjectType token
    Map<Id,Schema.RecordTypeInfo> recordTypeInfos = obj.getRecordTypeInfosByID();

    // Loop through all of the Record Types we found,
    //      and weed out those that are unavailable to the Running User
    for (SObject rt : results) {  
        if (recordTypeInfos.get(rt.Id).isAvailable()) {
            // This RecordType IS available to the running user,
            //      so add it to our map of RecordTypeIds by DeveloperName
            mapRecordTypes.put(String.valueOf(rt.get('DeveloperName')),rt.Id);
        }
    }

    return mapRecordTypes;
}

TO use this to accomplish your need, you could do something like the following:

// CONTROLLER
public class MyController() {

    public transient Id myRecordType {
         public get {
              if (myRecordType == null) {
                 myRecordType = GetRecordTypeIdsByDeveloperName(
                     DesiredObject__c.SObjectType
                 ).get('Desired_Record_Type_Developer_Name');
              } 
              return myRecordType;  
         } private set;
    }
}


 // Visualforce Page with Link to create a new record of this type
 <apex:page>
       <apex:commandLink value='{!URLFOR( $Action.Contact.NewContact , null, [CF00NJ0000000QIX7=Contact.Id, RecordType=myRecordType])}'/> 
 </apex:page>

Attribution to: zachelrath

Possible Suggestion/Solution #4

You can also do this with an on-click java script and to call an apex web-service to return the recordtype ID. Use the returned record type ID string to create your new contact.


Attribution to: Matt

Possible Suggestion/Solution #5

As an aide once you deploy to Production and refresh your sandboxes from Prod, record type ids and for that matter all ids (metadata) will be in sync (I.e. same ) across environments


Attribution to: techtrekker
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/1626

My Block Status

My Block Content