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
vanessa veronvanessa veron 

Class Apex Schedulable

Hello,
I would like to send an email 15 hours every day.
I did the code, tested it, but I am not receiving email.
What should I do?

Thank you!

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

 public void CSVTest(){
        planifier();
    }

public void newPlanifier (){
    String dailyCronExpression = '0 0 15 * * ?';
    System.schedule('test', dailyCronExpression, new CSVTest());    
    }
 
public void planifier(){
    String query=inputText;
    String premier=query.substringAfter('select ');
    premier=  premier.substringBefore('from');
   
    string titre= premier+'\n';
    string contenuCSV = titre;

    string queryResultatString = '';
    list<sObject> queryResultat = (List<sObject>)database.query(inputText);
    for(sObject a: queryResultat)
    {

        queryResultatString = queryResultatString + string.valueof(a);
    }

    list<string> queryLignes = queryResultatString.split('}');

    for(string s:queryLignes){
        list<string> queryColonnes = s.split(',');
        for(string st:queryColonnes){
            contenuCSV = contenuCSV + st.substringAfter('=') + ',';
        }
        contenuCSV = contenuCSV.substringBeforeLast(',').substringBeforeLast(',') + '\n';
    }
    String lignes = contenuCSV;
    List<String> parts = lignes.split('\n');
    integer lineNumber = queryResultat.size();
    integer nbLignesPJ = 50;
    integer compterParties=0;

    for(integer i=0;i<lineNumber;i++){

      string fichierParties = parts[0] + '\n';

      if(math.mod(i,nbLignesPJ)<>0) continue;
      if((lineNumber-i)<nbLignesPJ){
     
        for(integer j=1;j<=(lineNumber-i);j++){
            fichierParties = fichierParties + parts[i+j] + '\n';
        }
      }
      if((lineNumber-i)>=nbLignesPJ){
         for(integer j=1;j<=nbLignesPJ;j++){
            fichierParties = fichierParties + parts[i+j] + '\n';
        }
      }
      //Send Mail
      Messaging.EmailFileAttachment csvPJ = new Messaging.EmailFileAttachment();
      blob csvBlob = Blob.valueOf(fichierParties);
      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};
      compterParties++;
      String subject;
      if (compterParties >=2)
          subject = 'CSV - '+Date.today().format()+' - Partie '+compterParties;
      else
          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});
    }
}
}

-------------------------------------------------------------------------------------------------------------------------

PAGE

<apex:page controller="CSVTest">
  <apex:form >
  <apex:PageBlock >
    :::::::::: TEST TEST TEST :::::::::: <br /><br />
    Mail..........:&nbsp;<apex:inputText styleClass="classeMail" value="{!mailSouhaite}"/><br /><br />
    Request  :&nbsp;&nbsp;<apex:inputText styleClass="classeRequete" value="{!inputText}"/><br /><br /> 
    <apex:commandButton value="SEND" action="{!newPlanifier}"/> <br/><br/>
   
  </apex:PageBlock>
  </apex:form>
</apex:page>

Best Answer chosen by vanessa veron
vanessa veronvanessa veron
I solved this problem!
Thank you

<apex:page standardController="CronTrigger" extensions="BBBB">
<style type="text/css">
        .classeHoraire { width: 60px; }
        .classeBig { width: 600px; }
    </style>
	
  <apex:form >
  <apex:PageBlock >
    :::::::::: TEST TEST TEST :::::::::: <br /><br />  
    Mail..........:&nbsp;<apex:inputText styleClass="classeBig" value="{!mail}"/><br /><br />
    Request..:&nbsp;<apex:inputText styleClass="classeBig" value="{!request}"/><br /><br />
    Job Name.......:&nbsp;<apex:inputText value="{!nmJob}"/><br /><br />
        
    Schedule.....:&nbsp;
    <apex:inputText value="{!schedule}" />
    <br /> <br /><br />
	
    <apex:commandButton value="Schedule" action="{!schedulejob}" /> 
  </apex:PageBlock>
  </apex:form>
</apex:page>

--------------------------------------------------------------------------------------------------------------------------------------------------

global class BBBB implements System.Schedulable {

global String mail{get;set;}
global String nmJob{get;set;}
global String request{get;set;}
global String schedule{get;set;}


global void execute(SchedulableContext sc) {
  newPublier();
}

global BBBB () {}


global BBBB (String mail, String request, String schedule) {
this.mail= mail;
this.request= request;
this.schedule= schedule;

}

global void setMail(String mail) {
    this.mail= mail;
}

global String getMail() {
    return mail;
}

global void setRequete(String request) {
    this.request= request;
}

global String getRequete() {
    return request;
}

global void setSchedule(String schedule) {
    this.schedule= schedule;
}

global String getSchedule() {
    return schedule;
}


global void schedulejob(){      
        String email = getMail();
        String req = getRequete();
        String sch = getSchedule();
                       
        String NomJobSchedulable = nmJob;
        BBBB p = new BBBB(email , req, sch);
        system.schedule(NomJobSchedulable , sch, p);
}

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

    string queryResultatString = '';
 
    list<sObject> queryResultat = (List<sObject>)database.query(request);
    for(sObject a: queryResultat)
    {
        queryResultatString = queryResultatString + string.valueof(a);  
    }
   
    list<string> queryLignes = queryResultatString.split('}');

    for(string s:queryLignes){
        list<string> queryColonnes = s.split(',');
        for(string st:queryColonnes){
            contenuCSV = contenuCSV + st.substringAfter('=') + ',';
        }
        contenuCSV = contenuCSV.substringBeforeLast(',').substringBeforeLast(',') + '\n';
    }
      }

      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> {mail};
      String subject = 'CSV - '+Date.today().format();
      email.setSubject(subject);
      email.setToAddresses(adressMail);
      email.setPlainTextBody('mail body.........');   
      email.setFileAttachments(new Messaging.EmailFileAttachment[]{csvPJ});
      Messaging.SendEmailResult [] envoyer = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
    }
  }   
}

