執筆者:Salesforce 開発者
背景と応用シナリオ
Salesforce 環境において、データの品質はビジネスの成功を左右する極めて重要な要素です。特に、顧客データが中核をなす CRM プラットフォームでは、データの重複が多くの問題を引き起こします。例えば、同じ顧客に対して複数の営業担当者がアプローチしてしまったり、マーケティングキャンペーンで同一人物に複数のメールを送信してしまったり、不正確なレポートによって経営判断を誤らせたりする可能性があります。これらの問題を未然に防ぎ、データの整合性を維持するための強力な機能が Salesforce の Duplicate Management (重複管理) です。
標準機能として提供される重複管理は、ユーザがレコードを作成・編集する際にリアルタイムで重複を検知し、警告やブロックを行うことができます。しかし、実際のビジネスシナリオはより複雑です。例えば、外部システムとのデータ連携、一括でのデータ移行、あるいは特定のビジネスロジックに基づいて重複ルールを一時的にバイパスしたい場合など、標準のユーザインターフェースだけでは対応しきれないケースが多々あります。このような場面で、私たち Salesforce 開発者の出番となります。Apex を使用することで、重複管理の動作をプログラムレベルで制御し、より柔軟で堅牢なデータ品質管理ソリューションを構築することが可能になります。
本記事では、Salesforce 開発者の視点から、標準の重複管理機能の仕組みを解説し、さらに Apex を用いて重複ルールを能動的に操作する方法について、具体的なコード例を交えながら詳しく解説していきます。
原理説明
Salesforce の重複管理は、主に2つのコンポーネントで構成されています。これらの仕組みを理解することが、開発者として重複管理を使いこなすための第一歩です。
1. Matching Rule (一致ルール)
Matching Rule (一致ルール) は、「どのようなレコードを重複とみなすか」を定義するルールです。例えば、「取引先責任者の『姓』と『メールアドレス』が完全に一致する場合」や、「取引先の『会社名』が類似していて(Fuzzy Match)、かつ『市区郡』が一致する場合」といった条件を設定します。標準でいくつかのオブジェクト(取引先、取引先責任者、リードなど)に対して標準一致ルールが提供されていますが、ビジネス要件に合わせてカスタムの一致ルールを作成することも可能です。開発者としては、どの項目が重複のキーとなっているかを正確に把握することが、後述する Apex での制御において重要になります。
2. Duplicate Rule (重複ルール)
Duplicate Rule (重複ルール) は、一致ルールによって重複が検知された場合に、「どのようなアクションを実行するか」を定義するルールです。設定可能なアクションは以下の通りです。
- Allow (許可): ユーザに警告メッセージを表示し、重複レポートを作成しますが、レコードの保存は許可します。
- Block (ブロック): ユーザにエラーメッセージを表示し、レコードの保存をブロックします。
また、重複ルールはオブジェクト内(例:リード vs リード)だけでなく、オブジェクト間(例:作成しようとしている取引先責任者 vs 既存のリード)で重複をチェックすることも可能です。このルールがどのタイミングで、どのように動作するかを理解することが、DML (Data Manipulation Language) 操作の成功・失敗を左右します。
開発者にとっての重要なポイント:DMLOptions
開発者が Apex を用いてレコードの挿入や更新を行う際、デフォルトでは有効化されている重複ルールがトリガーされます。もし重複ルールのアクションが「ブロック」に設定されている場合、重複が検知されると DML 操作は失敗し、例外が発生します。これをプログラムで制御するために用意されているのが `Database.DMLOptions` クラスです。このクラス内の `DuplicateRuleHeader` を使用することで、DML 操作単位で重複ルールの動作を細かく指定できます。
具体的には、以下のような制御が可能です。
- 重複ルールを一時的にバイパスしてレコードを保存する。
- 重複が検知された場合でもエラーとせず、重複情報を結果として受け取る。
- 特定のユーザとして重複ルールを実行する。
この仕組みを利用することで、データ移行ツールや API 連携処理において、重複の可能性を認識しつつも処理を続行し、後続のバッチ処理で重複レコードをマージする、といった高度な実装が可能になります。
サンプルコード
ここでは、取引先責任者 (Contact) オブジェクトに「メールアドレスが完全に一致する場合にブロックする」という重複ルールが設定されていると仮定します。このルールを Apex でバイパスしつつ、重複情報を取得するサンプルコードを示します。このコードは、重複の可能性があるデータを挿入する必要があるが、その事実をログに記録しておきたい、というインテグレーションのシナリオで特に有効です。
このサンプルでは、`Database.insert()` メソッドと `Database.DMLOptions` を使用します。
// salesforce-developer として、重複管理をApexで制御するサンプル
// すでに 'test.duplicate@example.com' というメールアドレスを持つ取引先責任者が存在すると仮定
// 1. 重複を引き起こす可能性のある新しい取引先責任者レコードを作成
Contact newContact = new Contact(
LastName = '山田',
FirstName = '太郎',
Email = 'test.duplicate@example.com'
);
// 2. DML操作のオプションを制御するための DMLOptions オブジェクトを作成
Database.DMLOptions dmlOptions = new Database.DMLOptions();
// 3. DuplicateRuleHeader を設定
// allowSave を true に設定することで、重複ルールが「ブロック」に設定されていても、
// レコードの保存を許可します。
dmlOptions.DuplicateRuleHeader.allowSave = true;
// includeRecordDetails を true に設定すると、重複結果にレコードの詳細情報(項目値など)が含まれます。
dmlOptions.DuplicateRuleHeader.includeRecordDetails = true;
// runAsCurrentUser を true に設定すると、現在のユーザの権限で重複ルールが実行されます。
// これがデフォルトの動作です。
dmlOptions.DuplicateRuleHeader.runAsCurrentUser = true;
// 4. DMLOptions を指定して Database.insert() を実行
// 3番目のパラメータ `false` は、allOrNone を示し、一部のレコードが失敗しても
// 他のレコードの処理を続行することを意味します。(この例では1レコードのみですが)
Database.SaveResult sr = Database.insert(newContact, dmlOptions);
// 5. 結果を検証
if (sr.isSuccess()) {
System.debug('取引先責任者の作成に成功しました。ID: ' + sr.getId());
} else {
// isSuccess() が false を返す場合でも、allowSave = true のためレコードは保存されている可能性がある。
// エラー内容を精査する必要がある。
for (Database.Error err : sr.getErrors()) {
System.debug('エラーが発生しました: ' + err.getMessage());
}
}
// 6. 重複結果の確認
// isSuccess() の如何に関わらず、重複が検知された場合は getDuplicateResult() で情報を取得できる。
if (sr.getDuplicateResult() != null) {
System.debug('重複が検知されました!');
// DuplicateResult オブジェクトから情報を取得
Database.DuplicateResult dr = sr.getDuplicateResult();
// どの重複ルールに一致したか
System.debug('一致した重複ルール: ' + dr.getDuplicateRule());
// 一致したレコードの情報 (MatchResult のリスト)
for (Database.MatchResult mResult : dr.getMatchResults()) {
System.debug('--- 一致結果 ---');
// どのマッチングルールに一致したか
System.debug(' 一致したマッチングルール: ' + mResult.getMatchRule());
// 実際に一致したレコード (MatchRecord のリスト)
for (Database.MatchRecord mRecord : mResult.getMatchRecords()) {
System.debug(' 一致したレコードID: ' + mRecord.getRecord().Id);
// includeRecordDetails = true の場合に、レコードの詳細情報を取得できる
Contact matchedContact = (Contact)mRecord.getRecord();
System.debug(' 一致したレコードのメールアドレス: ' + matchedContact.Email);
}
}
}
注意事項
重複管理機能を Apex で利用する際には、いくつかの重要な点に注意する必要があります。
権限 (Permissions)
重複ルールをバイパスする、あるいは重複ジョブを実行するには、ユーザに適切な権限が必要です。プロファイルや権限セットで「重複ルールを編集」や「重複ルールを有効化」などの権限を確認してください。Apex コードが実行されるコンテキスト(ユーザコンテキストかシステムコンテキストか)によって、適用される権限が異なる場合があるため、注意が必要です。
API 制限 (API Limits) とパフォーマンス
複雑な一致ルール(特に複数の項目に対する Fuzzy Match を含むルール)は、レコードの保存時にパフォーマンスに影響を与える可能性があります。多数のレコードを一度に処理するバッチ Apex などで DML 操作を行う際は、重複ルールの評価が処理時間全体に与える影響を考慮する必要があります。大量のデータロードを行う際は、一時的に重複ルールを無効化し、ロード後に重複ジョブを実行するアプローチも有効です。
エラー処理 (Error Handling)
サンプルコードで示したように、`Database.DMLOptions` を使用する場合は、必ず `Database.SaveResult` を用いて結果を詳細に確認する必要があります。特に `allowSave = true` を設定した場合、`isSuccess()` が `true` を返しても、`getDuplicateResult()` には重複情報が含まれている可能性があります。この情報を適切にログに記録したり、後続処理に渡したりするロジックを実装することが、堅牢なシステムを構築する上で不可欠です。
一括処理 (Bulkification)
Apex のベストプラクティスとして、DML 操作は常に一括処理を念頭に置いて実装する必要があります。`Database.insert(recordList, dmlOptions)` のように、リスト形式でレコードを渡し、ループ内で DML を実行しないようにしてください。DMLOptions はリスト全体に適用されます。
まとめとベストプラクティス
Salesforce の重複管理は、データ品質を維持するための非常に強力なツールです。開発者としてその仕組みを深く理解し、`Apex` と `DMLOptions` を活用することで、標準機能だけでは実現できない柔軟なデータ管理プロセスを構築できます。
以下に、重複管理に関するベストプラクティスをまとめます。
- 分析から始める: 重複ルールを作成する前に、まず既存のデータを分析し、どのようなパターンで重複が発生しているかを把握します。データ分析に基づいて効果的な一致ルールを設計することが重要です。
- 標準機能を最大限に活用する: カスタムコードを記述する前に、まずは標準の一致ルールと重複ルールで要件を満たせないか検討します。宣言的な設定は、メンテナンス性に優れています。
- ユーザへの明確なガイダンス: 重複が検知された際に表示されるアラートメッセージをカスタマイズし、ユーザが次に何をすべきか(例:「既存のレコードを確認してください」「レコードをマージしてください」など)を明確に伝えます。
- プログラム制御は慎重に: Apex を用いて重複ルールをバイパスする機能は強力ですが、乱用するとデータ品質の低下を招きます。データ移行や特定のシステム連携など、目的が明確な場合にのみ使用し、なぜバイパスしたのかを必ずログに残すなどの対策を講じます。
- 定期的なクレンジング: 重複管理は新たな重複の発生を防ぐだけでなく、既存の重複データをクリーンアップするためにも使用できます。定期的に重複ジョブを実行し、データの棚卸しを行うことを推奨します。
優れた Salesforce 開発者であるためには、プラットフォームの標準機能を深く理解し、その上でコードを用いて機能を拡張する能力が求められます。重複管理は、そのスキルを証明するための絶好のテーマと言えるでしょう。本記事が、皆さんのデータ品質向上への取り組みの一助となれば幸いです。
コメント
コメントを投稿