Trigger.new、Trigger.newMap、Trigger.old、Trigger.oldMap の活用事例(標準オブジェクト)
Apexトリガーでは、レコードの 挿入・更新・削除時のデータを取得するために Trigger.new や Trigger.old などの変数が利用されます。
それぞれの用途を理解し、標準オブジェクト(商談や取引先)を例に活用事例を紹介します。
1. Trigger.new の活用例(商談作成時にデフォルトのフォローアップタスクを作成)
🔹 Trigger.new は 新しく作成されたレコードのリスト です。
🔹 before insert / after insert のタイミングで利用できます。
📌 事例: 商談が作成されたとき、自動でフォローアップタスクを作成する
trigger CreateFollowUpTask on Opportunity (after insert) {
List<Task> tasksToInsert = new List<Task>();
for (Opportunity opp : Trigger.new) {
Task newTask = new Task(
Subject = 'フォローアップ',
WhatId = opp.Id,
OwnerId = opp.OwnerId,
ActivityDate = Date.today().addDays(30), // 30日後のタスク
Status = 'Not Started',
Priority = 'High'
);
tasksToInsert.add(newTask);
}
if (!tasksToInsert.isEmpty()) {
insert tasksToInsert;
}
}
✅ ポイント
-
Trigger.newを使い、新しく作成された商談のリストを取得 -
after insertトリガーなので、レコードが保存された後 にタスクを作成
2. Trigger.newMap の活用例(取引先更新時に関連する商談の「取引先名」を更新)
🔹 Trigger.newMap は 更新後のレコードを ID をキーにして取得できる Map<Id, SObject> です。
🔹 大量データ処理(Bulk処理) の場合、レコードを ID で参照できるため 効率が良い です。
📌 事例: 取引先の「取引先名」が変更されたら、関連する商談の「取引先名」も更新する
trigger UpdateOpportunityAccountName on Account (after update) {
List<Opportunity> oppsToUpdate = new List<Opportunity>();
for (Account acc : Trigger.new) {
Account oldAcc = Trigger.oldMap.get(acc.Id);
if (acc.Name != oldAcc.Name) { // 取引先名が変わった場合
for (Opportunity opp : [SELECT Id, Name FROM Opportunity WHERE AccountId = :acc.Id]) {
opp.Name = acc.Name + ' 商談';
oppsToUpdate.add(opp);
}
}
}
if (!oppsToUpdate.isEmpty()) {
update oppsToUpdate;
}
}
✅ ポイント
-
Trigger.oldMap.get(acc.Id)を使い、更新前のデータと比較 - 取引先名 (
Name) が変更されたら、関連する商談のNameも変更 -
after updateで実行し、関連レコードの更新を許可
3. Trigger.old の活用例(商談のステージが「成立(Closed Won)」から変更されたら警告)
🔹 Trigger.old は 更新前のレコードのリスト を取得できます。
🔹 before update などで活用し、データ変更の制限 に使えます。
📌 事例: 「成立」済みの商談のステージが変更されそうになったらエラーを出す
trigger PreventStageChange on Opportunity (before update) {
for (Integer i = 0; i < Trigger.new.size(); i++) {
Opportunity newOpp = Trigger.new[i];
Opportunity oldOpp = Trigger.old[i];
if (oldOpp.StageName == 'Closed Won' && newOpp.StageName != 'Closed Won') {
newOpp.addError('成立した商談のステージを変更できません。');
}
}
}
✅ ポイント
-
Trigger.oldを使い、更新前のデータを取得 -
Closed Wonだった商談のステージを変更させない ように制御 -
before updateのaddErrorを使うことで 画面上でエラーメッセージを表示 可能
4. Trigger.oldMap の活用例(取引先削除時に関連する商談をクローズする)
🔹 Trigger.oldMap は 削除されるレコードの ID をキーとした Map<Id, SObject> です。
🔹 大量データ処理でも高速に関連レコードを検索 できます。
📌 事例: 取引先が削除されたら、関連する商談のステージを「Closed Lost」にする
trigger CloseOpportunitiesOnAccountDelete on Account (before delete) {
List<Opportunity> oppsToUpdate = new List<Opportunity>();
for (Account acc : Trigger.oldMap.values()) {
for (Opportunity opp : [SELECT Id, StageName FROM Opportunity WHERE AccountId = :acc.Id]) {
opp.StageName = 'Closed Lost';
oppsToUpdate.add(opp);
}
}
if (!oppsToUpdate.isEmpty()) {
update oppsToUpdate;
}
}
✅ ポイント
-
Trigger.oldMap.values()を使い、削除対象のAccountのリストを取得 - 関連する商談 (
Opportunity) を検索し、ステージを"Closed Lost"に変更 -
before deleteで実行し、取引先削除前に商談データを更新
まとめ
| 変数 | 用途 | 活用例 |
|---|---|---|
Trigger.new |
新しく作成された or 更新後のレコードのリスト | 商談作成時にタスクを追加 (after insert) |
Trigger.newMap |
新しく作成・更新後のレコードを ID で取得できる Map | 取引先名変更時に商談の取引先名も更新 (after update) |
Trigger.old |
更新前 or 削除前のレコードのリスト | 商談の成立済みステージ変更を制限 (before update) |
Trigger.oldMap |
更新前 or 削除前のレコードを ID で取得できる Map | 取引先削除時に関連商談をクローズ (before delete) |
使い分けポイント
✅ Trigger.new / Trigger.newMap → 新規作成・更新後のデータ処理
✅ Trigger.old / Trigger.oldMap → 更新前・削除前のデータチェックや制約
✅ 大量データを扱う場合 は Map を使うと 効率的に ID 参照できる
SalesforceのApexトリガーでは、これらの変数を使い分けることで、データの整合性を保ちつつ柔軟なビジネスロジックを実装できます!