function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
David SDavid S 

Trigger to monitor field updates

Hello.  I have created a trigger to minotor if certain fields are updated in a custom object. If the field is updated it creates a record in another custom object.  Below is the code:

 

trigger CheckFieldUpdate on Obj1__c (before update) {


    List<Obj1__c> stores = trigger.new;
    List<Obj2__c> tasks = new List<Obj2__c>();

    for(Obj1__c s : stores){

        if(s.Field1__c <> trigger.oldMap.get(s.id).Field1__c) {

            Obj2__c tsk = new Obj2__c(
                                Company__c = s.id, 
                                Name = 'Changed Field1 from "'+ trigger.oldMap.get(s.id).Field1__c +'" to ' + '"' + s.Field2__c + '"'
                                );
            tasks.add(tsk);
        }
        
        if(s.name <> trigger.oldMap.get(s.id).name) {
            Obj2__c tsk = new Obj2__c(
                                Company__c = s.id, 
                                Name = 'Changed Field2 from "'+ trigger.oldMap.get(s.id).Field2__c +'" to ' + '"' + s.Field2__c + '"'
                                );
            tasks.add(tsk);
        }    

    if (!tasks.isEmpty()) {
            insert tasks;
    }
} 

 

The code above only checks for 2 fields. What if there are more fields that i need to check, i'm wondering if there is a way to accomplish this in more efficient manner?  Is it possible to create a loop to go though a list of fields?

 

Thanks.

Best Answer chosen by Admin (Salesforce Developers) 
Rahul SharmaRahul Sharma

You could us hierarchial custom setting here. And in its name field put the csv field names and in your trigger access the custom setting and prepare list of Field names.

 

Below is the pseudo code, Hope it helps you ion understanding custom settings:

trigger CheckFieldUpdate on Obj1__c (before update) {
	
	/*
		// This part is for demonstrating the use of custom setting, replace the custom setting name in case you want to use it.
		// Fetching the list of Field names from custom settings
		CheckFieldUpdate__c objSetting = CheckFieldUpdate__c.getOrgDefaults();
		List<String> lstFieldNames = new List<String>();
		for(String eachField : objSetting.Name.split(',')) {
			// Remove leading and trailing spaces and convert to lower case
			eachField = eachField.trim().toLowerCase();
			lstFieldNames.add(eachField);
		}
	*/
	
	// For the instance test with List of string first.
	List<String> lstFieldNames = new List<String>{'Field1__c', 'name'};
	
	List<Obj1__c> stores = trigger.new;
	List<Obj2__c> tasks = new List<Obj2__c>();
	
	for(Obj1__c objNewStore : stores){
		Obj1__c objOldStore = trigger.oldMap.get(objNewStore.id);
		// Iterate the fields and and collect the tasks if the field value is changed
		for(String fieldName : lstFieldNames) {
			if(objNewStore.get(fieldName) <> objOldStore.get(fieldName)) {
			
				Obj2__c tsk = new Obj2__c( Company__c = objNewStore.id, 
				Name = 'Changed ' + fieldName + ' from "'+ objOldStore.get(fieldName) +'" to ' + '"' + objNewStore.get(fieldName) + '"');
				tasks.add(tsk);
			}
		}
	}
	if (!tasks.isEmpty()) {
		insert tasks;
	}
}

 

All Answers

Rahul SharmaRahul Sharma
Yes, better idea would be to iterate a list of the API names of object. and create task for each one rather than copy pasting and changing field names.
For making the list of string configurable you could either use field sets or custom setting(store comma separated field names it).
David SDavid S

Thanks for the response Rahul.  I have very limited experience with custom settings, but it sounds like that could work.  Would you be able to provide a small example on how you would use it in Apex trigger?

 

Thanks,
David

Rahul SharmaRahul Sharma

You could us hierarchial custom setting here. And in its name field put the csv field names and in your trigger access the custom setting and prepare list of Field names.

 

Below is the pseudo code, Hope it helps you ion understanding custom settings:

trigger CheckFieldUpdate on Obj1__c (before update) {
	
	/*
		// This part is for demonstrating the use of custom setting, replace the custom setting name in case you want to use it.
		// Fetching the list of Field names from custom settings
		CheckFieldUpdate__c objSetting = CheckFieldUpdate__c.getOrgDefaults();
		List<String> lstFieldNames = new List<String>();
		for(String eachField : objSetting.Name.split(',')) {
			// Remove leading and trailing spaces and convert to lower case
			eachField = eachField.trim().toLowerCase();
			lstFieldNames.add(eachField);
		}
	*/
	
	// For the instance test with List of string first.
	List<String> lstFieldNames = new List<String>{'Field1__c', 'name'};
	
	List<Obj1__c> stores = trigger.new;
	List<Obj2__c> tasks = new List<Obj2__c>();
	
	for(Obj1__c objNewStore : stores){
		Obj1__c objOldStore = trigger.oldMap.get(objNewStore.id);
		// Iterate the fields and and collect the tasks if the field value is changed
		for(String fieldName : lstFieldNames) {
			if(objNewStore.get(fieldName) <> objOldStore.get(fieldName)) {
			
				Obj2__c tsk = new Obj2__c( Company__c = objNewStore.id, 
				Name = 'Changed ' + fieldName + ' from "'+ objOldStore.get(fieldName) +'" to ' + '"' + objNewStore.get(fieldName) + '"');
				tasks.add(tsk);
			}
		}
	}
	if (!tasks.isEmpty()) {
		insert tasks;
	}
}

 

This was selected as the best answer
RocketRocket

Hi Rahul,

 

 

I also have similar requirement.Do I have to create custom field names in the custom settings with the same API names which I have created in objects in salesforce.

 

Can u advise.

Thanks,

 

 

 

 

 

 

 

 

Rahul SharmaRahul Sharma
The custom setting was just used in above requirement to store the mapping and also making the field tracking configurable.
David SDavid S

Hi Rahul,

I was able to get the code to work with a test List of string first.  When I tried to use the custom setting list, i get the following error message:   

 

Error:Apex trigger CheckFieldUpdate caused an unexpected exception, contact your administrator: CheckFieldUpdate: execution of BeforeUpdate caused by: System.SObjectException: Invalid field a0kg0000000d8qn for Obj1__c: Trigger.CheckFieldUpdateV2: line 28, column 1

 The line its referring to following if statement:

 

 if(objNewStore.get(fieldName) <> objOldStore.get(fieldName)) {

 

Did I incorrectly setup my custom setting?

 

Thanks,
David

 

Rahul SharmaRahul Sharma

In the above code, I have defined the custom setting with Name CheckFieldUpdate__c. In its Name field you need to add the Field API names in CSV format.

Example: 
In custom setting CheckFieldUpdate's Name field enter value as

Field1__c, Field2__c,.., Fieldn__c 

 In my original post I had commented the Custom setting part.

Refer this for Managing Custom Settings Data.