Apex トリガーのサンプルコード


[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)

過去の質問でいくつか書いてきたのでまとめておきたいと思います。

# 具体的なサンプルコード

+ [取引先の所有者が変更された場合に取引責任者の所有者も変更する](https://qiita.com/Keiji_otsubo/items/5e4c0aeb12f11d6785b7)
+ [取引責任者の件数をカウントするApexトリガー](https://qiita.com/Keiji_otsubo/items/0a136cc311e6c8ab346b)
+ [更新/追加されたレコードを含めないで親子関係のレコードを処理する](https://qiita.com/Keiji_otsubo/items/bfd23451735d90672d1c)
+ [拡張メモの内容を取引先オブジェクトに更新する](https://qiita.com/Keiji_otsubo/items/e40f79042198727901bc)
+ [拡張メモの内容を取引先オブジェクトに更新する2](https://qiita.com/Keiji_otsubo/items/3c0d694aef2fd85bcfd1)
+ [添付ファイルの名称取得](https://qiita.com/Keiji_otsubo/items/3344ef992a7016a5c5d1)
+ [商談でアップロードしたファイル（PDF、エクセルなど）を自動的に指定ライブラリに格納する方法](https://qiita.com/Keiji_otsubo/items/64be119e544253d833a4)
+ [取引先の所有者を変更した時に、商談の所有者を変更するトリガー](https://qiita.com/Keiji_otsubo/items/f7890cc40d329a46007c)
+ [Notes と Notes & Attachments にApexトリガーでレコードを作成する](https://qiita.com/Keiji_otsubo/items/3c1b8f76a20bf969a06b)
+ [freeeとSalesforceとの取引連携（freee for Salesforceを使う方法）](https://qiita.com/Keiji_otsubo/items/c000d837a7ac12aab02e)
+ [FeedComment Trigger のテストクラス](https://qiita.com/Keiji_otsubo/items/261524cc88be622eee7e)
+ [Caseを複製するトリガー](https://qiita.com/Keiji_otsubo/items/349b845b0d95fb2b7a90)
+ [多対多リレーションの重複禁止 Apexトリガーでの対応](https://qiita.com/Keiji_otsubo/items/5a264f179dd83045200c)
+ [関連するレコードを結びつけたい](https://qiita.com/Keiji_otsubo/items/00467b97f4c41bf776a2)
+ [復元を防止する処理について（undeleteトリガ）](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007HOR9i)
+ [Choosing Between Before and After Triggers in Salesforce](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007bL3FV)
+ [親レコードのステータスが「アクティブ」に設定されている場合に、関連レコードが削除されないようにするにはどうすればよいですか?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007erR9D)

# Apex バッチ
+ [Apexバッチのサンプル](https://qiita.com/Keiji_otsubo/items/58eabf3e31b2e24eebc7)
+ [CaseMilestone TargetDate on Case](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000A8ybC)
+ [Batch process which periodically archive SObjects to Big Objects](https://qiita.com/Keiji_otsubo/items/5ab78b06c91b8069249d)

# エラー、障害

+ [Apexトリガーが重複して起動する](https://qiita.com/Keiji_otsubo/items/22510574dd8475e1761d)
+ [System.FinalException: Record is read-only](https://qiita.com/Keiji_otsubo/items/83684ef4a41a806797d1)

+ [When i am going to check the challenge in [Apex triggers : Bulk API] This Error is Coming Even the task is successfully created on opportunity :](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Fyvhc)

:::note alert
We tried to insert Opportunity records as part of the challenge check, but the insert failed. Error: thException: OPP_INSERT | System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, ClosedOpportunityTrigger: execution of AfterInsert caused by: System.DmlException: Insert failed. First exception on row 0 with id 00T2w00001ATNBGEA5; first error: **INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id]** Trigger.ClosedOpportunityTrigger: line 12, column 1: [] Show Less
:::

インサートの場所が違っていた。ループの中で行っていたため

# 関連資料

+ [Difference between trigger.new and trigger.newmap](https://qiita.com/Keiji_otsubo/items/9d8165760783d1997076)
+ [Apex の Mapの使い方](https://qiita.com/Keiji_otsubo/items/3690c349420ada25b0ab)

```
Map<Id, Account> mapAccount = new Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id=:Trigger.New[0].AccountId]);

for(Contact cont: Trigger.new){
    if(cont.Id != null && mapAccount.containsKey(cont.AccountId)){
       t.AccountName__c = mapAccount.get(cont.AccountId).Name;
    }
} 
```

+ [オムニチャネルを通じて割り当てられたレコードは、ワークフロールール、エスカレーションルール、トリガーなどの自動化をトリガーしません](https://qiita.com/Keiji_otsubo/items/63338e1c061405f275fa)
+ [選択リストのデフォルト値を動的にセットする（ただし項目が多いので数式はNG）](https://qiita.com/Keiji_otsubo/items/8556341132a3a39d5c6a)

# add.Error

+ [add.Errorについて　add.Errorは上書きされる？](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007eqjfl)

:::note
１つのレコードの中で複数のAdd.Errorがあれば最初のAdd.Errorのところで処理が中断すると思います。よって複数のチェックがあってもエラーになったチェックで止まります。

回避策としては、チェック時にエラーになってもAdd.Errorを使わずに、
例えば、エラーメッセージを格納するようなString型のList変数に保存したり、String型の変数にエラー内容を連結します。

トリガーの更新処理の直前で、これらの変数に値が入っていれば、ここでAdd.Errorにその変数の内容を設定すれば、全てのチェックでのエラー内容が表示できると思います。

https://salesforce.stackexchange.com/questions/175728/how-to-write-a-trigger-with-two-adderror-conditions-at-different-places-on-the-s
:::