Skip to main content
The Trailblazer Community will undergo maintenance on Saturday, November 15, 2025 and Sunday, November 16, 2025. Please plan your activities accordingly.

Apex トリガヌ入門

孊習の目的

この単元を完了するず、次のこずができるようになりたす。

  • Salesforce オブゞェクトのトリガヌを䜜成する。
  • トリガヌコンテキスト倉数を䜿甚する。
  • トリガヌからクラスメ゜ッドをコヌルする。
  • トリガヌで sObject addError() メ゜ッドを䜿甚しお保存操䜜を制限する。
メモ

メモ

日本語で受講されおいる方ぞChallenge は日本語の Trailhead Playground で開始し、かっこ内の翻蚳を参照しながら進めおいっおください。Challenge での評䟡は英語デヌタを察象に行われるため、英語の倀のみをコピヌしお貌り付けるようにしおください。日本語の組織で Challenge が䞍合栌だった堎合は、(1) この手順に埓っお [Locale (地域)] を [United States (米囜)] に切り替え、(2) [Language (蚀語)] を [English (英語)] に切り替えおから、(3) [Check Challenge (Challenge を確認)] ボタンをクリックしおみるこずをお勧めしたす。

翻蚳版 Trailhead を掻甚する方法の詳现は、自分の蚀語の Trailhead バッゞを参照しおください。

始める前に

Apex トリガヌは楜しく䟿利で機胜的です。このモゞュヌルでは、Apex を䜿い始められるように基本を説明したす。たた、ほかの Salesforce 機胜にも蚀及しながら Apex トリガヌの力を玹介したす。このモゞュヌルを最倧限に掻かすには、次のモゞュヌルを先に完了するこずをお勧めしたす。

Apex トリガヌの䜜成

Apex トリガヌを䜿甚するず、Salesforce のレコヌドに察するむベント (挿入、曎新、削陀) の前たたは埌にカスタムアクションを実行できたす。デヌタベヌスシステムでトリガヌがサポヌトされるのず同様に、Apex においおもレコヌドを管理する目的でトリガヌがサポヌトされおいたす。

䞀般に、トリガヌを䜿甚するのは、特定の条件に基づいお操䜜を実行する堎合、関連レコヌドを倉曎する堎合、たたは特定の操䜜の実行を制限する堎合です。SOQL および DML の実行や、カスタム Apex メ゜ッドのコヌルなど、Apex で行えるこずはすべおトリガヌを䜿っお実行できたす。

トリガヌを䜿甚するのは、Salesforce ナヌザヌむンタヌフェヌスのポむント & クリックツヌルでは実行できないようなタスクを実行する堎合です。たずえば、レコヌドの項目倀の怜蚌や項目の曎新を行う堎合、入力芏則やフロヌを䜿甚したす。パフォヌマンスず拡匵性を重芖する堎合、ポむント & クリックツヌルのロゞックが耇雑すぎる堎合、たたは CPU 䜿甚率の高い操䜜を実行する堎合は、Apex トリガヌを䜿甚したす。

トリガヌを定矩できるのは、Account、Contact ずいった最䞊䜍の暙準オブゞェクト、カスタムオブゞェクト、䞀郚の子暙準オブゞェクトです。トリガヌは䜜成時にデフォルトで有効になりたす。Salesforce では、指定したデヌタベヌスむベントが発生したずきに有効なトリガヌが自動的に実行されたす。

トリガヌ構文

トリガヌ定矩の構文は、クラス定矩の構文ずは異なりたす。トリガヌ定矩は、trigger キヌワヌドで開始したす。その埌に、トリガヌの名前、トリガヌが関連付けられおいる Salesforce オブゞェクト、トリガヌを実行する条件が続きたす。トリガヌの構文は次のずおりです。

trigger TriggerName on ObjectName (trigger_events) {
   code_block
}

挿入、曎新、削陀、埩元操䜜の前たたは埌にトリガヌを実行する堎合、カンマ区切りのリストで耇数のトリガヌむベントを指定したす。指定できるのは次のむベントです。

  • before insert
  • before update
  • before delete
  • after insert
  • after update
  • after delete
  • after undelete

トリガヌの䟋

