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
marys pindamarys pinda 

Many mails with the same file divided into 3 parts

Is it possible to send a file attachment that contains only 10 lines?
If the file has more than 10 lines (30 lines for example), send a second email and a third email.

Many emails with the same file divided into 3 parts:
Email 1 - Part 1
Email 2 - Part 2
Email 3 - Part 3

Thank you,

global class AAAACSV implements System.Schedulable {
public String mailSouhaite {get; set;}
public string caseTT {get; set;}
    
global void execute(SchedulableContext sc) {
planifier();
}

public void planifier(){
String query = caseTT;
String premier=query.substringAfter('select');     
premier=  premier.substringBefore('from');
    
string titre= premier+'\n';
string contenuCSV = titre; 
string contenu;
    
for(Case a: (List<Case>)database.query(caseTT))
{    
    contenu = a.casenumber + ',' + a.subject+ ',' +a.Contact.Name+ ',' + a.status +'\n';
    contenuCSV = contenuCSV + contenu ;
}

Messaging.EmailFileAttachment csvPJ = new Messaging.EmailFileAttachment();
blob csvBlob = Blob.valueOf(contenuCSV);
string csvNom = 'cases_fermes_'+Date.today().format()+'.csv';
csvPJ.setFileName(csvNom);
csvPJ.setBody(csvBlob);
Messaging.SingleEmailMessage email =new Messaging.SingleEmailMessage();
String[] adressMail = new list<string> {mailSouhaite};
String subject = 'CSV - '+Date.today().format();
email.setSubject(subject);
email.setToAddresses(adressMail);

String lignes = contenuCSV;
List<String> parts = lignes.split('\n');
integer lineNumber = parts.size();

if (lineNumber >=10){
//???????????????????????????
email.setPlainTextBody('mail....................');     
email.setFileAttachments(new Messaging.EmailFileAttachment[]{csvPJ});
Messaging.SendEmailResult [] envoyer = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email}); 

}//if
}
}

