+ Start a Discussion
Cynthia Rodgers 12Cynthia Rodgers 12 

Apex class to update two fields to Null

I have not written an apex class yet so I'm not sure i have the hang of this yet.  I am needing to update two custom account fields to null once a date field has been met.  Im going the route of apex class because i need to add it to the scheduler for the update versus using workflow or process builder.  

Scenario:  When the TSS Temporary End Date = TODAY(), i want to update the TSS Designation field (picklist) to Null and update the TSS Temporary End Date to Null.

public class update_tss_fields {
    public static String saveData(){
        for (Account a : [SELECT Id FROM Account WHERE TSS_Temporary_End_Date__c = TODAY()]){
               if (a.TSS_Temporary_End_Date__c = TODAY()){ 
                   a.TSS_Designation__C = null;
                   a.TSS_Temporary_End_Date__c = null;
                   update a;
               } 
               }    
        }
     }


I've tried 'UPDATE', 'IF' and when i try to save it get an error when using those expressions.  So im now getting this error: Error: Compile Error: Expecting ']' but was: '(' at line 3 column 89) 

Any help would be appreciated.

I did recieve the following updated code from another user in the community but it did not resolve my issue.  I get a new error:  Error: Compile Error: Method does not exist or incorrect signature: void TODAY() from the type update_tss_fields at line 4 column 85

public class update_tss_fields {
    public static String saveData(){
     List<Account> accountsToUpdate = new LIST<Account>();
        for (Account a : [SELECT Id FROM Account WHERE TSS_Temporary_End_Date__c =: TODAY()]){
               if (a.TSS_Temporary_End_Date__c = TODAY()){ 
                   a.TSS_Designation__C = null;
                   a.TSS_Temporary_End_Date__c = null;
                   accountsToUpdate.add(a); // make use of collections to store records
                 
               } 
               }    
update accountsToUpdate; // do the dml outside of for loop
        }
     }
Best Answer chosen by Cynthia Rodgers 12
Shruti SShruti S
Here is the updated code. I have a couple of changes. Please have a look at the code below - 
public class update_tss_fields {
    public static void saveData() {
        List<Account> accsToUpdate = new List<Account>();

        for ( Account a : [ 
                            SELECT  Id
                            FROM    Account 
                            WHERE   TSS_Temporary_End_Date__c = TODAY 
                        ]
        ) {
               
            a.TSS_Designation__C         = null;
            a.TSS_Temporary_End_Date__c  = null;
           
            accsToUpdate.add( a );
        }    

        if( !accsToUpdate.isEmpty() ) {
            UPDATE accsToUpdate;
        }
    }
}
1. You don't need an IF clause to check if the date equals TODAY since your query will yield only those that satisfies the condition
2. You don't have to query fields unless you are reading values from them
3. We need to ensure we submit the records to the database ONLY if the query yielded something
4. We need to set the return type to void

All Answers

Shruti SShruti S
Here is the updated code. I have a couple of changes. Please have a look at the code below - 
public class update_tss_fields {
    public static void saveData() {
        List<Account> accsToUpdate = new List<Account>();

        for ( Account a : [ 
                            SELECT  Id
                            FROM    Account 
                            WHERE   TSS_Temporary_End_Date__c = TODAY 
                        ]
        ) {
               
            a.TSS_Designation__C         = null;
            a.TSS_Temporary_End_Date__c  = null;
           
            accsToUpdate.add( a );
        }    

        if( !accsToUpdate.isEmpty() ) {
            UPDATE accsToUpdate;
        }
    }
}
1. You don't need an IF clause to check if the date equals TODAY since your query will yield only those that satisfies the condition
2. You don't have to query fields unless you are reading values from them
3. We need to ensure we submit the records to the database ONLY if the query yielded something
4. We need to set the return type to void
This was selected as the best answer
Cynthia Rodgers 12Cynthia Rodgers 12
Hi Shruti, I was able to create the apex class!  thank you.  I am now trying to schedule it to run using apex scheduler but I cant select this class within the search.  Is there something i need to do in order to see that class to schedule it to run?
Glyn Anderson (Slalom)Glyn Anderson (Slalom)
Cynthia, In order to schedule a class, it must implement the Schedulable interface.  In this case, this should also be a batch class (that implements the Batchable interface) so that it can process an arbitrarily large number of Account records if necessary (up to 50 million).  Here's my version:

<pre>
public class update_tss_fields implements Schedulable, Database.Batchable<Account>
{
    // The Schedulable interface allows you to schedule the class and
    // makes it available in the scheduler UI.  To implement the interface,
    // you need the following method:

    public void execute( SchedulableContext context )
    {
        // all it will do is execute the batch process
        Database.executeBatch( this );
    }

    // The Batchable interface lets you process large numbers of records
    // in multiple small batches.  To implement the interface, you need
    // the following three methods:

    public Database.QueryLocator start( Database.BatchableContext context )
    {
        return Database.getQueryLocator
        (   'SELECT Id, TSS_Designation__c, TSS_Temporary_End_Date__c '
        +   'FROM Account '
        +   'WHERE TSS_Temporary_End_Date__c = TODAY'
        );
    }

    public void execute( Database.BatchableContext context, List<Account> accounts )
    {
        for ( Account account : accounts )
        {
            account.TSS_Designation__c = null;
            account.TSS_Temporary_End_Date__c = null;
        }
        update accounts;
    }

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

BTW: Shruti was spot-on with her advice #1 & #4.  #2 isn't entirely true - you must query fields that you will write, as well as the ones you will read.  #3 is a common misconception - doing DML on an empty list does not cause an error and it does not count against DML limits - it just does nothing.  Let me know if you have any compilation problems.  I didn't actually compile this and there might be typos.
Cynthia Rodgers 12Cynthia Rodgers 12
Hi Glyn,
Im working thru this now and trying to clear the compile errors.  Currently getting the following: Error: Compile Error: Class update_tss_fields must implement the method: System.Iterable<Account> Database.Batchable<Account>.start(Database.BatchableContext) at line 1 column 14
Cynthia Rodgers 12Cynthia Rodgers 12
Hey Glen,
Should i be creating multiple classes to handle the scheduler? or just one additional class with the code attached?
Richard Rodriguez 1Richard Rodriguez 1
Hey Cynthia,
Did you ever get this working without errors? Would love to see the code... it's exactly what I need to achieve.
Richard Rodriguez 1Richard Rodriguez 1
The batchable version, that is.