Erfassen Sie Ihre Fortschritte
Trailhead-Startseite
Trailhead-Startseite

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

Geplantes Apex

Mit der Apex-Planungsfunktion können Sie die Ausführung verzögern, um Apex zu einem festgelegten Zeitpunkt auszuführen. Das ist ideal für tägliche oder wöchentliche Wartungsaufgaben unter Verwendung von Batch-Apex. 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.

global class SomeClass implements Schedulable {
    global 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.

global class RemindOpptyOwners implements Schedulable {

    global 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
        TaskUtils.remindOwners(opptys);
    }
    
}

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 verwendet die Zeitzone des Benutzers als Grundlage aller Zeitpläne, wird jedoch im Systemmodus ausgeführt. Es werden alle Klassen ausgeführt, unabhängig davon, ob der Benutzer die Berechtigung zum Ausführen der Klasse aufweist.

Hinweis

Hinweis

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 Auftragsklassen hinzufügt als laut dem Limit zulässig sind. Berücksichtigen Sie vor allem API-Massenaktualisierungen, Importassistenten, Massenänderungen von Datensätzen über die Benutzeroberfläche und alle Vorgänge, bei denen jeweils mehr als ein Datensatz geändert werden kann.

Für die System.Schedule-Methode können drei Argumente festgelegt werden: ein Name für den Auftrag, ein CRON-Ausdruck zur Angabe der Uhrzeit und des Datums der geplanten Auftragsausführung und der Name der Klasse.

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.
  1. Geben Sie unter "Setup" im Feld Schnellsuche den Text Apex ein und wählen Sie dann Apex-Klassen aus.
  2. Klicken Sie auf Apex-Planung aktualisieren.
  3. Geben Sie als Auftragsname beispielsweise Tägliche Oppty-Erinnerung ein.
  4. 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.
  5. Wählen Sie "Weekly" oder "Monthly" als Häufigkeit aus und legen Sie die Häufigkeit wie gewünscht fest.
  6. Wählen Sie das Start- und das Enddatum sowie die gewünschte Startzeit aus.
  7. Klicken Sie auf Save.

Testen von geplantem Apex

Genau wie bei den anderen, bisher beschriebenen asynchronen Methoden müssen Sie auch bei geplantem Apex sicherstellen, dass der geplante Auftrag abgeschlossen ist, bevor Sie die Ergebnisse durch Tests prüfen. Dazu umgeben Sie die System.schedule-Methode mit startTest und stopTest, um sicherzustellen, dass die Verarbeitung vor der Durchführung von Tests abgeschlossen ist.

@isTest
private class RemindOppyOwnersTest {

    // Dummy CRON expression: midnight on March 15.
    // Because this is a test, job executes
    // immediately after Test.stopTest().
    public static String CRON_EXP = '0 0 0 15 3 ? 2022';

    static testmethod 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];
        System.assertEquals(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];
        System.assertEquals(opptyIds.size(), 
            lt.size(), 
            'Tasks were not created');

    }
}

Wichtige Punkte

Bei geplantem Apex müssen eine Reihe von Punkten beachtet werden (unter "Apex Scheduler" im Abschnitt "Ressourcen" finden Sie eine vollständige Liste). Allgemein gilt:
  • Die Anzahl gleichzeitiger geplanter Apex-Aufträge ist auf 100 begrenzt und es gibt zusätzlich noch ein Limit für die Anzahl geplanter Apex-Ausführungen innerhalb von 24 Stunden. Weitere Einzelheiten dazu finden Sie unter "Execution Governors and Limits" im Abschnitt "Ressourcen".
  • 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.
  • Für geplantes Apex werden synchrone Webservice-Callouts nicht unterstützt. 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

Hinweis

Hinweis

Nicht vergessen: Dieses Modul bezieht sich auf Salesforce Classic. Wenn Sie Ihre Übungs-Organisation starten, wechseln Sie zu Salesforce Classic, um diese Aufgabe abzuschließen.