+ Start a Discussion
MattyDHLMattyDHL 

Trigger firing on one field update.

Hi,

 

I am still new to coding triggers and coding in general but I have a problem that I am struggling to get around.

 

The trigger I currently have fires after update and transfers a completed field to another objects field. 

 

The problem is this happens after every Account update, I need this only to happen after the one field (IF_SAP__c) has changed, and if that field hasn't changed then do not do the update.

 

 This my current code, I understand I can use the Trigger.old, but I dont know how to compare the Trigger.old to the Trigger.new. Can some one please point me in the right direction.

 

Many Thanks


Matt

 

 

trigger UpdateToAccSetupForm on Account (after update) { Map<String, String> SetupFormMap = new Map<String, String>(); for (Account acc : System.Trigger.new){ if (acc.IF_SAP__c != null){ SetupFormMap.put(acc.ID, acc.IF_SAP__c); } else{ } } List<AccountSetupForm__c> recordsforupdates = new list<AccountSetupForm__c>(); for (AccountSetupForm__c aacc :[Select Id, AccountName__c, SAP_Number__c from AccountSetupForm__c where AccountName__c IN : SetupFormMap.keySet()] ){ if (SetupFormMap.containsKey(aacc.AccountName__c)) { aacc.SAP_Number__c = SetupFormMap.get(aacc.AccountName__c); recordsforupdates.add(aacc); } } update recordsforupdates; }

 

 

 

PragadheeshwariPragadheeshwari

Hai,

 

you can compare

if( trigger.old[0].IF_SAP__c != acc.IF_SAP__c)

{

/ / Do wat you want

 

}

MattyDHLMattyDHL

Hi,


Thanks for the code, can this be ran on before update and after update?

 

Kind Regards

 

Matt

ColinKenworthy1ColinKenworthy1

 

 

for(Integer i=0 ; i<Trigger.new.size() ; i++) {
if(trigger.old[i].IF_SAP__c <> trigger.new[i].IF_SAP__c) {
...

can be before update and after update

Message Edited by ColinKenworthy1 on 11-06-2009 05:33 PM
MattyDHLMattyDHL
What is the difference between the two solutions?
sfdcfoxsfdcfox

The difference has to do with the state that the database engine is in. If you are in a "before" state, that means that the changes have not yet been committed to the database. What this means is that you can change the value of the records, and those changes will survive through the rest of the database process. Consider this example:

 

 

trigger trgAcctCnt on Account (before insert, before update) { if(trigger.isinsert) for(account a:trigger.new) a.account_count__c=0; if(trigger.isupdate) for(account a:trigger.new) a.account_count__c=trigger.oldmap.get(a.id).account_count__c+1; }

Okay, so this isn't terribly impressive, but what this shows is that I can write code that will count the number of times an account has ever been edited. Note that this trigger is impervious to any attempts to intercept the number and change it-- as long as this trigger is active, the field will increment by one each and every time a successful save is applied to the account (also note that workflow field updates would cause this number to be incremented an additional time, but the update to the field won't actually trigger workflow rules again).

 

In an after event, you can't do this, because the data is already pending a commit to the database (it's actually already been saved once in a transaction, so no more changes can be applied to those records; workflow rules actually count as a second edit to that record). Also, before events allow you to actually prevent saving the record using addError(). This error is gracefully returned to the user so they can correct their input and try again. After the commit has occurred, an addError() call will cause an exception that will notify an administrator that something went wrong. The hapless user will also probably be confused about the multi-line error that states they should contact an administrator.

 

So, if you can validate data and even make trivial changes to data before it's saved, you might wonder why you'd want after triggers as well. It so happens that after triggers are useful for housekeeping tasks. For example, if you wanted to commit data to an external database, you'd want to do this in an after trigger-- in a before trigger, the record's changes might not be committed, but you could have inadvertently updated an external source. Ideally, this scenario will never occur in an after trigger, so committing data to another server would be ideal to do at this time.

 

Also, it might be that you'd want to update other, related records (or possibly even unrelated records) if the records were successfully updated. Normally, it's considered good form to do this in an after trigger, since there's no point in updating records in a before trigger if you're only going to throw an error and undo all those changes anyways. Of course, even in an after trigger, if an error occurs, all changes are rolled back so that your database is in the same consistent state it was before the insert/update/delete/etc was called.

 

So, the rule of thumb is: if you want to validate your input or make changes to the incoming records, use a before trigger. If you want to generate external events, update (possibly unrelated) other records, or perform additional business logic (i.e. assign a task or send an email), do so in an after trigger.

 

One final note: Trigger.old or Trigger.new might not be available in some contexts, so make sure you check with the documentation.

 

I hope this post clarifies the use of before and after events.