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
Surbhi Dham 10Surbhi Dham 10 

Hi, I need to count number of attachments attached on the tasks. I have the trigger but it doesn't work. Can anyone help here. URGENT!

Best Answer chosen by Surbhi Dham 10
UC InnovationUC Innovation
Hello Surbhi,

I think you may be overcomplicating things a bit. All you need to do is get the correct parent tasks, and update it with their attachment count. The following code should do what you need.
 
trigger CountAttachment on Attachment (after insert, after update, after delete, after undelete) {
    // Contains the IDs of all the parent tasks
    Set<Id> parentTaskIdSet = new Set<id>();

    if (trigger.new != null)
    {
        for (Attachment a: trigger.new)
        {
            parentTaskIdSet.add(a.parentId);
        }
    }
    
    if (trigger.old != null)
    {
        for (Attachment a: trigger.old)
        {
            parentTaskIdSet.add(a.parentId);
        }
    }    
    
    // List of tasks that needs to be updated
    List<Task> parentTaskList = [SELECT id, (SELECT id FROM Attachments) FROM Task WHERE id in: parentTaskIdSet];
    
    for (Task t: parentTaskList)
    {
        t.NumberOfAttachments__c = t.Attachments.size();
    }
    
    update parentTaskList;
}
Hope this helps. Feel free to ask any questions and please remember to select a best answer if it helped resolve your issue(s).
 

All Answers

Pruthvi KankunthalaPruthvi Kankunthala
@Surbhi : Can you post the code here ? We can see if any errors are there .
Surbhi Dham 10Surbhi Dham 10
@Pruthvl : Hi,

I am a salesforce administrator and learning development. So please guide me. I am trying this in my Developer Sandbox.
I created two custom fields on the Task. One for counting the attachments and one which displays the number on the task.

Code i am using is -

trigger countattachment on Attachment (after insert, after update, after delete, after undelete) {
  Map<Id,List<Attachment>> parent = new Map<Id,List<Attachment>>();
  set<id> attids = new set<id>();
    
   if(Trigger.new<>null){
       for(Attachment c:Trigger.new){
           Task l;
           if(c.ParentId != null)
               attids.add(c.parentid);
       }
          
   }else if(Trigger.old != null){
       for(Attachment c:Trigger.old){
           if(c.ParentId<>null)     
               attids.add(Trigger.oldMap.get(c.id).parentid);
       }
   }
   if(attids.size()>0){
       try{
           List<Attachment> a = new List<Attachment>();
           Map<id,Task> testmap = new Map<id,Task>([select id,CountAttachment__c from Task where id IN: attids]);
           a = [select id,parentid from Attachment where parentid IN:attids];
          
           for(Attachment at: a){
               List<Attachment> llist = new List<Attachment>();
               if(parent.get(at.parentid) == null){
                   llist = new List<Attachment>();
                   llist.add(at);
                   parent.put(at.parentid,llist);
               }else if(parent.get(at.parentid) != null){
                   llist = new List<Attachment>();
                   llist = parent.get(at.parentid);
                   llist.add(at);
                   parent.put(at.parentid,llist);
               }
           }
          
           for(Id i: attids){
               if(testmap.get(i) != null && parent.get(i) != null){
                  testmap.get(i).CountAttachment__c = parent.get(i).size();
              
               }else if(testmap.get(i) != null && parent.get(i) == null){
                  testmap.get(i).CountAttachment__c = 0;
               }
           }
      
           update testmap.values();
           System.Debug(testmap.values());
       }catch(Exception e){}
    }

}

 
UC InnovationUC Innovation
Hello Surbhi,

I think you may be overcomplicating things a bit. All you need to do is get the correct parent tasks, and update it with their attachment count. The following code should do what you need.
 
trigger CountAttachment on Attachment (after insert, after update, after delete, after undelete) {
    // Contains the IDs of all the parent tasks
    Set<Id> parentTaskIdSet = new Set<id>();

    if (trigger.new != null)
    {
        for (Attachment a: trigger.new)
        {
            parentTaskIdSet.add(a.parentId);
        }
    }
    
    if (trigger.old != null)
    {
        for (Attachment a: trigger.old)
        {
            parentTaskIdSet.add(a.parentId);
        }
    }    
    
    // List of tasks that needs to be updated
    List<Task> parentTaskList = [SELECT id, (SELECT id FROM Attachments) FROM Task WHERE id in: parentTaskIdSet];
    
    for (Task t: parentTaskList)
    {
        t.NumberOfAttachments__c = t.Attachments.size();
    }
    
    update parentTaskList;
}
Hope this helps. Feel free to ask any questions and please remember to select a best answer if it helped resolve your issue(s).
 
