一括Apexトリガー
このチャレンジでは、商談(Opportunity)オブジェクトのフェーズ(StageName)が "Closed Won" になった際に、ToDo(Task)を自動的に作成する Apex Trigger を作成します。
✅ 要件整理
-
トリガー名:
ClosedOpportunityTrigger
-
対象オブジェクト:
Opportunity
-
トリガーの発火タイミング:
after insert
およびafter update
-
条件:
StageName
が"Closed Won"
の場合 -
処理:
-
Task
(ToDo)を作成する -
Subject:
"テスト ToDo をフォローアップする"
-
WhatId:
Opportunity.Id
(商談と関連付け)
-
-
バルク処理対応(トリガーが一括処理に対応するようにする)
✅ Apex Trigger の実装
以下が要件を満たす ClosedOpportunityTrigger
のコードです。
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
List<Task> tasksToInsert = new List<Task>();
for (Opportunity opp : Trigger.new) {
// フェーズが "Closed Won" になった商談のみ処理
if (opp.StageName == 'Closed Won') {
Task followUpTask = new Task(
Subject = 'テスト ToDo をフォローアップする',
WhatId = opp.Id,
OwnerId = opp.OwnerId, // 商談の所有者をタスクの所有者に設定
Status = 'Not Started', // デフォルトのステータスを設定
Priority = 'Normal' // 優先度を設定
);
tasksToInsert.add(followUpTask);
}
}
// 一括挿入処理(DMLの回数を削減)
if (!tasksToInsert.isEmpty()) {
insert tasksToInsert;
}
}
✅ コードの解説
1. after insert, after update
のトリガー
- 商談が作成(insert)されたとき、または更新(update)されたときにトリガーが実行されます。
2. Trigger.new
をループ処理
-
Trigger.new
には、更新された商談のリストが入っているので、すべてのレコードをループします。
3. 条件: StageName == 'Closed Won'
- 商談の
StageName
が"Closed Won"
になった場合のみ ToDo を作成します。
4. Task
オブジェクトのリスト tasksToInsert
を作成
-
DML(データ操作言語)処理の最適化のため、
Task
をリストに格納し、一括insert
します。
5. insert tasksToInsert;
でまとめて ToDo を作成
-
DML の回数を最小限に抑えるため、リストに
Task
を追加した後、1 回のinsert
でデータを挿入します。
✅ バルク処理対応のポイント
このコードは、一度に 200 件以上の商談を処理できるようになっています。
具体的には、以下の点でバルク処理対応をしています。
-
リストを使用して DML を 1 回の実行に抑える
-
Task
をList<Task>
に格納し、最後にinsert tasksToInsert;
することで、DML 回数制限を回避。
-
-
ループ内で DML 操作を行わない
-
insert
をループ内で実行すると、DML 制限(1 トランザクションあたり 150 回)を超える可能性があるため、バッチ処理で一括insert
する。
-
-
if (!tasksToInsert.isEmpty())
で不要な DML を防ぐ-
Closed Won
の商談が 1 つもなかった場合、無駄なinsert
を実行しない。
-
✅ 動作確認
テストデータを作成
Apex Developer Console で以下のコードを実行して、トリガーの動作をテストできます。
// サンプル商談の作成
Opportunity testOpp = new Opportunity(
Name = 'Test Opportunity',
StageName = 'Closed Won',
CloseDate = Date.today()
);
insert testOpp;
// 作成された Task を確認
List<Task> createdTasks = [SELECT Id, Subject, WhatId FROM Task WHERE WhatId = :testOpp.Id];
System.debug(createdTasks);
期待される結果
-
テスト ToDo をフォローアップする
という Subject の ToDo が作成される。 -
WhatId
がOpportunity.Id
と一致する。
✅ まとめ
-
after insert, after update
のトリガーでStageName == 'Closed Won'
の場合にTask
を作成。 -
Task
をリストに格納し、最後に 一括insert
することでバルク処理に対応。 -
DML 操作をループの外で実行
し、ガバナ制限を回避。 -
OwnerId
やStatus
を設定し、より実用的なTask
にする。
これで、この Trailhead チャレンジの要件を満たす 効率的でスケーラブルな Apex Trigger になりました! 🚀