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

Trigger (to update account based on most recently created task)

Hi I was wondering whether this could be done.


I have a custom picklist on a task record, and based on what is selected there, it will update the picklist value on the account that the task associated to.  So everytime a new task is create for that account and the picklist value is selected, it will also update the picklist on the Account record. 


Any advise or suggestion?




Yes this can be done.  Tasks can be related to different objects so you need to watch this.  Also if the user does a batch upload you should ensure that your account update list does not contain duplicates.  I have knocked up the following and tested it against single tasks in the UI - if you base something on it then do bulk tests.  Hope this helps !!


trigger latest_picklist_trg on Task (after insert, after update) {

    // Get related identifiers on the task set
    Set<Id> relatedIds = new Set<Id>();
    for (Task indivTask : {
        if (indivTask.WhatId != null) relatedIds.add(indivTask.WhatId);
    // Get back from account - if they point to other objects it won't matter here
    Map<Id,Account> accountMap = new Map<Id,Account>([Select Id, Latest__c From Account Where Id in :relatedIds]);
    // Accounts for updates.  Use a map so if there are more than one task in the triggered batch for the same account
    // then repeat related refs get overwritten so we only keep the latest one
    Map<Id,Account> accountsForUpdate = new Map<Id,Account>();
    // Loop through triggered set
    for (Integer i=0;i<;i++) {
        // Process only if insert or the picklist has changed
        if ((Trigger.isInsert) || (Trigger.old[i].Custom__c !=[i].Custom__c)) {
            // only continue if we are related to an account
            if (([i].WhatId != null) && (accountMap.get([i].WhatId) != null)) {
                // Put the changed value in the map for update.
                accountsForUpdate.put([i].WhatId,new Account(Id =[i].WhatId, Latest__c =[i].Custom__c));
    } // end loop through triggered set
    // Create a list of accounts for update.  Only include them if the latest value
    // has actually changed
    List<Account> updateAccounts = new List<Account>();
    for (Account updateAccount : accountsForUpdate.values()) {
        if (updateAccount.Latest__c != accountMap.get(updateAccount.Id).Latest__c) {
    // If there are any changed accounts then issue the update
    if (updateAccounts.size() != 0) update updateAccounts;
} // end trigger


Thanks for the help!!  I appreciate it!!  I will definately lookover the code .. looks to make sense!!  Since I am new to Apex I actually had the following question:


- Since the trigger triggers on a creation or update of a task and from the whatID you find the Account it is associated to;  does that mean that now with the account id, you should traverse through all the tasks and look for the most recently updated/created task and look for that tasks field value before updating the account's field accordingly?


Hi there,


As the trigger fires on insert or update of the task,  when it fires you pretty much know that this very task that it triggers off is the latest one to be updated.  Therefore I just write the value into the account.


If you head off to the account and start looking through all the tasks then that is a lot of processing and if there are more than 1000 tasks on an account you will blow governor limits.  Imagine if there was a bulk upload of 200 tasks!


The whatId can also point to different objects (not just accounts) so it is good practice to trap this.  If someone related a task to an Opportunity and you do something like:


Account a = new Account(tsk.WhatId) then you will get a System.TypeException.  You can put a try .. catch on that type of exception.



Have fun !