Translate

2011年5月3日火曜日

レコードの追加更新時にApexトリガで重複チェックしてはじくサンプル

Apexトリガを使用する場合のよくあるパターンの一つに

重複チェックがある。



Salesforceのオンライン研修でも

レコード(見込み顧客)を追加する前に

ユーザにかならず重複チェックを

手動で行うように指導している。



とはいえ

営業担当者はIT弱者は少なくない(失礼)ので

自動でチェックさせてはじくようにしたい。



以下のサンプルは

Force.com開発者コース演習5-2のサンプルコード

である。





// Apex Code 演習5-2
// 応募者(Candidate)の重複防止
// 応募者(Candidate__c)が新規作成・更新直前→重複チェックApexクラス呼び出し
trigger CandidateKeyTrigger on Candidate__c (before insert, before update) {

// トリガ発生元となった応募者レコード群
private Candidate__c[] newCandidates = Trigger.new;
// 重複チェック
CandidateKey.hasCandidateDuplicates(newCandidates);
}


重複チェックなのでトリガとしては

追加更新の「直前」になるのだけど、

当然チェックしたレコードを格納させたくはない。



重複レコードをはじく方法として

以下のようにaddError()を使用する。

これが最大のポイントである。




// Apex Code 演習5-2
// 注意:
// 応募者の「姓」と「電子メールアドレス」を連結した文字列を使って
// 応募者の"名寄せ"を行っている
// 応募者(Candidate__c)オブジェクトの「unique_key__c」には
// 「LOWER(Last_Name__c & Email__c)」が設定されている
public class CandidateKey {

// 重複チェック処理
// 引数: candidates チェック対象の応募者レコード群
public static void hasCandidateDuplicates(Candidate__c[] candidates){

// unique_key__cとCandidate__cレコードのMap
Map<String,Candidate__c> candidateMap =
new Map<String,Candidate__c>();

// 応募者レコードループ
for(Candidate__c candidate:candidates) {
// 電子メールが設定されている場合
if (candidate.email__c != null){
// Map内の応募者レコードと重複している場合
if(candidateMap.containsKey(
candidate.unique_key__c))
// エラーメッセージを追加
candidate.addError(
'Duplicate LastName + Email found '+
'in batch');
else
// 重複がないのでMapへ追加
candidateMap.put(
candidate.unique_key__c,
candidate);
}
}

// Mapにレコードが存在する場合
if (!candidateMap.isEmpty()){
// Mapのレコードと重複するDB上の応募者レコードを取得
for(Candidate__c[] candidatesCheck:
[select unique_key__c
from Candidate__c
where unique_key__c IN
:candidateMap.keySet()]) {

// フェッチレコードループ
for(Candidate__c candidate:candidatesCheck) {
// 応募者レコードID
String currentCandidateId =
candidate.Id;

// Map内の重複レコードのIDが異なる場合
if(candidateMap.containsKey(
candidate.unique_key__c) &&
(currentCandidateId !=
candidateMap.get(
candidate.unique_key__c).Id)) {

// エラーメッセージ追加
candidateMap.get(
candidate.unique_key__c).
addError('Duplicate LastName' +
' + Email found in salesforc' +
'e(id: ' + candidate.id + ')');
}
}
}
}
}
}





このトリガはbeforeなので、

新規追加や更新される前の処理である。

addError()されたレコードは、

Database.insert() or Database.update()で呼び出された場合は

該当レコードは処理されず

画面呼び出しの場合は

addError()で渡された文字列が

画面の所定位置に表示され

こちらもDBは追加・更新されない。

0 件のコメント:

ClaudeをOpenAI O1のように思考させるDifyサンプルを試す

 Difyの「探索」タブにはさまざまなサンプルが載っており、その1つに「Thinking Claude (OpenAI O1 Alternative)」というものがある。   このサンプルがどういうものか、未だに自分でも解けない以下の問題をためしに聞いてみることにした。 『人類の...