Best Answer chosen by marys pinda
ShashForceShashForce
for(integer i=0;i<lineNumber;i++){
      //splitfile initated with the header
      string splitfile = parts[0] + '\n';
     //run the loop only when 'i' is a multiple of 3
      if(math.mod(i,numLinesPerAttach)<>0) continue;
      //if lineNumber-i < 3
      if((lineNumber-i)<numLinesPerAttach){
       // this is foir the final loop iteration, where there might be less than 3 lines left to be added. This avoids the "list out of bounds error".
        for(integer j=1;j<=(lineNumber-i);j++){
            // splitfile receive the row
            splitfile = splitfile + parts[i+j] + '\n';
        }
      }
      //if lineNumber-i >= 3
      if((lineNumber-i)>=numLinesPerAttach){
        // this is for all except final loop iteration. The loop adds each line to splitfile
        for(integer j=1;j<=numLinesPerAttach;j++){
            // splitfile receive the row
            splitfile = splitfile + parts[i+j] + '\n';
        }
      }

All Answers

ShashForceShashForce
Hi,

Please try something like this:

global class AAAACSV implements System.Schedulable {
public String mailSouhaite {get; set;}
public string caseTT {get; set;}
   
global void execute(SchedulableContext sc) {
planifier();
}

public void planifier(){
String query = caseTT;
String premier=query.substringAfter('select');    
premier=  premier.substringBefore('from');
   
string titre= premier+'\n';
string contenuCSV = titre;
string contenu;

for(Case a: (List<Case>)database.query(caseTT))
{    
    contenu = a.casenumber + ',' + a.subject+ ',' +a.Contact.Name+ ',' + a.status +'\n';
    contenuCSV = contenuCSV + contenu ;
}


String lignes = contenuCSV;
List<String> parts = lignes.split('\n');
integer lineNumber = parts.size();

//I made changes from here

integer count = 0;
for(integer i=0;i<lineNumber;i++){
	string splitfile = '';
	for(j=0;j<10;j++){
		splitfile = splitfile + lignes[count] + '/n';
		count++;
	}
	Messaging.EmailFileAttachment csvPJ = new Messaging.EmailFileAttachment();
	blob csvBlob = Blob.valueOf(splitfile);
	string csvNom = 'cases_fermes_'+Date.today().format()+'.csv';
	csvPJ.setFileName(csvNom);
	csvPJ.setBody(csvBlob);
	Messaging.SingleEmailMessage email =new Messaging.SingleEmailMessage();
	String[] adressMail = new list<string> {mailSouhaite};
	String subject = 'CSV - '+Date.today().format();
	email.setSubject(subject);
	email.setToAddresses(adressMail);
	email.setPlainTextBody('mail....................');     
	email.setFileAttachments(new Messaging.EmailFileAttachment[]{csvPJ});
	Messaging.SendEmailResult [] envoyer = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
}

If this answers your question, please mark this as the Best Answer for this post, so that others can benefit from this post.

Thanks,
Shashank
marys pindamarys pinda
Thank you...
I tried, but I have an error:
Error: Compile Error: Expression must be a list type: String at line 33 column 33

How do I solve this error?

String lignes = contenuCSV;
List<String> parts = lignes.split('\n');
integer lineNumber = parts.size();

integer count = 0;
for(integer i=0;i<lineNumber;i++){
    string splitfile = '';
    for(integer j=0;j<10;j++){
        splitfile = splitfile + lignes[count] + '/n';
        count++;
    }
ShashForceShashForce
Please change from:

splitfile = splitfile + parts[count] + '/n';
count++;

to:

if(count<lignes.size()){
splitfile = splitfile + parts[count] + '/n';
count++;
}
marys pindamarys pinda
I have an error in the preview VisualPage:

SendEmail failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, No body specified in the file attachment: []
Error is in expression '{!planifier}' in component <apex:commandButton> in page aaabctestpage
An unexpected error has occurred. Your development organization has been notified.


I changed

if(count<lignes.size()){
splitfile = splitfile + parts[count] + '/n';
count++;
}

for

if(count<parts.size()){
splitfile = splitfile + parts[count] + '/n';
count++;
}

because: Error: Compile Error: Variable does not exist: lines

What should I do?
Thank you
ShashForceShashForce
Please check if there is a typo in "lignes". The error says "lines" does not exist. Please check if you typed "lines" instead of "lignes" somewhere.
ShashForceShashForce
count<parts.size() may not work, you may have to try count<lignes.size()
marys pindamarys pinda
I changed parts for lignes, but I have un error:
Error: Compile Error: Method does not exist or incorrect signature: [String].size()

integer count = 0;
for(integer i=0;i<lineNumber;i++){
    string splitfile = '';
    for(integer j=0;j<=2;j++){
    if(count<lignes.size()){
        splitfile = splitfile + parts[count] + '/n';
        count++;
    }

What should I do?
Thank you!
ShashForceShashForce
Oops sorry, the correct method to get string size is lignes.length().

Please use:

count<lignes.length()
ShashForceShashForce
I made some corrections in your plainifeir method. Please try this:

public void planifier(){
String query = caseTT;
String premier=query.substringAfter('select');    
premier=  premier.substringBefore('from');
   
string titre= premier+'\n';
string contenuCSV = titre;
  
for(Case a: (List<Case>)database.query(caseTT))
{
    string contenu = a.casenumber + ',' + a.subject+ ',' +a.Contact.Name+ ',' + a.status +'\n';
    contenuCSV = contenuCSV + contenu ;
}
String lignes = contenuCSV;
List<String> parts = lignes.split('\n');
integer lineNumber = parts.size();

for(integer i=0;i<lineNumber;i++){
  string splitfile = parts[i];
  Messaging.EmailFileAttachment csvPJ = new Messaging.EmailFileAttachment();
  blob csvBlob = Blob.valueOf(splitfile);
  string csvNom = 'cases_fermes_'+Date.today().format()+'.csv';
  csvPJ.setFileName(csvNom);
  csvPJ.setBody(csvBlob);
  Messaging.SingleEmailMessage email =new Messaging.SingleEmailMessage();
  String[] adressMail = new list<string> {mailSouhaite};
  String subject = 'CSV - '+Date.today().format();
  email.setSubject(subject);
  email.setToAddresses(adressMail);
  email.setPlainTextBody('mail....................');    
  email.setFileAttachments(new Messaging.EmailFileAttachment[]{csvPJ});
  Messaging.SendEmailResult [] envoyer = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
}
}
marys pindamarys pinda
Thank you...It worked =D
But where's the part that when the CSV has over 4 lines I send 2 on 2 lines? eg ...

I received 5 email (1 with each line of the CSV).
Have as I receive every two rows and the header in each email?

Thank you so much
marys pindamarys pinda
I tried:

for(integer i=0;i<lineNumber;i+2){
  string splitfile = parts[i];
  Messaging.EmailFileAttachment csvPJ = new Messaging.EmailFileAttachment();

and:

for(integer i=0;i<lineNumber;i++){
  string splitfile = parts[i+2];
  Messaging.EmailFileAttachment csvPJ = new Messaging.EmailFileAttachment();

and

for(integer i=0;i<lineNumber;i+2){
  string splitfile = parts[i+2];
  Messaging.EmailFileAttachment csvPJ = new Messaging.EmailFileAttachment();

But I have an error.
Another tip?
Thank you
ShashForceShashForce
Please try something like this:

for(integer i=1;i<=lineNumber;i++){
  if(math.mod(i,2)==0) continue;
  if(i==linenumber) string splitfile = parts[i]
  if(i<lineNumber) string splitfile = parts[i] + '/n' + parts[i+1];
  Messaging.EmailFileAttachment csvPJ = new Messaging.EmailFileAttachment();
ShashForceShashForce
Sorry, there is a semi-colon missing, please correct:

if(i==linenumber) string splitfile = parts[i] ;
ShashForceShashForce
I see that you are trying to do it for 3 lines. It will not work by just changing to mod(i,3), since I modified it to work with only 2 lines per attachment in mind.

I have re-written your planifier() method to work for any number of lines, with each attachment holding the header as well, considering parts[0] is the header. The variable "numLinesPerAttach" determines how many lines are allowed per attachment. I used "4" in this code. You can try it out with any number. I haven't tested it out though, please try it and let me know how it went:

public void planifier(){
	String query = caseTT;
	String premier=query.substringAfter('select');   
	premier=  premier.substringBefore('from');
	  
	string titre= premier+'\n';
	string contenuCSV = titre;
	 
	for(Case a: (List<Case>)database.query(caseTT))
	{
		string contenu = a.casenumber + ',' + a.subject+ ',' +a.Contact.Name+ ',' + a.status +'\n';
		contenuCSV = contenuCSV + contenu ;
	}
	String lignes = contenuCSV;
	List<String> parts = lignes.split('\n');
	integer lineNumber = parts.size();

	integer numLinesPerAttach = 4;

	for(integer i=0;i<lineNumber;i++){
	  string splitfile = parts[0] + '/n';
	  if(math.mod(i,numLinesPerAttach)<>0) continue;
	  if((lineNumber-i)<numLinesPerAttach){
		for(integer j=1;j<=(lineNumber-i);j++){
			splitfile = splitfile + parts[i+j] + '/n';
		}
	  }
	  if((lineNumber-i)>=numLinesPerAttach){
		for(integer j=1;j<=numLinesPerAttach;j++){
			splitfile = splitfile + parts[i+j] + '/n';
		}
	  }
	  Messaging.EmailFileAttachment csvPJ = new Messaging.EmailFileAttachment();
	  blob csvBlob = Blob.valueOf(splitfile);
	  string csvNom = 'cases_fermes_'+Date.today().format()+'.csv';
	  csvPJ.setFileName(csvNom);
	  csvPJ.setBody(csvBlob);
	  Messaging.SingleEmailMessage email =new Messaging.SingleEmailMessage();
	  String[] adressMail = new list<string> {mailSouhaite};
	  String subject = 'CSV - '+Date.today().format();
	  email.setSubject(subject);
	  email.setToAddresses(adressMail);
	  email.setPlainTextBody('mail....................');   
	  email.setFileAttachments(new Messaging.EmailFileAttachment[]{csvPJ});
	  Messaging.SendEmailResult [] envoyer = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
	}
}

If this answers your question, please mark this as the Best Answer for this post, so that others can benefit from this post.

Thanks,
Shashank

marys pindamarys pinda
Thank you...I tested your code!
There is an error in the preview Visualpage:

List index out of bounds: 5
Error is in expression '{!planifier}' in component <apex:commandButton> in page aaabctestpage
An unexpected error has occurred. Your development organization has been notified.


ShashForceShashForce
Hi,

I am testing it out in mhy developer org now.

Can you provide me the values you are testing with, for these fields?

Mail..........:
Requête :
marys pindamarys pinda
Shashank_SFDC, you have skype?
ShashForceShashForce
I have tested in my org, and realized that I am counting the header as well for number of lines, which should not be done. please change

from:

integer lineNumber = parts.size();

to:

integer lineNumber = parts.size()-1;

Also, looks like I typed '/n' instead of '\n' at some places. Sorry about that, please change them to '\n'

Make these changes and you should be good. I have tested it and it is working, YAY! I am not allowed to skype from the machine I am using right now :(
marys pindamarys pinda
Thank you!
You helped me so much ...
I am new to Apex and I not find many information on the internet.

Here is the code with the derangements:
global class AAABCTest implements System.Schedulable {
public String mailSouhaite {get; set;}
public string caseTT {get; set;}
public string nomFichierCSV {get; set;} 
  
global void execute(SchedulableContext sc) {
planifier();
}

public void planifier(){
    String query = caseTT;
    String premier=query.substringAfter('select');   
    premier=  premier.substringBefore('from');
      
    string titre= premier+'\n';
    string contenuCSV = titre;
     
    for(Case a: (List<Case>)database.query(caseTT))
    {
        string contenu = a.casenumber + ',' + a.subject+ ',' +a.Contact.Name+ ',' + a.status +'\n';
        contenuCSV = contenuCSV + contenu ;
    }
    String lignes = contenuCSV;
    List<String> parts = lignes.split('\n');
    integer lineNumber = parts.size()-1;
    

    integer numLinesPerAttach = 3;

    for(integer i=0;i<lineNumber;i++){
      string splitfile = parts[0] + '\n';
      if(math.mod(i,numLinesPerAttach)<>0) continue;
      if((lineNumber-i)<numLinesPerAttach){
        for(integer j=1;j<=(lineNumber-i);j++){
            splitfile = splitfile + parts[i+j] + '\n';
        }
      }
      if((lineNumber-i)>=numLinesPerAttach){
        for(integer j=1;j<=numLinesPerAttach;j++){
            splitfile = splitfile + parts[i+j] + '\n';
        }
      }
      Messaging.EmailFileAttachment csvPJ = new Messaging.EmailFileAttachment();
      blob csvBlob = Blob.valueOf(splitfile);
      string csvNom = 'cases_fermes_'+Date.today().format()+'.csv';
      csvPJ.setFileName(csvNom);
      csvPJ.setBody(csvBlob);
      Messaging.SingleEmailMessage email =new Messaging.SingleEmailMessage();
      String[] adressMail = new list<string> {mailSouhaite};
      String subject = 'CSV - '+Date.today().format();
      email.setSubject(subject);
      email.setToAddresses(adressMail);
      email.setPlainTextBody('mail....................');   
      email.setFileAttachments(new Messaging.EmailFileAttachment[]{csvPJ});
      Messaging.SendEmailResult [] envoyer = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
    }
}
}

I have a last question: https://developer.salesforce.com/forums/ForumsMain?id=906F0000000AUePIAW


Is is possible to make this part creation of content into CSV dynamics?

for(Case a: (List<Case>)database.query(caseTT))
    {
        string contenu = a.casenumber + ',' + a.subject+ ',' +a.Contact.Name+ ',' + a.status +'\n';
        contenuCSV = contenuCSV + contenu ;
    }


I want to use any request I imagine and not only this: select casenumber,subject,Contact.Name,status from Case where ClosedDate=TODAY

I tried generics objects, but dont worked.

THANK YOU!!!
ShashForceShashForce
for(integer i=0;i<lineNumber;i++){
      //splitfile initated with the header
      string splitfile = parts[0] + '\n';
     //run the loop only when 'i' is a multiple of 3
      if(math.mod(i,numLinesPerAttach)<>0) continue;
      //if lineNumber-i < 3
      if((lineNumber-i)<numLinesPerAttach){
       // this is foir the final loop iteration, where there might be less than 3 lines left to be added. This avoids the "list out of bounds error".
        for(integer j=1;j<=(lineNumber-i);j++){
            // splitfile receive the row
            splitfile = splitfile + parts[i+j] + '\n';
        }
      }
      //if lineNumber-i >= 3
      if((lineNumber-i)>=numLinesPerAttach){
        // this is for all except final loop iteration. The loop adds each line to splitfile
        for(integer j=1;j<=numLinesPerAttach;j++){
            // splitfile receive the row
            splitfile = splitfile + parts[i+j] + '\n';
        }
      }
This was selected as the best answer
marys pindamarys pinda
Thank you, thank you, thank you!!!