Salesforceの入力チェックは、複数項目の相関チェックや正規表現など、ある程度までなら入力規則でプログラムレスにできます。
しかし、それよりも複雑な場合、たとえば、チェックの際に、関連するレコードの状態を判断するためにSOQL文を発行しないといけないとか、外部のロジックをWebAPIで呼び出すなどは、入力規則だけでは対処できないため、Apexコードを書く必要がありますね。
具体的な手順は、以下の通りです。
Apexトリガで入力チェックを行う手順
入力チェックを行うのは、多くの場合、オブジェクトを保存する直前になりますから、Apexトリガを作成して、insertやupdateの時に、
入力された値をチェックすればよいですよね。
そのため、対象となるオブジェクトにトリガを作成します。
trigger SampleTrigger on Account (after delete, after insert, after undelete, after update, before delete, before insert, before update) {
if(Trigger.isInsert || Trigger.isUpdate){
if(Trigger.isBefore){
SampleTriggerHandler.checkInputVariables(trigger.new, trigger.OldMap);
}
}
}
トリガを定義したら、そのクラスか、そのクラスから呼ばれるクラスで入力のチェックを行います。
ここでのサンプルは、トリガ・ハンドラという別のクラスを呼び出しています。
public class SampleTriggerHandler {
public static void checkInputVariables(List<Account> triggerNew, Map<Id, Account> triggerOldMap){
System.debug('***checkInputVariables Called***');
for(Account newRecord : triggerNew){
//InsertとUpdateのケース
if(triggerOldMap==null){
//insert時
System.debug('***checkInputVariables insert時***');
}else{
Account oldRecord = triggerOldMap.get(newRecord.Id);
//update時
System.debug('***checkInputVariables update時***');
}
//項目チェック
Integer singleErrorCnt = 0;
if(String.isEmpty(newRecord.Language__c)){
singleErrorCnt++;
newRecord.Language__c.addError('言語は必須です。');
}
//デフォルト値セット
if(newRecord.Country__c==null){
newRecord.Country__c = 'Japan';
}
//正規表現でチェック
Boolean regTest= Pattern.matches('^([0-1][0-9]|[2][0-3]):[0-5][0-9]$', newRecord.Jikan__c);
if(!regTest){
singleErrorCnt++;
newRecord.Jikan__c.addError('時間は「HH:MM」の形式で入力してください。');
}
if(singleErrorCnt>0){
return;
}
//マスタ1(Master1__c)からSOQLで検索してデフォルト値をセット
if(newRecord.Some__c!=null){
Master1__c ms1 = [select Id, Name, Master1_Name__c from Master1__c where Id =:newRecord.Some__c limit 1];
newRecord.Some2__c = ms1.Name;
newRecord.Some3__c = ms1.Master1_Name__c;
}
}
}
}
少し、無駄なソースも入っていますが、なるべく汎用的に、コピペで使えるようにと思ってのことです。
解説すると、はじめに「InsertとUpdateのケース」があります。
トリガでは、OldとNewの2つのリストが渡ってきます。リスト形式とMap形式が使えますが、私はよくNewをリストで、OldをMap形式で渡します。
それは、Newをリストの拡張For文のループで回し、それに対応するOldの値をMapでNewのIdをキーに取得するやり方が簡単だからです。
で、Oldがnullであれば、新規作成時(Insert)だと判断できます。
「Salesforceのトリガでのoldとnewの使い方」も参考に。
Salesforceのトリガでのoldとnewの使い方また、それ以降は入力チェックです。
Newに入っている値が、画面から入力された値なので、それに対して、チェックを行っています。
また、必要であれば、値を上書きしてあげると「デフォルト値セット」などが出来ます。
エラーメッセージのセットの仕方
入力チェックエラーの場合、メッセージを返す必要がありますよね。
その場合には、「newRecord.Language__c.addError(‘言語は必須です。’);」のように、項目に対してメッセージをセットします。
その後、returnすれば、レコードは保存されずに、入力画面に戻り、セットしたエラーメッセージが表示されるというわけです。