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
Jeff BomarJeff Bomar 

Problem Creating a Apex trigger

What is needed: 
custom object: Custom_Programming__c
fields to validate: Custom_Programming__c.Custom_Type__c and  Custom_Programming__c.Total_Hours__c

Any time the record is inserted or changed:
Custom_Type__c field changes and Total_Hours__c is greater than 0 or the Total_Hours__c is changed and meets the criteria it will get the price from the price book and update custom.Testing_Balance__c

I get is this message when testing:
There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger UpdateBalanceTapeDrop caused an unexpected exception, contact your administrator: UpdateBalanceTapeDrop: execution of BeforeUpdate caused by: System.NullPointerException: Argument cannot be null.: Trigger.UpdateBalanceTapeDrop: line 29, column 1".

Code: 

trigger UpdateBalanceTapeDrop on Custom_Programming__c (before insert, before update) 
{
 for (Custom_Programming__c custom : Trigger.new) 
    {
        //SQL statement to lookup price 
        List<PricebookEntry> sqlResult = [SELECT UnitPrice FROM PricebookEntry WHERE Product2.Name IN('Custom Development','Tape Drop')AND PriceBook2.Name='DAKCS'];
          
        //Conditions FOR Tapedrop
        if (custom.Custom_Type__c == 'Tape Drop' && custom.Total_Hours__c >0)

       //Calculate Balance for Tapedrop  
        {
            custom.Testing_Balance__c = sqlResult[1].UnitPrice + (sqlResult[0].UnitPrice * custom.Total_Hours__c);
           }
        
        //Conditions for No Billing or Bug Fix
        if (custom.Custom_Type__c =='No Billing' || custom.Custom_Type__c =='Bug Fix' && custom.Total_Hours__c >0)
            
       //Calculate Balance for No Billing or Bug Fix 
        {
            custom.Testing_Balance__c = sqlResult[0].UnitPrice * 0;
        }
        
        //Conditions for everything else
       if (custom.Custom_Type__c != 'No Billing' || custom.Custom_Type__c !='Bug Fix' || custom.Custom_Type__c != 'Tape Drop' && custom.Total_Hours__c >0)
           
       //Calculate Balance for everything else
        {
            custom.Testing_Balance__c =sqlResult[0].UnitPrice * custom.Total_Hours__c;
        }
    }
}

Sorry if confusing I am new to Apex triggers and any help would be much appreciated. 

 
Best Answer chosen by Jeff Bomar
AnudeepAnudeep (Salesforce Developers) 
Here is what is present in line 30 column 1
 
//Calculate Balance for everything else
        {
            custom.Testing_Balance__c =sqlResult[0].UnitPrice * custom.Total_Hours__c;
        }

sqlResult[0] does not have any value which is why I believe you are seeing this error

You can do a size check here
 
If(sqlResult.size()>0) {
//execute rest of the code here
}

