4 Declaring and Initializing Variables and Data Structures

This chapter contains the following topics:

4.1 Understanding Variables and Data Structures

Variables and data structures must be defined and initialized before they can be used to store data. This chapter describes how to declare and initialize them. It includes topics on using define statements, using typedef, creating function prototypes, initializing variables, initializing data structures, and using standard variables.

4.2 Using Define Statements

A define statement is a directive that sets up constants at the beginning of the program. A define statement always begins with a pound sign (#). All business functions include the system header file: jde.h. System-wide define statements are included in the system header file.

If you need define statements for a specific function, include the define statement in uppercase letters within the source file for the function whenever possible. The statement should directly follow the header file inclusion statement.

Usually, you should place define statements in the source file, not the header file. When placed in the header file, you can redefine the same constant with different values, causing unexpected results. However, rare cases exist when it is necessary to place a define statement in the function header file. In these cases, precede the definition name with the business function name to ensure uniqueness.

4.2.1 Example: #define in Source File

This example includes define statements within a business function source file:

/*************************************************************
* Notes
*************************************************************/
#include <bxxxxxxx.h>
/*************************************************************
 * Global Definitions
 *************************************************************/
#define CACHE_GET            '1'
#define CACHE_ADD            '2'
#define CACHE_UPDATE         '3'
#define CACHE_DELETE         '4'

4.2.2 Example: #define in Header File

This example includes define statements within a business function header:

/**********************************************************
 * External Business Function Header Inclusions
 **********************************************************/

#include <bxxxxxxx.h>

/**********************************************************
 * Global definitions
 **********************************************************/
#define BXXXXXXX_CACHE_GET         '1'
#define BXXXXXXX_CACHE_ADD         '2'
#define BXXXXXXX_CACHE_UPDATE      '3'
#define BXXXXXXX_CACHE_DELETE      '4'

4.3 Using Typedef Statements

When using typedef statements, always name the object of the typedef statement using a descriptive, uppercase format. If you are using a typedef statement for data structures, remember to include the name of the business function in the name of the typedef to make it unique. See the example for using a typedef statement for a data structure.

4.3.1 Example: Using Typedef for a User-Defined Data Structure

This is an example of a user-defined data structure:

/**************************************************************
 * Structure Definitions
 **************************************************************/

typedef struct
{
   HUSER         hUser;           /** User handle **/
   HREQUEST      hRequestF0901;   /** File Pointer to the
                                    * Account Master **/
   DSD0051       dsData;          /** X0051 - F0902 Retrieval **/
   int           iFromYear;       /** Internal Variables **/
   BOOL          bProcessed;
   MATH_NUMERIC  mnCalculatedAmount;
   JCHAR         szSummaryJob[13];
   JDEDATE       jdStartPeriodDate;
} DSX51013_INFO, *LPDSX51013_INFO;

4.4 Creating Function Prototypes

Refer to these guidelines when defining function prototypes:

  • Always place function prototypes in the header file of the business function in the appropriate prototype section.

  • Include function definitions in the source file of the business function, preceded by a function header.

  • Ensure that function names follow the naming convention defined in this guide.

  • Ensure that variable names in the parameter list follow the naming convention defined in this guide.

  • List the variable names of the parameters along with the data types in the function prototype.

  • List one parameter per line so that the parameters are aligned in a single column.

  • Do not allow the parameter list to extend beyond 80 characters in the function definition. If the parameter list must be broken up, the data type and variable name must stay together. Align multiple-line parameter lists with the first parameter.

  • Include a return type for every function. If a function does not return a value, use the keyword void as the return type.

  • Use the keyword void in place of the parameter list if nothing is passed to the function.

4.4.1 Example: Creating a Business Function Prototype

This is an example of a standard business function prototype:

/*****************************************************************
 * Business Function: BusinessFunctionName
 *
 *    Description: Business Function Name
 *
 *     Parameters:
 *      LPBHVRCOM  lpBhvrCom Business Function Communications
 *      LPVOID   lpVoid  Void Parameter - DO NOT USE!
 *    LPDSD51013 lpDS   Parameter Data Structure Pointer
 *
 *****************************************************************/

JDEBFRTN (ID) JDEBFWINAPI BusinessFunctionName (LPBHVRCOM  lpBhvrCom,
                                                LPVOID     lpVoid,
                                                LPDSXXXXXX lpDS)

4.4.2 Example: Creating an Internal Function Prototype

This is an example of a standard internal function prototype:

Type XXXXXXXX_AAAAAAAA( parameter list ... );

type     : Function return value
XXXXXXXX : Unique source file name
AAAAAAAA : Function Name

4.4.3 Example: Creating an External Business Function Definition

This is an example of a standard external business function definition:

/*
 *  see sample source for standard business function heading
 */
JDEBFRTN (ID) JDEBFWINAPI GetAddressBookDescription(LPBHVRCOM  lpBhvrCom,
                                                    LPVOID     lpVoid,
                                                    LPDSNNNNNN lpDS)
{
   ID idReturn = ER_SUCCESS;
   /*--------------------------------------------------------------
    * business function code
    */
   return idReturn;
}

4.4.4 Example: Creating an Internal Function Definition

This is an example of a standard internal function definition:

/*-----------------------------------------------------------------------
 *  see sample source for standard function header
 */
void I4100040_GetSupervisorManagerDefault( LPBHVRCOM lpBhvrCom,
                                           LPSTR lpszCostCenterIn,
                                           LPSTR lpszManagerOut,
                                           LPSTR lpszSupervisorOut )
/*-----------------------------------------------------------------------
 * Note: b4100040 is the source file name
 */
{
   /*
    * internal function code
    */
}

4.5 Initializing Variables

Variables store information in memory that is used by the program. Variables can store strings of text and numbers.

When you declare a variable, you should also initialize it. Two types of variable initialization exist: explicit and implicit. Variables are explicitly initialized if they are assigned a value in the declaration statement. Implicit initialization occurs when variables are assigned a value during processing.

This information covers standards for declaring and initializing variables in business functions and includes an example of standard formats.

Use these guidelines when declaring and initializing variables:

  • Declare variables using this format:

    datatype variable name = initial value; /* descriptive comment*/
    
  • Declare all variables used within business functions and internal functions at the beginning of the function. Although C allows you to declare variables within compound statement blocks, this standard requires all variables used within a function to be declared at the beginning of the function block.

  • Declare only one variable per line, even if multiple variables of the same type exist. Indent each line three spaces and left align the data type of each declaration with all other variable declarations. Align the first character of each variable name (variable name in the preceding format example) with variable names in all other declarations.

  • Use the naming conventions set forth in this guide. When initializing variables, the initial value is optional depending on the data type of the variable. Generally, all variables should be explicitly initialized in their declaration.

  • The descriptive comment is optional. In most cases, variable names are descriptive enough to indicate the use of the variable. However, provide a comment if further description is appropriate or if an initial value is unusual.

  • Left align all comments.

  • Data structures should be initialized to zero using the memset function immediately after the declaration section.

  • Some Application Program Interfaces (APIs), such as the JDB ODBC API, provide initialization routines. In this case, the variables intended for use with the API should be initialized with the API routines.

  • Always initialize pointers to NULL and include an appropriate type call at the declaration line.

  • Initialize all variables, except data structures, in the declaration.

  • Initialize all declared data structures, MATH_NUMERIC, and JDEDATE to NULL.

  • Ensure that the byte size of the variable matches the size of the data structure you want to store.

4.5.1 Example: Initializing Variables

This example shows how to initialize variables:

JDEBFRTN (ID) JDEBFWINAPI F0902GLDateSensitiveRetrieval
                          (LPBHVRCOM   lpBhvrCom,
                           LPVOID     lpVoid,
                           LPDSD0051   lpDS)
/****************************************************************
 * Variable declarations
 ***************************************************************/
   ID             idReturn      = ER_SUCCESS;
   JDEDB_RESULT   eJDEDBResult  = JDEDB_PASSED;
   long           lDateDiff     = 0L;
   BOOL           bAddF0911Flag = TRUE;
   MATH_NUMERIC   mnPeriod      = {0};

/****************************************************************
 * Declare structures
 ***************************************************************/
   HUSER          hUser         = (HUSER) NULL;
   HREQUEST       hRequestF0901 = (HREQUEST) NULL;
   DSD5100016     dsDate        = {0};
   JDEDATE        jdMidDate     = {0};

/****************************************************************
 * Pointers
 ***************************************************************/
   LPX0051_DSTABLES lpdsTables = (LPX0051_DSTABLES) 0L;

/****************************************************************
 * Check for NULL pointers
 **************************************************************/
   if ((lpBhvrCom == (LPBHVRCOM) NULL) ||
       (lpVoid    == (LPVOID)    NULL) ||
       (lpDS      == (LPDSD0051)   NULL))
   {
      jdeErrorSet (lpBhvrCom, lpVoid, (ID) 0,
                   _J(4363), (LPVOID) NULL);
      return ER_ERROR;
   }

/**************************************************************
 * Main Processing
 **************************************************************/
   eJDEDBResult = JDB_InitBhvr ((void*)lpBhvrCom,
                                &hUser,
                                (JCHAR *) NULL,
                                JDEDB_COMMIT_AUTO);

 memcopy ((void*)) &dsDate.jdPeriodEndDate,
          (const void*) &lpDS->jdGLDate, sizeof(JDEDATE));

