[SalesForce] Apex compile error : variable does not exist

I'm having issues with creating a pretty simple test Utility Class. I want to create two records: an account and a related child contact. The error I see in the developer console is:

Variable does not exist: a.ID

My code, based on the Salesforce Apex Workbook, is as follows. I've played around with various things, but it's not working. Where am I going wrong? Thanks in advance.

@isTest
public class AccountSaveTestSuite {

    public static Account createOneAccount(){  
        Account testAccount = createAcct('ABC Computing inc.');     
        Contact testContact = createContact(); 
        return testAccount;        
    }

    // Helper methods //
    //   
    private static Account createAcct(string accountName) { 
        Account a = new Account(
            Name=accountName);
        insert a;
        return a;
    }

    private static Contact createContact(){
        Contact c = new Contact (
            FirstName = 'Jane' 
            , LastName = 'Smith'
            , Account = a.ID); // *** Error is here ***
        insert c;
        return c; 
    } 
}

Best Answer

Curly brackets are used to indicate scope in Apex (and other C-like languages). It could be the scope of your class, method, or a separate scope that you've defined within one of those.

You can access variables that have been declared in your current scope and parent scope(s), but not those defined in child scopes or parallel scopes.

In addition to this you cannot access instance variables from a static scope without an object reference.

In your case you are trying to access a variable a that has been defined in a parallel scope (the createAcct method) to your current scope (the createContact method).

This can be resolved be passing a reference to your Account object to you createContact method:

private static Contact createContact(Account a)
{
    Contact c = new Contact 
    (
        FirstName = 'Jane', 
        LastName = 'Smith', 
        Account = a.ID
    );

    insert c;
    return c; 
} 

Scope Examples

Instance Variables

public class Examples
{ // Begin class scope

    Integer classVariable;

    private void instanceMethod()
    { // Begin method scope

        Integer methodVariable;

        // We can access classVariable because it is defined in a parent scope
        classVariable = 0; // OK!

        // We can access methodVariable because it's defined in the current scope
        methodVariable = 0; // OK!

        { // Begin method inner scope

            Integer methodInnerVariable;

            // We can access classVariable because it is defined in a parent scope
            classVariable = 0; // OK!

            // We can access methodVariable because it's defined in a parent scope
            methodVariable = 0; // OK!

            // We can access methodInnerVariable because it's defined in the current scope
            methodInnerVariable = 0; // OK!

        } // End method inner scope

        // We cannot access methodInnerVariable here because it is in a child scope
        methodInnerVariable = 0; // ERROR!

        if(true)
        { // Begin 'if' scope

            Integer methodIfVariable;

        } // End 'if' scope

        // We cannot access methodIfVariable here because it is in a child scope
        methodIfVariable = 0; // ERROR!

    } // End method scope

} // End class scope

Static Variables

public class StaticExamples
{ // Begin class scope

    static Integer staticClassVariable;

    private static void staticMethod()
    { // Begin method scope

        Integer staticMethodVariable;

        // We can access classVariable because it is defined in a parent scope
        staticClassVariable = 0; // OK!

        // We can access methodVariable because it's defined in the current scope
        staticMethodVariable = 0; // OK!

        { // Begin method inner scope

            Integer staticMethodInnerVariable;

            // We can access classVariable because it is defined in a parent scope
            staticClassVariable = 0; // OK!

            // We can access methodVariable because it's defined in a parent scope
            staticMethodVariable = 0; // OK!

            // We can access methodInnerVariable because it's defined in the current scope
            staticMethodInnerVariable = 0; // OK!

        } // End method inner scope

        // We cannot access methodInnerVariable here because it is in a child scope
        staticMethodInnerVariable = 0; // ERROR!    

        if(true)
        { // Begin 'if' scope

            Integer staticMethodIfVariable;

        } // End 'if' scope

        // We cannot access methodIfVariable here because it is in a child scope
        staticMethodIfVariable = 0; // ERROR!   

    } // End method scope

} // End class scope

Parallel Scopes

public class ParallelExamples
{ // Begin class scope

    private void instanceMethod1()
    { // Begin method1 scope

        Integer method1Variable;

        // We can access method1Variable because it's defined in the current scope
        method1Variable = 0; // OK!

    } // End method1 scope

    private void instanceMethod2()
    { // Begin method2 scope

        Integer method2Variable;

        // We can access method2Variable because it's defined in the current scope
        method2Variable = 0; // OK!

        // We cannot access method1Variable because it's defined in a parallel scope
        method1Variable = 0; // ERROR!

    } // End method2 scope

    private void instanceMethod()
    { // Begin method scope

        { // Begin inner scope 1

            Integer innerScope1Variable;

            // We can access innerScope1Variable because it's defined in the current scope
            innerScope1Variable = 0; // OK!

        } // End inner scope 1

        { // Begin inner scope 2

            // We cannot access innerScope1Variable because it's defined in a parallel scope
            innerScope1Variable = 0; // ERROR!

        } // End inner scope 2

    } // End method scope

} // End class scope

Mixing Instance & Static Variables

public class MixedExamples
{
    Integer instanceClassVariable;
    static Integer staticClassVariable;

    private void AnInstanceMethod()
    { // Begin instance method scope

        // We can access instanceClassVariable because it's defined in a parent scope
        instanceClassVariable = 0; // OK!

        // We can access staticClassVariable because it's defined in a parent scope
        staticClassVariable = 0; // OK!

    } // End instance method scope

    private static void staticMethod(MixedExamples examples)
    { // Begin static method scope

        // We cannot access instanceClassVariable because it's an instance variable and we are in a static scope
        instanceClassVariable = 0; // ERROR!

        // We can however access it if we have an object reference (passed into the function)
        examples.instanceClassVariable = 0; // OK!

        // We can access staticClassVariable because it's defined in a parent scope
        staticClassVariable = 0; // OK!

    } // End static method scope
}
Related Topic