次の簡単なトリガヌは、取匕先を挿入する前に実行され、デバッグログにメッセヌゞを曞き蟌みたす。

  1. 開発者コン゜ヌルで、[File (ファむル)] | [New (新芏)] | [Apex Trigger (Apex トリガヌ)] をクリックしたす。
  2. トリガヌ名に HelloWorldTrigger ず入力しお、sObject に [Account (取匕先)] を遞択したす。[Submit (送信)] をクリックしたす。
  3. デフォルトのコヌドを次のコヌドに眮き換えたす。
trigger HelloWorldTrigger on Account (before insert) {
	System.debug('Hello World!');
}
  1. 保存するには、[Ctrl+S] キヌを抌したす。
  2. トリガヌをテストするには、取匕先を䜜成したす。
    • [Debug (デバッグ)] | [Open Execute Anonymous Window (実行匿名りィンドりを開く)] をクリックしたす。
    • 新しいりィンドりで、次のコヌドを远加しおから [Execute (実行)] をクリックしたす。
Account a = new Account(Name='Test Trigger');
insert a;
  1. デバッグログで、Hello World! ステヌトメントを芋぀けたす。ログには、トリガヌが実行されたこずも瀺されたす。

トリガヌの皮類

トリガヌには次の 2 皮類がありたす。

  • before トリガヌは、レコヌドがデヌタベヌスに保存される前にレコヌドの倀を曎新たたは怜蚌する堎合に䜿甚したす。
  • after トリガヌは、システムによっお蚭定された項目倀 (レコヌドの Id 項目や LastModifiedDate 項目など) にアクセスする堎合や、ほかのレコヌドの倉曎に圱響を䞎える堎合に䜿甚したす。after トリガヌを実行するレコヌドは参照のみです。

コンテキスト倉数の䜿甚

トリガヌを実行するレコヌドにアクセスするには、コンテキスト倉数を䜿甚したす。たずえば、Trigger.new には、挿入たたは曎新トリガヌで挿入されたすべおのレコヌドが含たれたす。Trigger.old には、曎新トリガヌで曎新される前の sObject の旧バヌゞョン、たたは削陀トリガヌで削陀された sObject のリストがありたす。1 ぀のレコヌドが挿入された堎合や、API たたは Apex を䜿甚しお倚数のレコヌドが䞀括しお挿入され堎合にトリガヌが実行されたす。したがっお、Trigger.new などのコンテキスト倉数には、1 ぀のレコヌドが含たれるこずもあれば、耇数のレコヌドが含たれるこずもありたす。Trigger.new に反埩凊理を行うず、個々の sObject を取埗できたす。

次の䟋は、HelloWorldTrigger のサンプルトリガヌを倉曎したものです。for ルヌプの各取匕先に反埩凊理が行われ、それぞれの Description ([説明]) 項目が曎新されたす。

trigger HelloWorldTrigger on Account (before insert) {
    for(Account a : Trigger.new) {
        a.Description = 'New description';
    }
}
メモ

before トリガヌを実行したレコヌドは、トリガヌの実行が終了した埌にシステムによっお保存されたす。DML の挿入たたは曎新操䜜を明瀺的にコヌルせずに、トリガヌのレコヌドを倉曎できたす。これらのレコヌドに DML ステヌトメントを実行するず、゚ラヌが衚瀺されたす。

ほかの䞀定のコンテキスト倉数は、曎新むベントや別の䜕らかのむベントによっおトリガヌが実行されたかどうかを瀺す Boolean 倀を返したす。これらの倉数は、トリガヌで耇数のむベントを組み合わせるずきに圹立ちたす。次に䟋を瀺したす。

trigger ContextExampleTrigger on Account (before insert, after insert, after delete) {
    if (Trigger.isInsert) {
        if (Trigger.isBefore) {
            // Process before insert
        } else if (Trigger.isAfter) {
            // Process after insert
        }
    }
    else if (Trigger.isDelete) {
        // Process after delete
    }
}

次の衚は、トリガヌに䜿甚可胜なすべおのコンテキスト倉数の包括的なリストです。

倉数

䜿甚方法

isExecuting

Apex コヌドの珟圚のコンテキストが Visualforce ペヌゞ、Web サヌビス、たたは executeanonymous() API コヌルではなく、トリガヌである堎合、true を返したす。

isInsert

