[SalesForce] Retrieve All Notes and Attachments From a Specified Timeframe

I am looking for a way to retrieve all attachments from a particular object over a particular
time frame.

Can I use Standard SFDC Email functionality to Email attachments retrieved from a SOQL?

I have the SOQL operating properly – I am basically wondering if I can use Apex to run the SOQL and attach the documents to an email.

Here is the SOQL…

SELECT Id FROM Attachment WHERE Parentid IN 
               (Select Id from FF__Custom_Object__c WHERE recordtypeid = '0000000000000' 
                AND Custom_Record_Age_Field_In_Days__c <= 31))

Best Answer

Below is some Apex that will hopefully get you started. I have tested this with a simpler SOQL query and it worked.

Depending on the number and size of the attachments you might run into issues here with the Heap size limits. In an email service context the heap size is 36 MB. Otherwise you will need to stay within 10MB, which isn't very large when dealing with multiple attachments.

// As Mohith suggests, try to avoid hardcording a recordTypeId here
// If you deploy the code between orgs the value can change
Id requiredRecordTypeId = '0000000000000';

List<Attachment> attachments = 
                [SELECT Id, Name, Body, ContentType FROM Attachment 
                 WHERE Parentid IN 
                   (Select Id from FF__Custom_Object__c 
                    WHERE recordtypeid = :requiredRecordTypeId AND 
                          Custom_Record_Age_Field_In_Days__c <= 31))];

Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] {'me@example.com'};
email.setToAddresses(toAddresses);
email.setSubject('Foo');
email.setPlainTextBody('Bar');

List<Messaging.EmailFileAttachment> emailAttachments = new List<Messaging.EmailFileAttachment>();
for(Attachment att : attachments) {

    Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
    // You may need to do some work here to figure out the correct file extension
    efa.setFileName(att.Name);
    // Take the blob data from the Attachment and put it on the email.
    efa.setBody(att.Body);
    efa.setContentType(att.ContentType);
    emailAttachments.add(efa);
}

email.setFileAttachments(emailAttachments);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { email });

It will probably be beneficial for the heap size to express the SOQL query directly in the for loop rather than first assigning it to a list and then looping over the list.

SOQL For Loops Versus Standard SOQL Queries
SOQL for loops differ from standard SOQL statements because of the method they use to retrieve sObjects. While the standard queries discussed in SOQL and SOSL Queries can retrieve either the count of a query or a number of object records, SOQL for loops retrieve all sObjects, using efficient chunking with calls to the query and queryMore methods of the SOAP API. Developers should always use a SOQL for loop to process query results that return many records, to avoid the limit on heap size.

So rather than doing:

List<Attachment> attachments = 
            [SELECT Id, Name, Body, ContentType FROM Attachment 
             WHERE Parentid IN 
               (Select Id from FF__Custom_Object__c 
                WHERE recordtypeid = :requiredRecordTypeId AND 
                      Custom_Record_Age_Field_In_Days__c <= 31))];
// ...
for(Attachment att : attachments) {
    // ...
}

Try:

// ...
for(Attachment att : [SELECT Id, Name, Body, ContentType FROM Attachment 
             WHERE Parentid IN 
               (Select Id from FF__Custom_Object__c 
                WHERE recordtypeid = :requiredRecordTypeId AND 
                      Custom_Record_Age_Field_In_Days__c <= 31))]) {
    // ...
}
Related Topic