Salesforce研修カリキュラム
座学と実践課題を組み合わせた、ClassLabの開発に必要なスキルを段階的に習得するための包括的なカリキュラムです。
学習トピックと課題は難易度が段階的に上がり、前のステップで学んだ内容を活用します。課題で作成するオブジェクトやデータは後の課題でも継続して使用するため、丁寧に構築してください。
📘 ステップ1: 基礎
Salesforceの基本操作、カスタムオブジェクト・項目、入力規則、重複ルールなど
必須🔧 ステップ2: 開発
ワークフロー、プロセスビルダー、フロー、Apexトリガーなど自動化の基礎
重要🚀 ステップ3: 応用
VisualForce、バッチ処理、ガバナ制限対策など高度な開発技術
実践📦 ステップ4: リリース
変更セット、Apexテストクラス、LWC、REST APIなど本番適用の知識
応用📚 リファレンス資料
開発ソリューションの比較、Apexの独自仕様、ガバナ制限など
参考✍️ 実践課題
6つの段階的課題で実務スキルを習得
実装1. 研修スケジュール
ステップ1: 前提知識(Salesforceの基礎)
| トピック | 詳細 | 参考リンク |
|---|---|---|
| 操作方法とSalesforceの画面 | Lightning Experience の基本操作 | - |
| カスタムオブジェクト・カスタム項目 | オブジェクト、項目とは / オブジェクトに設定できること / 入力規則、ページレイアウト、レコードタイプ | Trailhead: データモデリング |
| カスタム項目の種類 | 各データ型の特性と使い分け | Help: カスタム項目の種類 |
| レコードタイプ | レコードタイプの概念と用途 | 解説記事 |
| ページレイアウト | レイアウトの設定方法 | Help: ページレイアウト |
| プロファイル | ユーザのアクセス制御 | Help: プロファイル |
| タブ | タブの追加方法 | Help: タブ |
| リストビュー | データ一覧の表示とカスタマイズ | Trailhead: リストビュー |
| 入力規則 | データ品質を保つバリデーション | Help: 入力規則 |
| 重複ルール・一致ルール | データ重複の防止 | 解説記事 |
ステップ2: 開発
| トピック | 詳細 | 参考リンク |
|---|---|---|
| 開発手段一覧と選定基準 | 各開発手法と選定の基準について | ソリューション比較表 |
| SandBox | テスト環境の使い方 | - |
| ワークフロー実装 | 項目の更新、メールアラートの実行、Todoの作成 | - |
| プロセスビルダー実装 | レコードの更新・作成、承認申請、Chatter投稿、通知、フロー実行、Apex実行 | - |
| フロー実装 | 画面フロー(LEXのみ)、レコードトリガフロー | - |
| データの一括投入 | データローダーの使い方 | - |
| Apexトリガー | トリガーイベント、コンテキスト変数(Trigger.old, Trigger.new等) | サンプルコード |
| SOQL | SOQLの書き方(*不可、参照先は__r、バインド変数は:変数名) |
SOQL リファレンス |
| Apexクラス | Apexでのみ利用する特殊な記述と考慮すべき制限 | Apex独自仕様 |
ステップ3: 応用
ステップ4: リリース・追加知識
| トピック | 詳細 |
|---|---|
| 変更セット | リリース方法(STG→本番のデプロイフロー) |
| Apexテストクラス | テストの書き方、@TestSetup、@isTest |
| LWC(時間があれば) | Lightning Web Components の基礎 |
| REST API 作成(時間があれば) | @RestResource によるAPI公開 |
| API 連携(時間があれば) | Callout、Named Credential |
2. リファレンス資料
開発で利用するソリューションの比較
レコードの作成・更新・削除を起点に動くソリューション
| ソリューション | 概要 | 処理実行の起点 | 他レコード検索・更新 | 処理速度 | 注意点 |
|---|---|---|---|---|---|
| Apexトリガ | レコードのCRUDを起点にプログラムコードを実行 | レコードの更新・削除・作成 | ○ | 速い | コードカバー率75%以上のテストコードが必須 |
| プロセスビルダー | ノーコードでSFが提供するアクションを実行 | レコードの更新・作成 | △(主従関係の親のみ) | 遅い | 同オブジェクト内に複数存在すると処理が重くなる |
| フロー | ノーコードでApexトリガと同等の処理が可能 | レコードの更新・削除・作成、PBからの呼出、スケジュール、画面フロー | ○ | 遅い | ハッシュマップがなく不要なループ・クエリが発生しやすい |
| ワークフロー | ノーコードで簡単な自動化。PBより簡単 | レコードの更新・作成 | △(主従関係の親のみ) | 速い | 条件ごとにWFとアクションを作成する必要あり。近年SFはフローを推奨 |
画面の構築が可能なソリューション
| ソリューション | 概要 |
|---|---|
| VisualForce + Apexコントローラ | HTML形式で画面構築 + バックエンドのプログラム開発 |
| Lightning Web Components (LWC) | HTML+JavaScript+XMLでUI部品を開発、Lightningページに自由配置 |
| フロー | LEXで利用可能な画面と処理を定義(ノーコード) |
Apexの独自仕様
| 仕様 | 説明 | 参考 |
|---|---|---|
| SOQL | SQLではなくSOQL(SELECT * 不可、JOIN は参照/主従項目のみ) |
SOQL リファレンス |
| ガバナ制限 | トランザクション単位でリソース制限あり | ガバナ制限詳細 |
| 独自アノテーション | @isTest, @future, @InvocableMethod 等 |
解説記事 |
| Sharing キーワード | with sharing / without sharing / inherited sharing |
公式ドキュメント |
Apexクラスの実行手段
| 実行元 | 概要 | 参考 |
|---|---|---|
| フロー | Apexアクションとして実行。@InvocableMethod アノテーション、global static メソッド、引数は独自クラスの配列またはList |
Help |
| Apexトリガ | トリガー内から直接呼び出し | - |
| VisualForce | VFページのコントローラとして利用 | 記事 |
| API | Apexクラスを REST API として公開(@RestResource) |
記事 |
| プロセスビルダー | Apexアクションとして実行 | 記事 |
| スケジュールバッチ | 予め予定された日時にApexを実行(Schedulable インターフェース) |
Help |
| メールサービス | 受信メールを起点にApexを実行。受信用アドレスはSFから発行 | Help |
Apexトリガーのサンプルコード
trigger invoiceTrigger on ff_invoice__c (after insert, after update) {
// triggerの定義: trigger <トリガの名前> on <オブジェクト名> (<イベント>)
// イベント: before insert, before update, before delete,
// after insert, after update, after delete, after undelete
// 【注意点】
// トリガーは1オブジェクトにつき一つまでの設計を行う
// 処理が膨大になる場合は別途Apexクラスを作成して処理を分割する
// ---- 利用頻度の高いコンテキスト変数 ----
// アップデートする前の値、削除時のレコードの配列
// ※参照先の項目は含まない、このリストを使ってUpdateはできない
system.debug(trigger.old);
// 更新後、挿入後のレコードの配列
// ※参照先の項目は含まない、このリストを使ってUpdateはできない
system.debug(trigger.new);
// 作成時にのみ動かしたい処理を書く場合
if (trigger.isInsert) {
// insert時の処理
}
// 更新時にのみ動かしたい処理を書く場合
if (trigger.isUpdate) {
// update時の処理
}
// その他のコンテキスト変数:
// https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_triggers_context_variables.htm
// ---- SOQLについて ----
// ・SOQLは * が使えない
// ・結合は参照項目、主従項目でのみ行える
// ・参照先の項目を取得: "参照項目__r.項目名" の形式
// ・サブクエリも利用可能
// ・Where句に変数を利用する場合: 変数の前に ':' をつける
List<ff_invoice__c> insertList = [
SELECT Id, Order__r.Staff__r.Email__c
FROM ff_invoice__c
WHERE Id IN :trigger.new
];
// ---- ループの書き方 ----
// 回数を指定する場合
for (Integer i = 0; i < 10; i++) {
system.debug(i);
}
// List型や配列を利用する場合
// for (<型> <変数名> : <配列またはリスト>) {}
for (ff_invoice__c inv : insertList) {
system.debug(inv);
}
}
Apexバッチ処理
バッチ処理は、処理をスケジュールしたり大量のデータを扱う際に使用します。
構成: Database.Batchable<sObject> と Schedulable インターフェースを実装
global class dailyReportBatch implements Database.Batchable<sObject>, Schedulable {
List<Employee__c> NoReportEmpList;
// スケジュール用メソッド(SFのUIから実行日時を設定)
global void execute(SchedulableContext sc) {
dailyReportBatch b = new dailyReportBatch();
// 実行: バッチクラス, バッチサイズ
database.executebatch(b, 1);
}
/*
* バッチを別のAPEXから呼び出す時など、引数を利用する場合はコンストラクタを利用
* 1. メンバ変数を定義: Id hogeId;
* 2. コンストラクタ: global dailyReportBatch(String id) { this.hogeId = id; }
* 3. 呼び出し元: dailyReportBatch b = new dailyReportBatch(id);
*/
// 初期処理(1度だけ実行される)
global Database.QueryLocator start(Database.BatchableContext bc) {
this.NoReportEmpList = new List<Employee__c>();
// 社員マスタのデータを取得するクエリを引数に
return Database.getQueryLocator(
'SELECT Id, Email__c, FirstName__c, LastName__c, Dept__c FROM Employee__c'
);
}
// 実際に処理されるメソッド
// getQueryLocatorの結果がバッチサイズごとに実行される
// 例) クエリ結果2000件、バッチサイズ20 → 20件ずつ合計100回実行
global void execute(Database.BatchableContext bc, List<Employee__c> empList) {
List<Order__c> orders = [SELECT Id FROM Order__c WHERE Staff__c IN :empList];
if (orders.size() == 0) {
this.NoReportEmpList.add(empList[0]);
return;
}
}
// 終了後処理(1度だけ実行される)
global void finish(Database.BatchableContext bc) {
if (this.NoReportEmpList.size() != 0) {
// 未受注・未納品の社員一覧メールを送信
}
}
}
ポイント: Executeメソッド内でメンバ変数を利用する場合はDatabase.Statefulを実装する必要があります。
参考: https://esp-labo.com/db_stateful/#toc4
ガバナ制限の一覧と対処法
| 説明 | 同期制限 | 非同期制限 | 対処法 |
|---|---|---|---|
| SOQLクエリの合計数 | 100 | 200 | ループ内でSOQLを使わない / 1オブジェクトに対する更新ソリューションを減らす(WF+PB+フロー+トリガではなくフローのみ等) / フローの「レコードを取得」もSOQLに含まれる |
| SOQL取得レコードの合計数 | 50,000 | 50,000 | LIMIT句をつける / 必要な分だけ取得 / 50,000件以上はバッチ処理で分割 |
| Database.getQueryLocator取得レコード数 | 10,000 | 10,000 | - |
| SOSLクエリの合計数 | 20 | 20 | VFコントローラの検索では1トランザクションでSOSLを複数書かず、画面へ一度リターンする |
| 1つのSOSLクエリの取得レコード数 | 2,000 | 2,000 | LIMITをつける |
| DMLステートメントの合計数 | 150 | 150 | Insert/Update/DeleteはList(配列)を使い1オブジェクトにつき1回のDMLにする / 再帰処理を防ぐ |
| DML処理レコードの合計数 | 10,000 | 10,000 | 再帰処理を防ぐ / バッチ処理で分割 |
| Apex呼び出しスタックの深さ | 16 | 16 | 再帰処理を防ぐ / 1オブジェクトに対する更新ソリューションを減らす |
| コールアウト(HTTP/WS)の合計数 | 100 | 100 | API通信を分割する / 設計を見直す |
| コールアウトタイムアウト累積値 | 120秒 | 120秒 | API側の処理時間短縮 / 非同期コールバック方式の検討 |
| ヒープサイズ | 6MB | 12MB | 再帰処理を防ぐ / 不要な変数を解放 |
| CPU時間 | 10,000ms | 60,000ms | Mapクラスでネストループを減らす / 時間がかかる処理は非同期で行う |
| トランザクション最大実行時間 | 10分 | 10分 | Mapクラスでネストループを減らす / 非同期処理を活用 |
公式ドキュメント: Apex ガバナ制限
重要: 親子リレーションのサブクエリは追加クエリとしてカウントされます(最上位クエリ数の3倍が制限)。カスタムメタデータ型のSOQLクエリはこの制限の対象外です。
エラーの発生を考慮する箇所
開発・デバッグ時に確認すべきポイント一覧:
| カテゴリ | 確認ポイント |
|---|---|
| カスタム項目の設定 | 桁数、必須、ユニークの制限に引っかかっていないか |
| プロファイル | 項目レベルセキュリティ / オブジェクト権限 / VisualForceへのアクセス権限 |
| レコードタイプ | 正しいレコードタイプが割り当てられているか |
| ユーザの設定 | フローを実行できるユーザか |
| 入力規則 | 入力規則に抵触していないか |
| メールの送信設定 | メール送信が許可されているか |
| 一致ルール・重複ルール | 重複ルールでブロックされていないか |
| CSP信頼済みサイト | VisualForceから外部JSを利用する場合の許可設定 |
| リモートサイト | コールアウト先の許可設定 |
ClassLabのデータ構造(参考)
ClassLabで実際に使用しているオブジェクトの関係を理解するための参考データです。
不動産会社(取引先)
| ID | Name |
|---|---|
| 1 | テストA |
| 2 | テストB |
| 3 | テストC |
入居(MoveIn__c)
| ID | 紹介元不動産 | セイ | メイ |
|---|---|---|---|
| 1 | 1 (テストA) | テスト | てすと |
| 2 | 1 (テストA) | テスト | てすと |
| 3 | 2 (テストB) | テスト | てすと |
関係: 不動産会社 → 入居 → サービス案内 ← サービス(1つの入居に複数のサービス案内が紐づく)
3. 研修課題
課題1: BtoB社用車ディーラーの受注管理システムの作成
目標: カスタムオブジェクト・カスタム項目・入力規則・重複ルールの作成を学ぶ
期限目安: ステップ1終了時 必須
課題2: プロセスビルダーとフローの構築
目標: プロセスビルダーとフローによる自動化を学ぶ
期限目安: ステップ2前半 重要
課題3: Apexトリガの作成
目標: Apexトリガーの基本を学ぶ
期限目安: ステップ2後半 重要
課題4: Apexクラスの作成とテストデータのインポート
目標: トリガーからクラスの呼び出し、テストデータの作成を学ぶ
期限目安: ステップ3前半 実践
課題5: 日報バッチの作成
目標: バッチ処理とスケジュール実行を学ぶ
期限目安: ステップ3中盤 実践
課題6: VisualForceの作成
目標: VisualForceページとApexコントローラの基本を学ぶ
期限目安: ステップ3後半〜ステップ4 応用
課題1の詳細を見る
① オブジェクト・項目の作成
以下のオブジェクトとカスタム項目を作成し、タブをアプリケーションに追加してください。
取引先(Account)※標準オブジェクト
| 項目名 | 型 | 選択値 |
|---|---|---|
| 取引先名 | 文字列 | - |
| 業種 | 選択リスト | 卸売業, 情報通信業, コンサルティング業 |
| 住所 | 住所 | - |
| 電話番号 | 電話 | - |
受注(Order__c)
レコードタイプ: リース / 販売
| 項目名(表示ラベル) | API名 | 詳細 | 型 | 選択値 |
|---|---|---|---|---|
| 取引先 | - | 取引先へのリレーション | 参照型 | - |
| 担当社員 | Staff__c | 社員マスタへのリレーション | 参照型 | - |
| 受注金額 | Amount__c | - | 通貨型 | - |
| ステータス | Status__c | - | 選択リスト | 販売: アポイント, 提案準備中, 見積-提案済み, 受注, 失注 リース: 作成中, 受注 |
② 入力規則の作成
- 予算オブジェクト: 年月が正当でなければエラー(年: 2000〜2099、月: 1〜12 等)
- 受注オブジェクト: ステータスが「受注」の時に担当者が未入力ならエラー
③ 重複ルールの作成
- 予算オブジェクト: 「年」「月」「部署」が一致していると重複として保存不可にする
- 取引先オブジェクト: 電話番号が一致していると重複にする
課題2の詳細を見る
① オブジェクト構成の変更
課題1のオブジェクトに以下を追加・変更してください。
受注(Order__c) に追加する項目:
| 項目名(表示ラベル) | API名 | 型 | 選択値 |
|---|---|---|---|
| 取引先 | - | 主従型(取引先) | ※参照型から変更 |
| 税込受注金額 | TaxInAmount__c | 通貨型 | - |
| 納品ステータス | DeliveryStatus__c | 選択リスト | 未納品(デフォルト), 納品済み |
| 納品日 | DeliveryDate__c | 日付型 | - |
② プロセスビルダーの実装
②-1: 受注の納品ステータスが「納品済み」に変更された時、納品日へ本日の日付を入力する
②-2: 受注の納品ステータスが「納品済み」に変更された時、以下の請求レコードを作成する
③ フローの作成
受注が作成された時、受注日・担当者が変更された時に、下記の条件でデータを検索し、受注の予算項目へ設定する:
- 受注.受注日.年 = 予算の年
- 受注.受注日.月 = 予算の月
- 受注.担当者.部署 = 予算の部署
課題3の詳細を見る
① オブジェクト構成の変更
課題2の請求(Invoice__c)に以下の項目を追加:
| 項目名 | API名 | 型 |
|---|---|---|
| 備考 | Remarks__c | ロングテキストエリア |
② Apexトリガの実装
②-1: 請求レコードが作成された時に、受注の担当社員と同じ部署の社員マスタすべてのメールアドレスに以下の情報を含むメールを送る
メール内容:
- 受注No
- 請求金額
- 請求日
- 入金予定日
- 取引先名
②-2: 請求の備考に、通知を送信したメールアドレスの一覧を入力して保存
・アドレス1
・アドレス2
...
4. Trailhead 推奨学習パス
初級
中級
公式ドキュメント
5. 学習のヒント
- Scratch Orgを活用: 壊しても問題ない環境で自由に実験してください
- エラーメッセージを読む: Salesforceのエラーメッセージは情報量が多いです
- ガバナ制限を意識: 少量データでは問題なくても、大量データで問題が出ることがあります
- 既存コードを参考にする:
force-app/main/default/classes/にある既存のApexクラスを読んでみてください - Claude Codeに聞く: わからないことはClaude Codeに質問すると効率的です
- 課題は段階的に構築: 課題1で作ったオブジェクトに課題2〜6で機能を追加していく流れです。各課題が前の課題の上に成り立っているため、順番に進めてください