All Answers

Vyacheslav Ramazanov 6Vyacheslav Ramazanov 6
There is no need in a visualforce page at all. Have a look at the Setup > Monitor > Jobs > Scheduled Jobs build in page and play with settings.
vanessa veronvanessa veron
Thank you,

I know of to do at Salesforce.
But I want to create an application to do it with my logo and my colors.
I have to do in Apex?

Why my code creates the job but I did not get the email?
Vyacheslav Ramazanov 6Vyacheslav Ramazanov 6
Vanessa, from your code I see you misunderstand the basic salesforce principals.

Schedulable theory: 
http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content%2Fapex_qs.htm

Sub-schedulable class is just a trigger-like apex code. All data are stored in database objects during long time (except for a fast response-request calculations from a page to the server). You cannot set values in class properties from outside and invoke constructor. So your class won't work and invoke an error when beeng executed.
A proper way is create database objects for storing list of emails and data to be send. Then implement the logic into the app for managementing them. Then activate the job (your class). Job will be triggered on server at particular time and will do the work. In this case class can access the data needed for the required calculations.
vanessa veronvanessa veron
Thank you,

Can you please give me an example of code.
I never did that.

Should I use a Batchable class with the logic  and another Schedulable class to permir planning?
vanessa veronvanessa veron
I solved this problem!
Thank you

<apex:page standardController="CronTrigger" extensions="BBBB">
<style type="text/css">
        .classeHoraire { width: 60px; }
        .classeBig { width: 600px; }
    </style>
	
  <apex:form >
  <apex:PageBlock >
    :::::::::: TEST TEST TEST :::::::::: <br /><br />  
    Mail..........:&nbsp;<apex:inputText styleClass="classeBig" value="{!mail}"/><br /><br />
    Request..:&nbsp;<apex:inputText styleClass="classeBig" value="{!request}"/><br /><br />
    Job Name.......:&nbsp;<apex:inputText value="{!nmJob}"/><br /><br />
        
    Schedule.....:&nbsp;
    <apex:inputText value="{!schedule}" />
    <br /> <br /><br />
	
    <apex:commandButton value="Schedule" action="{!schedulejob}" /> 
  </apex:PageBlock>
  </apex:form>
</apex:page>

--------------------------------------------------------------------------------------------------------------------------------------------------

global class BBBB implements System.Schedulable {

global String mail{get;set;}
global String nmJob{get;set;}
global String request{get;set;}
global String schedule{get;set;}


global void execute(SchedulableContext sc) {
  newPublier();
}

global BBBB () {}


global BBBB (String mail, String request, String schedule) {
this.mail= mail;
this.request= request;
this.schedule= schedule;

}

global void setMail(String mail) {
    this.mail= mail;
}

global String getMail() {
    return mail;
}

global void setRequete(String request) {
    this.request= request;
}

global String getRequete() {
    return request;
}

global void setSchedule(String schedule) {
    this.schedule= schedule;
}

global String getSchedule() {
    return schedule;
}


global void schedulejob(){      
        String email = getMail();
        String req = getRequete();
        String sch = getSchedule();
                       
        String NomJobSchedulable = nmJob;
        BBBB p = new BBBB(email , req, sch);
        system.schedule(NomJobSchedulable , sch, p);
}

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

    string queryResultatString = '';
 
    list<sObject> queryResultat = (List<sObject>)database.query(request);
    for(sObject a: queryResultat)
    {
        queryResultatString = queryResultatString + string.valueof(a);  
    }
   
    list<string> queryLignes = queryResultatString.split('}');

    for(string s:queryLignes){
        list<string> queryColonnes = s.split(',');
        for(string st:queryColonnes){
            contenuCSV = contenuCSV + st.substringAfter('=') + ',';
        }
        contenuCSV = contenuCSV.substringBeforeLast(',').substringBeforeLast(',') + '\n';
    }
      }

      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> {mail};
      String subject = 'CSV - '+Date.today().format();
      email.setSubject(subject);
      email.setToAddresses(adressMail);
      email.setPlainTextBody('mail body.........');   
      email.setFileAttachments(new Messaging.EmailFileAttachment[]{csvPJ});
      Messaging.SendEmailResult [] envoyer = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
    }
  }   
}

This was selected as the best answer