当ブログではアフィリエイト広告を利用しています

サンプルコード

Batch Apexサンプルコード(取引先の部門を一括更新するバッチ処理)

バッチ処理の概要

処理概要:取引先の部門項目を一括で更新するApexバッチ処理となります。

以下、取引先部門が未設定の取引先レコードに対して、一括で'未設定'という固定値を設定する処理

バッチを実行することで、以下のように取引先部門に’未設定’の文言が一括でセットされます。

Batch Apexのサンプルコード

Batch Apexのサンプルクラス、スケジューラ、テストクラスの基本セット

詳細な仕様は公式の開発者ガイドを参照「Apexの一括処理」してください。

取引先の部門更新処理バッチ(BatchApexUpdateAccount.cls)

/**
 * プログラム名:BatchApexUpdateAccount
 * 概   要 :取引先の部門を一括で更新するためのバッチ処理
 * 作 成 日 :2022/07.01
 * 作 成 者 :cclt(David)
 * 変更履歴  :
 */
global class BatchApexUpdateAccount implements Database.Batchable<sObject>, Database.Stateful {

    //取引先部門に設定する固定値を定義
    private final String SITE_DEFAULT_VALUE = '未指定';

    /**
     * スタートメソッドでは、QueryLocatorを使ってバッチ処理を行うレコードを取得する
     * 本サンプルでは、取引先の部門を更新するため部門がNULLのレコードを全て取得する
     **/
    global Database.QueryLocator start(Database.BatchableContext BC) {
        
        //取引先部門(Site)が未設定の取引先レコードをすべて取得
        String query = 'SELECT Id, Name, Site FROM Account Where Site = null';
        return Database.getQueryLocator(query);
    }
        
    /**
     * スタートで取得したレコードのリストをパラメータとして、メイン処理を実行
     * バッチ実行時に処理するレコード数が指定されていない場合、デフォルトでは200レコードずつ分割して処理される。
     */
    global void execute(Database.BatchableContext BC, List<Account> accList) {
        
        //取得した取引先部門が未指定のレコードについて、固定値'未指定'をセットする。
        for(Account acc : accList) {        
            try {
                //取引先部門に固定値をセット
                acc.Site = this.SITE_DEFAULT_VALUE;
            } catch(Exception e) {
                //桁数を超過する文字列をセットした場合などにエラーが発生します
                System.debug('エラーが発生しました。' + e.getMessage());
            }
        }
        /**
         * Database.SaveResultを使って処理したレコード1件ずつチェックし
         * 異常終了(エラー)の場合にはCSVファイルにエラーメッセージを添付しメール通知する
         * **/
        Database.SaveResult [] updResultList = Database.update(accList,false);
        for (Database.SaveResult di : updResultList) {
            //エラーの場合は、レコードにエラーメッセージを設定
            if (!di.isSuccess()) {
                for(Database.Error err : di.getErrors()){
                    System.debug(err.getStatusCode() + ': ' + err.getMessage());
                    System.debug('登録エラー: ' + err.getFields());
                }   
            } else {
                System.debug('正常終了');
            }
        }
    }   
    
    /**
     * バッチ処理の最後に実行する処理を定義
     * バッチが異常終了した場合にもfinishで定義した処理は実行される
     */
    global void finish(Database.BatchableContext BC) {
        // 
        System.debug('finish');
    }
}

注意ポイント

バッチ処理を実装するには、Database.Batchableを継承する必要がありますが、合わせてDatabase.Statefulを指定することを忘れないように。

Database.Statefulを指定しない場合、Execute内で更新されたメンバ変数が引き継がれなくなります。

開発コンソールでバッチを直接実行する

//バッチ処理を開発コンソールで実行する場合は、以下のコメントを利用してください。
BatchApexUpdateAccount xbatch = new BatchApexUpdateAccount();
Id batchId = Database.executeBatch(xbatch);

スケジュールクラス(ScheduledBatchUpdateAccount.cls)

/**
 * プログラム名:ScheduledBatchUpdateAccount
 * 概   要 :取引先部門一括更新バッチのスケジューラ
 * 作 成 日 :2022/07.01
 * 作 成 者 :cclt(David)
 * 変更履歴  :
 */