I strongly recommend adding a try/catch as well in the code as described in the documentation here (https://help.salesforce.com/HTViewSolution?id=000063739)

Let me know if this helps

All Answers

AnudeepAnudeep (Salesforce Developers) 
Appears that the exception is coming at the below line and sqlResult[0].UnitPrice * custom.Total_Hours__c must be returning a null value.
 
custom.Testing_Balance__c =sqlResult[0].UnitPrice * custom.Total_Hours__c;

 I recommend doing a size check of sqlResults before using it in the code

As per this help article, the execution of a trigger will sometimes generate an error message, "execution of [EventName] caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.[TriggerName]: line [XX], column [XX]"

This error is caused by a line of code that is trying to use an object that has not been instantiated, or an object's attribute that has not been initialized.


Resolve NullPointerException

The solution is to make sure the Object and/or the Attribute to be used is not null. In this example, the code needs to be modified as follows:
 
Account newAccount = accountMap.get(oldAccount.Name);

        if (newAccount != null) 

          if (newAccount.Site != null) 

            i = newAccount.Site.length();

Exception handling routine
 
Account newAccount = accountMap.get(oldAccount.Name);

        try {

             i = newAccount.Site.length();

            }
            catch (System.NullPointerException e) {

            e1 = e; // can be assigned to a variable to display a user-friendly error message

        }

Let me know if this helps, if it does, please close the query by marking it as solved. It may help others in the community. Thank You!
Jeff BomarJeff Bomar
I am a little confused will this allow to update the custom field. what I need is if the status is changed and the hours are changed to fire off the trigger to update the amount of custom. the query just grabs the amounts from the pricebook. Sorry new to this.
Jeff BomarJeff Bomar
Tried to change to after update since I just want it to fire when a field in the same object is updated and I get a different error 

Review all error messages below to correct your data.
Apex trigger UpdateBalanceTapeDrop caused an unexpected exception, contact your administrator: UpdateBalanceTapeDrop: execution of AfterUpdate caused by: System.FinalException: Record is read-only: Trigger.UpdateBalanceTapeDrop: line 29, column 1

Any help would be greatly appreciated 
Jeff BomarJeff Bomar
made another change and got 

Apex script unhandled trigger exception by user/organization: 00550000006JDH2/00D290000001OCv
Source organization: 00D50000000JWQF (null)
UpdateBalanceTapeDrop: execution of AfterUpdate

caused by: System.NullPointerException: Argument cannot be null.

Trigger.UpdateBalanceTapeDrop: line 30, column 1

Code: 
trigger UpdateBalanceTapeDrop on Custom_Programming__c (after insert, after update) 
{

    for (Custom_Programming__c custom : [Select Id, Custom_Type__c, Total_Hours__c, Testing_Balance__c From Custom_Programming__c where Id in :Trigger.new]) 
    {
        //SQL statement to lookup price 
        List<PricebookEntry> sqlResult = [SELECT UnitPrice FROM PricebookEntry WHERE Product2.Name IN('Custom Development','Tape Drop')AND PriceBook2.Name='DAKCS'];
          
        //Conditions FOR Tapedrop
        if (custom.Custom_Type__c == 'Tape Drop' && custom.Total_Hours__c >0)

       //Calculate Balance for Tapedrop  
        {
            custom.Testing_Balance__c = sqlResult[1].UnitPrice + (sqlResult[0].UnitPrice * custom.Total_Hours__c);
           }
        
        //Conditions for No Billing or Bug Fix
        if (custom.Custom_Type__c =='No Billing' || custom.Custom_Type__c =='Bug Fix' && custom.Total_Hours__c >0)
            
       //Calculate Balance for No Billing or Bug Fix 
        {
            custom.Testing_Balance__c = sqlResult[0].UnitPrice * 0;
        }
        
        //Conditions for everything else
       if (custom.Custom_Type__c != 'No Billing' || custom.Custom_Type__c !='Bug Fix' || custom.Custom_Type__c != 'Tape Drop' && custom.Total_Hours__c >0)
           
       //Calculate Balance for everything else
        {
            custom.Testing_Balance__c =sqlResult[0].UnitPrice * custom.Total_Hours__c;
        }
    }
}
Jeff BomarJeff Bomar
don't know if this needs to be an after insert, after update since the way the trigger is triggered is if a status or an amount of hours is changed on a record that already exists. 
AnudeepAnudeep (Salesforce Developers) 
Here is what is present in line 30 column 1
 
//Calculate Balance for everything else
        {
            custom.Testing_Balance__c =sqlResult[0].UnitPrice * custom.Total_Hours__c;
        }

sqlResult[0] does not have any value which is why I believe you are seeing this error

You can do a size check here
 
If(sqlResult.size()>0) {
//execute rest of the code here
}

I strongly recommend adding a try/catch as well in the code as described in the documentation here (https://help.salesforce.com/HTViewSolution?id=000063739)

Let me know if this helps
This was selected as the best answer
Jeff BomarJeff Bomar
after thinking this through I think the trigger needs to be after insert after update because I only want the trigger to run if there is a change to custom.Total_Hours__c been trying different variations but not really sure on what to change. I think I need to use map and trigger .old.