4.6 Initializing Data Structures

When writing to the table, the table recognizes these default values:

  • Space-NULL if string is blank

  • 0 value if math numeric is 0

  • 0 JDEDATE if date is blank

  • Space if character is blank

Always memset to NULL on the data structure that is passed to another business function to update a table or fetch a table.

4.6.1 Example: Using Memset to Reset the Data Structure to Null

This example resets the data structure to NULL when initializing the data structure:

bOpenTable = B5100001_F5108SetUp( lpBhvrCom, lpVoid,
                                  lphUser, &hRequestF5108);

if ( bOpenTable )
{
   memset( (void *)(&dsF5108Key), 0x00, sizeof(KEY1_F5108) );
   jdeStrcpy( (JCHAR*) dsF5108Key.mdmcu,
              (const JCHAR*) lpDS->szBusinessUnit );
   memset( (void *)(&dsF5108), 0x00, sizeof(F5108) );

   jdeStrcpy( (JCHAR*) dsF5108.mdmcu,
            (const JCHAR*) lpDS->szBusinessUnit );
   MathCopy(&dsF5108.mdbsct, &mnCentury);
   MathCopy(&dsF5108.mdbsfy, &mnYear);
   MathCopy(&dsF5108.mdbtct, &mnCentury);
   MathCopy(&dsF5108.mdbtfy, &mnYear);
   eJDEDBResult = JDB_InsertTable( hRequestF5108,
                                   ID_F5108,
                                   (ID)(0),
                                   (void *) (&dsF5108) );
}