This was selected as the best answer
Surbhi Dham 10Surbhi Dham 10
@Ken : Hi Ken,

Thank you for the response. I tried this as well but it does not work. i mean i have added two attachments on my task but the total still shows zero and not two. Can we connect to discuss this please.
Surbhi Dham 10Surbhi Dham 10
Hi Ken, I tried but this is also not working. I am trying this in my Developer Sandbox. Can that be the reason? Also, I am new to writing this code so can you confirm that I only need to write the trigger in Developer Console and save it. Do I need to do anything else as well for it to run? I am not sure how this works. Please elaborate and help. Thanks Surbhi
UC InnovationUC Innovation
Hi Surbhi,

Saving it in Developer Console and saving it should be sufficient. You can always go to setup -> develop -> apex triggers and see the list of triggers that are in your org there.

First, check if the field updates when you edit the attachment and save the attachment. Also see if deleting the attachment updates the field. Those should at least work.

So the problem is probably because when you create attachments on a task, you need to edit the task, create the attachments, then save the task. When you are saving the task, you are probably writing over the trigger's update on task.

So to fix this you will actually need to write another trigger, this time on Task. And since we will be updating task in the task trigger, we need a class to prevent recursion.

Here's what the trigger on Task would look like:
 
trigger UpdateAttachmentCount on Task (after insert, after update) {
    
    if (checkRecursive.runOnce())
    {
        List<Task> taskList = new List<Task>();
        Set<ID> taskIDSet = new Set<ID>();
        
        if (trigger.old != null)
        {
            for (Task t: trigger.old)
            {
                taskIDSet.add(t.ID);
            }
        }
        
        if (trigger.new != null)
        {
            for (Task t: trigger.new)
            {
                taskIDSet.add(t.ID);
            }
        }
        
        // Query for the attachment children of the tasks
        taskList = [SELECT id, (SELECT id FROM attachments) FROM Task WHERE ID in: taskIDSet];
    
        for (Task t: taskList)
        {
            t.NumberOfAttachments__c = t.Attachments.size();
        }
        
        update taskList;
    }

And here's what the class that prevents recursion looks like:
 
public Class checkRecursive{
    private static boolean run = true;
    public static boolean runOnce(){
        if (run){
            run = false;
            return true;
        }
        else
        {
            return run;
        }
    }
}

I just tested this code on my own org, and it works fine. Let me know if this works for you.
Surbhi Dham 10Surbhi Dham 10
Hi Ken, Shall I only create this class and trigger now. Delete the previous one? Also, do I need to create two fields – one which is used in trigger and the second which displays the value on the pagelayout? Please confirm. Thanks Surbhi
UC InnovationUC Innovation
Hi Surbhi,

You should only need one field that you update in your trigger and display on the page layout. Also you need to keep the attachment trigger as well, because that will update the field when you update/delete/undelete the attachment. The task trigger is basically only for when you're inserting the attachments. 
Surbhi Dham 10Surbhi Dham 10
Hi Ken, What should be the data type of the field that I should create which needs to be displayed on the page? Thanks Surbhi
UC InnovationUC Innovation
Hi Surbhi,

It depends on your other needs, but I'm inclined to say a number field should suffice in most cases. The trigger I wrote is assuming that it is a number field.
Surbhi Dham 10Surbhi Dham 10
Hi Ken, Thanks for all the help but I am still stuck. I will detail the steps with the screenshots that I have done. 1. Create the field – NumberofAttachments with data type number. 2. Write the Trigger on attachment. 3. Write the trigger on Task. 4. Write the Class Now I receive the below error after writing the task trigger and Class. [cid:image003.jpg@01D209BA.FDE9A300] Because of this, I get the error while saving a task. [cid:image004.jpg@01D209BA.FDE9A300] Please advise. Thanks Surbhi
UC InnovationUC Innovation
Hi Surbhi,

Please reupload those attachments, so I can see what errors you are getting.
Surbhi Dham 10Surbhi Dham 10
Hi Ken,
 
Thanks for all the help but I am still stuck. I will detail the steps with the screenshots that I have done.
 
  1. Create the field – NumberofAttachments with data type number.
  2. Write the Trigger on attachment.
  3. Write the trigger on Task.
  4. Write the Class
 
Now I receive the below error after writing the task trigger and Class.
User-added image

Because of this, I get the error while saving a task

User-added image

Please advise.

Thanks
Surbhi

 
Surbhi Dham 10Surbhi Dham 10
Hi Ken, Done that. I have replied separately. Please advise. Thanks Surbhi
UC InnovationUC Innovation
Hi Surbhi,

It looks like the trigger is not recognizing checkRecursive.xyz(). Are you sure you named your function xyz()? If you copied my code it should be called runOnce(). The reason why you're getting the depth error on saving the task is because the trigger is getting called recursively. Maybe post your class code, and I'll be able to tell what happened. If you directly copy pasted my code, you shouldn't be calling xyz. 
Surbhi Dham 10Surbhi Dham 10
Hi Ken, I copied your code only and it was runOnce() only. I received the same error with runOnce(). I changed the name to see if it works but no luck. Same error ☹ Is it possible to connect with you and discuss this please. This is very URGENT for me. Thanks Surbhi
UC InnovationUC Innovation
Hi Surbhi,

Please double check to see if your class is saved correctly, and that all spelling is correct. The error is just saying that the method doesn't exist, so the trigger is unable to find that method for some reason. It's difficult to see your code in the screenshot, maybe just post the code as text here. Please include the class too.
Surbhi Dham 10Surbhi Dham 10
Hi Ken, It worked. Thanks a lot for all the help. I will replicate this in my production environment and confirm. Thanks Surbhi
UC InnovationUC Innovation
Good, glad to hear it worked! Please don't forget to choose the best answer to mark the case as solved!
Surbhi Dham 10Surbhi Dham 10
Hi Ken, I have written the class and trigger in my Developer Edition. Can you please help me in getting this deployed in my production as well. Can you provide the steps please. Thanks Surbhi
UC InnovationUC Innovation
Hi Surbhi,

Can you mark best answer so that this can help others in the future and i will be glad to answer your follow up question in another thread. It's just that your follow up question is about deployment, which is a very different topic! 
Surbhi Dham 10Surbhi Dham 10
Hi Ken, I have done that. Can you please tell me the steps now. Thanks Surbhi
UC InnovationUC Innovation
Hi Surbhi,

Please post a new thread with your new question regarding deployment!
Surbhi Dham 10Surbhi Dham 10
Hi Ken, Done that. Please advise. https://developer.salesforce.com/forums/ForumsMain#!/feedtype=SINGLE_QUESTION_DETAIL&dc=Developer_Forums&criteria=OPENQUESTIONS&id=906F0000000g2mpIAA Thanks Surbhi
Surbhi Dham 10Surbhi Dham 10
Hi Ken, Can you please advise on my new question - https://developer.salesforce.com/forums/ForumsMain?id=906F0000000g2mp This is very important and urgent. Thanks Surbhi From: Surbhi Dham Sent: 14 September 2016 10:37 To: 'reply' Subject: RE: (Salesforce Developers): New reply to your question. Hi Ken, Done that. Please advise. https://developer.salesforce.com/forums/ForumsMain#!/feedtype=SINGLE_QUESTION_DETAIL&dc=Developer_Forums&criteria=OPENQUESTIONS&id=906F0000000g2mpIAA Thanks Surbhi
UC InnovationUC Innovation
Hi Surbhi,

It looks like others beat me to the punch! Follow the change set instructions and you should be set.

Good luck!
Surbhi Dham 10Surbhi Dham 10
Hi Ken, Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well. Thanks Surbhi
Surbhi Dham 10Surbhi Dham 10
Hi Ken, Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well. Thanks Surbhi From: Surbhi Dham Sent: 03 October 2016 17:36 To: 'reply' Subject: RE: (Salesforce Developers): New reply to your question. Hi Ken, Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well. Thanks Surbhi
Surbhi Dham 10Surbhi Dham 10
Hi Ken,
Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well.

Link for the this Query is - https://developer.salesforce.com/forums/ForumsMain?id=906F0000000g2mp

Thanks Surbhi
Surbhi Dham 10Surbhi Dham 10
Hi Ken, Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well. Thanks Surbhi From: Surbhi Dham Sent: 04 October 2016 17:13 To: 'reply' Subject: RE: (Salesforce Developers): New reply to your question. Hi Ken, Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well. Thanks Surbhi From: Surbhi Dham Sent: 03 October 2016 17:36 To: 'reply' > Subject: RE: (Salesforce Developers): New reply to your question. Hi Ken, Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well. Thanks Surbhi
Saurav RajputSaurav Rajput
Hi Ken/Surbhi,

I tried same on a custom object and it did not allowed me to even attach file under notes and attachment system as long as Trigger was active.

Kindly help me in this case.