Salesforce Developer Group Rookies
#10
2018/06/19(木)@株式会社 ユー・エス・イー
本日のメニュー
2
• 19:00~19:10 ルーキー会の簡単な説明
• 19:10~19:30 自己紹介タイム
• 19:30~20:40 モブプログラミング
• 20:40~20:50 成果発表
• 20:55~21:00 締め&集合写真タイム
• 21:00~21:30 ご歓談タイム
注意事項
会場の様子は写真に撮って公開される可能性があります。予めご了承下さい。
(顔出しNGの方がいらっしゃいましたらサッと隠れるか運営までお知らせ下さ
い)
今日の進行役
名前:小林 亮理(リョウスケ)
所属:株式会社日本システムデザイン
:@ryosuke921186
SF歴:7年くらい
最近:PM、PLが7割、開発者が3割
趣味:運動(ソフトテニス、ゴルフ、ジムトレ)、寝る
3
SFDG Rookiesの紹介
これからSalesforceを学ぶデベロッパーのコミュニティ
4
運営メンバー
5
株式会社テラスカイ
讃岐 行
@i_sanuki
株式会社フレクト
齊藤 俊
株式会社テラスカイ
須山 洋輔
@suyaman_jp
株式会社
日本システムデザイン
小林 亮理
@ryosuke921186
ServiceCloud
の達人
Apexの神MVP テストの鬼
今日の参加者割合
6
Salesforceで確認!
7
自己紹介タイム
■Salesforceでのプログラミング経験年数
■普段どんなことやってる?
■今日の意気込み
今日のお題である
「Apexトリガー」の基本
概要
Apexトリガーではレコードの登録・更新・削除・復元を契機に独自の
処理を実行することができます。
9
例えば、
・登録・更新対象レコードの編集
・入力チェック
・関連レコードの作成
・Webサービスの呼び出し 、、などなど
そんなのプロセスビルダーとフローでできちゃうよ!
① コミット前のレコードにアクセスする
② 削除、復元に対する処理記述
10
多くのことは、プロセスビルダー、フロー、入力規則でも
実現可能です。
そんな中、トリガーでしかできないことは、
トリガーでしかできないこと、標準機能でもできることを覚え、
適切な設計ができるようになりましょう
Apexトランザクションの処理順
11
1. 古いレコードをデータベースからロード(または、新しい挿入の初期化)
2. 新しいレコードの値で古い値を上書き(Trigger.Newの上書き)
3. システムの入力規則の実行(例:数値項目に英字等が入っていないかのチェック)
4. すべての before トリガを実行
5. カスタム入力規則(作成した入力規則)
6. レコードをデータベースに保存(コミットはされていないがSFIDが発行される)
7. レコードをデータベースから再ロード
8. すべての after トリガを実行
9. 割り当てルール
10. 自動応答ルール
11. ワークフロー ルールプロセス
12. エスカレーション ルール
13. 積み上げ集計数式の値の更新(存在する場合)
14. データベースのコミット
15. コミット後のロジック(メールの送信)
参考:https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm
トリガーに関するお約束や心得について
12
大体の場合、オブジェクト名+「Trigger」というものが多い名称
イベント判定をトリガーで行い、実処理をハンドラークラスに記述する
のが一般的。
またトリガーはテストクラスから直接呼び出せないため、テストクラス
作成も考慮するとハンドラークラスの利用が望ましい
トリガーハンドラーの利用
トリガーでのみ(一部例外あり)利用できる変数。更新対象のレコード
へのアクセスやイベント判定に利用する
コンテキスト変数の活用
ビューやDataloaderで一括更新された際に、複数レコードが同時に処理
されるため、それに対応できるようコードを記述する
複数件処理を前提に
1オブジェクトに対して、複数トリガーを作成できますが、処理順は保
証されないため、なるべく1つにしましょう
1つのオブジェクトに対して、
トリガーは(なるべく)1つ
トリガーの例
13
trigger OpportunityTrigger on Opportunity (before insert, before update) {
OpportunityTriggerHandler handler = new OpportunityTriggerHandler();
if (Trigger.isBefore) {
if(Trigger.isInsert){
handler.isBeforeInsert(Trigger.New);
}else if (Trigger.isUpdate) {
handler.isBeforeUpdate(Trigger.newMap,Trigger.oldMap);
}
}
}
トリガー
public class OpportunityTriggerHandler {
public void isBeforeInsert(List<Opportunity> oppList){
method1(oppList);
}
public void isBeforeUpdate(Map<Id,Opportunity> oppNewMap,Map<Id,Opportunity> oppOldMap){
method2 (oppNewMap,oppOldMap);
}
private void method (List<Opportunity> oppList){
for(Opportunity opp:oppList){
opp.xxxxx__c = ‘test’;
}
}
}
トリガーハンドラー
コンテキスト変数
参考
https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_triggers_context_variables.htm
14
変数 利用方法
Trigger.isInsert 挿入操作により、トリガが実行された場合に、true を返します。
Trigger.isBefore レコードが保存される前にこのトリガが実行された場合に、
true を返します。
Trigger.New 更新後の sObject レコードリストを返します。
(List<sObject>が返される)
Trigger.NewMap 更新前の sObject レコードMapを返します
(Map<ID,sObject>が返される)
トリガーのイベント判定や、更新対象レコードにアクセスするために
コンテキスト変数を利用します
Apexトランザクションの処理順
15
1. 古いレコードをデータベースからロード(または、新しい挿入の初期化)
2. 新しいレコードの値で古い値を上書き(Trigger.Newの上書き)
3. システムの入力規則の実行(例:数値項目に英字等が入っていないかのチェック)
4. すべての before トリガを実行
5. カスタム入力規則(作成した入力規則)
6. レコードをデータベースに保存(コミットはされていないがSFIDが発行される)
7. レコードをデータベースから再ロード
8. すべての after トリガを実行
9. 割り当てルール
10. 自動応答ルール
11. ワークフロー ルールプロセス
12. エスカレーション ルール
13. 積み上げ集計数式の値の更新(存在する場合)
14. データベースのコミット
15. コミット後のロジック(メールの送信)
参考:https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm
おさらい
• データ登録・更新を契機にトリガーは実行される
• Apexトランザクション処理順も意識しましょう
• 実処理部分はトリガーハンドラーへ
• コンテキスト変数を利用する
• 複数件対応は必須
16
Let's モブプログラミング
 ドライバーを一人決め、それ以外はナビゲータとしてサポート
 ドライバーが詰まっても、周りは優しくサポート!
 疑問点があったら遠慮なく周りの人やメンターに聞いてみよう!
 適度なところでドライバーを交代しよう
 ~20:40まで(チーム内での振り返り含めて)
