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
April Barclay 8April Barclay 8 

Apex class to update a check box field

Hello all.  I am VERY new to the development side of SF but have been doing admin for over 5 years.  I want to use Apex to edit a checkbox on the contacts object every day...it can run once daily or throughout the day if possible.  How do I accomplish this?  I assume I need to write an apex class but have no idea what the code should be.  Please help.
Best Answer chosen by April Barclay 8
Abhijeet Anand 6Abhijeet Anand 6
Hope this helps.

This is your batch class. Just replace checkbox__c with the API name of your checkbox field on Contact. 

global class UpdateContacts implements Database.Batchable<sObject>
{
    
   global Database.queryLocator start(Database.BatchableContext ctx )
   {
          
        String str = 'SELECT Id, checkbox__c FROM Contact WHERE checkbox__c = false';
        
        return Database.getQueryLocator(str);
        
   }
    
    global void execute(Database.BatchableContext ctx, List<Contact> contactToProcess)
     {
        
       List<Contact> contactList = new List<Contact>();
       
       for(Contact conObj : contactToProcess){
               checkbox__c = true;
            contactList.add(conObj);
          }
        
        update contactList;
     }
   
   global void finish(Database.BatchableContext ctx)
    {
   
      AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
                          TotalJobItems, CreatedBy.Email
                          FROM AsyncApexJob WHERE Id =
                          :ctx.getJobId()];
   // Send an email to the Apex job's submitter notifying of job completion. 
    
   Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
   String[] toAddresses = new String[] {a.CreatedBy.Email};
   mail.setToAddresses(toAddresses);
   mail.setSubject('Apex Sharing Recalculation ' + a.Status);
   mail.setPlainTextBody
   ('The batch Apex job processed ' + a.TotalJobItems +
   ' batches with '+ a.NumberOfErrors + ' failures.');
   Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
           
    }    
}

You also need to run this batch from developer console as follows:
Id batchJobId = Database.executeBatch(new UpdateContacts(), 200);

All Answers

Abhijeet Anand 6Abhijeet Anand 6
Do you need to update all the contacts of your ORG or some specific ones only? First you have to query all such records and collect them in a Map/List, iterate over the Map/List, set the value of the checkbox to true and finally update the Map/List.

List<Contact> listName = [SELECT Id, checkbox FROM Contact where checkbox = false]; // This query needs to be selective else you can hit the governor limits.

for(Contact obj : listName){
   obj.checkbox = true;
}

update listName;

You need to make use of batch apex if you want this to happen once daily or at regular intervals.

Thanks
Abhijeet
April Barclay 8April Barclay 8
Yes - I want to update all contacts.  I basically want to just trigger an edit on all the records so it updates information.  
Abhijeet Anand 6Abhijeet Anand 6
Hope this helps.

This is your batch class. Just replace checkbox__c with the API name of your checkbox field on Contact. 

global class UpdateContacts implements Database.Batchable<sObject>
{
    
   global Database.queryLocator start(Database.BatchableContext ctx )
   {
          
        String str = 'SELECT Id, checkbox__c FROM Contact WHERE checkbox__c = false';
        
        return Database.getQueryLocator(str);
        
   }
    
    global void execute(Database.BatchableContext ctx, List<Contact> contactToProcess)
     {
        
       List<Contact> contactList = new List<Contact>();
       
       for(Contact conObj : contactToProcess){
               checkbox__c = true;
            contactList.add(conObj);
          }
        
        update contactList;
     }
   
   global void finish(Database.BatchableContext ctx)
    {
   
      AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
                          TotalJobItems, CreatedBy.Email
                          FROM AsyncApexJob WHERE Id =
                          :ctx.getJobId()];
   // Send an email to the Apex job's submitter notifying of job completion. 
    
   Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
   String[] toAddresses = new String[] {a.CreatedBy.Email};
   mail.setToAddresses(toAddresses);
   mail.setSubject('Apex Sharing Recalculation ' + a.Status);
   mail.setPlainTextBody
   ('The batch Apex job processed ' + a.TotalJobItems +
   ' batches with '+ a.NumberOfErrors + ' failures.');
   Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
           
    }    
}

