Scheduled actions in Apex are great to use when you need to have a section of code run at a particular time in the future and Time-Based workflows will not work. In the example below I’ll talk about how to schedule code to run at the first of every month, in addition talk about some constructs you can use to make your life easier when you have to redeploy/change this code
The key part of the apex class is that it must implement Schedulable and it must have an excecute method.
Now, we can fill out the class. Below is an example where we iterate through all of the accounts of a specific record type and insert a new list of MyObject based on that account. This could be as complex as you want.
To schedule this class we could call it from any number of places, such as a VisualForce page, a Trigger or the Developer Console. Since scheduled classes cannot be pushed out or changed when there are jobs in the queue we want to add a helper method to schedule this job. In our instance it will only be ran once a month, so we include our CRON_EXP as a static variable (for easy use) and to reduce the change of mis-scheduling.
To reset our schedule all we have to do is use type the following into the Developer console.
And by looking in Setup->Monitoring->Scheduled Jobs we can see that our scheduledMonthly class is there.
There are seven fields for Salesforce’s cron syntax, unlike *nix’s 5 fields.
- Seconds [0-59]
- Minutes [0-59]
- Hours [0-23]
- Day of month [1-31]
- Month [1-12 or JAN-DEC]
- Day of week [1-7 or SUN-SAT]
- Year [1970-2099]
There are also some special characters you can use:
- , used to delimit values [hours, day of month, month, day of week, year]
- - used to specify a range [hours, day of month, month, day of week, year]
- * used to specify all values [hours, day of month, month, day of week, year]
- ? used to specify no specific value [day of month, day of week]
- / used to specify increments [hours, day of month, month, day of week, year]
- L used to specify the end of a range [day of month, day of week]
- W used to specify the nearest weekday [day of month]
- # used to specify the nth day of the month [day of week]
Testing for scheduled apex may seem confusing but it’s very straight forward. Like @future calls, scheduled apex will not fire until after the Test.stopTest() has been run. In the test below we test the following:
- The Cron Expression is the same
- The job has not been triggered yet
- The scheduled date is correct
- No MyObjects were created
- One object was created after the scheduled job was ran
Limitations / Notes
There are three big limitations / notes about scheduled Apex
- It will be put on the queue at the given time, it is not guaranteed to run at that time.
- You can only have 25 classes scheduled at a time
- You cannot use getContent or getContentAsPDFPageReference