4.7 Using Standard Variables

This section discusses how to:

  • Use flag variables.

  • Use input and output parameters.

  • Use fetch variables.

4.7.1 Using Flag Variables

When creating flag variables, use these guidelines:

  • Any true-or-false flag used must be a Boolean type (BOOL).

  • Name the flag variable to answer a question of TRUE or FALSE.

These are examples of flag variables, with a brief description of how each is used:

Flag Variable Description
bIsMemoryAllocated Apply to memory allocation
bIsLinkListEmpty Link List

4.7.2 Using Input and Output Parameters

Business functions frequently return error codes and pointers. The input and output parameters in the business function data structure should be named as follows:

Input and Output Parameter Description
cReturnPointer When allocating memory and returning GENLNG.
cErrorCode Based on cCallType, cErrorCode returns a 1 when it fails or a 0 when it succeeds.
cSuppressErrorMessage If the value is 1, do not display error message using jdeErrorSet(...). If the value is 0, display the error.
szErrorMessageId If an error occurs, return an error message ID (value). Otherwise, return four spaces.

4.7.3 Using Fetch Variables

Use fetch variables to retrieve and return specific information, such as a result; to define the table ID; and to specify the number of keys to use in a fetch.

Fetch Variable Description
idJDEDBResult APIs or JD Edwards EnterpriseOne functions, such as JDEDB_RESULT
idReturnValue Business function return value, such as ER_WARNING or ER_ERROR
idTableXXXXID Where XXXX is the table name, such as F4101 and F41021, the variable used to define the Table ID.
idIndexXXXXID Where XXXX is the table name, such as F4101 or F41021, the variable used to define the Index ID of a table.
usXXXXNumColToFetch Where XXXX is the table name, such as F4101 and F41021, the number of the column to fetch. Do not put the literal value in the API functions as the parameter.
usXXXXNumOfKeys Where XXXX is the table name, such as F4101 and F41021, the number of keys to use in the fetch.

