Planen von Aufträgen mit der Apex-Planungsfunktion
Lernziele
Nachdem Sie diese Lektion abgeschlossen haben, haben Sie Folgendes gelernt:
- Wann Sie geplantes Apex verwenden sollten
- Überwachen geplanter Aufträge
- Syntax von geplantem Apex
- Geplante Methoden – bewährte Vorgehensweisen
Mit Trail Together einem Dozenten folgen
Möchten Sie bei diesem Schritt einem Dozenten folgen?
Möchten Sie bei diesem Schritt einem Dozenten folgen?
Geplantes Apex
Mit der Apex-Planungsfunktion können Sie die Ausführung verzögern, um Apex zu einem festgelegten Zeitpunkt auszuführen. Zur Verwendung der Planungsfunktion schreiben Sie eine Apex-Klasse, die die Schedulable-Schnittstelle implementiert, und planen sie für die Ausführung nach einem bestimmten Zeitplan.
Syntax von geplantem Apex
Wenn Sie Apex-Klassen für die Ausführung zu bestimmten Zeitpunkten aufrufen möchten, implementieren zunächst die Schedulable-Schnittstelle für die Klasse. Dann planen Sie eine Instanz der Klasse mit der System.schedule()-Methode für die Ausführung zu einem bestimmten Zeitpunkt.
public class SomeClass implements Schedulable {
public void execute(SchedulableContext ctx) {
// awesome code here
}
}Die Klasse implementiert die Schedulable-Schnittstelle und muss nur die einzige Methode implementieren, die diese Schnittstelle enthält, und zwar die execute()-Methode.
Der Parameter für diese Methode ist ein SchedulableContext-Objekt. Nach der Planung einer Klasse wird ein CronTrigger-Objekt erstellt, das den geplanten Auftrag repräsentiert. Es stellt eine getTriggerId()-Methode zur Verfügung, das die ID eines CronTrigger-API-Objekts zurückgibt.
Beispielcode
Die Klasse fragt offene Opportunities ab, die zum aktuellen Datum bereits abgeschlossen sein sollten, und erstellt eine Aufgabe zu jeder dieser Opportunities, durch die der Inhaber an die Aktualisierung der Opportunity erinnert wird.
public class RemindOpptyOwners implements Schedulable {
public void execute(SchedulableContext ctx) {
List<Opportunity> opptys = [SELECT Id, Name, OwnerId, CloseDate
FROM Opportunity
WHERE IsClosed = False AND
CloseDate < TODAY];
// Create a task for each opportunity in the list
List<Task> tasks = new List<Task>();
for (Opportunity opp : opptys) {
Task newTask = new Task(
Subject = 'Update the Opportunity!',
Priority ='Normal',
Status = 'Not Started',
WhatId = opp.Id
);
tasks.add(newTask);
}
insert tasks;
}
}
Sie können die Klasse entweder programmgesteuert oder über die Benutzeroberfläche der Apex-Planungsfunktion für die Ausführung planen.
Verwenden der System.Schedule-Methode
Nach der Implementierung einer Klasse mit der Schedulable-Schnittstelle verwenden Sie die System.Schedule()-Methode, um sie auszuführen.
Die System.Schedule()-Methode akzeptiert drei Argumente: einen Namen für den Auftrag, einen CRON-Ausdruck, der Uhrzeit und Datum der Ausführung des Auftrags angibt, und eine Instanz einer Klasse, die die Schedulable-Schnittstelle implementiert.
RemindOpptyOwners reminder = new RemindOpptyOwners();
// Seconds Minutes Hours Day_of_month Month Day_of_week optional_year
String sch = '20 30 8 10 2 ?';
String jobID = System.schedule('Remind Opp Owners', sch, reminder);Weitere Informationen über den für die Planung verwendeten CRON-Ausdruck finden Sie im Abschnitt über die Verwendung der System.Schedule-Methode in der Beschreibung der Apex-Planungsfunktion.
Planen eines Auftrags über die Benutzeroberfläche
Sie können eine Klasse auch mithilfe der Benutzeroberfläche planen.
- Klicken Sie auf Schedule Apex (Apex-Planung).
- Geben Sie als Auftragsname beispielsweise
Tägliche Oppty-Erinnerungein. - Klicken Sie auf die Schaltfläche zum Nachschlagen neben der Apex-Klasse und geben Sie
*als Suchbegriff ein, um eine Liste aller planbaren Klassen abzurufen. Klicken Sie in den Suchergebnissen auf den Namen Ihrer geplanten Klasse. - Wählen Sie
Weekly(Wöchentlich) oderMonthly(Monatlich) als Häufigkeit aus, und legen Sie die Häufigkeit wie gewünscht fest. - Wählen Sie das Start- und das Enddatum sowie die gewünschte Startzeit aus.
- Klicken Sie auf Save (Speichern).
Testen von geplantem Apex
@IsTest
private class RemindOppyOwnersTest {
// Placeholder CRON expression: midnight on March 15.
// Because this is a test, job executes
// immediately after Test.stopTest(), not at the time set in the CRON expression
public static String CRON_EXP = '0 0 0 15 3 ? 2042';
@IsTest
static void testScheduledJob() {
// Create some out-of-date Opportunity records
List<Opportunity> opptys = new List<Opportunity>();
Date closeDate = Date.today().addDays(-7);
for (Integer i=0; i<10; i++) {
Opportunity o = new Opportunity(
Name = 'Opportunity ' + i,
CloseDate = closeDate,
StageName = 'Prospecting'
);
opptys.add(o);
}
insert opptys;
// Get the IDs of the opportunities we just inserted
Map<Id, Opportunity> opptyMap = new Map<Id, Opportunity>(opptys);
List<Id> opptyIds = new List<Id>(opptyMap.keySet());
Test.startTest();
// Schedule the test job
String jobId = System.schedule('ScheduledApexTest',
CRON_EXP,
new RemindOpptyOwners());
// Verify the scheduled job has not run yet.
List<Task> lt = [SELECT Id
FROM Task
WHERE WhatId IN :opptyIds];
Assert.areEqual(0, lt.size(), 'Tasks exist before job has run');
// Stopping the test will run the job synchronously
Test.stopTest();
// Now that the scheduled job has executed,
// check that our tasks were created
lt = [SELECT Id
FROM Task
WHERE WhatId IN :opptyIds];
Assert.areEqual(opptyIds.size(),
lt.size(),
'Tasks were not created');
// Check the scheduled time
List<CronTrigger> ct = [SELECT Id, TimesTriggered, NextFireTime
FROM CronTrigger WHERE Id = :jobId];
System.debug('Next Fire Time ' + ct[0].NextFireTime);
}
}Wichtige Punkte
- Seien Sie extrem vorsichtig, wenn Sie vorhaben, eine Klasse von einem Auslöser aus zu planen. Sie müssen garantieren können, dass der Auslöser nicht mehr geplante Aufträge hinzufügt als laut dem Limit zulässig sind.
- Wenn Sie Callouts durchführen möchten, verwenden Sie asynchrone Callouts, indem Sie den Callout in einer Methode mit der Anmerkung
@future(callout=true)platzieren und diese Methode innerhalb des geplanten Apex aufrufen. Falls Ihr geplantes Apex jedoch einen Batchauftrag ausführt, werden Callouts innerhalb der Batch-Klasse unterstützt.
Ressourcen
