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
Anto HotelbedsAnto Hotelbeds 

How to use a batch apex

Hi,

 

I created a Batch Apex but I guess im using it wrong because I get the error:

 

System.Exception: Attempted to schedule too many concurrent batch jobs in this org

 

I have a trigger that when the field Team__c in Users is modified, I have to retrieve all the accounts from this user and update a field Area__c in the account.

 

This is the trigger code where I check if the field Team__c has changed and if changed, send it the the apex batch to update all the accounts:

 

trigger UpdateKAMandCommAreawhenModUser on User (after update) { 
	Set<id> ownerIds = new Set<id>();
    Map<id, User> owners = new Map<id, User>();
    for (Integer i=0;i<Trigger.new.size();i++){
    	if (Trigger.new[i].Team__c!=Trigger.old[i].Team__c){
           Database.executeBatch(new AccountAreaReassignment(Trigger.new[i].Team__c,Trigger.new[i].Id));

    }
}

 

And this is my batch:

 

global class AccountAreaReassignment implements Database.Batchable<sObject>{
    
    //Receiving Area and Id of the user
    String Area{get;set;}
    Id UserId{get;set;}
    global AccountareaReassignment(String Area,Id UserId){
        this.Area=Area;
        this.UserId=UserId;
    } 
global Database.QueryLocator start(Database.BatchableContext BC) { return DataBase.getQueryLocator([SELECT Id,Area__c FROM account WHERE OwnerId=:UserId]); } global void execute(Database.BatchableContext BC,List<Account> scopeAcc) { for (Integer i=0;i<scopeAcc.size();i++){ scopeAcc.get(i).Area__c=Area; } update scopeAcc; } global void finish(Database.BatchableContext BC) { //Send an email to the User after your batch completes Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); String[] toAddresses = new String[] {'a.tejado@hotelbeds.com'}; mail.setToAddresses(toAddresses); mail.setSubject('Apex Batch Job is done'); mail.setPlainTextBody('The batch Apex job processed '); Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); } }

 

I want to change my code in order to send to the Batch the list of User Id's that have been modified. But then I dont know how to work with that list in the batch, could someone help please?

 

Thanks a lot!

 

Antonio

Best Answer chosen by Admin (Salesforce Developers) 
SLockardSLockard

You are close, just need to put evertyhing into the lists like this:

 

trigger UpdateKAMandCommAreawhenModUser on User (after update) 
{ 
    Map<id, User> owners = new Map<id, User>();
    for (Integer i=0;i<Trigger.new.size();i++)
	{
    	if (Trigger.new[i].Team__c!=Trigger.old[i].Team__c)
		{
			owners.put(Trigger.new[i].Id, Trigger.new[i]);
		}
    }
	
	if (owners.size() > 0)
	{
		Database.executeBatch(new AccountAreaReassignment(owners));
	}
}

/////////////////////////////

global class AccountAreaReassignment implements Database.Batchable<sObject>
{
    
    //map of userid - user
	Map<Id, User> ownerMap = new Map<Id, User>();
    global AccountareaReassignment(Map<Id, User> owners)
	{
        ownerMap = owners;
    } 

    global Database.QueryLocator start(Database.BatchableContext BC)
	{
		return DataBase.getQueryLocator([SELECT Id,Area__c, OwnerId FROM account WHERE OwnerId IN : ownerMap.keySet()]);
	}
	
    global void execute(Database.BatchableContext BC,List<Account> scopeAcc)
	{
		
        for (Integer i=0;i<scopeAcc.size();i++){
        	scopeAcc.get(i).Area__c=ownerMap.get(scopeAcc.get(i).OwnerId).Team__c;
    	}
    	update scopeAcc;
	}
    
    global void finish(Database.BatchableContext BC)
	{
    	//Send an email to the User after your batch completes
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
		String[] toAddresses = new String[] {'a.tejado@hotelbeds.com'};
		mail.setToAddresses(toAddresses);
		mail.setSubject('Apex Batch Job is done');
		mail.setPlainTextBody('The batch Apex job processed ');
		Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
	}
}

 Good luck!

All Answers

SLockardSLockard

You are close, just need to put evertyhing into the lists like this:

 

trigger UpdateKAMandCommAreawhenModUser on User (after update) 
{ 
    Map<id, User> owners = new Map<id, User>();
    for (Integer i=0;i<Trigger.new.size();i++)
	{
    	if (Trigger.new[i].Team__c!=Trigger.old[i].Team__c)
		{
			owners.put(Trigger.new[i].Id, Trigger.new[i]);
		}
    }
	
	if (owners.size() > 0)
	{
		Database.executeBatch(new AccountAreaReassignment(owners));
	}
}

/////////////////////////////

global class AccountAreaReassignment implements Database.Batchable<sObject>
{
    
    //map of userid - user
	Map<Id, User> ownerMap = new Map<Id, User>();
    global AccountareaReassignment(Map<Id, User> owners)
	{
        ownerMap = owners;
    } 

    global Database.QueryLocator start(Database.BatchableContext BC)
	{
		return DataBase.getQueryLocator([SELECT Id,Area__c, OwnerId FROM account WHERE OwnerId IN : ownerMap.keySet()]);
	}
	
    global void execute(Database.BatchableContext BC,List<Account> scopeAcc)
	{
		
        for (Integer i=0;i<scopeAcc.size();i++){
        	scopeAcc.get(i).Area__c=ownerMap.get(scopeAcc.get(i).OwnerId).Team__c;
    	}
    	update scopeAcc;
	}
    
    global void finish(Database.BatchableContext BC)
	{
    	//Send an email to the User after your batch completes
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
		String[] toAddresses = new String[] {'a.tejado@hotelbeds.com'};
		mail.setToAddresses(toAddresses);
		mail.setSubject('Apex Batch Job is done');
		mail.setPlainTextBody('The batch Apex job processed ');
		Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
	}
}

 Good luck!

This was selected as the best answer
Anto HotelbedsAnto Hotelbeds

Thank you so much!!