【Salesforce】バッチ処理入門：Accountテストレコード作成

# はじめに
今回は、Salesforceのバッチ処理（Apex一括処理）について学び、Accountオブジェクトのテストレコードを作成する方法を実装します。

# Salesforceのバッチ処理

https://trailhead.salesforce.com/ja/content/learn/modules/asynchronous_apex/async_apex_batch

https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_batch_interface.htm

Salesforceでは、Apexクラスを使用してレコードをバッチ単位で非同期に一括処理できます。これには`Database.Batchable`インターフェースを実装し、以下の3つのメソッドを含める必要があります。

1. `start`メソッド
処理するレコードまたはオブジェクトを収集するために使用します。
開始時に1回コールされ、`Database.QueryLocator`オブジェクトか、ジョブに渡すレコードやオブジェクトが含まれる`Iterable`オブジェクトを返します。

2. `execute`メソッド
メソッドに渡されたデータの処理単位（バッチ）ごとに実際の処理を実行します。
このメソッドでは、以下を取得します。
・`Database.BatchableContext`オブジェクトへの参照
・`List<sObject>`などの`sObject`のリストまたはパラメーター化された型のリスト
・`Database.QueryLocator`を使用している場合は、返されたリスト

3. `finish`メソッド
すべてのバッチ処理が完了した後に1回呼び出され、後処理（例: メール通知など）を実行します。

# Apex一括処理クラスの呼び出し
クラスを呼び出すにはインスタンス化し、そのインスタンスを使用して`Database.executeBatch`をコールします。
```java
MyBatchClass myBatchObject = new MyBatchClass();
Id batchId = Database.executeBatch(myBatchObject);
```

# レコードを追加するApexクラスの作成
```java
public class AccountCreateBatch implements Database.Batchable<sObject>, Database.Stateful {
  private Id recordTypeId;
  
  public Database.QueryLocator start(Database.BatchableContext BC) {
      getRecordTypeId();
      return Database.getQueryLocator('SELECT Id FROM Account LIMIT 1');
  }

  public void execute(Database.BatchableContext BC, List<SObject> scope) {
      List<Account> acc = new List<Account>();
      for (Integer i = 0; i < 100; i++) {
          acc.add(new Account(
              Name = 'Test Account 0' + i,
              Phone = '123-456-7890',
              Email__c = 'test0' + i + '@example.com',
              RecordTypeId = recordTypeId
          ));
      }
      insert(acc);
  }

  public void finish(Database.BatchableContext BC) {
      System.debug('Batch job completed.');
  }

  private void getRecordTypeId() {
      recordTypeId = [SELECT Id FROM RecordType WHERE SObjectType = 'Account' AND DeveloperName = 'JobSeeker' LIMIT 1].Id;
  }
}
```

`start`メソッドでは、追加するレコードのレコードタイプを取得します。
レコードタイプIdの取得をstartメソッドにそのまま記述すると、期待通りの動作をしなかったので、`getRecordTypeId`メソッドを作成して呼び出す形で実装しています。
```java
public Database.QueryLocator start(Database.BatchableContext BC) {
    getRecordTypeId();
```

下記の記述は、バッチ処理の対象データを指定するために必要な部分です。この記述がないと、バッチ処理がどのデータを処理するのかをSalesforceに伝えることができず、正常に動作しません。
```java
return Database.getQueryLocator('SELECT Id FROM Account LIMIT 1');
```

`excute`メソッドでは、Accountオブジェクトのリストを作成し、テストデータを追加します。
SalesforceのUI上での操作と同様、必須項目に値を入れなかったり、入力規則でエラーが出る状態で作成することはできません。

`finish`メソッドでは、今回はデバッグログを出力するだけですが、必要に応じて後処理を追加できます。

作成したApexクラスをデプロイします。
デプロイしたいファイルを右クリックでもデプロイできますが、`組織から削除`と並んでいるので、コマンドパレットから実行する方がおすすめです。
```
>SFDX: Deploy This Source to Org
```

![スクリーンショット 2025-04-05 21.33.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577266/1e00f52f-8956-4d34-81ed-ca2ba55d35b4.png)

# バッチ処理の実行
作成したバッチクラスを実行するには、以下のコードを使用します。
```java
AccountCreateBatch batch = new AccountCreateBatch();
Database.executeBatch(batch, 200);
```
このコードを`scripts`フォルダ内に新規ファイルとして保存します。

コードの上部にある`Excute`から実行できます。
![runBatch_apex_—_sf-dev-edition.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577266/ac5a3ad8-d217-4d79-bb84-8a9ed14c1c6d.png)

# テストレコードの削除
作成したテストレコードを削除したいときには、以下のコードを実行します。
```java
List<Account> accountsToDelete = [SELECT Id FROM Account WHERE Name LIKE 'Test Account 0%'];
if (!accountsToDelete.isEmpty()) {
    delete accountsToDelete;
    System.debug(accountsToDelete.size() + ' records deleted.');
} else {
    System.debug('No records found to delete.');
}
```
先ほどと同様に`scripts`フォルダ内に新規ファイルとして保存し、`Excute`から実行できます。


# まとめ
バッチ処理で[データローダー](https://developer.salesforce.com/docs/atlas.ja-jp.dataLoader.meta/dataLoader/data_loader.html)を使わずにテストレコードを作成することが可能になりました。

しかし、必須項目や入力規則の数が多いと上手く作成できないことが多いので、バッチ処理やApexクラスの知見を深めて、簡易的にテストレコードを作成する方法を見つけていきたいと思います。