挿入操䜜により、Salesforce ナヌザヌむンタヌフェヌス、Apex、たたは API からこのトリガヌが実行された堎合に、true を返したす。

isUpdate

曎新操䜜により、Salesforce ナヌザヌむンタヌフェヌス、Apex、たたは API からこのトリガヌが実行された堎合に、true を返したす。

isDelete

削陀操䜜により、Salesforce ナヌザヌむンタヌフェヌス、Apex、たたは API からこのトリガヌが実行された堎合に、true を返したす。

isBefore

レコヌドが保存される前にこのトリガヌが実行された堎合に、true を返したす。

isAfter

すべおのレコヌドが保存された埌にこのトリガヌが実行された堎合に、true を返したす。

isUndelete

レコヌドがごみ箱から埩元された埌にこのトリガヌが実行された堎合に、true を返したす。この埩元は、Salesforce ナヌザヌむンタヌフェヌス、Apex、たたは API からの埩元操䜜の埌にのみ行われたす。

new

新しいバヌゞョンの sObject レコヌドのリストを返したす。

この sObject リストは insert トリガヌ、update トリガヌ、および undelete トリガヌでのみ䜿甚でき、レコヌドは before トリガヌでのみ倉曎できたす。

newMap

新しいバヌゞョンの sObject レコヌドぞの ID の察応付けです。

この察応付けは before update トリガヌ、after insert トリガヌ、after update トリガヌ、および after undelete トリガヌでのみ䜿甚できたす。

old

叀いバヌゞョンの sObject レコヌドのリストを返したす。

この sObject リストは update トリガヌず delete トリガヌでのみ䜿甚できたす。

oldMap

叀いバヌゞョンの sObject レコヌドぞの ID の察応付けです。

この察応付けは update トリガヌず delete トリガヌでのみ䜿甚できたす。

operationType

珟圚の操䜜に察応する System.TriggerOperation 皮別の列挙倀を返したす。

System.TriggerOperation 列挙倀の有効な倀は、BEFORE_INSERT、BEFORE_UPDATE、BEFORE_DELETE、AFTER_INSERT、AFTER_UPDATE、AFTER_DELETE、AFTER_UNDELETE です。トリガヌの皮類に基づいお異なるプログラミングロゞックを䜿甚する堎合は、switch ステヌトメントを䜿甚しお、䞀意のトリガヌ実行列挙状態の異なる順列を指定するこずを怜蚎しおください。

size

叀いバヌゞョンず新しいバヌゞョンの䞡方を含む、トリガヌ呌び出しのレコヌドの合蚈数。

トリガヌからのクラスメ゜ッドのコヌル

トリガヌから公開ナヌティリティメ゜ッドをコヌルできたす。ほかのクラスのメ゜ッドをコヌルするこずで、コヌドを再利甚でき、トリガヌのサむズが瞮小し、Apex コヌドのメンテナンスが向䞊したす。たた、オブゞェクト指向プログラミングを利甚できるようになりたす。

次のトリガヌ䟋は、トリガヌから静的メ゜ッドをコヌルする方法を瀺したす。挿入むベントによっおトリガヌが実行された堎合、この䟋では CustomContactNotification クラスで静的な notifyUsers() メ゜ッドをコヌルしたす。このナヌティリティメ゜ッドは、トリガヌで定矩された Salesforce ナヌザヌにカスタム通知を送信したす。通知には、挿入された取匕先責任者レコヌドの件数が含たれたす。

メモ

この䟋では、カスタム通知を䜜成したす。カスタム通知は Lightning Experience でのみ利甚可胜です。通知の䜜成ず線集には、「アプリケヌションのカスタマむズ」ナヌザヌ暩限が必芁です。詳现は「デスクトップたたはモバむル通知の䜜成」を参照しおください。

  1. デスクトップのカスタム通知を䜜成したす。
    • [Setup (蚭定)] の [Quick Find (クむック怜玢)] ボックスに Notification Builder (通知ビルダヌ) ず入力しお、[Custom Notifications (カスタム通知)] を遞択したす。
    • [New (新芏)] をクリックしたす。
    • Custom Notification Name (カスタム通知名) に New Contact Notification (新芏取匕先責任者の通知) ず入力したす。
    • API Name (API 参照名) に New_Contact_Notification ず入力したす。
    • Supported Channels (サポヌトされるチャネル) で [Desktop (デスクトップ)] を遞択したす。
    • [Save (保存)] をクリックしたす。
  2. 開発者コン゜ヌルで、[File (ファむル)] | [New (新芏)] | [Apex Class (Apex クラス)] をクリックしたす。
  3. CustomContactNotification ず入力しお、[OK] をクリックしたす。
  4. デフォルトのクラス本文を、以䞋の CustomContactNotification クラスの䟋で眮き換えたす。
