1

I had formula fields on my custom object, but the Formula got too big so Salesforce wouldn't let me save it. It went Formula Field to Formula Field to Formula Field.

So I am trying to create one of the Formulas in APEX by updating a Custom field that is in the middle of the set - so it now goes Formula Field to Custom Field to Formula Field. But I can't get the value of the 1st Formula Field in a Before Insert trigger since it doesn't exist.

Is there a way to make a trigger fire an Update trigger after the insert? Or is there a way to run a Before trigger inside an After trigger? The trigger I have works great when you Edit and Save the record... but I need it to work right when it's created.

Code that works for update... need it to work for insert:

trigger ClientCare_UpdateClient on Submitted_Documents__c (before update) {

List<ID> RequireContactId = new  List<ID>() ;

for(Submitted_Documents__c  SD : trigger.new) 
{
    if(SD.Contact_ID__c != null && SD.RecordTypeId == '012J00000004aQ4'){ 
        RequireContactId.add(SD.Contact_ID__c);
    }    
}

Map<ID,Contact> ContactData = new Map<Id,Contact>([Select Minor__c,Program__c, ID from Contact where id in : RequireContactId limit 1000 ]);

        Map<Id,Submitted_Documents__c> newSDMap = Trigger.newMap;
        for(Id SDId:newSDMap.keySet()){
            Submitted_Documents__c myNewSD = newSDMap.get(SDId);
            Contact theContact1 = ContactData.get(myNewSD.Contact_ID__c);
               if ((theContact1.Program__c == 'Open Doors' && myNewSD.TT_NUM__c == 10) || (theContact1.Minor__c == TRUE && myNewSD.TT_NUM__c == 12) || (theContact1.Program__c == 'Project HEAL' && myNewSD.TT_NUM__c == 11)){
                   myNewSD.All_Received_Client_Graduate2__c = TRUE;
                   if(theContact1.Program__c == 'Open Doors'){
                       myNewSD.Received_Client_Graduate2__c = myNewSD.TT_NUM__c + ' out of 10.';
                   }else if(theContact1.Minor__c == TRUE){
                       myNewSD.Received_Client_Graduate2__c = myNewSD.TT_NUM__c + ' out of 12.';                   
                   }else if(theContact1.Program__c == 'Project HEAL'){
                       myNewSD.Received_Client_Graduate2__c = myNewSD.TT_NUM__c + ' out of 11.';                   
                   }
               }else{
                   myNewSD.All_Received_Client_Graduate2__c = FALSE;
                   if(theContact1.Program__c == 'Open Doors'){
                       myNewSD.Received_Client_Graduate2__c = myNewSD.TT_NUM__c + ' out of 10.';
                   }else if(theContact1.Minor__c == TRUE){
                       myNewSD.Received_Client_Graduate2__c = myNewSD.TT_NUM__c + ' out of 12.';                   
                   }else if(theContact1.Program__c == 'Project HEAL'){
                       myNewSD.Received_Client_Graduate2__c = myNewSD.TT_NUM__c + ' out of 11.';                   
                   }
               }
        }        

}

7
  • Why not just use an AFTER INSERT & AFTER UPDATE trigger?
    – Mike Chale
    Jan 9, 2014 at 18:02
  • 1
    I get a "record is read only" error when trying to update fields on the same object.
    – Jennifer
    Jan 9, 2014 at 18:06
  • 1
    Can you share code? It sounds like you're trying to update the old objects instead of the new.
    – Mike Chale
    Jan 9, 2014 at 18:08
  • Review this table for which variables you can update. You may need to make copies of records. salesforce.com/us/developer/docs/apexcode/Content/…. Also, you may want to review salesforce.stackexchange.com/questions/9480/…
    – Mike Chale
    Jan 9, 2014 at 18:11
  • I just added the code that works for the update. But I need it to do the same thing on insert.
    – Jennifer
    Jan 9, 2014 at 18:25

2 Answers 2

3

Members of Trigger.new are read only in the after cycle.

In order to take action on an record in Trigger.new after insert/update, you need to create a new instance of each sObject record you want to work with and add it to a new list for update purposes.

...assuming after insert trigger on account...
List<Account> accts = new List<Account>();
for (Account a: Trigger.new) {

  if (some condition) {
    ...take action on a...
    Account acctToUpdate = new Account(id=a.Id, ...other updates...);
    accts.add(acctToUpdate);
  }
}

update accts; 

The only thing here is if you also do this on update, you will run into a recursive trigger problem, but this is easily remedied by using the recursive trigger pattern found here in this cookbook recipe.

3
  • I still get the error: ClientCare_UpdateClient: execution of AfterInsert caused by: System.FinalException: Record is read-only: Trigger.ClientCare_UpdateClient
    – Jennifer
    Jan 9, 2014 at 18:57
  • Did you get that error when trying to update copied list?
    – Mike Chale
    Jan 9, 2014 at 20:20
  • that's what I get for writing code without testing! you actually need a whole new instance of the sobject with the id of the original copied over. I thought the lock was on the Trigger.new list, not each individual element of the list. see corrections above.
    – pchittum
    Jan 10, 2014 at 10:22
1

If you add a workflow field update, then the triggers will be called again as an update trigger.

Here is the order of execution of triggers. When a new record is inserted, in steps 3 and 6, before and after insert are called. If there are workflow field updates (step 10), then the trigger fires again as a update trigger (step 11).

You must log in to answer this question.

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