+ Start a Discussion
Richard Rodriguez 1Richard Rodriguez 1 

Scheduled Apex Class to update record on a related object (attached via Lookup field)

I have a Custom (Managed) object called Individual Email Result (et4ae5__IndividualEmailResult__c) which contains a Lookup field to a Contact record (et4ae5__Contact__c) and I want to create a schedulable Apex Class to execute daily and update all of the related Contact records (with specific data from the fields of the Individual Email Result record) when it detects that a particular Individual Email Result checkbox (MC_ANY_Sent__c) equals 'true'.

Here is the code that I have so far: 
public class MCANYSent implements Schedulable, Database.Batchable<sObject>{

    public void execute( SchedulableContext context )
    {
        Database.executeBatch( this );
    }

    public Database.QueryLocator start( Database.BatchableContext context )
    {
        return Database.getQueryLocator
        (   'SELECT Id, MC_ANY_Sent__c, et4ae5__DateSent__c, Name, et4ae5__FromName__c, et4ae5__FromAddress__c, et4ae5__Contact__c'
        +   'FROM et4ae5__IndividualEmailResult__c'
        +   'WHERE MC_ANY_Sent__c = true'
        );
    }

    public void execute( Database.BatchableContext context, List<et4ae5__IndividualEmailResult__c> individualemailresults )
    {
        for ( et4ae5__IndividualEmailResult__c ier : individualemailresults )
        {
            ier.et4ae5__Contact__r.MC_Date_of_Last_ANY_Sent__c = ier.et4ae5__DateSent__c;
            ier.et4ae5__Contact__r.MC_Last_Email_Title__c = ier.Name;
            ier.et4ae5__Contact__r.MC_Last_Email_Sender__c = ier.et4ae5__FromName__c + '(' + ier.et4ae5__FromAddress__c + ')';
        }
        update individualemailresults.et4ae5__Contact__c;
    }

    public void finish( Database.BatchableContext context )
    {
        // nothing to do here
    }
}
However, when I try to save this, I am getting the following error;
Error: Compile Error: Variable does not exist: et4ae5__Contact__c at line 25 column 39

Line 25 is the 'update individualemailresults.et4ae5__Contact__c;' line.

I don't need to update the Individual Email Result record, as it isn't being changed, so I'm only looking to update the Contact record in the Lookup field (et4ae5__Contact__c), which is the default Salesforce Contact object, where all of the changes have been made.

Any ideas? 
Best Answer chosen by Richard Rodriguez 1
Hemant_SoniHemant_Soni
Yes i know why this happen. When we are appending SOQL we should always add space before and after single quote.
Please try like below.
public Database.QueryLocator start( Database.BatchableContext context )
    {
        return Database.getQueryLocator
        (   ' SELECT Id, MC_ANY_Sent__c, et4ae5__DateSent__c, Name, et4ae5__FromName__c, et4ae5__FromAddress__c, et4ae5__Contact__c '
        +   ' FROM et4ae5__IndividualEmailResult__c '
        +   ' WHERE MC_ANY_Sent__c = true '
        );
    }
You dont need to wait for schedule run. If you just want to make sure that batch is working fine or not and this is ONLY AND ONLY FOR SANDBOX then you can simpliy use below script and run in developer console.
database.execute(new MCANYSent());
Let me know if still you are getting same error.

Thanks
Hemant

All Answers

Hemant_SoniHemant_Soni
Hi Richard,
Please try below code this will help you to achive whatever you try to achive as i am also from same recruitment industry so i know what you are trying to achive here.
public class MCANYSent implements Schedulable, Database.Batchable<sObject>{

    public void execute( SchedulableContext context )
    {
        Database.executeBatch( this );
    }

    public Database.QueryLocator start( Database.BatchableContext context )
    {
        return Database.getQueryLocator
        (   'SELECT Id, MC_ANY_Sent__c, et4ae5__DateSent__c, Name, et4ae5__FromName__c, et4ae5__FromAddress__c, et4ae5__Contact__c'
        +   'FROM et4ae5__IndividualEmailResult__c'
        +   'WHERE MC_ANY_Sent__c = true'
        );
    }