17
今日のお題:テストメソッド
18
お題① トリガーの起動
お題② 入力チェック
お題③ 更新データの操作
お題④ 引数ありのメソッドやifの分岐
お題① トリガーの起動
取引先に対してトリガーを設定し、
新規登録時に下記DEBUGログに出力しなさい。
「トリガー処理が走りました」
※対象イベントは、before Insertのみとします。
19
お題② 入力チェック
取引先責任者の登録・更新時に、電話(Phone)が
空白の場合はエラーとしなさい。
エラーメッセージは以下とする。
「電話番号は必須です。」
※複数件同時に登録・更新された場合にも対応してください
20
お題③ 更新データの操作
取引先の登録・更新時、国(納入先)が空白の場合、
国(請求先)の値をコピーしなさい
※実処理部分は、Handlerクラスを作成し、そちらに記述してください
※複数件同時に登録・更新された場合にも対応してください
21
お題④ 関連レコードの作成
商談の登録時、紐づくTodoを自動的に作成しない。
Todoの内容は以下とする。
件名 :担当者訪問
任命先:商談所有者;
期日 :7日後
優先度:High
状況 :Not Started
※優先度、状況については、各自環境のものに置き換えて問題ありません。
※実処理部分は、Handlerクラスを作成し、そちらに記述してください
※複数件同時に登録・更新された場合にも対応してください
22
成果発表
チームごとにお願いします!
■代表者1名から
どんな感じに進めたか(難しかったとか?)
どこまで、できたか
などなど
■メンターから
フィードバック
23
Trailblazer Community
Salesforceのユーザやアドミンや開発者が集まるコミュニティ
24
• https://success.salesforce.com/_ui/
core/chatter/groups/GroupProfilePa
ge?g=0F93A000000HTtr
【開発者向け】
• Salesforce Developer Group ルーキー会
• Tokyo Salesforce Developer Group
• Salesforce女子部
など
今日の勉強会レポートを書いてくれる方
大募集!
DGルーキー会 次回予告
• 7月中旬を予定
• 日時・場所は決まり次第connpassでお知
らせします!
25
各種イベント紹介
• 6月22日(金) 08:00- Admin女子部 東京 #4
– https://sfadminwgjp.connpass.com/event/89634/
• 6月28日(木) 19:00- [Tokyo] Salesforce Developers Meetup #18
– https://www.meetup.com/ja-JP/Tokyo-Salesforce-Developer-Group/events/250412406/
• 7月9日(木) 19:00- Salesforce女子部 #19 ~楽しくHerokuを学ぶ~
– https://sfggjp.connpass.com/event/90516/
• 7月25日(水) Salesforce Summer
– https://www.salesforce.com/jp/events/summer18/
26
20180619_第10回ルーキー会資料

20180619_第10回ルーキー会資料