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
jadenjaden 

System.Exception: Too many script statements: 200001"

I have a trigger which caused above error during a bulk test by the user. 

 

So I am splitting into a trigger which will call a @future class.

 

I pass the id's for the trigger.old and trigger.new to the class but when I get the account values using the Id's from trigger old; it already has the new value. 

 

Here is the trigger:

trigger ZipAcctChangeShare on Account (after update)  {

 //   AccountShare[] newShares = new AccountShare[0];
    
    set<id> idsn = new set<id>();
    for (Account AcctRecs : trigger.new)
    {
        idsn.add(AcctRecs.Id);
        system.debug('in trigger the new postal code is ' + AcctRecs.BillingPostalCode + ' and the id is ' + AcctRecs.Id);
    }  
    //BUild Set of trigger old id's 
    set<id> idso = new set<id>();
    for (Account AcctRecsold : trigger.old)
    {
        idso.add(AcctRecsold.Id);
        system.debug('in trigger the old postal code is ' + AcctRecsold.BillingPostalCode + ' and the id is ' + AcctRecsold.Id);
    }  

    ProcessZipChangeOnAcct.ChangeShare(idsn, idso);
}

 

Now here is the class I created; I am testing it by commenting out the @future:

 

public class ProcessZipChangeOnAcct {
//@Future
     public static void ChangeShare(Set<Id> idsn, Set<Id> idso) {
 	
    AccountShare[] newShares = new AccountShare[0];

 	list<Account> zipsrecs = [SELECT BillingPostalCode from Account WHERE id in :idso]; 
	set<string> zipso = new set<string>();
	for (Account zr : zipsrecs)
    {
        zipso.add(zr.BillingPostalCode);
     }
	
	List<Territory_Zip_Code__c> tc = new List<Territory_Zip_Code__c>();
	For(List< Territory_Zip_Code__c> t: [SELECT id, GroupId__c, name FROM Territory_Zip_Code__c WHERE Name in :zipso])
                Tc.addall(t);
                
	Map<id,Account> acctold = new Map<id,Account>([SELECT ID, BillingPostalCode from Account WHERE id in :idso]);	   
	system.debug('the acct old map is ' + acctold); 
	
    list<Account> AcctRecs = [SELECT Id, BillingPostalCode FROM Account WHERE ID in :idsn]; 
    system.debug('the New list is ' +AcctRecs); 
    
	//List of account share to be deleted
	List<AccountShare> tbdACCShList = New List<AccountShare>();

	//get list of AccountShares that have an ID matching the Account ID’s in the set
	List<AccountShare> lAS = [Select id, AccountID, UserOrGroupID From AccountShare WHERE AccountID in : idsn];
	
	//system.debug('the list is ' + las); 
	
	For(Account acc :AcctRecs)
	{
	//system.debug('the acc  ' + acc); 
		//If (trigger.oldMap.get(Acc.Id).BillingPostalCode != Acc.BillingPostalCode) {
        If (acctold.get(Acc.id).BillingPostalCode != Acc.BillingPostalCode) {    
           for (Territory_Zip_Code__c tzc: tc) { 
	           	 //if (tzc.name == Trigger.oldMap.get(Acc.Id).BillingPostalCode) 
	           	 if (tzc.name == acctold.get(Acc.Id).BillingPostalCode) 
	           	 {
	           	     for (AccountShare Ashare :lAS) 
	           	     {	
					    // system.debug('the las  list is ' + las); 
					     if(Ashare.accountid == Acc.id && AShare.UserOrGroupId == tzc.GroupID__c) 
					     {
					   	 	//system.debug('inside ashare ');
							tbdACCShList.add(Ashare);
							//system.debug('the to be deleted ' + tbdACCShList );
					     }	
					}   //for (AccountShare Ashare :lAS)
	           	 }	  //(tzc.name == 
           	 }    //For Terr_Zip 
        }   //If trigger old              

    }  //For Account 
      
      
   	//If we have records to be deleted, delete the records    
   	system.debug('the size of the delete list is ' + tbdACCShList.size());       	 
	If(tbdACCShList.size() > 0)
	    Delete tbdACCShList;  
    	
    }
}

 Thank you for any assistace.

Best Answer chosen by Admin (Salesforce Developers) 
jadenjaden

After sleeping on it...

 

I found that the solution was to do just a little more in the trigger and then pass the specific list of Account ID's to be updated to the class and by making it a 'Before Update' trigger. the class has access to the old values:

 

Here is teh trigger now:

 	set<id> idso = new set<id>();
	For(Account acc :trigger.new)
	{
		//Only send id's for those accounts with zip changes
		//system.debug('the new zip is ' + Acc.BillingPostalCode);
		//system.debug('the old zip is ' + trigger.oldMap.get(Acc.Id).BillingPostalCode);
		If (trigger.oldMap.get(Acc.Id).BillingPostalCode != Acc.BillingPostalCode)
		{ 
			idso.add(Acc.Id);
		}
	}

	system.debug('the size of idso is ' + idso.size());
	if(idso.size() > 0)
    	ProcessZipChangeOnAcct.ChangeShare(idso);
 

 By doing the compare of the old zip to the new zip in the trigger; I no longer needed to get to to both old and new in the class.

 

Thanks