+ Start a Discussion
Markey1Markey1 

Trigger Help Needed - Update Child field based on update to Parent record

Hi, I'm fairly new to Triggers and am hoping someone can give me a bit of direction.

 

I want a custom field "Record_Mode__c" on Child Object B to be updated to value "Edit" when Parent Object A's custom field "Status__c" is updated to "Open". Basically, any time the parent record's status changes, I want the child record's Record Mode field to be updated accordingly.

 

The Record Mode change will then drive workflow that will flip record types and page layouts. I prefer to use out of the box solutions, but I cannot use cross object workflows as there is no master detail relationship between Parent Object A and Child Object B.

 

Any assistance with code or alternate solutions are much appreciated! 

Best Answer chosen by Admin (Salesforce Developers) 
vishal@forcevishal@force

As you correctly stated that Workflows will not serve your purpose here, here is a code example for you:

 

I want a custom field "Record_Mode__c" on Child Object B to be updated to value "Edit" when Parent Object A's custom field "Status__c" is updated to "Open". Basically, any time the parent record's status changes, I want the child record's Record Mode field to be updated accordingly.

 

trigger tgrA on A__c (after insert, after update){
		
		// 1
		List<B__c> childRecords = [Select A__c, Record_Mode__c FROM B__c WHERE A__c IN Trigger.newMap.keySet()];
		
		// 2
		for(B__c child :childRecords){
			// 3
			if(trigger.isInsert && child.Status__c == 'Open'){
				child.Record_Mode__c = 'Edit';
			}
			// 4
			else if(trigger.isUpdate && child.Status == 'Open' && trigger.NewMap.get(child.A__c).Status__c != trigger.OldMap.get(child.A__c).Status__c){
				child.Record_Mode__c = 'Edit';
			}
		}
		
		// 5
		if(childRecords.size() > 0)
			update childRecords;
}

 

1. Querying child records from B Object related to A records that are being edited, inserted.
2. Iterating through all the child records and updating them as per the conditions.
3. If it is an insert, we simply check the status and if it meets the condition, update the child
4. If it is an update, we check if the Status value has been changed. If yes, then we update the child
5. Update all the related child records

 

This should help you get started.

All Answers

vishal@forcevishal@force

As you correctly stated that Workflows will not serve your purpose here, here is a code example for you:

 

I want a custom field "Record_Mode__c" on Child Object B to be updated to value "Edit" when Parent Object A's custom field "Status__c" is updated to "Open". Basically, any time the parent record's status changes, I want the child record's Record Mode field to be updated accordingly.

 

trigger tgrA on A__c (after insert, after update){
		
		// 1
		List<B__c> childRecords = [Select A__c, Record_Mode__c FROM B__c WHERE A__c IN Trigger.newMap.keySet()];
		
		// 2
		for(B__c child :childRecords){
			// 3
			if(trigger.isInsert && child.Status__c == 'Open'){
				child.Record_Mode__c = 'Edit';
			}
			// 4
			else if(trigger.isUpdate && child.Status == 'Open' && trigger.NewMap.get(child.A__c).Status__c != trigger.OldMap.get(child.A__c).Status__c){
				child.Record_Mode__c = 'Edit';
			}
		}
		
		// 5
		if(childRecords.size() > 0)
			update childRecords;
}

 

1. Querying child records from B Object related to A records that are being edited, inserted.
2. Iterating through all the child records and updating them as per the conditions.
3. If it is an insert, we simply check the status and if it meets the condition, update the child
4. If it is an update, we check if the Status value has been changed. If yes, then we update the child
5. Update all the related child records

 

This should help you get started.

This was selected as the best answer
Markey1Markey1

Vishal,

 

First, thank you for your reply, your assistance is appreciated!

 

I plugged in the code you provided and am receiving an error "Error: Compile Error: unexpected token: 'Trigger.newMap.keySet' at line 4 column 137".

 

