Memos About Salesforce

Salesforceにハマってたこと!

sfdc バッチ 集計関数使えん? 使える方法ある

f:id:jude2016:20190920155743j:plain

こんにちは、管理人の@Salesforce.Zです。


SFDCの導入にあたって、
バッチを使う場合が少なくないか
と思います。
特に月初に
請求書を作ったり、
未払い請求書を管理したり
することがあります。

その時にバッチが要望次第に
登場する場合があります。


さらに集計する必要の時も
ありえます。
今回、集計関数を
バッチ内で使うようにします。
※本来、バッチで集計関数は使用できませんよう。
直接使うと下記のようなエラーがあります。
Aggregate query does not support queryMore(), use LIMIT to restrict the results to a single batch

そこで、バッチでの集計関数の使用について
今回、共有します。




読んだら得ること
★ バッチ内で、集計関数の使用方法

目次

コール順番

 1:バッチクラスで、SearchResultIterableをコールし
 2:SearchResultIterableの中でSearchResultIteratorをコールする

インタフェースIterator

public class SearchResultIterator Implements Iterator<AggregateResult>{
    public AggregateResult [] results {get;set;}
    public Integer index {get;set;}

    public SearchResultIterator(String query){
        this.index = 0;
        results = Database.query(query);
    }

    public boolean hasNext(){
        return results !=null && !results.isEmpty() && index < results.size();
    }

    public AggregateResult next(){
        return results[index++];
    }
}


インタフェースIterable Apex class

public class SearchResultIterable implements Iterable<AggregateResult>{
	private String query;

    public SearchResultIterable(String soql){
    	this.query = soql;
  	}

    public Iterator<AggregateResult> Iterator(){
        return new SearchResultIterator(this.query);
    }
}

バッチクラス

global class SampleAggregateBatch implements Database.Batchable<AggregateResult> {
  // The batch job starts
  global Iterable<AggregateResult> start(Database.BatchableContext bc){
    String query = 'SELECT COUNT(Id) cnt, AccountId FROM Contact GROUP BY AccountId';
    return new SearchResultIterable(query);
  } 
  // The batch job executes and operates on one batch of records
  global void execute(Database.BatchableContext bc, List<sObject> scope){ 
    for(sObject sObj : scope) {
      AggregateResult ar = (AggregateResult)sObj;
      System.debug('>>>> COUNT : ' + ar.get('cnt'));
    }
  }
  // The batch job finishes
  global void finish(Database.BatchableContext bc){ }
}

動作確認

// Run batch apex
SampleAggregateBatch batch = new SampleAggregateBatch();
Database.executebatch(batch, 200);

// Debug log output
11:36:35.0 (14518157)|USER_DEBUG|[11]|DEBUG|>>>> COUNT : 1
11:36:35.0 (14903974)|USER_DEBUG|[11]|DEBUG|>>>> COUNT : 3
11:36:35.0 (15035196)|USER_DEBUG|[11]|DEBUG|>>>> COUNT : 1


終わりに

SFDCのサポートのアドバイスによるともう一つ方法があります。
興味あるかた、リンクへどうぞ!

help.salesforce.com