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
alaschgarialaschgari 

Schedule class one time / once

Hey folks!

I want to run a scheduled class right after a trigger has fired. This is my cron expression so far:

 

Datetime n = Datetime.now();
CRON_EXP = '0 ' + n.addMinutes(1).format('m') + ' ' + n.format('H') + ' ' + n.format('d') + ' ' + n.format('M') + ' ? '+ n.format('yyyy');

 

How do I modify this expression so that the code is only executed one time / once?

 

Thanks for your help

Josh :-)

Best Answer chosen by Admin (Salesforce Developers) 
gaisergaiser

One more thing - you can also query CronTrigger object to find Id of your job to abort Schedule.

As usually there is a catch - CronTrigger object does not currently support query by job Name, so you will have to specify "where" condition using other field(s), e.g. CronExpression.

 

If you do use that method and System.abortJob(retrievedId) does not work then try:

- passing actual value of type Id

- or truncate String Id value returned from CronTrigger query to 15 characters as discussed here: 

http://boards.developerforce.com/t5/Apex-Code-Development/CronTrigger/m-p/503725#M93462

All Answers

Jeff MayJeff May

Do you mean make sure it only happens once ever, or once for each time the trigger fires?

 

For the "once ever", you can check and add a flag on the record in the trigger to know whether this record has already met the condition for firing the scheduled job and only set it the first time, and clear it any other time.  Your scheduled class can then look at the same flag to know if it has to do any work on the records being processed. 

alaschgarialaschgari

Once I execute the scheduled class there's an entry in the system table "Scheduled jobs". Once the class execution is completed I want the entry to disappear.

gaisergaiser

If you want to run something once and NOW you do not need a Scheduled class.

You can just execute whatever your scheduled class is supposed to execute directly.

 

For example, assuming your scheduler is supposed to trigger a batch apex job called  MyBatch, you could use Database.executeBatch(b) in the trigger to start that batch job like so:

 

MyBatch b = new MyBatch();
Database.executeBatch(b);

 

Keep in mind that the number of simultaneous batch jobs is very limited. Make sure you control how many jobs you execute from your trigger.

 

alaschgarialaschgari

Gaiser,

thanks for your idea!

Well, I don't want to use a batch, but a scheduled class. My question is: How can I remove the entry under "Scheduled Jobs" after the job is done?

gaisergaiser

If you want to use apex code to remove the job then you can use System.abortJob('Job_ID').

 

The problem is - when you schedule a job in the first place you have to save Job_ID somewhere to abort it later.

And also you have to be sure that your scheduled job has completed, otherwise you can cancel it too early.

 

I am not sure what your use case is but is sounds to me that a Workflow with a Time Based trigger may be a better fit for your situation.

i.e. you setup a workflow and time-based-trigger to do a field update. Then in an apex trigger you watch for this field to be a certain value (set by field update caused by time-based-trigger) and execute necessary code when your flag filed is set to that value.

gaisergaiser

One more thing - you can also query CronTrigger object to find Id of your job to abort Schedule.

As usually there is a catch - CronTrigger object does not currently support query by job Name, so you will have to specify "where" condition using other field(s), e.g. CronExpression.

 

If you do use that method and System.abortJob(retrievedId) does not work then try:

- passing actual value of type Id

- or truncate String Id value returned from CronTrigger query to 15 characters as discussed here: 

http://boards.developerforce.com/t5/Apex-Code-Development/CronTrigger/m-p/503725#M93462

This was selected as the best answer
alaschgarialaschgari

Thanks gaiser!!