[SalesForce] Populating Lookup field from picklist on same object

trigger Wholesale_State on Account (after insert, after update) 
{
    for (Account a : Trigger.new) 
    {
        if (a.Wholesale_State__c == null)
        {
            a.Wholesale_State__c = a.Account_State__c; 
        }
        else if (a.Account_State__c == null) 
        {
            a.Account_State__c = a.Wholesale_State__c;
        }
    }
}

Error:Apex trigger Wholesale_State caused an unexpected exception,
contact your administrator: Wholesale_State: execution of AfterUpdate
caused by: System.StringException: Invalid id: Texas:
Trigger.Wholesale_State: line 7, column 1

I need to use the Name instead of the ID to populate the look up field, from what I researched. I don't understand how to do that though. Any help would be greatly appreciated.

Best Answer

When setting lookup fields programmatically with Apex, you need to reference the id of the "looked-up" object, not the name. The following code is untested, so there may be some syntactical errors, but intentionally readable - here's the general idea of what you want to do.

When designing a trigger like this, think backwards from your desired end result. In this case:

  1. You know that you will need a data structure in which you can access the Wholesale_State__c id (to assign the lookup) where the Name of that object matches the Picklist value...a Map<{picklist value}, {id of the Wholesale_State__c}> will work.
  2. To create that, you need to know the Wholesale_State__c records that you will need, i.e. the records whose Names match the values of the Picklist on Accounts for which this trigger will be firing.
  3. You already know those Accounts, because Trigger.new is a List of them!

Basically what you have to do is:

trigger Wholesale_State on Account (after insert, after update) {
   // set to hold the string values of the picklist that are used in the affected Accounts
   Set<String> picklistNameSet = new Set<String>();

   // add each of the picklist values, removing duplicates
   for (Account a : trigger.new) {
      picklistNameSet.add(a.Account_State__c);
   }

   // List of actual Wholesale_State__c records that we'll use to make our map
   List<Wholesale_State__c> ourWholesales = [SELECT id, Name FROM Wholesale_State__c WHERE Name IN :picklistNameSet];

   // Map that we'll use to access Wholesale_State__c Name/id pairs
   Map<String, id> wholesaleMap = new Map<String, id>();

   for (Wholesale_State__c w : ourWholesales) {
      wholesaleMap.put(w.Name, w.id);
   }

   for (Account a : Trigger.new) 
   {
      if (a.Wholesale_State__c == null) {
         a.Wholesale_State__c = wholesaleMap.get(a.Account_State__c);
      }
      else if (a.Account_State__c == null) {
         a.Account_State__c = a.Wholesale_State__r.Name;
      }
   }
}
Related Topic