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
BroncoBoyBroncoBoy 

Batch Apex: Passing Argument into Iterator Constructor

As you can see in my code below I've hard-coded a query in my AggregateResultIterator class and it works great.  However, I'd like to modify the code so that I can pass the query into the main BatchActivityGrouping class, then pass it to the AggregateResultIterable class, then finally pass the query to the AggregateResultIterator constructor which it calls.  The purpose is to give me the ability to pass in the query and execute the BatchActivityGrouping-batch all from another schedulable class that I have.

 

When I try to modify the classes I keep running into "Constructor Not Defined Errors" and am stuck.  Any thoughts on how to do this?  Thanks in advance.

 

CODE:

 

global class BatchActivityGrouping implements Database.Batchable<AggregateResult>

{

    

  global Iterable<AggregateResult> start(Database.BatchableContext info){

 

        return new AggregateResultIterable();

   }

  

   

  global void execute(Database.BatchableContext BC, List<Sobject> scope){

     List<Activity_Grouping__c> lstMoRecordsToProcess = new List<Activity_Grouping__c>();  

     for (Sobject so : scope)  {       

           //iterate through list 

      }        

   }

 

  

  global void finish(Database.BatchableContext BC)

  {

    //send completion email

  }

  

  global class AggregateResultIterable implements Iterable<AggregateResult> {

        global Iterator<AggregateResult> Iterator(){

            return new AggregateResultIterator();

       }             

   }

   

   global class AggregateResultIterator implements Iterator<AggregateResult> {

        AggregateResult [] results {get;set;}

        Integer index {get; set;} 

 

        global AggregateResultIterator() {

            index = 0;

            String query = 'SELECT a.Contact_Id__c, a.Completed_Date__c FROM Accumulated_Activity__c a '

            'WHERE a.Completed_Date__c = LAST_MONTH GROUP BY a.Completed_Date__c';

            results = Database.query(query);            

        } 

 

        global boolean hasNext(){ 

           return results != null && !results.isEmpty() && index < results.size(); 

        }    

 

        global AggregateResult next(){ 

            return results[index++];            

        }       

    }   

}

Best Answer chosen by Admin (Salesforce Developers) 
Neeraj_ChauriyaNeeraj_Chauriya

Hi,

 

Have you tried to create parameterized constructors for the classes?

I hope the below code helps!

 

global class BatchActivityGrouping implements Database.Batchable<AggregateResult>

{

  public String query;  

  global BatchActivityGrouping (String query){

      this.query = query;

  }

  global Iterable<AggregateResult> start(Database.BatchableContext info){

 

        return new AggregateResultIterable(query);

   }

  

   

  global void execute(Database.BatchableContext BC, List<Sobject> scope){

     List<Activity_Grouping__c> lstMoRecordsToProcess = new List<Activity_Grouping__c>();  

     for (Sobject so : scope)  {       

           //iterate through list 

      }        

   }

 

  

  global void finish(Database.BatchableContext BC)

  {

    //send completion email

  }

  

  global class AggregateResultIterable implements Iterable<AggregateResult> {

        public String query;  

        global AggregateResultIterable (String query){

             this.query = query;

         }

        global Iterator<AggregateResult> Iterator(){

            return new AggregateResultIterator(query);

       }             

   }

   

   global class AggregateResultIterator implements Iterator<AggregateResult> {

        AggregateResult [] results {get;set;}

        Integer index {get; set;} 

      

        global AggregateResultIterator(String query) {

            index = 0;

            /*

            String query = 'SELECT a.Contact_Id__c, a.Completed_Date__c FROM Accumulated_Activity__c a '

            'WHERE a.Completed_Date__c = LAST_MONTH GROUP BY a.Completed_Date__c';

            */

            results = Database.query(query);            

        } 

 

        global boolean hasNext(){ 

           return results != null && !results.isEmpty() && index < results.size(); 

        }    

 

        global AggregateResult next(){ 

            return results[index++];            

        }       

    }   

}

 

 

Thanks,

Neeraj

All Answers

Neeraj_ChauriyaNeeraj_Chauriya

Hi,

 

Have you tried to create parameterized constructors for the classes?

I hope the below code helps!

 

global class BatchActivityGrouping implements Database.Batchable<AggregateResult>

{

  public String query;  

  global BatchActivityGrouping (String query){

      this.query = query;

  }

  global Iterable<AggregateResult> start(Database.BatchableContext info){

 

        return new AggregateResultIterable(query);

   }

  

   

  global void execute(Database.BatchableContext BC, List<Sobject> scope){

     List<Activity_Grouping__c> lstMoRecordsToProcess = new List<Activity_Grouping__c>();  

     for (Sobject so : scope)  {       

           //iterate through list 

      }        

   }

 

  

  global void finish(Database.BatchableContext BC)

  {

    //send completion email

  }

  

  global class AggregateResultIterable implements Iterable<AggregateResult> {

        public String query;  

        global AggregateResultIterable (String query){

             this.query = query;

         }

        global Iterator<AggregateResult> Iterator(){

            return new AggregateResultIterator(query);

       }             

   }

   

   global class AggregateResultIterator implements Iterator<AggregateResult> {

        AggregateResult [] results {get;set;}

        Integer index {get; set;} 

      

        global AggregateResultIterator(String query) {

            index = 0;

            /*

            String query = 'SELECT a.Contact_Id__c, a.Completed_Date__c FROM Accumulated_Activity__c a '

            'WHERE a.Completed_Date__c = LAST_MONTH GROUP BY a.Completed_Date__c';

            */

            results = Database.query(query);            

        } 

 

        global boolean hasNext(){ 

           return results != null && !results.isEmpty() && index < results.size(); 

        }    

 

        global AggregateResult next(){ 

            return results[index++];            

        }       

    }   

}

 

 

Thanks,

Neeraj

This was selected as the best answer
BroncoBoyBroncoBoy

That works, thank you!  One question, when you say "this.query",  "this" refers to the ecompansing class, correct?

Neeraj_ChauriyaNeeraj_Chauriya
Correct! this refers to the instance of the class.