function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
sihmeieossihmeieos 

ユニークなName項目=NULLの時だけ、自動的に値を割り当てたい。

こんにちは。

 

カスタムオブジェクトのName項目をユニークにしたいのですが、必ずしもName項目に値があるとは限らず、悩んでいます。

 

[問題]

・Name項目をユニークにしたい。

・Name項目に必ず値があるわけではない。

[対応策]

・Indexのようなものがあれば、Triggerを使ってInsert時に、Name項目の値がNULLの場合のみIndexから数値を取得し、Name項目の値としたい。

[例]

・Name項目:ドキュメント番号

・古すぎてドキュメント番号の不明なドキュメントがある。この時、連番で良いのでSalesforce側でドキュメント番号を自動的に割り当てたい。

・ただし、Name項目のドキュメント番号はユニークでなければならない。

 

こういった場合に使用できるIndexのようなものは実装されているのでしょうか。

ざっと調べてみた限り無かったのですが…。

他に良い実現方法などあれば、ご指摘いただけると非常に助かります。

 

よろしくお願いします。

 

----------------------

sihmeieos

Best Answer chosen by Admin (Salesforce Developers) 
ikouikou

やるとしたら別オブジェクトで管理テーブルを用意してTriggerで判断、という方法ですかね。

All Answers

ikouikou

やるとしたら別オブジェクトで管理テーブルを用意してTriggerで判断、という方法ですかね。

This was selected as the best answer
sihmeieossihmeieos

ikouさん、レスありがとうございます。

 

私も同じ方法しか思いつきませんでした。今回、以下のように実装してみました。

 

[やりたいこと]

・カスタムオブジェクトAのName項目の値が空白の場合のみ、自動的に連番を割り当てたい。

 

[実装方法]

・連番採番用のカスタムオブジェクトBを作成。

・カスタムオブジェクトBのカスタム項目を作成。自動採番。(ここは、カスタムオブジェクトBのName項目を利用しても良いと思います。)

・カスタムオブジェクトAのInsert前に起動するTriggerを用意。以下のようなロジックを実装。

 

for(CustomObjectA a:Trigger.new){
    if(a.Name == '-'){
	CustomObjectB b = new CustomObjectB();
	insert b;
	CustomObjectB br = [select Id, Name, SequenceNum__c from CustomObjectB where Id = :b.Id];
	a.Name = br.SequenceNum__c;
    }   	
}

 

Name項目が空白であることはありえないため、Name項目='-'の時のみ、Name項目が上書きされるようにしました。

ただ、この方法だと、いちいちカスタムオブジェクトを用意しなければならないのが勿体無いです。

 

ご参考まで。

 

 

 

ikouikou

やるとしたらそんな感じですよね。

 

実装方法とは関係ないのですが、サンプルソースの中で気になるのが1点。

ループ内でinsertやselectを実行してるので、これだとデータローダーとかで大量データを投入した場合にDMLやSOQLのガバナーエラーになると思います。

 

直すとしたらループの前にTrigger.newの中からnameが'-'の数を調べて、その数だけオブジェクトBを先に作ってしまった方がいいかもしれません。

んで、set<ID>か何かにInsertされたオブジェクトBのIDを入れておいて、SOQLのwhereでId in :set変数 みたいにすればSOQLも一度で済みます。

 

まぁ、前提としてオブジェクトAは画面からしか登録しないとか、データローダーで入れる場合もbatchsizeを調整するというのであれば問題なさそうですが。

sihmeieossihmeieos

ikouさん、レスありがとうございます。

 

仰る通り、このままだと大量データのINSERT時にガバナ制限にひっかかりますね。

いつもは、以下のような感じで書いています。

 

 

Set<ID> BIds;
Integer i = 0:
for(CustomObjectA a:Trigger.new){
	if(a.Name=='-'){
		i = i+1;
		CustomObjectB b = new CUstomObject();
		BIds.add(b.Id);
	}
}
CustomObjectB[] br = [select Id, Name,SequenceNum__c from CUstomObjectB where Id in :BIds];
Integer j = 0;
for(CustomObjectA a:Trigger.new){
	if(a.Name=='-'){
		a.Name = br[j].SequenceNum__c;
		j = j+1;
	}
}

 ちょっと汚いコードですが…。

 

ikouさん、いつもありがとうございます。