You need to sign in to do that
Don't have an account?
Multi dimension list/map notation help needed
Having alittle challenge in building multi dimensional lists and maps for a bulk processing class. This is being designed to handle thousands of records, and given the limitations of 1000 members per list or per map I have chosen to handle by creating multiple lists and maps to address this.
Current code frag I am working on is indicating that I have a List Index out of Bounds:
List<List<OpportunityTeamMember>> otm = new List<List<OpportunityTeamMember>>();
List<Map<string,OpportunityTeamMember>> oppMap = new List<Map<string,OpportunityTeamMember>>();
j = 0;
for(OpportunityTeamMember opt: [Select o.id, o.opportunityid, o.teammemberrole, o.opportunityaccesslevel, o.userid,
o.Opportunity.accountid From OpportunityTeamMember o where o.Opportunity.accountid in :accIds and isDeleted = False
and userid in :userIds])
{j = setOffset(i); // sets the variable j up by 1 for each 1000 records read to move to next list array
opplist[j].add(opt); // adds the record read to the list
i++; // increment the record count
}
// Now, build maps from each list and construct a compound key
for(j=0; j<10; j++) {for(OpportunityTeamMember ox1: opplist[j]) { oppMap[j].put(ox1.userid +
':' + ox1.Opportunity.accountid + ':' + ox1.opportunityid, ox1);}
}
In looking at the debug log it shows that the code fails on the first iteration through the for select loop after reading the record and that the setOffset(i) is returning a zero as expected. The code doesn't make it to the map building phase, but I would assume that there will be a similar issue there as well.
I am assuming that I am not dereferencing the list properly, or that I am not creating it properly, or both. Any assistance would be appreciated.
Does this work for you?
LIMIT 10000] ) { if (math.mod(i, 1000) == 0) { innerMap = new Map<string,OpportunityTeamMember>(); oppMap.add(innerMap); } innerMap.put(otm.userid + ':' + otm.Opportunity.accountid + ':' + otm.opportunityid, otm); i++; }
All Answers
Where is the declaration statement for opplist[]?
I see the declaration for otm - so is this a typo in the example below or a typo in the actual code?
For nested lists, make sure both the outer and inner lists are properly created as well as the entries within.
In the declaration for otm, an empty list is created. You need to create an inner list (via new) and then add it to the outer list in order to reference any element of it. If you don't, the reference of opplist[0] will give you the out of bounds error. Are you doing this in the setOffset method?
You should have code that looks something like this for each group of 1000 records (including the first group):
// Create an inner list and add it to the outer list.
List<OpportunityTeamMember> innerList = new List<OpportunityTeamMember>();
otm.add(innerList);
Hope this helps and makes sense!
Typo when I created the posting. Here is the code:
i=1;
for(OpportunityTeamMember opt: [Select o.id, o.opportunityid,o.teammemberrole,o.opportunityaccesslevel,o.userid,o.Opportunity.accountidFrom OpportunityTeamMember o where o.Opportunity.accountid in :accIds and isDeleted = False and
userid in :userIds]) {j = setOffset(i); // simply set j based on what 1000 records we are working on (0-1000 = 0, 1000-2000=1, etc)
opplist[j].add(opt);
i++; // increment number of records count
} // End of for loop over opportunityteam members
// Now, build maps from each listfor(j=0; j<10; j++) {
for(OpportunityTeamMember ox1: opplist[j]) { oppMap[j].put(ox1.userid + ':' + ox1.Opportunity.accountid + ':' + ox1.opportunityid, ox1);}
}
Based upon your reply, would I need to explicity define each list of 1000 records as in the example below (and do I even need to nest a list definition within another to create the outerlist):
List<OpportunityTeamMember> innerlist1 = new List<OpportunityTeamMember>();
List<OpportunityTeamMember> innerlist2 = new List<OpportunityTeamMember>();
...
...
List<OpportunityTeamMember> innerlistn = new List<OpportunityTeamMember>();
List<List<OpportunityTeamMember>> outerlist = new List<List<OpportunityTeamMember>>();
outerlist.add(innerlist1);
outerlist.add(innerlist2);
Also, how would you dereference innerlist items from the outerlist (i.e. OpportunityTeamMember oppMember = outerlist[0].innerlist[x])? Or in the case of a list of maps - e.g. OpportunityTeamMember oppMapelement = outerlist[0].innerlist.get(keyname))?
Does this work for you?
LIMIT 10000] ) { if (math.mod(i, 1000) == 0) { innerMap = new Map<string,OpportunityTeamMember>(); oppMap.add(innerMap); } innerMap.put(otm.userid + ':' + otm.Opportunity.accountid + ':' + otm.opportunityid, otm); i++; }
Thanks Venkat. Your suggestion was right on target, and your offset solution of Math.Mod was far more elegant than the brute force coding I had done. Regards,
Bill Suycott
VP Internal Systems/Director Enterprise Sales Operations
Metavante Technologies