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の使い方」も参考に。
また、それ以降は入力チェックです。
Newに入っている値が、画面から入力された値なので、それに対して、チェックを行っています。
また、必要であれば、値を上書きしてあげると「デフォルト値セット」などが出来ます。
エラーメッセージのセットの仕方
入力チェックエラーの場合、メッセージを返す必要がありますよね。
その場合には、「newRecord.Language__c.addError(‘言語は必須です。’);」のように、項目に対してメッセージをセットします。
その後、returnすれば、レコードは保存されずに、入力画面に戻り、セットしたエラーメッセージが表示されるというわけです。