    public void execute( Database.BatchableContext context, List<et4ae5__IndividualEmailResult__c> individualemailresults ) {
		Map<Id, List<et4ae5__IndividualEmailResult__c>> mapContactIdWiseEmailResult = new Map<Id, List<et4ae5__IndividualEmailResult__c>>();
		List<Contact> lstContact = new List<Contact>();
        for ( et4ae5__IndividualEmailResult__c ier : individualemailresults ){
			if(!mapContactIdWiseEmailResult.containsKey(ier.et4ae5__Contact__c)){
				mapContactIdWiseEmailResult.put(ier.et4ae5__Contact__c, new List<et4ae5__IndividualEmailResult__c>());
			}
			mapContactIdWiseEmailResult.get(ier.et4ae5__Contact__c).add(ier);
            //ier.et4ae5__Contact__r.MC_Date_of_Last_ANY_Sent__c = ier.et4ae5__DateSent__c;
            //ier.et4ae5__Contact__r.MC_Last_Email_Title__c = ier.Name;
            //ier.et4ae5__Contact__r.MC_Last_Email_Sender__c = ier.et4ae5__FromName__c + '(' + ier.et4ae5__FromAddress__c + ')';
        }
		if(!mapContactIdWiseEmailResult.isEmpty()){
			for(Contact oContact : [SELECT Id, Name, MC_Date_of_Last_ANY_Sent__c, MC_Last_Email_Title__c, MC_Last_Email_Sender__c FROM Contact Where Id IN : mapContactIdWiseEmailResult]){
				if(mapContactIdWiseEmailResult.containsKey(oContact.Id)){
					for(et4ae5__IndividualEmailResult__c ier : mapContactIdWiseEmailResult.get(oContact.Id)){
						oContact.MC_Date_of_Last_ANY_Sent__c = ier.et4ae5__DateSent__c;
						oContact.MC_Last_Email_Title__c = ier.Name;
						oContact.MC_Last_Email_Sender__c = ier.et4ae5__FromName__c + '(' + ier.et4ae5__FromAddress__c + ')';
					}
					lstContact.add(oContact);
				}
			}
		}
		if(lstContact.size() > 0){
			update lstContact;
		}
        //update individualemailresults.et4ae5__Contact__c;
    }

    public void finish( Database.BatchableContext context )
    {
        // nothing to do here
    }
}

Please let me know if you have any question or concern. You can directly contact me on my email id as well if need any other assistance in salesforce.

Thanks
Hemant
Email : sonihemant.jaipur@gmail.com
Richard Rodriguez 1Richard Rodriguez 1
Thank you, Hemant. I'm getting the following error with your code:
Error: Compile Error: IN operator must be used with an iterable expression at line 30 column 36

Line 30 is the line which reads "for(Contact oContact : [SELECT Id, Name, MC_Date_of_Last_ANY_Sent__c, MC_Last_Email_Title__c, MC_Last_Email_Sender__c FROM Contact Where Id IN : mapContactIdWiseEmailResult]){"
Hemant_SoniHemant_Soni
Please use below 
for(Contact oContact : [SELECT Id, Name, MC_Date_of_Last_ANY_Sent__c, MC_Last_Email_Title__c, MC_Last_Email_Sender__c FROM Contact Where Id IN : mapContactIdWiseEmailResult.keyset()]){

 
Richard Rodriguez 1Richard Rodriguez 1
Thank you. That's saved, so I'll just schedule it and see if it works.
Hemant_SoniHemant_Soni
If it helps you, can you close your query by marking it as solved so that it can help others in the future. It will help to keep this community clean.
Richard Rodriguez 1Richard Rodriguez 1
Hello Hemant. I noticed that the Contact records weren't changing, so I check the Apex Jobs and found the following error.
26/12/2019 2:00 PM Batch Apex Failed First error: unexpected token: MC_ANY_Sent__c
Any ideas?
Hemant_SoniHemant_Soni
Yes i know why this happen. When we are appending SOQL we should always add space before and after single quote.
Please try like below.
public Database.QueryLocator start( Database.BatchableContext context )
    {
        return Database.getQueryLocator
        (   ' SELECT Id, MC_ANY_Sent__c, et4ae5__DateSent__c, Name, et4ae5__FromName__c, et4ae5__FromAddress__c, et4ae5__Contact__c '
        +   ' FROM et4ae5__IndividualEmailResult__c '
        +   ' WHERE MC_ANY_Sent__c = true '
        );
    }
You dont need to wait for schedule run. If you just want to make sure that batch is working fine or not and this is ONLY AND ONLY FOR SANDBOX then you can simpliy use below script and run in developer console.
database.execute(new MCANYSent());
Let me know if still you are getting same error.

Thanks
Hemant
This was selected as the best answer
Richard Rodriguez 1Richard Rodriguez 1
Thank you, Hemant! You've done it!

Finally. I've been working on this for much longer than I've posted here.

I hope you realise that I'm now coming to you FIRST everytime I need help. :)
You're the best around. Nothing's ever gonna keep you down.
Hemant_SoniHemant_Soni
I am working on talent Rover from last two years and i know this very well. Keep working brother.