1

Received Error below when bulk inserting lead records into system

LeadCompany: execution of BeforeInsert caused by: System.ListException: List index out of bounds: 4 Trigger.LeadCompany: line 12, column 1

Trigger

trigger LeadCompany on Lead (before insert ) {
   List<String> Accounts = new List<String>();
    for(Lead ld: trigger.new){
        Accounts.add(ld.company);
    }
    List <Account> acctlist = [select Name from account where Name in :Accounts];
    if (acctlist.size() > 0 ){
        for(Integer i = 0; i < Trigger.new.size(); i++)
        {
            if (Trigger.new[i].Company != null)
            {
                trigger.new[i].Company__c=acctlist[i].ID;
            }
    else
    {
            trigger.new[i].Company__c = null;
    }
        }  
    }
}
3

The problem is that the size of acctlist may be less than the size of the trigger.new collection. Hence the index can be out of bounds.

Instead of directly accessing trigger.new[i] you could build up a Map rather than a List of account names. Then you can lookup the corresponding Lead record using the map rather than the index.

Also, your SOQL select fields aren't selecting the Account Id.

As @superfell commented, unless you specify an order by clause in the SOQL query the Accounts could come back in any order. The order is highly unlikely to match the Lead order for Accounts.size() > 1.

Try something like the following:

trigger LeadCompany on Lead (before insert ) {
    Map<string, List <Lead>> accountNamesToLeadsMap = new Map<string, List <Lead>>();

    for(Lead ld : trigger.new){
        // It is possible that multiple leads will have the same account name in a transaction
        if(!String.isBlank(ld.company)) {
            List<Lead> leadsForCompany = null;
            if(accountNamesToLeadsMap.containsKey(ld.company)) {
                leadsForCompany = accountNamesToLeadsMap.get(ld.company);
            } else {
                leadsForCompany = new List<Lead>();
                accountNamesToLeadsMap.put(ld.company, leadsForCompany);
            }
            leadsForCompany.add(ld);
        } else {
            ld.Company__c = null;
        }
    }

    List <Account> acctlist = [select Id, Name from Account where Name in :accountNamesToLeadsMap.keySet()];

    for(Account acc : acctlist) {

        // TODO: Consider doing a containsKey(acc.Name) check on accountNamesToLeadsMap
        List<Lead> leadsForCompany = accountNamesToLeadsMap.get(acc.Name);
        for(Lead ld : leadsForCompany) {
            ld.Company__c = acc.Id;
        }
    }
}
|improve this answer|||||
  • 2
    the other reason to use a map is that the query won't necessarily return records in the order provided in the :Accounts array. – superfell Dec 2 '14 at 0:34
  • I'm Not sure I know where to insert the map of leads to get this to process same account name in a bulk load. I added after the close of the SOQL query and still it's only processing one of multiple leads with the same Account Name – Andrew Sims Dec 2 '14 at 17:16
  • @AndrewSims Support for multiple Leads with the same company name corresponds to the first TODO in the example code. You will need to switch to a Map<string, List<Lead>> to maintain all the Leads with the same campaign name. Then update the Company__c for all the Leads in that list. – Daniel Ballinger Dec 2 '14 at 19:54
  • @DanielBallinger still having trouble with this. I posted the updated code above. – Andrew Sims Dec 2 '14 at 23:46
  • @AndrewSims I've refined the example code to keep a list of Leads with the same company name and then update them all based on the SOQL results. – Daniel Ballinger Dec 2 '14 at 23:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.