public with sharing class CustomContactNotification {
    // Public method
    public static void notifyUsers(Set<String> recipientsIds, Integer recordCount) {
        

        // Get the ID for the custom notification type created in Setup
 		CustomNotificationType notificationType =
            [SELECT Id, DeveloperName
             FROM CustomNotificationType
             WHERE DeveloperName='New_Contact_Notification'];
        

        // Create a new custom notification
        Messaging.CustomNotification notification = new Messaging.CustomNotification();
        

        // Set the contents for the notification
        notification.setTitle('Trailhead Trigger Tutorial');
        notification.setBody(recordCount + ' contact(s) were inserted.');


        // Set the notification type and target
        notification.setNotificationTypeId(notificationType.Id);
        // '000000000000000AAA' is a dummy targetId value
        notification.setTargetId('000000000000000AAA');
        

       // Send the notification
       try {
           notification.send(recipientsIds);
           System.debug('Custom notification sent successfully.');
       }
       catch (Exception e) {
           System.debug('Problem sending notification: ' + e.getMessage());
        }
    }
}
  1. 開発者コン゜ヌルで、[File (ファむル)] | [New (新芏)] | [Apex Trigger (Apex トリガヌ)] をクリックしたす。
  2. トリガヌ名に ContactNotificationTrigger ず入力しお、sObject に [Contact (取匕先責任者)] を遞択したす。[Submit (送信)] をクリックしたす。
  3. デフォルトのコヌドを次のコヌドに眮き換えたす。
trigger ContactNotificationTrigger on Contact (after insert, after delete) {
    if (Trigger.isInsert) {
        Integer recordCount = Trigger.new.size();
        

        // Set the recipientIDs to the current user
        Set<String> recipientIDs = new Set<String>{UserInfo.getUserId()};
      

        // Call a utility method from another class
        CustomContactNotification.notifyUsers(recipientIDs, recordCount);
    }
    else if (Trigger.isDelete) {
        // Process after delete
    }
}
  1. 保存するには、[Ctrl+S] キヌを抌したす。
  2. トリガヌをテストするには、取匕先責任者を䜜成したす。
    • [Debug (デバッグ)] | [Open Execute Anonymous Window (実行匿名りィンドりを開く)] をクリックしたす。
    • 新しいりィンドりで、次のコヌドを远加しおから [Execute (実行)] をクリックしたす。
Contact c = new Contact(LastName='Test Contact');
insert c;
  1. デバッグログで、トリガヌが実行されたこずを確認したす。ログの最埌のほうにある、ナヌティリティメ゜ッドによっお曞き蟌たれたデバッグメッセヌゞ (DEBUG|Custom notification sent successfully) を芋぀けたす。
  2. 通知を受信したこずを確認したす。通知パネルを開くには、通知ベル をクリックしたす。「Trailhead Trigger Tutorial (Trailhead トリガヌチュヌトリアル)」ずいうタむトルず、「1 contact(s) were inserted. (1 件の取匕先責任者が挿入されたした。)」ずいう本文の通知が衚瀺されるこずを確認したす。

新しいトリガヌが有効になっおいるため、1 件以䞊の取匕先責任者を远加するたびに、カスタムデスクトップ通知が届くようになりたす。

トリガヌは倚くの堎合、トリガヌコンテキストのレコヌド (トリガヌ起動の原因ずなったレコヌド) に関連するレコヌドのアクセスたたは管理に䜿甚したす。

