New to Apex and while I'm normally able to edit / manipulate code I'm struggling with the nuances of SF and the references to certain things. From looking round the board I've found the following code and attempted to update it to fit the job I'm doing.

Basically I have a custom field (Task_SR__c) for Activity History,it updates based on the Subject line of an Activity against a Contact. i.e. if an Email comes in with the Subject of 3 Stars the custom field updates to read 3.

I've also got a custom field (SR_short__c) on Contact that when a value is entered it updates another custom field on a Contact to display an image of the Star Rating.

So, I'm trying to get SR_short__c on a Contact to automatically populate when Task_SR__C on an Activity has a value entered.

Here's the code I've attempted to use / manipulate:

trigger TaskTrigger on Task (after update) {
    List<Contact> cons = [
        Select Id, SR_short__c, Task_SR__c
        From Contact
        Where ActivityHistoryId In :Trigger.newMap.keySet()
    for (Contact con : cons) {
        con.SR_short__c = con.Task_SR__c;
    update cons;

I guess one of my questions is: given that Task_SR__c is a custom field on a different object, what do I need to change to ensure the reference is correct?

Thanks in advance!


Activity History is just another way of saying "Tasks in the past".

You should be able to modify your query by using the WhoId of the Trigger.new (which returns Contacts and Lead IDs associated).

Set<String> whoIds = new Set<String>();
for (Task t : Trigger.new)
List<Contact> cons = [SELECT Id, SR_Short__c FROM Contact WHERE Id =: whoIds]

From here, you'd have all the contacts that you want to modify. At this point, what often would work best is iterating over the Tasks and creating a Map of Tasks keyed by the WhoId. This allows you to iterate over Contacts and find the Task associated.

Map<String, Task> taskMap = new Map<String, Task>();
for (Task t : Trigger.new)
  taskMap.put(t.WhoId, t);

Once you have that map, it is just a matter of iterating over the Contacts you've retrieved and setting the value.

for (Contact c : cons)
  if (taskMap.containsKey(c.Id))
    c.SR_Short__c = taskMap.get(c.Id).Task_SR__c;
update cons;

One caveat to this implementation is that if you have multiple tasks for the same contact in the trigger, only one will win. If you need custom logic around that, you'd need to implement something to determine the winner.

  • Many thanks Michael, I'll attempt to make the changes and see how I can on. in terms of the custom logic, I'm working on the basis that the "newest" Task for the contact will take priority i.e. if 3 emails come in the most recent will write to the Task_SR__c field and take priority over the previous emails.
    – PWride
    Dec 26 '13 at 16:28
  • I can't recall off the top of my head the order of the Trigger.new, but you could always add a quick check against the existing Task in the map to compare dates before overwriting. Good luck! Dec 26 '13 at 16:30
  • As a follow up question, in the code that you've supplied there's no reference to the custom field on the Task (Task_SR__c), is that now redundant due to the Map?
    – PWride
    Dec 26 '13 at 16:48
  • Sorry, forgot to add the reference to that field -- will update. Dec 26 '13 at 16:48
  • Hi again Michael, just input your code and tried to compile it and the following error was returned: Error: Compile Error: Entity 'Task' is not supported for semi join inner selects at line 2 column 26 Given the nature of the relationship do I need to reference it in a different way?
    – PWride
    Dec 26 '13 at 16:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.