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
ckellieckellie 

Error: List Index Out of Bounds - Updating the region

I am writing a trigger where if the region field on the opportunity owner's user record are certain values, to pull those values onto the Region field on the opportunity page, else look to the account owner's user record. I am getting the following error:

 

 

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger OpportunityOwnersAddress2 caused an unexpected exception, contact your administrator: OpportunityOwnersAddress2: execution of BeforeUpdate caused by: System.ListException: List index out of bounds: 0: Trigger.OpportunityOwnersAddress2: line 47, column 13

 

 

This error is at the end of the trigger. I am stared at this ad nausium, and it looks correct to me. But apparently it is not.

Here is the trigger:

 

 

trigger OpportunityOwnersAddress2 on Opportunity (before insert, before update) {

    Set<Id> UserIds = new Set<Id>();
    for (Opportunity oppo: Trigger.new){
    System.debug('**** 0 userids id : '+oppo.ownerid);
    
            UserIds.add(oppo.ownerId);
     System.debug('**** 1 oppo id : '+oppo.id);
     
     }
    
    Map<Id, User> entries = new Map<Id, User>();
    List<user> us = [select Id, User_Address__c, Phone, Fax, Email, Region__c from User where id in :UserIds];
    
    string txt = '';
    txt = us[0].User_Address__c;          
    txt = txt.replaceAll('<br>', '\n');
    System.debug('**** 1 ****txt txt txt txt *********:'+txt );


    string uc = 'US/Canada';
    string euro = 'Europe';
    string Inter = 'InterCon';
    string auc = 'US/Canada';
    string aeuro = 'Europe';
    string aInter = 'InterCon';
        
    for(Opportunity unity: Trigger.new) {
       unity.Opp_Owner_Address__c = txt;
       unity.Opp_Owner_Phone__c = us[0].Phone;
       unity.Opp_Owner_Fax__c = us[0].Fax;
       unity.Opp_Owner_Email__c = us[0].Email;
       
       UserIds.add(unity.ownerId);


    If( us[0].Region__c == uc || us[0].Region__c == euro || us[0].Region__c == Inter ){

       unity.Opportunity_Region__c =us[0].Region__c;
  
      }

    Map<Id, Account> a = new Map<Id, Account>();
    List<Account> ac = [select Id, OwnerId from Account where id =: unity.Accountid];
    List<user> aus = [select Id, Region__c from User where id =: unity.account.ownerid];
    
    If( aus[0].Region__c != auc || aus[0].Region__c != aeuro || aus[0].Region__c != aInter ){

       unity.Opportunity_Region__c = aus[0].Region__c;
    } else {
    unity.Opportunity_Region__c= txt;
    }
  }
}

 

 

How do I solve the error?

 

Thank you,

ckellie

Best Answer chosen by Admin (Salesforce Developers) 
orikkerorikker

your aus list on line 46 is not populated, therefore there is no element [0]. Most likely opportunity is not attached to an account... hope that helps.

All Answers

orikkerorikker

your aus list on line 46 is not populated, therefore there is no element [0]. Most likely opportunity is not attached to an account... hope that helps.

This was selected as the best answer
goabhigogoabhigo

I hope you are getting this error when new record is inserted, am I right?

Because you are using "before insert" Oppoprtunity's(or unity) ID is not retreived.

Are you getting the IDs in the log?

System.debug('**** 0 userids id : '+oppo.ownerid);

 

 

orikkerorikker

System.debug('**** 0 userids id : '+oppo.ownerid);

 

this line will not result an error - owner already has id defaulted to a running user...

ckellieckellie

Thank you for all of your help.

chubsubchubsub

Hey ckellie, I'm having the same issue, how did you populate your aus list?  The red line below in my code is where I have the same kind of error message:System.ListException: List index out of bounds: 0: 

 

list<Opportunity> allopps = [select Id, AccountId, CreatedDate
from Opportunity
where Id in :accids
and CreatedDate in :createdDates
order by AccountId, CreatedDate];
map<Id, Integer> oppid2seqnummap = new map<Id, Integer>();

//reset placeholders: last Account, last Date, current counter
Id thisaccid = allopps[0].AccountId;
Date thisdate = allopps[0].CreatedDate.date();
Integer counter = 0;

 

Thanks!

__

your query returned no results...

 

put this in the log

 

system.debug(allopps.size());

 

if it will be zero;

chubsubchubsub

Thanks for introducing me to the debug logsOlegForce, you are corect, the query returned no results, here is the dubug log:

 

But, how would I correct it?  Should I modify the query, I don't understand why it's not returning any results.

 

07:25:22.082 (82396000)|SOQL_EXECUTE_BEGIN|[76]|Aggregations:0|select Id, AccountId, CreatedDate
            from Opportunity
            where Id in :accids
                and CreatedDate in :createdDates
            order by AccountId, CreatedDate
