You need to sign in to do that
Don't have an account?
System.ListException: List index out of bounds:
I've been working on this trigger for days and I'm stuck.
It's supposed to add the number of hours from a new budget to the hours that already exist on a project. The first version worked, but testing was throwing Too many SOQL queries: 101 error.
So I tried to add the lists in and now I'm getting the following message and the trigger doesn't work.
System.DmlException: Insert failed. First exception on row 0; first error:
CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, SumChangeHours: execution of AfterInsert
caused by: System.ListException: List index out of bounds: 0
Trigger.SumChangeHours: line 49, column 1: []
Can someone help me, please?
Version 1
trigger SumChangeHours on pse__Budget__c (after insert, after update ,after delete) { List<pse__Proj__c> listProjToUpdate = new List<pse__Proj__c>(); Set<ID> setProjIds = new Set<ID>(); List<Database.SaveResult> dmlResults; if(trigger.isInsert || trigger.isUpdate){ for(pse__Budget__c B : trigger.new){ if(B.pse__Project__c != null) { setProjIds.add(B.pse__Project__c); } } } if(trigger.isDelete){ for(pse__Budget__c B : trigger.old){ if(B.pse__Project__c != null ){ setProjIds.add(B.pse__Project__c); } } } System.debug('##########setProjIds:'+setProjIds); for(pse__Proj__c proj : [Select Id, Total_Installation_Hours_Sold__c, Total_CAD_Hours_Sold__c, Total_Commissioning_Hours_Sold__c, Total_Network_Engineer_Hours_Sold__c, Total_Programming_Hours_Sold__c, Total_Pro_Services_Hours_Sold__c, (Select Id, pse__Project__c, CAD_Hours__c, Commissioning_Hours__c, Installation_Hours__c, Network_Engineer_Hours__c, Programming_Hours__c, Pro_Services_Hours__c From pse__Budgets__r) From pse__Proj__c Where Id IN :setProjIds]){ proj.Total_CAD_Hours_Sold__c=0; proj.Total_Commissioning_Hours_Sold__c=0; proj.Total_Installation_Hours_Sold__c=0; proj.Total_Network_Engineer_Hours_Sold__c=0; proj.Total_Programming_Hours_Sold__c=0; proj.Total_Pro_Services_Hours_Sold__c=0; for(pse__Budget__c B : proj.pse__Budgets__r){ if( B.CAD_Hours__c != null){ proj.Total_CAD_Hours_Sold__c+= B.CAD_Hours__c;} if(B.Pro_Services_Hours__c != null){ proj.Total_Pro_Services_Hours_Sold__c += B.Pro_Services_Hours__c;} if(B.Programming_Hours__c!= null){ proj.Total_Programming_Hours_Sold__c += B.Programming_Hours__c;} if(B.Installation_Hours__c != null){ proj.Total_Installation_Hours_Sold__c += B.Installation_Hours__c;} if(B.Network_Engineer_Hours__c != null){ proj.Total_Network_Engineer_Hours_Sold__c += B.Network_Engineer_Hours__c;} } listProjToUpdate.add(proj); } //Update Project Records dmlResults = Database.update(listProjToUpdate,false); //Process the Update results. addErrorMsgs(dmlResults); public void addErrorMsgs(List<Database.SaveResult> results){ for(Database.SaveResult result : results){ if( !result.isSuccess() ){ for(Database.Error DbError : result.getErrors()){ // Check if the error is related to trival access level. // Access levels equal or more permissive than the object's default // access level are not allowed. // These sharing records are not required and thus an insert exception is acceptable. if(DbError.getStatusCode() == StatusCode.FIELD_INTEGRITY_EXCEPTION && DbError.getMessage().contains('AccessLevel')){ // Indicates success. continue; }else{ System.debug('##Error:'+DbError.getMessage()); if(trigger.isInsert || trigger.isUpdate) trigger.new[0].addError(DbError.getMessage()); if(trigger.isDelete) trigger.old[0].addError(DbError.getMessage()); } } } } } }
Version 2
trigger SumChangeHours on pse__Budget__c (after insert, after update ,after delete) { List<pse__Proj__c> listProjToUpdate = new List<pse__Proj__c>(); //set of ids for triggered budgets set<ID> setBudgetIds= new set<ID>(); // set of project ids for triggered transaction line items. set<ID> setProjectIds=new set<ID>(); //Map from Project.Id to Project object map<ID,pse__Proj__c> mapProjIdToProject = new map<ID,pse__Proj__c>(); //temp project for updating pse__Proj__c oTmpProject; List<Database.SaveResult> dmlResults; //when budget is added or updated if(trigger.isInsert|| trigger.isUpdate){ //adding budget ids from trigger.new for(pse__Budget__c OB : Trigger.new){ setBudgetIds.add(OB.id); } } //when budget is deleted if(trigger.isDelete){ //adding budget ids from trigger.old for(pse__Budget__c OB : Trigger.old){ setBudgetIds.add(OB.id); } } //making map of projects for updating List<pse__Proj__c> proj = [Select Id, Total_Installation_Hours_Sold__c, Total_CAD_Hours_Sold__c, Total_Commissioning_Hours_Sold__c, Total_Network_Engineer_Hours_Sold__c, Total_Programming_Hours_Sold__c, Total_Pro_Services_Hours_Sold__c, (Select Id, pse__Project__c, CAD_Hours__c, Commissioning_Hours__c, Installation_Hours__c, Network_Engineer_Hours__c, Programming_Hours__c, Pro_Services_Hours__c From pse__Budgets__r) From pse__Proj__c Where Id IN :setProjectIds];{ //clearing out the older values for project's specific fields proj[0].Total_CAD_Hours_Sold__c=0; proj[0].Total_Commissioning_Hours_Sold__c=0; proj[0].Total_Installation_Hours_Sold__c=0; proj[0].Total_Network_Engineer_Hours_Sold__c=0; proj[0].Total_Programming_Hours_Sold__c=0; proj[0].Total_Pro_Services_Hours_Sold__c=0; //adding to map projects mapProjIdToProject.put(proj[0].Id, Proj[0]); //Making set of all related budget ids. for(pse__Budget__c OBH : Proj[0].pse__Budgets__r){ setBudgetIds.add(OBH.id); } //updates project's fields to new value oTmpProject = mapProjIdToProject.get(proj[0].id); for(pse__Budget__c OB : proj[0].pse__Budgets__r){ if(OB.CAD_Hours__c != null){ oTmpProject.Total_CAD_Hours_Sold__c+= OB.CAD_Hours__c;} if(OB.Pro_Services_Hours__c != null){ oTmpProject.Total_Pro_Services_Hours_Sold__c += OB.Pro_Services_Hours__c;} if(OB.Programming_Hours__c!= null){ oTmpProject.Total_Programming_Hours_Sold__c += OB.Programming_Hours__c;} if(OB.Installation_Hours__c != null){ oTmpProject.Total_Installation_Hours_Sold__c += OB.Installation_Hours__c;} if(OB.Network_Engineer_Hours__c != null){ oTmpProject.Total_Network_Engineer_Hours_Sold__c += OB.Network_Engineer_Hours__c;} } } //Update Project Records dmlResults = Database.update(mapProjIdToProject.values(),false); //Process the Update results. addErrorMsgs(dmlResults); public void addErrorMsgs(List<Database.SaveResult> results){ for(Database.SaveResult result : results){ if( !result.isSuccess() ){ for(Database.Error DbError : result.getErrors()){ // Check if the error is related to trival access level. // Access levels equal or more permissive than the object's default // access level are not allowed. // These sharing records are not required and thus an insert exception is acceptable. if(DbError.getStatusCode() == StatusCode.FIELD_INTEGRITY_EXCEPTION && DbError.getMessage().contains('AccessLevel')){ // Indicates success. continue; }else{ System.debug('##Error:'+DbError.getMessage()); if(trigger.isInsert || trigger.isUpdate) trigger.new[0].addError(DbError.getMessage()); if(trigger.isDelete) trigger.old[0].addError(DbError.getMessage()); } } } } } }
Thanks!
Hello Mander,
Always before accessing the list, you must check for whether list is empty.
Consider the following Example:
Before refering to the 0th index of list you must perform a check on whether the list is empty or not. Whenever you try to access records from list first check if its empty or not.
Hope this helps!
First check whether list if empty or not and then proceed-
if(!proj.isEmpty()){
//your logic
}
I don't have any real training in Apex Triggers. I've tried adding the logic that checks to see if the list is empty in a few different spots and I guess I don't know where to put that. Where should that go?