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
N _RodN _Rod 

Trigger fails when updating with data loader. List index out of bounds.

Hi,

 

The trigger below was created to update all records on the Opportunity when Field_1__c on Object__c is updated.  The trigger works fine when updates are done on the detail page but fails when updating more than 1value using data loader.  I receive the error:  List index out of bounds.  Any help would be greatly appreciated.  Code copied below.

 

Thank you,

 

trigger EstimatedUpdateOnOpp on Estimated_Capital_Adder__c (before update)
{


     list<Opportunity> listUpdate = new list<Opportunity>();
     list<Opportunity> listOppUpdate = new list<Opportunity>();
     Integer j = 0;
     Integer i = 0;

     for(Object__c obj : Trigger.new)
     {
         if (trigger.new[j].Field_1__c != trigger.old[j].Field_1__c)
         {
            set<string> setI = new set<string>();
            set<Decimal> setM = new set<Decimal>();
            set<string> setP = new set<string>();

            

                    setI.add(obj.Field_I__c);
             setM.add(obj.Field_M__c);
             setP.add(obj.Field_P__c);

         
             listOppUpdate = [SELECT id,
                                     Field_I_2__c,
                                     Field_M_2__c,
                                     Field_P_2__c,
                                     Field_E__c,
                                     StageName
                               FROM Opportunity
                              WHERE Field_I_2__c IN :setI
                                AND Field_M_2__c IN :setM
                                AND Field_P_2__c IN :setP
                                AND (StageName != 'Won' AND StageName != 'Lost' AND StageName != 'Terminated')
                                AND Field_Co__c = 'Prod'];
            
            

        
            for(Opportunity opp : listOppUpdate)
            {
      
                Opportunity Updates = new Opportunity (Id = listOppUpdate[i].Id,
                                                       Field_E__c = trigger.new[j].Field_1__c
                                                       );
                listUpdate.add(Updates);
            i++;         
            } // for(Opportunity opp : listOppUpdate)
            
           update listUpdate;    
           system.debug('listUpdate:  '+listUpdate);
           
           
                          
         }
             
    j++;
     }

}

 

Best Answer chosen by Admin (Salesforce Developers) 
MoggyMoggy

was late yesterday sorry,

 

when I get it right , you browse through Trigger ( j )

and update every oppportunity if the field is  !=

with

Opportunity (Id = listOppUpdate[ i ].Id,  Field_E__c = trigger.new[ j ].Field_1__c );

within the loop counting I++

 

but once you are through that loop it will do the first

update listUpdate;  

 

NOW adding j++

and again you running throught

if (trigger.new[ j ].Field_1__c != trigger.old[ j ].Field_1__c)

 

again you try to update 

Opportunity (Id = listOppUpdate[ i ].Id,  Field_E__c = trigger.new[ j ].Field_1__c );

 

But this time i already exceeds the index , because you didn't set it back to 0

it is still at the value where it left the first loop

 

I would suggest to try 

//

// rest of your code before

//

 for(Opportunity opp : listOppUpdate)
            {
      
                Opportunity Updates = new Opportunity (Id = listOppUpdate[i].Id,
                                                       Field_E__c = trigger.new[j].Field_1__c
                                                       );
                listUpdate.add(Updates);
            i++;         
            } // for(Opportunity opp : listOppUpdate)
            
           update listUpdate;    
           system.debug('listUpdate:  '+listUpdate);

 

           i = 0; // set i back to zero to be able to cope with the new index count on the second run through the loop

          }
             
    j++;
 }

 

// rest of your code after

 

 

the other point to pay attention with the dataloader is, if it is an upsert and within all the updates is all of the sudden an insert

you won't have any trigger.old[j].Field_1__c), but for the moment try the I back to 0

All Answers

MoggyMoggy

the only question here to check is, Do you get the same amount of records in

listOppUpdate = [SELECT id,
Field_I_2__c,
Field_M_2__c,
Field_P_2__c,
Field_E__c,
StageName
FROM Opportunity
WHERE Field_I_2__c IN :setI
AND Field_M_2__c IN :setM
AND Field_P_2__c IN :setP
AND (StageName != 'Won' AND StageName != 'Lost' AND StageName != 'Terminated')
AND Field_Co__c = 'Prod'];

 

as you try to update with the use of the variable counter i or j in

Opportunity Updates = new Opportunity (Id = listOppUpdate[i].Id,
Field_E__c = trigger.new[j].Field_1__c

 

because you get a fixed amount of records through your select query but you loop through using i++ and j++

so you might use a sytem debug or an comparism if i <= listOppUpdate.size(), if you know what i mean

 

Lets say the above SELECT retrieves 10 records put into the list but your i is at 11 when it comes to your update, then your are out of bounds

N _RodN _Rod

Thanks for responding!

 

Could you explain to me what you mean but the  "if i <= listOppUpdate.size()" and how that would help.

 

I have been using debug to view the size and contents of listOppUpdate.  The lists are correct while looping but when it reaches the second update on the list, the code seems to fail at "Id = listOppUpdate[i].Id". 

 

For example, I update 2 Field_1__c  fields using data loader.  All of the set values are correct and the list pulls in 2 records which is correct (using a small sample right now).  listUpdate also has the correct values for the first Field_1__c update.  When the second Field_1__c is updated everything I listed before is correct until it reaches the listUpdate.  That is where it fails.

MoggyMoggy

was late yesterday sorry,

 

when I get it right , you browse through Trigger ( j )

and update every oppportunity if the field is  !=

with

Opportunity (Id = listOppUpdate[ i ].Id,  Field_E__c = trigger.new[ j ].Field_1__c );

within the loop counting I++

 

but once you are through that loop it will do the first

update listUpdate;  

 

NOW adding j++

and again you running throught

if (trigger.new[ j ].Field_1__c != trigger.old[ j ].Field_1__c)

 

again you try to update 

Opportunity (Id = listOppUpdate[ i ].Id,  Field_E__c = trigger.new[ j ].Field_1__c );

 

But this time i already exceeds the index , because you didn't set it back to 0

it is still at the value where it left the first loop

 

I would suggest to try 

//

// rest of your code before

//

 for(Opportunity opp : listOppUpdate)
            {
      
                Opportunity Updates = new Opportunity (Id = listOppUpdate[i].Id,
                                                       Field_E__c = trigger.new[j].Field_1__c
                                                       );
                listUpdate.add(Updates);
            i++;         
            } // for(Opportunity opp : listOppUpdate)
            
           update listUpdate;    
           system.debug('listUpdate:  '+listUpdate);

 

           i = 0; // set i back to zero to be able to cope with the new index count on the second run through the loop

          }
             
    j++;
 }

 

// rest of your code after

 

 

the other point to pay attention with the dataloader is, if it is an upsert and within all the updates is all of the sudden an insert

you won't have any trigger.old[j].Field_1__c), but for the moment try the I back to 0

This was selected as the best answer
N _RodN _Rod

Resetting i=0 worked!  Thank you very much!

 

Pretty disappointed I spent so much time when the solution was so simple.