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
New_DeveloperNew_Developer 

Error: Too many code statements: 200001

Hi All,

 

Iam getting the error of too many code statements for my below class. I know its because of the for loops which iterates 40 times and each statement is counted against code statement. But iam not sure of what the workaround would be to overcome this error.

 

global class OCrLine1 implements Schedulable{
global void execute(SchedulableContext SC) {

Set<Id> ids = new Set<Id>();
Map<Id , String> ocrMap = new Map<Id , String>();
Integer ifactor= 2;
Integer iResult;
Integer iSum = 0;
Integer i;
String total;
List<Contact> contacts = new List<Contact>();

List<Contact> cons = [Select id ,Total_Due__c, OCR_Check_Digit__c,OCR_ClientID__c,Billing_Cycle__c ,PayNotIfType__c from Contact where Billing_Cycle__c = '1' AND PayNotIfType__c = 'Statement' AND Number_Of_Sponsored_Children__c!=0];
List<cv__Recurring_Gift_Designation_Relationship__c> rdg = [Select id , cv__Recurring_Gift__r.cv__Contact__c ,cv__Recurring_Gift__r.cv__Recurring_Gift_Status__c, cv__Designation__r.Name from cv__Recurring_Gift_Designation_Relationship__c
where cv__Designation__r.Name != 'Child Sponsorship' AND cv__Recurring_Gift__r.cv__Recurring_Gift_Status__c = 'Active' ];

for(Contact c : cons)
{
ids.add(c.id);
}

for(cv__Recurring_Gift_Designation_Relationship__c rr : rdg)
{
ids.add(rr.cv__Recurring_Gift__r.cv__Contact__c);
}

Map<Id, Double> ChildBalance = new Map<Id,Double>();

for(AggregateResult groupedResults:[SELECT sum(Total_Amount_Due__c) Due , cv__Contact__c from cv__Recurring_Gift__c Where cv__Recurring_Gift_Status__c='Active'
AND cv__Payment_Type__c = 'Check'AND cv__Next_Payment_date__c <= THIS_MONTH AND cv__Contact__c IN :ids Group By cv__Contact__c ]){

ChildBalance.put((String)groupedResults.get('cv__Contact__c'),(Double)groupedResults.get('Due'));
}

for(Contact c : cons){
if(ChildBalance.get(c.id)!=null)
c.Total_Due__c = ChildBalance.get(c.id);
else
c.Total_Due__c = 0;
if(c.Total_Due__c==0)
total = '000000';
else
total = String.valueOf(c.Total_Due__c);
if(total.contains('.'))
total = total.remove('.');

if(total.length()==3)
total = '00'+total+'0';
if(total.Length()==4)
total = '0'+total+'0';
if(total.length()==5)
total = total+'0';
else
total = total;

ocrMap.put(c.id , c.OCR_ClientID__c+'01000000000000000000000000'+total);
for(i=0; i<=40 ; i++){
if(i<40)
iResult = Integer.valueOf(ocrMap.get(c.id).SubString(i,i+1))* iFactor;
if(i==40)
iResult = Integer.valueOf(ocrMap.get(c.id).right(1))* iFactor;

if(iResult>9){
iResult = Integer.valueOf(String.valueOf(iResult).SubString(1,2)) + Integer.valueOf(String.valueOf(iResult).right(1));
}
iSum = iSum+iResult;


if(iFactor == 1)
iFactor = 2;
else
iFactor = 1;
}

iResult = math.mod(iSum,10);

if(iResult == 0)
c.OCR_Check_Digit__c = '0';
else
c.OCR_Check_Digit__c = String.valueOf(10-iResult);

contacts.add(c);
}
if(contacts.size()>0)
update contacts;


}
}

 

Any help is greatly appreciated.

 

Thanks

Deepak Kumar ShyoranDeepak Kumar Shyoran

Hi,

 

Exactly this Exception is due to the iteration of for loop and to avoid this Exception you need to put some limit on you SOQL like

for your Query append limit 10000  modify it according to your need what ever limit suits to you.

 

If this post helps you then hit kudus by clicking on star and accept my post as a solution to your question.

Avidev9Avidev9

You will probably need a Batch Apex to do this operation.

Also you can do some re-structuring of code to reduce the number of lines executed.

 