global class ScheduledBatchUpdateAccount implements Schedulable {
    global void execute(SchedulableContext sc) {
        //取引先部門一括更新バッチクラスをインスタンス化
        BatchApexUpdateAccount b = new BatchApexUpdateAccount(); 
        //execcuteBatchでバッチ処理を実行
        Database.executeBatch(b);
    }
}

Schedulableとすることで、以下の画面からスケジュールジョブとして設定することができるようになります。

登録するとスケジュール済みジョブの画面にて、次回の実行予定を確認することができます。

注意ポイント

  • スケジュール登録の際に、作成したスケジューラのバッチが選択できない場合があります。その場合には、一度開発コンソールで直接スケジュール設定を行うと表示されるようになります。
  • スケジュール済み Apex ジョブは一度に 100 件しか設定できません。(分単位でバッチを登録すると1つのバッチだけで60個のジョブ枠が使われてしまうため注意が必要)※サポートに問い合わせしても変更できません。
  • スケジュール済み Apex の 24 時間あたりの最大実行数も制限されているため、ジョブの実行回数についても注意が必要です。

//開発コンソールで直接スケジュールを設定する

ScheduledBatchUpdateAccount m = new ScheduledBatchUpdateAccount();
String sch = '20 30 8 10 2 ?';
String jobID = system.schedule('取引先部門一括更新ジョブ', sch, m);

sch(スケジュール)に設定する内容については、

'Seconds(秒) Minutes(分) Hours(時間) Day_of_month(日) Month(月)Day_of_week(曜日)'の順

設定方法に関する説明は以下の通り

Name Values Special Characters
Seconds 0–59 None
Minutes 0–59 None
Hours 0–23 , - * /
Day_of_month 1–31 , - * ? / L W
Month 1–12 or the following:

  • JAN
  • FEB
  • MAR
  • APR
  • MAY
  • JUN
  • JUL
  • AUG
  • SEP
  • OCT
  • NOV
  • DEC
, - * /
Day_of_week 1–7 or the following:

  • SUN
  • MON
  • TUE
  • WED
  • THU
  • FRI
  • SAT
, - * ? / L #
optional_year null or 1970–2099 , - * /

【特殊なスケジュール設定方法】

・Special Charactersの文字列を使うことで、複雑なスケジュールの指定が可能となります。

①カンマ','を使った場合、月のパラメータに"JAN,FEB,MAR”といったように複数の月を指定することができます。

②半角ハイフン'-'を使うと、月のパラメータの場合、"JAN-MAR"といったように月のFROM-TO指定が可能となります。

※そのほかの例は、以下公式HELPサイトよりご確認ください。

「https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_scheduler.htm」

Batch Apexテストクラス()

@isTest
private class ScheduledBatchUpdateAccountTest {

    public static String CRON_EXP = '0 0 * * * ? 2022';
    static testmethod void testScheduledJob() {
        // 処理対象の取引先データを作成
        List<Account> accRecs = new List<Account>();
        for (Integer i=0; i<10; i++) {
            Account acc = new Account(
                Name = 'テスト取引先 ' + i,
                Site =  null);
            accRecs.add(acc);
        }
        insert accRecs;
        
        // インサート後のレコードIDとレコードをマップに格納(検証用)
        Map<Id, Account> accMap = new Map<Id, Account>(accRecs);

        // テスト開始
        Test.startTest();
            // スケジュールジョブ実行
            String jobId = System.schedule('ScheduledBatchUpdateAccountTest',
                CRON_EXP, new ScheduledBatchUpdateAccount());
                
        //テスト終了
        Test.stopTest();

        //テスト結果の検証
        for(Account acc:[SELECT Id,Name,Site FROM Account
                        WHERE Id IN :accMap.keyset()]){
            System.assertEquals(acc.Site , null);
        }
    }
}

 

 

注意ポイント

  • System.schedule メソッドを使って、スケジュールした結果を確認する場合には、Test.startTest()→System.schedule メソッド→Test. stopTest()の順に実行する必要があります。

サンプルコード一覧へ戻る場合は、こちらへ

参考サンプルコード(テンプレート)Apex/Lwc/Visualforce/Flow

Salesforceの開発を行うときにベースとなるサンプルコードを探すことが多いので、カテゴリごとにサンプルをまとめてみました。 Apex Apex処理サンプル タイトル サンプルコード 説明 カスタ ...

続きを見る

-サンプルコード
-, , , , ,