+ Start a Discussion
singledotsingledot 

Restrict Trigger to fire only if field condition is met - lookup rollup try/catch

Hi. I'm facing what seems like it would be an easy fix. I have some open rollup code (Copyright (c) 2012 tgerm.com) that mimics that rollup function on a lookup object (If you need the Apex class it calls I can append it). My "child" object Milestones__c however has two different "master/parent" objects: Goal__c and Class__c. I'm finding that when there is no Goal__c object set (and the child object is only related to Class__c) I'm getting this error:

 

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger MilestoneRollup caused an unexpected exception, contact your administrator: MilestoneRollup: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0; first error: MISSING_ARGUMENT, Id not specified in an update call: []: Trigger.MilestoneRollup: line 67, column 1

 

Basically I just need to limit this trigger to only update when a certain field condition is met - when Milestones__c.Goal_Name__c != NULL. I'm very new to this and I've read this might need a try-catch (see:http://boards.developerforce.com/t5/Apex-Code-Development/Conditional-Trigger/m-p/538539#M97783), but I've tried different iterations and can't seem to get it to work. Here is the trigger with no conditions.

 

trigger MilestoneRollup on Milestones__c (after insert, after update
                                            ) {
      // modified objects whose parent records should be updated
     Milestones__c[] objects = null;   
     
     if (Trigger.isDelete) {
         objects = Trigger.old;
     } else {
        /*
            Handle any filtering required, specially on Trigger.isUpdate event. If the rolled up fields
            are not changed, then please make sure you skip the rollup operation.
            We are not adding that for sake of similicity of this illustration.
        */
        objects = Trigger.new;
     }


     /*
      First step is to create a context for LREngine, by specifying parent and child objects and
      lookup relationship field name
     */

     
     LREngine.Context ctx = new LREngine.Context(Goal__c.SobjectType, // parent object
                                            Milestones__c.SobjectType,  // child object
                                            Schema.SObjectType.Milestones__c.fields.Goal_Name__c  // relationship field name
                                            );
       
     /*
      Next, one can add multiple rollup fields on the above relationship.
      Here specify
       1. The field to which aggregated value will be saved in master/parent object
       2. The field to aggregate in child object
       3. The aggregate operation to be done i.e. SUM, AVG, COUNT, MIN/MAX
     */
     ctx.add(
            new LREngine.RollupSummaryField(Schema.SObjectType.Goal__c.fields.Number_of_Related_Milestones_Rollup__c,
                                            Schema.SObjectType.Milestones__c.fields.Number_for_LREngine__c,
                                            LREngine.RollupOperation.Sum
                                         ));
                                         
     ctx.add(
                                         
            new LREngine.RollupSummaryField(Schema.SObjectType.Goal__c.fields.Milestones_Closed_Not_Completed_Rollup__c,
                                            Schema.SObjectType.Milestones__c.fields.Closed_Not_Completed__c,
                                            LREngine.RollupOperation.Sum
                                         ));
                                         
     ctx.add(
            
            new LREngine.RollupSummaryField(Schema.SObjectType.Goal__c.fields.Number_of_Milestones_Complete_Rollup__c,
                                            Schema.SObjectType.Milestones__c.fields.Milestones_Complete__c,
                                            LREngine.RollupOperation.Sum
                                         ));
                                    

     /*
      Calling rollup method returns in memory master objects with aggregated values in them.
      Please note these master records are not persisted back, so that client gets a chance
      to post process them after rollup
      */
     Sobject[] masters = LREngine.rollUp(ctx, objects);    

     // Persiste the changes in master
     update masters;

    
}

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
SarfarajSarfaraj

Your code was trying to do this: 

Update Milestonse__c set Field1 = value where id = null

 That is the reason of the error. Use the following code:

 

trigger MilestoneRollup on Milestones__c (after insert, after update
                                            ) {
      // modified objects whose parent records should be updated
     Milestones__c[] objectsTemp = null;   
     
     if (Trigger.isDelete) {
         objectsTemp = Trigger.old;
     } else {
        /*
            Handle any filtering required, specially on Trigger.isUpdate event. If the rolled up fields
            are not changed, then please make sure you skip the rollup operation.
            We are not adding that for sake of similicity of this illustration.
        */
        objectsTemp = Trigger.new;
     }
	List<Milestones__c> objects = new List<Milestones__c>();
	for(Milestones__c m : objectsTemp)
		if(m.Goal_Name__c <> null)
			objects.add(m)

     /*
      First step is to create a context for LREngine, by specifying parent and child objects and
      lookup relationship field name
     */

     
     LREngine.Context ctx = new LREngine.Context(Goal__c.SobjectType, // parent object
                                            Milestones__c.SobjectType,  // child object
                                            Schema.SObjectType.Milestones__c.fields.Goal_Name__c  // relationship field name
                                            );
       
     /*
      Next, one can add multiple rollup fields on the above relationship.
      Here specify
       1. The field to which aggregated value will be saved in master/parent object
       2. The field to aggregate in child object
       3. The aggregate operation to be done i.e. SUM, AVG, COUNT, MIN/MAX
     */
     ctx.add(
            new LREngine.RollupSummaryField(Schema.SObjectType.Goal__c.fields.Number_of_Related_Milestones_Rollup__c,
                                            Schema.SObjectType.Milestones__c.fields.Number_for_LREngine__c,
                                            LREngine.RollupOperation.Sum
                                         ));
                                         
     ctx.add(
                                         
            new LREngine.RollupSummaryField(Schema.SObjectType.Goal__c.fields.Milestones_Closed_Not_Completed_Rollup__c,
                                            Schema.SObjectType.Milestones__c.fields.Closed_Not_Completed__c,
                                            LREngine.RollupOperation.Sum
                                         ));
                                         
     ctx.add(
            
            new LREngine.RollupSummaryField(Schema.SObjectType.Goal__c.fields.Number_of_Milestones_Complete_Rollup__c,
                                            Schema.SObjectType.Milestones__c.fields.Milestones_Complete__c,
                                            LREngine.RollupOperation.Sum
                                         ));
                                    

     /*
      Calling rollup method returns in memory master objects with aggregated values in them.
      Please note these master records are not persisted back, so that client gets a chance
      to post process them after rollup
      */
     Sobject[] masters = LREngine.rollUp(ctx, objects);    

     // Persiste the changes in master
     update masters;

    
}

All Answers

SarfarajSarfaraj

Your code was trying to do this: 

Update Milestonse__c set Field1 = value where id = null

 That is the reason of the error. Use the following code:

 

trigger MilestoneRollup on Milestones__c (after insert, after update
                                            ) {
      // modified objects whose parent records should be updated
     Milestones__c[] objectsTemp = null;   
     
     if (Trigger.isDelete) {
         objectsTemp = Trigger.old;
     } else {
        /*
            Handle any filtering required, specially on Trigger.isUpdate event. If the rolled up fields
            are not changed, then please make sure you skip the rollup operation.
            We are not adding that for sake of similicity of this illustration.
        */
        objectsTemp = Trigger.new;
     }
	List<Milestones__c> objects = new List<Milestones__c>();
	for(Milestones__c m : objectsTemp)
		if(m.Goal_Name__c <> null)
			objects.add(m)

     /*
      First step is to create a context for LREngine, by specifying parent and child objects and
      lookup relationship field name
     */

     
     LREngine.Context ctx = new LREngine.Context(Goal__c.SobjectType, // parent object
                                            Milestones__c.SobjectType,  // child object
                                            Schema.SObjectType.Milestones__c.fields.Goal_Name__c  // relationship field name
                                            );
       
     /*
      Next, one can add multiple rollup fields on the above relationship.
      Here specify
       1. The field to which aggregated value will be saved in master/parent object
       2. The field to aggregate in child object
       3. The aggregate operation to be done i.e. SUM, AVG, COUNT, MIN/MAX
     */
     ctx.add(
            new LREngine.RollupSummaryField(Schema.SObjectType.Goal__c.fields.Number_of_Related_Milestones_Rollup__c,
                                            Schema.SObjectType.Milestones__c.fields.Number_for_LREngine__c,
                                            LREngine.RollupOperation.Sum
                                         ));
                                         
     ctx.add(
                                         
            new LREngine.RollupSummaryField(Schema.SObjectType.Goal__c.fields.Milestones_Closed_Not_Completed_Rollup__c,
                                            Schema.SObjectType.Milestones__c.fields.Closed_Not_Completed__c,
                                            LREngine.RollupOperation.Sum
                                         ));
                                         
     ctx.add(
            
            new LREngine.RollupSummaryField(Schema.SObjectType.Goal__c.fields.Number_of_Milestones_Complete_Rollup__c,
                                            Schema.SObjectType.Milestones__c.fields.Milestones_Complete__c,
                                            LREngine.RollupOperation.Sum
                                         ));
                                    

     /*
      Calling rollup method returns in memory master objects with aggregated values in them.
      Please note these master records are not persisted back, so that client gets a chance
      to post process them after rollup
      */
     Sobject[] masters = LREngine.rollUp(ctx, objects);    

     // Persiste the changes in master
     update masters;

    
}
This was selected as the best answer
singledotsingledot

Thank you so much for this. For your time and explanation.

Fantatic.

L

SarfarajSarfaraj

You are welcome. :)