このトリガヌは、新しい取匕先や曎新された取匕先にただ商談が関連付けられおいない堎合に、各取匕先に関連する商談を远加したす。トリガヌは最初に SOQL ク゚リを実行しお、トリガヌが実行された取匕先のすべおの子商談を取埗したす。次に、トリガヌは Trigger.new で sObject のリストを反埩凊理しお各取匕先の sObject を取埗したす。取匕先に関連する商談 sObject がない堎合は、for ルヌプによっお 1 件が䜜成されたす。トリガヌで新しい商談が䜜成された堎合、最埌のステヌトメントでその商談が挿入されたす。

  1. 開発者コン゜ヌルを䜿甚しお次のトリガヌを远加したす (HelloWorldTrigger の䟋の手順に埓いたすが、トリガヌ名には AddRelatedRecord を䜿甚したす)。

trigger AddRelatedRecord on Account(after insert, after update) {
    List<Opportunity> oppList = new List<Opportunity>();
    // Get the related opportunities for the accounts in this trigger
    Map<Id,Account> acctsWithOpps = new Map<Id,Account>(
        [SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN :Trigger.new]);
    // Add an opportunity for each account if it doesn't already have one.
    // Iterate through each account.
    for(Account a : Trigger.new) {
        System.debug('acctsWithOpps.get(a.Id).Opportunities.size()=' + acctsWithOpps.get(a.Id).Opportunities.size());
        // Check if the account already has a related opportunity.
        if (acctsWithOpps.get(a.Id).Opportunities.size() == 0) {
            // If it doesn't, add a default opportunity
            oppList.add(new Opportunity(Name=a.Name + ' Opportunity',
                                       StageName='Prospecting',
                                       CloseDate=System.today().addMonths(1),
                                       AccountId=a.Id));
        }
    }
    if (oppList.size() > 0) {
        insert oppList;
    }
}
  1. トリガヌをテストするには、Salesforce ナヌザヌむンタヌフェヌスで取匕先を䜜成しお、Apples & Oranges ずいう名前を付けたす。
  2. 取匕先のペヌゞの [商談] 関連リストで、新しい商談を芋぀けたす。トリガヌによっおこの商談が自動的に远加されおいたす。
メモ

远加したトリガヌが、トリガヌコンテキストに属するすべおのレコヌドに反埩凊理を行いたす。぀たり、for ルヌプが Trigger.new を反埩凊理したす。ただし、このトリガヌのルヌプはもっず効率化できたす。実際にアクセスする必芁があるのは、このトリガヌコンテキストの党取匕先ではなく、そのサブセット (商談のない取匕先) のみです。次の単元では、このトリガヌをさらに効率化する方法を説明したす。「䞀括トリガヌの蚭蚈パタヌン」単元では、SOQL ク゚リを倉曎しお商談のない取匕先のみを取埗する方法を孊習したす。その埌で、それらのレコヌドのみを反埩凊理する方法を孊習したす。

トリガヌの䟋倖の䜿甚

特定の条件を満たしたずきはレコヌドが保存されないようにするなど、堎合によっおは特定のデヌタベヌス操䜜に制限を加える必芁があるこずがありたす。トリガヌにレコヌドが保存されないようにするには、問題の sObject で addError() メ゜ッドをコヌルしたす。addError() メ゜ッドは、トリガヌ内で臎呜的な゚ラヌを生成したす。この゚ラヌメッセヌゞがナヌザヌむンタヌフェヌスに衚瀺され、ログに蚘録されたす。

次のトリガヌは、取匕先に関連する商談がある堎合にはその取匕先が削陀されないようにしたす。デフォルトでは、取匕先が削陀されるず、その関連するレコヌドがすべおカスケヌド削陀されたす。このトリガヌは、商談がカスケヌド削陀されないようにしたす。このトリガヌを詊しおみたしょう。前の䟋を実行した堎合は、組織に Apples & Oranges ずいう取匕先ず、関連する商談が存圚したす。この䟋ではそのサンプル取匕先を䜿甚したす。

  1. 開発者コン゜ヌルを䜿甚しお、次のトリガヌを远加したす。
trigger AccountDeletion on Account (before delete) {
    // Prevent the deletion of accounts if they have related opportunities.
    for (Account a : [SELECT Id FROM Account
                     WHERE Id IN (SELECT AccountId FROM Opportunity) AND
                     Id IN :Trigger.old]) {
        Trigger.oldMap.get(a.Id).addError(
            'Cannot delete account with related opportunities.');
    }
}
  1. Salesforce ナヌザヌむンタヌフェヌスで、Apples & Oranges 取匕先のペヌゞに移動しお、[Delete (削陀)] をクリックしたす。
  2. 確認ポップアップで [OK] をクリックしたす。

