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
Dchris222Dchris222 

Cannot Modify a Collection While It Is Being Iterated + Questions

Morning,

 

I am running into this error when I run my apex class in the system log: "Cannot Modify a Collection While It Is Being Iterated"  What can I do to resolve this issue?

 

I also have a question regarding my logic for the code. Currently I have two lists: one for all the Opportunites and one for all the Opportunitiy feed items. I want to evaluate them both and assign a value to the Activity Status field in Opportunity based on the critera in the If statements.

 

My question is, how do I make sure when it is evaluating the Opportunity feed that it updates the correct corresponding Opportunity?? Is the Opportunity feed id the same as the original Opportunity Id?? If so what would be the best way to implement that in my code when the critera is met?

 

Here is my code, I am very new to Salesforce development and still learning so help would be greatly appreciated.

 

 

public with sharing class OppPoliceController {

public void Opportunity() {

List<Opportunity> Opptys2 = [SELECT id, LastActivityDate, Activity_Status__c FROM Opportunity WHERE LastActivityDate != NULL ORDER BY LastActivityDate DESC];
List<OpportunityFeed> Opptys = [SELECT id, CreatedDate, (SELECT CreatedDate FROM FeedComments ORDER BY CreatedDate DESC) FROM OpportunityFeed];

for(OpportunityFeed o : Opptys) {

for(Opportunity Op : Opptys2){

datetime LastActivityDate = Op.LastActivityDate; //Last Activity Date in datetimeformat
datetime CreatedDate = o.CreatedDate; //Created Date in datetime format

datetime t = System.now(); // Current date unformated
date d = Date.newInstance(t.year(),t.month(),t.day()); //Current Date Formated

if(LastActivityDate == null || d > LastActivityDate.addDays(14) || d > CreatedDate.addDays(14)) {

string strStatus = 'High';
Opportunity Opp = New Opportunity(Activity_Status__c = strStatus);
Opptys2.add(Opp);
}

else if(d >= LastActivityDate.addDays(7) && d < LastActivityDate.addDays(14)
|| d >= CreatedDate.addDays(7) && d < CreatedDate.addDays(14)) {

string strStatus = 'Medium';
Opportunity Opp = New Opportunity(Activity_Status__c = strStatus);
Opptys2.add(Opp);
}

else if(d < LastActivityDate.addDays(7) || d < CreatedDate.addDays(7)) {

string strStatus = 'Low';
Opportunity Opp = New Opportunity(Activity_Status__c = strStatus);
Opptys2.add(Opp);
}
else {

string strStatus = 'Error';
Opportunity Opp = New Opportunity(Activity_Status__c = strStatus);
Opptys2.add(Opp);
}
}
}

update Opptys2;
}
}

 

 

 

 

 

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
Ritesh AswaneyRitesh Aswaney
Hey on a train so a lil constrained with resources! The conditions look okay. Try and put brackets around the expressions where you are checking an OR of two Ands So if( (a &&b) || (c && d) ) Because without enclosing the individual logical conditions in brackets, the logical operations may not commute the way you intend for them to. Also the no open tasks check for high status is missing right.

All Answers

Ritesh AswaneyRitesh Aswaney

To answer the first part of your question, you are modifying (adding elements) to the Collection Opptys2, whilst iterating over it. This is not permitted in Apex. Look at collections being read only whilst iterating over them, though you can modify existing elements in the collection, but you can't add or remove elements from it.

Dchris222Dchris222

You say I can modify existing elements, I belive that is what I am trying to achieve here. The code will be ran nightly and I want it to update (modify) the value Activity Status. What needs to be changed in order for it to update the Activity Status field, while not running into this error? 

Ritesh AswaneyRitesh Aswaney

 

I've tried to simplify your code and correct a few bits, based on my understanding of what you're trying to do. Not sure you need a separate soql query for feeds, as you're not doing anything with the FeedComments selected in the 2nd query.
public with sharing class OppPoliceController {
 
  public void Opportunity() {
 
     List<Opportunity> Opptys2 = [SELECT id, LastActivityDate, Activity_Status__c, (SELECT id, CreatedDate from Feeds ) FROM Opportunity WHERE LastActivityDate != NULL ORDER BY LastActivityDate DESC];
     
        for(Opportunity Op : Opptys2){
         
        datetime LastActivityDate = Op.LastActivityDate; //Last Activity Date in datetimeformat
        datetime CreatedDate = Op.Feeds[0].CreatedDate;  //Created Date in datetime format 
        
        
        date d = Date.Today();  //Current Date Formated
       
            if(LastActivityDate == null || d > LastActivityDate.addDays(14) || d > CreatedDate.addDays(14)) {
              
              Op.Activity_Status__c = 'High';
               
            }
            
            else if(d >= LastActivityDate.addDays(7) && d < LastActivityDate.addDays(14) 
                     || d >= CreatedDate.addDays(7) && d < CreatedDate.addDays(14)) {
         
                  Op.Activity_Status__c = 'Medium';
               
            }
            
            else if(d < LastActivityDate.addDays(7) || d < CreatedDate.addDays(7)) {
                Op.Activity_Status__c = 'Low';
            }
            else {
            
                Op.Activity_Status__c = 'Error';   
            }
        }    
      
           update Opptys2;
  }     
}

 

Dchris222Dchris222

Thanks! I am now at least seeing the updated fields being populated :smileyvery-happy: .  It seems I was just over complicating things. Now I just need to work on the logic for the if else statement... Have a question, in my If else statements does it make sense for what I am trying to accomplish? In my mind it does, but the results arn't lol.

 

High
If Opportunity LastActivityDate and Opportunity Chatter CreatedDate are greater than 14 days and there are no open tasks set for the opportunity


Med
If Opportunity LastActivityDate and Opportunity Chatter CreatedDate are in between 7 and 14
days

Low
 Anything lower than 7 days for Opportunity LastActivityDate and Opportunity Chatter CreatedDate.

 

 

Ritesh AswaneyRitesh Aswaney
Hey on a train so a lil constrained with resources! The conditions look okay. Try and put brackets around the expressions where you are checking an OR of two Ands So if( (a &&b) || (c && d) ) Because without enclosing the individual logical conditions in brackets, the logical operations may not commute the way you intend for them to. Also the no open tasks check for high status is missing right.
This was selected as the best answer
Ritesh AswaneyRitesh Aswaney
To check for No open tasks, reckon you need to check that NextActivityDate or ActivityDueDate or whatever that field is called on Opportunity. There is one right, which indicates the next activity due date. That's the one you should be checking rather than LastActivityDate, me thinks.
Dchris222Dchris222

Its odd becuase two Opportunities have the same Last activty date and also created date, but yet one is given a Low (which it should be) and the other a medium...I am stumped...

Dchris222Dchris222

Got it! Thank you so much for your help! 

Ritesh AswaneyRitesh Aswaney
Sweet! So which one was it? The brackets or the field? Or both?
Dchris222Dchris222

It was the brackets, but was also bad test data on my part. Turns out I had set one of the opportunbites as closed won and that was screwing things up. Going to change the code to not touch closed Opps and I should be all set.

 

 

This is litterally my first small project. In order to get this into Salesforce I have to create a test class correct? What all should be included in the class?

Dchris222Dchris222

I am now seeing what you mean in reagards to activities. The way Last Activity date works is that it is not updated until an Activity is actually marked completed. This is troublsome due to new opportunities will have open activites and the field will remain blank thus assigning it the wrong Status. I used the Apex explorer and can not find the fields you were refering to. What are my options?