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トリガーでは、これらの変数を使い分けることで、データの整合性を保ちつつ柔軟なビジネスロジックを実装できます!