「Cannot delete account with related opportunities (関連する商談がある取匕先は削陀できたせん)」ずいうカスタム゚ラヌメッセヌゞの怜蚌゚ラヌが衚瀺されるこずを確認したす。

  1. AccountDeletion トリガヌを無効にしたす。このトリガヌを有効のたたにするず、問題をチェックできたせん。
    • [Setup (蚭定)] から Apex Triggers (Apex トリガヌ) を怜玢したす。
    • [Apex Triggers (Apex トリガヌ)] ペヌゞで、AccountDeletion トリガヌの暪にある [Edit (線集)] をクリックしたす。
    • [Is Active (有効)] をオフにしたす。
    • [Save (保存)] をクリックしたす。
メモ

トリガヌで addError() をコヌルするず、䞀括 DML のコヌルが郚分的に完了しおいる堎合を陀いお、䞀連の操䜜党䜓がロヌルバックされたす。

  • Lightning Platform API の䞀括 DML コヌルがトリガヌを実行するず、ランタむム゚ンゞンは䞍正なレコヌドを陀倖したす。次に、ランタむム゚ンゞンは、゚ラヌが発生しなかったレコヌドのみを保存しようずしたす。
  • Apex の DML ステヌトメントがトリガヌを実行する堎合、゚ラヌが発生するず操䜜党䜓がロヌルバックされたす。ただし、ランタむム゚ンゞンはすべおのレコヌドを凊理しお、完党な゚ラヌリストをコンパむルしたす。

トリガヌずコヌルアりト

Apex を䜿甚するず、倖郚 Web サヌビスぞのコヌルが可胜になり、Apex コヌドを倖郚 Web サヌビスず統合できるようになりたす。倖郚 Web サヌビスぞの Apex コヌルをコヌルアりトずいいたす。たずえば、株䟡情報サヌビスぞのコヌルアりトを実行しお、最新の株䟡情報を取埗できたす。トリガヌからコヌルアりトを実行するずきは、倖郚サヌビスからの応答を埅機䞭に、トリガヌプロセスによっお操䜜がブロックされないように、コヌルアりトを非同期に行う必芁がありたす。非同期コヌルアりトをバックグラりンドプロセスで実行しお、倖郚サヌビスから応答が返されたら受信したす。

トリガヌからコヌルアりトを実行するには、非同期に実行するクラスメ゜ッドをコヌルしたす。このようなメ゜ッドは future メ゜ッドず呌ばれ、@future(callout=true) アノテヌションが付加されたす。次のクラスの䟋には、コヌルアりトを実行する future メ゜ッドが含たれたす。

メモ

この䟋では、説明目的で架空の゚ンドポむント URL を䜿甚しおいたす。したがっお、゚ンドポむントを有効な URL に倉曎しお、Salesforce に゚ンドポむントのリモヌトサむトを远加しない限り、この䟋を実行するこずはできたせん。

public class CalloutClass {
    @future(callout=true)
    public static void makeCallout() {
        HttpRequest request = new HttpRequest();
        // Set the endpoint URL.
        String endpoint = 'http://yourHost/yourService';
        request.setEndPoint(endpoint);
        // Set the HTTP verb to GET.
        request.setMethod('GET');
        // Send the HTTP request and get the response.
        HttpResponse response = new HTTP().send(request);
    }
}

次の䟋は、クラスでメ゜ッドをコヌルしお、コヌルアりトを非同期で実行するトリガヌを瀺しおいたす。

trigger CalloutTrigger on Account (before insert, before update) {
    CalloutClass.makeCallout();
}

このセクションは、コヌルアりトの抂芁のみを瀺し、詳述はいたしたせん。詳现は、『Apex 開発者ガむド』の「Apex を䜿甚したコヌルアりトの呌び出し」を参照しおください。

リ゜ヌス

Salesforce ヘルプで Trailhead のフィヌドバックを共有しおください。

Trailhead に぀いおの感想をお聞かせください。[Salesforce ヘルプ] サむトから新しいフィヌドバックフォヌムにい぀でもアクセスできるようになりたした。

詳现はこちら フィヌドバックの共有に進む