07:25:22.084 (84863000)|SOQL_EXECUTE_END|[76]|Rows:0
07:25:22.084 (84961000)|EXCEPTION_THROWN|[85]|System.ListException: List index out of bounds: 0
__

could you post the whole thing and explain what you are trying to do? 

chubsubchubsub

Sure, I have a trigger that references a class.  I've accomplished the before insert functionality of the trigger so far and now I'm trying to complete the before Update function.

 

Below explains a bit more about the before insert.

The trigger references a class, and the query is in the class.  What it does is place a number in a field (Daily_Trackingt_Number__c) that picks up from the last opportunity for the day, and will reset every day.  So, if I created an opportunity for Client A, the field would read 1, then I created another opportunity, for Client A, the feid would read 2, then it would reset back to 1 the next day.  Now, I'm trying to figure out how I can reset back to 1 based on the Account as well.  So, if I created an opportunity for Client A, the field would read 1, but then I created another opportunity for a different client, the field would read 1 as well

 

11/15 - Client A

- Opportunity.Daily_Tracking_Number__c = 1

- Opportunity.Daily_Tracking_Number__c = 2

- Opportunity.Daily_Tracking_Number__c = 3

 

11/15 - Client B

- Opportunity.Daily_Tracking_Number__c = 1

- Opportunity.Daily_Tracking_Number__c = 2

- Opportunity.Daily_Tracking_Number__c = 3

 

11/16 - Client A

- Opportunity.Daily_Tracking_Number__c = 1

- Opportunity.Daily_Tracking_Number__c = 2

- Opportunity.Daily_Tracking_Number__c = 3

 

 

Now for the Before Update

My goal is to bulk update the previous opportunities to update the daily tracking number field in sequence by created date and by account, as long as the Opportunity has a date in the SOF_Released_Date__c.  So, let say Client A had 5 Opportunities created within the date range of 5/01/2010 and 6/01/2010.  Once these are updated, I'm trying to have the Daily_Tracking_Number__c field update in sequence by the CreatedDate.  Below is a chart of what I'm trying to explain:

 

Client A:

Opportunity created on 5/1 - Daily_Tracking_Number will = 1

Opportunity created on 5/4 - Daily_Tracking_Number will = 2

