※逆もありますが
ということで強引に作ってみた。
A.設定
・取引先の親取引先を使っています。
・実行する際にはフラグを利用しています。
>チェックして保存したら実行
・Database.Batchableを利用して大量データにも対応しています。
・先祖のIDを数式で持たせ、その項目に対してLikeで検索して反映対象を取得しています。
ParentId & Parent.ParentId & Parent.Parent.ParentId ・・・・.ParentId・・・これはひどいww
これが20個ぐらい続きます。
ガチでやろうとすると、子を取得して、子を参照する孫を取得して孫を参照(以下略
となるのですが、面倒なので今回はこのようにしています。
B.SFDC側の設定
取引先に
1.実行用のフラグ(batchActionFlg)
2.さきほどの先祖のIDを連結した数式(pID)
をカスタム項目として定義
C.Apex
面倒なので、そのままソースを貼ります。
AccountTrigger.trigger
trigger AccountTrigger on Account (Before update) { AccountUpdate aupObj = new AccountUpdate(); for (Account acc : Trigger.new) { aupObj.execute(acc); } }AccountUpdate.cls
/** * バッチ呼び出しクラス * 実行判定を行う。 * */ public class AccountUpdate { public void execute(Account acc) { System.debug('■■■■■■AccountUpdate■■■■■■'); if (acc.batchActionFlg__c) { acc.batchActionFlg__c = false; AccountSyncBatch job = new AccountSyncBatch(acc); ID batchprocessid = Database.executeBatch(job); } } }AccountSyncBatch.cls
/** * バッチ * 更新対象の取引先を取得し、更新する。 * 親の種別(Type),評価(Rating)を子に反映させます。 */ global class AccountSyncBatch implements Database.Batchable{ // 更新した親 Account parentObj = null; // コンストラクタ public AccountSyncBatch(Account p) { System.debug('■■■■■■AccountSyncBatch コンストラクタ■■■■■■'); this.parentObj = p; } global database.querylocator start(Database.BatchableContext bc){ System.debug('■■■■■■AccountSyncBatch start■■■■■■'); System.debug('□対象のObj start :' + parentObj); System.debug('■■検索SOQL :' + 'select Id from Account where pID__c Like \'%' + String.valueOf(parentObj.Id).substring(0,15) + '%\''); // 親IDが含まれる 数式は15桁IDのためIDをStringにキャストして15桁を切り出し検索条件とする。 return Database.getQueryLocator('select Id from Account where pID__c Like \'%' + String.valueOf(parentObj.Id).substring(0,15) + '%\''); } global void execute(Database.BatchableContext bc, SObject[] objects){ System.debug('■■■■■■AccountSyncBatch execute■■■■■■'); System.debug('□対象のObj execute :' + parentObj); Account[] accns = new Account[]{}; for(SObject s : objects){ Account a = (Account)s; a.Rating = parentObj.Rating; // 評価をセット a.Type = parentObj.Type; // 種別をセット accns.add(a); System.debug('■ update entity:' + a); } system.debug('□□□□□□iterator done.□□□□□□ '); update accns; } global void finish(Database.BatchableContext bc){ system.debug('□□□□□□all done.□□□□□□ '); } }
これで、batchActionFlgをTrueにして保存すれば動きます。
テストメソッドとか、データローダでドカンと保存したらどうなるのよ!とかは考慮してません。
長くなりました。
もっといい実装方法があったらコメント頂けると幸いです。