trigger tgrMCCReq on MCC_Request__c (after insert, after update){
        
        // 1
        List<MCC_Relationship__c> childRecords = [Select MCC_Request__c, Record_Mode__c FROM MCC_Relationship__c WHERE MCC_Request__c IN Trigger.newMap.keySet()];
        
        // 2
        for(MCC_Relationship__c child :childRecords){
            // 3
            if(trigger.isInsert && child.Status__c == 'Open'){
                child.Record_Mode__c = 'Edit';
            }
            // 4
            else if(trigger.isUpdate && child.Status == 'Open' && trigger.NewMap.get(child.MCC_Request__c).Status__c != trigger.OldMap.get(child.MCC_Request__c).Status__c){
                child.Record_Mode__c = 'Edit';
            }
        }
        
        // 5
        if(childRecords.size() > 0)
            update childRecords;
}

 

Below is updated parent/child information... maybe I entered information incorrectly?

 

Parent Object: MCC_Request__c

Parent Object Field: Status__c

 

Child Object: MCC_Relationship__c

Child Object Field: Record_Mode__c

 

Logic I'm after: Any time MCC_Request__c.Status__c is changed/updated, if MCC_Request__c.Status__c = "Draft" or "Rejected", the MCC_Relationship__c.Record_Mode__c should be updated to "EDIT", otherwise, the MCC_Relationship__c.Record_Mode__c should be updated to "READ"

 

Hope this makes sense and thanks again for your help!

vishal@forcevishal@force

oops, my bad! Sorry.

 

 

List<MCC_Relationship__c> childRecords = [Select MCC_Request__c, Record_Mode__c FROM MCC_Relationship__c WHERE MCC_Request__c IN :Trigger.newMap.keySet()];

 

I missed out the colon (:) in the SOQL.

 

Let me know if any questions/ issues! 

cbrocbro

I am having an issue with my trigger.  The problem is probably that the Object B (Asset) is NOT a child record, but a related object via a lookup field.

 

Can anyone help with this code?  

 

It is not compiling b/c of it, I guess:   Save error: No such column 'Contract' on entity 'Asset'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names.

 

trigger ContractStatusUpdatesAsset on Contract (after insert, after update) 
{


// 1
List<Asset> childAsset = [Select Contract, Status FROM Asset WHERE Asset IN: Trigger.newMap.keySet()];
        
// 2
    for(Asset child :childAsset)
    {
// 3
    //if(trigger.isInsert && child.Status == 'Active', 'Pending')
    //    {
    //        child.Status = 'Inactive';
    //    }
// 4
    //else 
    if(trigger.isUpdate && child.Status == 'Active', 'Pending' && trigger.NewMap.get(child.Contract).Status != trigger.OldMap.get(child.Contract).Status)
        {
            child.Status = 'Inactive';
        }
    }
        
// 5
    if(childRecords.size() > 0)
            
    {
    //System.debug('Chris has values to insert = '+ newConList.size());
    try
         {
        update childAsset;
         }
         catch (System.Dmlexception e)  
         {
         system.debug (e); 
         }
    }
}
}

 

 

Vetriselvan ManoharanVetriselvan Manoharan
Hi,

Below is my trigger

string OnHold = 'On Hold';
       string HoldwithResume = 'Hold with Resume Date';
       string Finished = 'Finished';
       string OnProgram = 'On Program';
       //Loop through all records in the Trigger.new collection
       List<Opportunity> opportunity = [SELECT Id, Name, Account.Program_Status__c FROM Opportunity where Account.Id in :accountNewMap.keySet() Order By CreatedDate Desc LIMIT 1];
       for(Opportunity accountsWithOpps : opportunity)
       { 
            //opps.Id = accountsWithOpps.Id;
            if(accountsWithOpps.Account.Program_Status__c == OnHold || accountsWithOpps.Account.Program_Status__c == HoldwithResume) 
            { 
                accountsWithOpps.StageName = 'On Hold';
            }
            else if(accountsWithOpps.Account.Program_Status__c == Finished || accountsWithOpps.Account.Program_Status__c == 'Never Started') 
            {
                accountsWithOpps.StageName = 'Closed Lost';
                accountsWithOpps.CloseDate = Date.today();
            } 
            else if(accountsWithOpps.Account.Program_Status__c == OnProgram) 
            {
                accountsWithOpps.StageName = 'On Program';
            } 
       }
       update opportunity; 

Here Account is my parent object and Opportunity is my child object. What is my problem is If the record size is 1 means the update is working perfectly. But if we update from data loader it is updating the first record in file only. remaining records are not updated in child object.