Opportunity created on 5/10 (but there is no date in the SOF Releasted Date - Daily_Tracking_Number will = 0

Opportunity created on 5/12 - Daily_Tracking_Number will = 3

 

Below is the code I have so far,class followed by the trigger, but when I try and update an old opportunity, I received the Out of Bounds error message:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
trigger ManageOpportunitiesBeforeUpdate on Opportunity (before insert, before update) { 


    if(Trigger.isInsert && Trigger.isBefore){

        ManageOpportunitiesBeforeUpdate.beforeInsert(Trigger.New); 
    } 
    
    
        if(Trigger.isUpdate && Trigger.isBefore){

        ManageOpportunitiesBeforeUpdate.beforeUpdate(Trigger.New); 
    }   
} //end trigger

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
public with sharing class ManageOpportunitiesBeforeUpdate {

 /*
  Purpose:   - When Opportunity is created
          
          Before Insert
            Update a the Daily_Tracking_Number field with a sequencing number sequenced by Account and Created Date.
            The daily tracking number is then tied to a formulated field update workflow to update the Opportunity name.
            The Opportunity Name will be the first [3 digits of the Account Name] - [CreatedDate] - [Daily_Tracking_Number]
          
          After Update
            If there is a date in the SOF Requested Date field
            Update the Daily Tracking Number field, which will update the name
            
                       
            
  
  
  Current Version:   v1.0
  
  Revision Log:    v1.0 - (JN 11/16/11) Modified this trigger
  
  */


//Tracking Numbers are reset each day, so we'll query for the current number and add to it for the optys
public static void beforeInsert(Opportunity [] optys) {

Set<Id> accId = new Set<Id>();
for(Opportunity o : optys){
{
accId.add(o.AccountId);
}
}

Decimal todaystrackingnumber;
//get the current number - there might not be one, so we'll query into a list

Opportunity [] todaysoptys =  [Select Id, AccountId, Daily_Tracking_Number__c from Opportunity where CreatedDate = TODAY 
AND Daily_Tracking_Number__c != null AND AccountId IN :accId order by Daily_Tracking_Number__c Desc];

//if there is a case, then use the first one, since it is ordered by number
    if (todaysoptys.size() > 0) {
        todaystrackingnumber = todaysoptys[0].Daily_Tracking_Number__c + 1;
    }
    else {
        todaystrackingnumber = 1;
    }

//Now loop through the new cases and allocate a number

for (Opportunity o: optys) {
o.Daily_Tracking_Number__c = todaystrackingnumber;
todaystrackingnumber ++;
}
    
} //end before insert

    public static void beforeUpdate(list<Opportunity> optys)
    {
        set<Id> accids = new set<id>();
        set<Date> createdDates = new set<Date>();
        
        for (Opportunity o : optys)
        {
            if (o.SOF_Requested_Date__c == null)
            {
                accids.add(o.AccountId);
                createdDates.add(o.CreatedDate.date());
            }
        }
        
        //this will include the opps we need to count
        list<Opportunity> allopps = [select Id, AccountId, CreatedDate
            from Opportunity
            where Id in :accids
                and CreatedDate in :createdDates
            order by AccountId, CreatedDate];
        map<Id, Integer> oppid2seqnummap = new map<Id, Integer>();
        
        //reset placeholders: last Account, last Date, current counter
        Id thisaccid = allopps[0].AccountId;
        Date thisdate = allopps[0].CreatedDate.date();
        Integer counter = 0;

        
        //keep track of all sequence numbers
        for (Opportunity o : allopps)
        {
            
            //same account as the last one?
            if (thisaccid == o.AccountID)
            {
                //same date as the last one?
                if (thisdate == o.CreatedDate.date())
                {
                    counter++;
                }
                else //new date
                {
                    counter = 1;
                }
            }
            else //new account
            {
                counter = 1;
            }
            
            //store counter for this Opp
            oppid2seqnummap.put(o.Id, counter);
            
            //reset to compare to next Opp
            thisdate = o.CreatedDate.date();
            thisaccid = o.AccountId;
        }
        
        //now go back through passed Opp list
        for (Opportunity o :optys)
        {
            Integer seqnum = oppid2seqnummap.get(o.Id);
//TODO: populate Name field or store seq num somewhere

o.Daily_Tracking_Number__c = seqnum;



        }
        
    } //end before update
    
    
} //end class
__

line 70... o.createdDate.date() ? Does it let you compile? 

chubsubchubsub

No, it didn't compile any results in the debug log. I've since then updated lines 75 to 85 and the error message doesn't appear now, but it also doesn't work either. Below is my updated code, but it updates the daily tracking number to null every time before update: Thanks, i like that debug log, can I see that log in the Force.com IDE?

 

     //this will include the opps we need to count
        Id thisaccid;
        Date thisdate;
        list<Opportunity> allopps = [select Id, AccountId, CreatedDate
            from Opportunity
            where Id in :accids
                and CreatedDate in :createdDates 
            order by AccountId, CreatedDate];
        map<Id, Integer> oppid2seqnummap = new map<Id, Integer>();
        
        //check the size of the list before getting the value

        if(allopps.size()>0){
                 thisaccid = allopps[0].AccountId;
                 thisdate = allopps[0].CreatedDate.date();
                    }
        Integer counter = 0;

chubsubchubsub

I also correct this the query:

 

 list<Opportunity> allopps = [select Id, AccountId, CreatedDate
            from Opportunity
            where Id in :accids
                and CreatedDate in :createdDates 
            order by AccountId, CreatedDate];

 

 

 

To:

 list<Opportunity> allopps = [select Id, AccountId, CreatedDate
            from Opportunity
            where AccountId in :accids
                and CreatedDate in :createdDates 
            order by AccountId, CreatedDate];

__

I don't get it... how does it let you save with this ?   createdDates.add(o.CreatedDate.date());  there is no such function on the date... also do system.debug ( createdDates); to see what's in there... debug log can be accessed from ide too if you run tests there... or you can simply execute annonymous something along the lines 

 

opportunity opp = new Opportunity (Name = 'test', closeDate = system.today(), stage = 'closed');

insert opp;

 

make sure you put stage that you have in your org or any other required fields

chubsubchubsub

I'm really liking this execute anonymous, I entered the following code and the execution was successful.

 

public static void beforeUpdate(list<Opportunity> optys)
{
set<Id> accids = new set<id>();
set<Date> createdDates = new set<Date>();

for (Opportunity o : optys)
{
if (o.SOF_Requested_Date__c == null)
{
accids.add(o.AccountId);
createdDates.add(o.CreatedDate.date());
}
}

Id thisaccid;
Date thisdate;
list<Opportunity> allopps = [select Id, AccountId, CreatedDate
from Opportunity
where AccountId in :accids
and CreatedDate in :createdDates
order by AccountId, CreatedDate];
}

chubsubchubsub

Here are some other updates I made:

 

Line 124:      o.Daily_Tracking_Number__c = counter;

 

Line 85:  Integer counter = 1;

 

 

It will still let me save it, but it will always update the daily tracking number to the number I set in Line 85, which is one now.

 

__

for the last time I am saying... o.CreatedDate.date()  - is strange. there is no such method for Date... not sure how you save the trigger. 

 

opportunity o = new opportunity (closedate = system.today());

system.debug (o.closedate.date());

 

Compile error at line 2 column 15

Method does not exist or incorrect signature: [Date].date()