You also need to run this batch from developer console as follows:
Id batchJobId = Database.executeBatch(new UpdateContacts(), 200);
This was selected as the best answer
April Barclay 8April Barclay 8
When I replace this part: for(Contact conObj : contactToProcess){
               checkbox__c = true;
            contactList.add(conObj);

With my api name for the field it variable does not exist.

After I have the class created...don't I need to build a trigger to run this each morning?
Abhijeet Anand 6Abhijeet Anand 6
You also need to run this batch from developer console as follows:
Id batchJobId = Database.executeBatch(new UpdateContacts(), 200);
April Barclay 8April Barclay 8
When I try to save...I get an error on this part:

for(Contact conObj : contactToProcess){
               checkbox__c = true;
            contactList.add(conObj);

I replace the field with my api name and it says variable does not exist.

And when I create the Apex trigger with the above code...when will it know to run?  I want it to run each day at 6AM
Abhijeet Anand 6Abhijeet Anand 6
try this:

for(Contact conObj : contactToProcess){
              conObj.checkbox__c = true;
            contactList.add(conObj);

Create a scheduler class as follows:

global class MySchedulableClass implements Schedulable {
      global void execute(SchedulableContext ctx) {
           database.executeBatch(new new UpdateContacts(),200);
      }
}

Please follow below Steps:-
Step1 :- go to classes
Setup->Apex classes then click on Schedule Apex button 

Step 3:- Then add date and time & select the above scheduler class in Apex class lookup
April Barclay 8April Barclay 8
So I have created 2 classes...one scheduled.  And I also created a trigger.  I have it scheduled and waiting to see if it works as I intended. Thank you so much for all of your help!
Abhijeet Anand 6Abhijeet Anand 6
Actually, you can move the logic of your trigger to the batch class itself. You don't even need a trigger here. Can you please post your trigger here?
April Barclay 8April Barclay 8
Here is the first class:
global class UpdateContacts implements Database.Batchable<sObject>
{    
   global Database.queryLocator start(Database.BatchableContext ctx )
   {
          
        String str = 'SELECT Id, update_contact__c FROM Contact WHERE update_contact__c = false';
        
        return Database.getQueryLocator(str);
        
   }
    
    global void execute(Database.BatchableContext ctx, List<Contact> contactToProcess)
     {
        
       List<Contact> contactList = new List<Contact>();
       
       for(Contact conObj : contactToProcess){
              conObj.update_contact__c = true;
            contactList.add(conObj);
       }
        update contactList;
     }
   
   global void finish(Database.BatchableContext ctx)
    {
   
      AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
                          TotalJobItems, CreatedBy.Email
                          FROM AsyncApexJob WHERE Id =
                          :ctx.getJobId()];
   // Send an email to the Apex job's submitter notifying of job completion. 
    
   Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
   String[] toAddresses = new String[] {a.CreatedBy.Email};
   mail.setToAddresses(toAddresses);
   mail.setSubject('Apex Sharing Recalculation ' + a.Status);
   mail.setPlainTextBody
   ('The batch Apex job processed ' + a.TotalJobItems +
   ' batches with '+ a.NumberOfErrors + ' failures.');
   Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
           
    }    
}
April Barclay 8April Barclay 8
Here is the scheduled class:
global class MySchedulableClass implements Schedulable {
      global void execute(SchedulableContext ctx) {
           database.executeBatch(new UpdateContacts(),200);
      }
}
April Barclay 8April Barclay 8
Trigger:

trigger Update_Contacts_Trigger on Contact (before insert) {
Id batchJobId = Database.executeBatch(new UpdateContacts(), 200);
}
Abhijeet Anand 6Abhijeet Anand 6
What is the purpose of this trigger? Why are you calling the batch class form the trigger?
April Barclay 8April Barclay 8
I thought that is what I needed to do...sorry.  I am new to this
Abhijeet Anand 6Abhijeet Anand 6
We don't need a trigger in your scenario here. The batch class as scheduled by you will run every morning and pick all those contacts which have update_contact__c = false and update it to true. I think this is what you were looking for. Let me know it that's correct.
April Barclay 8April Barclay 8
Yes.  I can delete the trigger.  Do I need to move that logic somewhere else?  And I assume I need a workflow field update to uncheck the box so it will update them again the next day
Abhijeet Anand 6Abhijeet Anand 6
Yes, delete the trigger. No need to move the logic anywhere. We don't need it. Workflow field update will do the job.
April Barclay 8April Barclay 8
You have been so helpful!  Thank you so much for everything.
Abhijeet Anand 6Abhijeet Anand 6
If you problem is solved, mark the best answer.

Thanks
Abhijeet
April Barclay 8April Barclay 8
Now I have tried to deploy to production via a change set...but it is requiring me to create test classes for both of those classes I created.  How do I go about doing that so I can get these in prod?
Abhijeet Anand 6Abhijeet Anand 6
@isTest
private class TestUpdateContacts {
       
   static testMethod void testSchedule() {

        Test.StartTest();
        
        List<Contact> contactList = new List<Contact>();
        
        for(Integer i = 0; i<20; i++){
            Contact conObj = new Contact();
            conObj.LastName = 'Test Batch Apex' + i;
            conObj.update_contact__c = false;
            contactList.add(conObj);
        }
        
        insert contactList;
        
        MySchedulableClass sh1 = new MySchedulableClass();
        String sch = '0 0 23 * * ?'; 
        system.schedule('Test Update Contacts Check', sch, sh1); 
        
        Test.stopTest();
        
   }

    
}

This will be your test class. Create a new class as above, save it and click on the 'Run Test' button.
April Barclay 8April Barclay 8
Thank you.  I ran into  a code coverage error so I assume the group before I got here did nto ahve anough test classes.  So I am stuck still not being able to deploy.