global class OCrLine1 implements Schedulable {
    global void execute(SchedulableContext SC) {

        Set < Id > ids = new Set < Id > ();
        Map < Id, String > ocrMap = new Map < Id, String > ();
        Integer ifactor = 2;
        Integer iResult;
        Integer iSum = 0;
        Integer i;
        String total;
        List < Contact > contacts = new List < Contact > ();

        List < Contact > cons = [Select id, Total_Due__c, OCR_Check_Digit__c, OCR_ClientID__c, Billing_Cycle__c, PayNotIfType__c from Contact where Billing_Cycle__c = '1'
            AND PayNotIfType__c = 'Statement'
            AND Number_Of_Sponsored_Children__c != 0
        ];
        List < cv__Recurring_Gift_Designation_Relationship__c > rdg = [Select id, cv__Recurring_Gift__r.cv__Contact__c, cv__Recurring_Gift__r.cv__Recurring_Gift_Status__c, cv__Designation__r.Name from cv__Recurring_Gift_Designation_Relationship__c
            where cv__Designation__r.Name != 'Child Sponsorship'
            AND cv__Recurring_Gift__r.cv__Recurring_Gift_Status__c = 'Active'
        ];
/* comment this one to save few iterations for (Contact c: cons) { ids.add(c.id); } */ for (cv__Recurring_Gift_Designation_Relationship__c rr: rdg) { ids.add(rr.cv__Recurring_Gift__r.cv__Contact__c); } Map < Id, Double > ChildBalance = new Map < Id, Double > (); for (AggregateResult groupedResults: [SELECT sum(Total_Amount_Due__c) Due, cv__Contact__c from cv__Recurring_Gift__c Where cv__Recurring_Gift_Status__c = 'Active' AND cv__Payment_Type__c = 'Check' AND cv__Next_Payment_date__c <= THIS_MONTH AND (cv__Contact__c IN: ids OR cv_Contact__c IN:cons)Group By cv__Contact__c ]) { ChildBalance.put((String) groupedResults.get('cv__Contact__c'), (Double) groupedResults.get('Due')); } for (Contact c: cons) { if (ChildBalance.get(c.id) != null) c.Total_Due__c = ChildBalance.get(c.id); else c.Total_Due__c = 0; if (c.Total_Due__c == 0) total = '000000'; else total = String.valueOf(c.Total_Due__c); if (total.contains('.')) total = total.remove('.'); if (total.length() == 3) total = '00' + total + '0'; if (total.Length() == 4) total = '0' + total + '0'; if (total.length() == 5) total = total + '0'; else total = total; ocrMap.put(c.id, c.OCR_ClientID__c + '01000000000000000000000000' + total); for (i = 0; i <= 40; i++) { if (i < 40) iResult = Integer.valueOf(ocrMap.get(c.id).SubString(i, i + 1)) * iFactor; if (i == 40) iResult = Integer.valueOf(ocrMap.get(c.id).right(1)) * iFactor; if (iResult > 9) { iResult = Integer.valueOf(String.valueOf(iResult).SubString(1, 2)) + Integer.valueOf(String.valueOf(iResult).right(1)); } iSum = iSum + iResult; if (iFactor == 1) iFactor = 2; else iFactor = 1; } iResult = math.mod(iSum, 10); if (iResult == 0) c.OCR_Check_Digit__c = '0'; else c.OCR_Check_Digit__c = String.valueOf(10 - iResult); contacts.add(c); } if (contacts.size() > 0) update contacts; } }

 

New_DeveloperNew_Developer

Thanks Avi for the reply. I tried the way you mentioned and also tried to optimise the code as much as possible , but still its giving same error. Not sure how to write batch apex for this. I have seen the limitations of batch apex

 

Total number of executed code statements for Batch Apex and future methods 1,000,000

 

does this mean that this limitation is for each batch of records or for the whole records!! Any guidance is greatly appreciated.

 

Thanks

 

Avidev9Avidev9

Dont worry about the limits!

If you are going to switch to batch it should work. The skleton of the batch method should be something like below

 

 

global class MyBatch implements Database.Batchable<sObject>{
 
   global MyBatch(){
        
   }

   global Database.QueryLocator start(Database.BatchableContext BC){
       //You can place your code here but it should follow the governor limits for EACH batch
//You can have a explicit query here that can pull 50K records(same with other methods)
return Database.getQueryLocator('Your Query');
/*the above query can retrieve 50 million records but they are broken into smaller batches, by default the batch size is 200. These smaller batches are fed to execute method*/ } global void execute(Database.BatchableContext BC,List<Sobject> scope){
//the scope variable gets a max of 200 records from the batch query //Per transaction/ per batch governor limit applies
} global void finish(Database.BatchableContext BC){ //You can place your code here but it should follow the governor limits for EACH batch } }
New_DeveloperNew_Developer

Thanks so much. Will give it a try.