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
Aa HashAa Hash 

trigger that only fires when field value in the custom object is changed

I have created an apex code which is populating account lookup on custom object but I want my trigger only fires when field value EXT ID__c in the custom object is changed it also create an error message on another log__c object when duplication occurs
Here is my code: 
trigger Test_Account on Populate_Account__c (before insert, before update) {
    set<string> externalids = new set<string>();
for(Populate_Account__c cobj:trigger.new){
if(cobj.External_ID__c != Null && cobj.Account__c==Null ){
externalids.add(cobj.External_ID__c);
}
}
Map<string,id> mapaccidswithexternalids = new Map<string,id>();
for(Account acc: [select id,External_ID__c from account where External_ID__c=:externalids]){
mapaccidswithexternalids.put(acc.External_ID__c,acc.id);
}
for(Populate_Account__c cobj:trigger.new){
if(mapaccidswithexternalids.containskey(cobj.External_ID__c)){
cobj.Account__c = mapaccidswithexternalids.get(cobj.External_ID__c);
}
}
}
 
AnkaiahAnkaiah (Salesforce Developers) 
Hi ,

What is the issue you were facing. ? The code seems to be fine.

If you to fire the trigger only when field changes then you need to modify the code like below.
trigger Test_Account on Populate_Account__c (before insert, before update) {
    set<string> externalids = new set<string>();

if(trigger.Isinsert && trigger.Isbefore){
for(Populate_Account__c cobj:trigger.new){
if(cobj.External_ID__c != Null && cobj.Account__c==Null ){
externalids.add(cobj.External_ID__c);
}
}
}

if(trigger.Isupdate && trigger.Isbefore){
for(Populate_Account__c cobj:trigger.new){
Populate_Account__c oldAccount = Trigger.oldMap.get(cobj.ID);
if(cobj.External_ID__c != oldAccount.External_ID__c && cobj.External_ID__c != Null && cobj.Account__c==Null ){
externalids.add(cobj.External_ID__c);
}
}
}
Map<string,id> mapaccidswithexternalids = new Map<string,id>();
for(Account acc: [select id,External_ID__c from account where External_ID__c=:externalids]){
mapaccidswithexternalids.put(acc.External_ID__c,acc.id);
}
for(Populate_Account__c cobj:trigger.new){
if(mapaccidswithexternalids.containskey(cobj.External_ID__c)){
cobj.Account__c = mapaccidswithexternalids.get(cobj.External_ID__c);
}
}
}

If this helps, Please mark it as best answer.!!

Thanks!!
Aa HashAa Hash
Yes the code is fine and working but I want two things:
1. The trigger only fires when the value of field changes means EXT ID__c changes.
2.If an error occurs ,it is generated in another custom object error__c.
AnkaiahAnkaiah (Salesforce Developers) 
Hi 
try with below code.
 
trigger Test_Account on Populate_Account__c (before update) {
set<string> externalids = new set<string>();

if(trigger.Isupdate && trigger.Isbefore){
for(Populate_Account__c cobj:trigger.new){
Populate_Account__c oldAccount = Trigger.oldMap.get(cobj.ID);
if(cobj.External_ID__c != oldAccount.External_ID__c && cobj.External_ID__c != Null && cobj.Account__c==Null ){
externalids.add(cobj.External_ID__c);
}
}
}
Map<string,id> mapaccidswithexternalids = new Map<string,id>();
for(Account acc: [select id,External_ID__c from account where External_ID__c=:externalids]){
mapaccidswithexternalids.put(acc.External_ID__c,acc.id);
}
List<error__c> errorcapture = new List<error__c>();
for(Populate_Account__c cobj:trigger.new){
try{
if(mapaccidswithexternalids.containskey(cobj.External_ID__c)){
cobj.Account__c = mapaccidswithexternalids.get(cobj.External_ID__c);
}
}catch(TypeException ex){
error__c err = new error__c();
err.errormessage__c = ex.germessage();
errorcapture.add(err);

}
}
insert errorcapture;
}

If this helps, Please mark it as best answer.

Thanks!!​​​​​​​
Aa HashAa Hash
Thanks @Ankaiah but I am getting error: Method does not exist or incorrect signature: void germessage() from the type System.TypeException (24:27), it's not working for me
AnkaiahAnkaiah (Salesforce Developers) 
Hi ,

instead of TypeException, you use Exception.

try with below.
trigger Test_Account on Populate_Account__c (before update) {
set<string> externalids = new set<string>();

if(trigger.Isupdate && trigger.Isbefore){
for(Populate_Account__c cobj:trigger.new){
Populate_Account__c oldAccount = Trigger.oldMap.get(cobj.ID);
if(cobj.External_ID__c != oldAccount.External_ID__c && cobj.External_ID__c != Null && cobj.Account__c==Null ){
externalids.add(cobj.External_ID__c);
}
}
}
Map<string,id> mapaccidswithexternalids = new Map<string,id>();
for(Account acc: [select id,External_ID__c from account where External_ID__c=:externalids]){
mapaccidswithexternalids.put(acc.External_ID__c,acc.id);
}
List<error__c> errorcapture = new List<error__c>();
for(Populate_Account__c cobj:trigger.new){
try{
if(mapaccidswithexternalids.containskey(cobj.External_ID__c)){
cobj.Account__c = mapaccidswithexternalids.get(cobj.External_ID__c);
}
}catch(Exception ex){
error__c err = new error__c();
err.errormessage__c = ex.getMessage();
errorcapture.add(err);

}
}
insert errorcapture;
}

If this helps, Please mark it as best answer.

Thanks!!