4.7.3.1 Example: Using Standard Variables

This example illustrates the use of standard variables:

 /****************************************************************
  * Variable declarations
  **************************************************************/
 ID      idJDEDBResult  = JDEDB_PASSED;
 ID      idTableF0901   = ID_F0901;
 ID      idIndexF0901   = ID_F0901_ACCOUNT_ID;
 ID      idFetchCol[]   = { ID_CO, ID_AID, ID_MCU, ID_OBJ,
                            ID_SUB, ID_LDA, ID_CCT };
 ushort    usNumColToFetch = 7;
 ushort    usNumOfKeys     = 1;

 /***************************************************************
  * Structure declarations
  ****************************************************************/
 KEY3_F0901     dsF0901Key = {0}
 DSX51013_F0901 dsF0901 = {0}

 /***************************************************************
  * Main Processing
  ***************************************************************/
 /** Open the table, if it is not open **/
   if ((*lpdsInfo->lphRequestF0901) == (HREQUEST) NULL)
   {
      if ( (*lpdsInfo->lphUser) == (HUSER) 0L )
      {
         idJDEDBResult = JDB_InitBhvr ((void*)lpBhvrCom,
                                       &lpdsInfo->lphUser,
                                       (JCHAR *) NULL,
                                       JDEDB_COMMIT_AUTO);
      }
      if (idJDEDBResult == JDEDB_PASSED)
      {
         idJDEDBResult = JDB_OpenTable( (*lpdsInfo->lphUser),
                                         idTableF0901,
                                         idIndexF0901,
                                         (LPID)(idFetchCol),
                                         (ushort)(usNumColFetch),
                                         (JCHAR *) NULL,
                                         &lpdsInfo->hRequestF0901 );
      }
   }
 /** Retrieve Account Master - AID only sent **/
 if (idJDEDBResult == JDEDB_PASSED)
 {
    /** Set Key and Fetch Record **/
    memset( (void *)(&dsF0901Key),
            (int) _J('\0'), sizeof(KEY3_F0901) );
    jdeStrcpy ((char *) dsF0901Key.gmaid,
               (const JCHAR*) lpDS->szAccountID );
    idJDEDBResult = JDB_FetchKeyed ( lpdsInfo->hRequestF0901,
                                     idIndexF0901,
                                     (void *)(&dsF0901Key),
                                     (short)(1),
                                     (void *)(&dsF0901),
                                     (int)(FALSE) );
    /** Check for F0901 Record **/
    if (eJDEDBResult == JDEDB_PASSED)
    {
       statement
    }
 }