バッチ処理の概要
処理概要:取引先の部門項目を一括で更新する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:
|
, - * / |
Day_of_week | 1–7 or the following:
|
, - * ? / 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処理サンプル タイトル サンプルコード 説明 カスタ ...
続きを見る