保存時のBefore・Afterトリガと入力規則の順序
検証用オブジェクトと入力規則、Before・Afterトリガを用意し、保存時に各処理が動く順番を確認します。Beforeトリガは入力規則より先に動きます。
なぜ順番を知る必要があるか
Beforeトリガの中で「入力規則さえ後で通れば安全」と思って処理を書くと、実際には違反したままのデータに対してもBeforeトリガが動いてしまいます。逆にAfterトリガは、必須項目チェックと入力規則の両方を通って保存が成功した後にしか動きません。この前後関係を知らないと、想定した処理が想定したタイミングで動きません。
保存時の実行順序
Salesforceの公式リファレンス「トリガーと実行の順序」では、レコード保存時の処理が次の順で並んでいます。
| 順番 | 処理 |
|---|---|
| 1 | システム入力規則(必須項目の有無など) |
| 2 | 保存前に実行するよう設定されたレコードトリガフロー |
| 3 | Beforeトリガ |
| 4 | 入力規則(カスタムのバリデーションルール) |
| 5 | データベースへの保存(コミットはまだしない) |
| 6 | Afterトリガ |
| 7 | 割り当てルール |
| 8 | 自動応答ルール |
| 9 | ワークフロールール |
| 10 | 保存後に実行するよう設定されたレコードトリガフロー |
| 11 | 積み上げ集計項目の再計算 |
| 12 | データベースへのコミット |
Beforeトリガ(3)は、入力規則(4)より先に動きます。必須項目チェック(1)より後ではありますが、カスタムの入力規則の合否はまだ分かっていません。Afterトリガ(6)は、入力規則を通って保存された(5)後に動きます。
検証用オブジェクトを準備する
カスタムオブジェクトを作る
オブジェクトマネージャで表示ラベル「testObject1」、オブジェクト名「testObject1」を作成します。API参照名は自動的に
testObject1__cになります。レコード名の項目を自動採番に変える
標準の「testObject1名」項目をテキストから自動採番へ変更します。表示形式は
TO1-{0000}、開始番号は1にします。必須のカスタム項目を作る
表示ラベル「testText」、項目名「testText」、データ型テキスト(255文字)で作成し、「必須項目」にチェックを入れます。項目レベルセキュリティは全プロファイルに公開し、全ページレイアウトへ追加します。
入力規則を作る
ルール名「Within10characters」、エラー条件式
LEN(testText__c) > 10、エラーメッセージ「文字数が10以内にしてください。」、エラー表示場所は項目「testText」にします。
トリガとハンドラの実装
before・afterのどちらのタイミングで動いたかを、デバッグログへ書き出すだけのシンプルな作りにします。
testObject1Trigger.trigger
trigger testObject1Trigger on testObject1__c (before insert, after insert) { testObject1TriggerHandler handler = new testObject1TriggerHandler(); if (Trigger.isBefore) { handler.beforeInsert(Trigger.new); } if (Trigger.isAfter) { handler.afterInsert(Trigger.new); } }
beforeとafterの両方で、実行されたタイミングをログへ書き出すだけのトリガです
testObject1TriggerHandler.cls
public with sharing class testObject1TriggerHandler { public void beforeInsert(List<testObject1__c> newRecords) { System.debug('before insert: ' + newRecords.size()); } public void afterInsert(List<testObject1__c> newRecords) { System.debug('after insert: ' + newRecords.size()); } }
beforeInsertとafterInsertが呼ばれたことをデバッグログへ記録します
trigger本文とハンドラクラスを「Before用」「After用」で2組用意すると、同じクラス名のファイルが2つできてしまい、両方を同時にデプロイできません。ここでは1本のトリガと1つのハンドラで、beforeとafterの両方を扱います。
保存したときの挙動
testTextへ入れる値を変えて保存すると、次のように動きます。
| testTextの入力 | 必須項目チェック | Beforeトリガ | 入力規則 | 保存 | Afterトリガ |
|---|---|---|---|---|---|
| 空白 | エラー | 実行されない | 到達しない | されない | 実行されない |
| 11文字(規則に違反) | 通過 | 実行される | エラー | されない | 実行されない |
| 10文字(規則を満たす) | 通過 | 実行される | 通過 | される | 実行される |
Beforeトリガは、11文字を入れた行でも実行されています。必須項目チェックの後、入力規則より前に位置するためです。Afterトリガは、10文字を入れて保存が成功した行でしか実行されていません。
addError()を呼んで止める必要があります。入力規則はBeforeトリガより後に評価されるので、Beforeトリガの実行そのものは止まりません。ここで間違えやすい
| 間違い | 何が起きるか |
|---|---|
| Beforeトリガの中でレコードが保存済みだと思い込む | まだ保存前です。insertならIdは空のままです |
| Afterトリガは必ず動くと思い込む | 必須項目チェックか入力規則でエラーになると、Afterトリガまで到達しません |
| 同じ名前のクラスを2つ用意する | コンパイルエラーになり、デプロイできません |
| 保存前後のフローとトリガの順序を無視する | 保存前フローはBeforeトリガより先、保存後フローはAfterトリガより後に動きます |
確認した環境
- 2026年9月 / Salesforce Summer '26(APIバージョン67.0)時点の公式リファレンス「トリガーと実行の順序」で、保存時の処理の並びを確認しています
まとめ
- 保存時は、システム入力規則→保存前フロー→Beforeトリガ→入力規則→保存→Afterトリガ→割り当てルール→自動応答ルール→ワークフロールール→保存後フロー→積み上げ集計→コミットの順で進みます
- Beforeトリガは入力規則より先に動きます。規則違反のデータに対しても実行されます
- Afterトリガは、必須項目チェックと入力規則の両方を通って保存が成功した後にしか動きません
- Beforeトリガの中で保存を止めたいときは、入力規則を待たず
addError()で自分で止めます - 同じ名前のクラスを2つ用意すると、デプロイできません
参考:当時の画面
記事を最初に書いた当時の画面です。いまの手順と違うところは、各画像の説明に書いています。
Salesforceの導入・運用についてご相談ください
導入前の検討から、お使いの環境の改修・運用、AIとの連携まで承ります。状況を伺ったうえで、進め方をご提案します。