Creating Objects and Values

«« Previous
Next »»

This section describes how data objects and instances are created and values constructed.

1. Creating Objects
2. Constructing Values

Creating Objects

Creating an object or data object is equivalent to creating an instance of a data type or a class dynamically. While instances of classes can only be created as described in this section, instances of data types (data objects) that are declared with the statement DATA, or related statements, such as CONSTANTS, are created automatically as named data objects when their context is loaded into the internal session. Data objects only need to be created dynamically if the data type is made known for the first time only when the program is executed, or if large amounts of memory are allocated only for short periods of time.

Dynamically created objects can only be addressed using reference variables, and can be deleted from the internal session by the Garbage Collector if they are no longer referenced.

Objects can be created in the following ways:

◈ CREATE DATA
◈ CREATE OBJECT
◈ Instance operator NEW for creating objects in general expression positions and functional operand positions

Data objects and objects are created by default in the internal session of the current program, and only programs of the same internal session can access them. Alongside these, however,

◈ shared objects can be created in the shared memory and
◈ parameters created in the user memory.

can be created.

Note: The use of the statement ASSIGN LOCAL COPY to create objects is now obsolete.

Constructing Values

The attribute values of a new instance of a class can be constructed using the instance constructor of the class. The input parameters of the instance constructor can be filled using the EXPORTING addition of the statement CREATE OBJECT or using actual parameters for the instance operator NEW.

The values of dynamically or statically declared data objects can be constructed using the following constructor expressions:

◈ When anonymous data objects are created dynamically using the instance operator NEW, values for all data types, particularly structured and tabular types, can be constructed and assigned to the new data object.
◈ The value operator VALUE can also be used to construct the content of complex data objects (structures, internal tables). This is more than can be done using the VALUE addition.

Note: Like any constructor expression, the value operator VALUE can be used in general expression positions and functional operand positions, in particular the right side of an assignment to an inline declaration.

Example

Inline declarations of a reference variable dref and a structured variable dobj. The instance operator NEW creates an anonymous data object, referenced by dref. Using functional method calls, the instance operator NEW and the value operator VALUE are used to construct and assign values for the components of the structures.

DATA(dref) = NEW struct( col1 = meth->get_col1( )
                         col2 = meth->get_col1( ) ).

DATA(dobj) = VALUE struct( col1 = meth->get_col1( )
                           col2 = meth->get_col1( ) ).

⚫ CREATE DATA 


Syntax Forms

Defines the data type implicitly

1. CREATE DATA dref [ area_handle].

Defines the data type using predefined ABAP types

2. CREATE DATA dref [area_handle]
                   TYPE {abap_type|(name)}
                        [LENGTH len] [DECIMALS dec].

Defines the data type using an existing type

3. CREATE DATA dref [area_handle]
                   { {TYPE [LINE OF] {type|(name)}}
                   | {LIKE [LINE OF] dobj} }.

Creates data with reference to a type description object

4. CREATE DATA dref [area_handle]
                   TYPE HANDLE handle.

Creates reference variables

5. CREATE DATA dref [ area_handle]
                   TYPE REF TO {type|(name)}.

Creates internal tables

6. CREATE DATA dref [ area_handle]
                   { {TYPE [STANDARD]|SORTED|HASHED TABLE
                      OF [REF TO] {type|(name)}}
                   | {LIKE [STANDARD]|SORTED|HASHED TABLE OF dobj} }
                   [ {WITH [UNIQUE|NON-UNIQUE]
                           {KEY {comp1 comp2 ...}|(keytab)}|{DEFAULT KEY}}
                   | {WITH EMPTY KEY} ]
                   [INITIAL SIZE n].

Effect

The statement CREATE DATA creates an anonymous data object and assigns the reference to the data object of the dref reference variables.

By default, the data object is created in the internal session (heap) of the current program and remains there for as long as it is required. If no data references and no field symbols point to the data object or to a part of the data objects, it is deleted by Garbage Collector. The data object can be created as a shared object using the addition area_handle.

The reference variable dref must be declared as a data reference variable. The content of a data object that is created with CREATE DATA can only be accessed using dereferenced data variables or field symbols (see Data objects in operand positions).

The data type of the data object that is created can be defined using the addition TYPE and a type specification or with the addition LIKE and the specification of a data object. The syntax permits the dynamic definition of elementary data types, reference types, and table types. The addition HANDLE can reference any RTTS type description objects. According to the rules in section Assignments Between Data Reference Variables, the static type of the data reference variables has to be more general than the data type of the data object created, or be identical with it.

If a handleable exception is raised when the object is being created, the object is not created and the dref data reference variable retains its previous state.

Notes

◈ Unlike the statement DATA, CREATE DATA creates the data object at execution time. DATA creates declared data objects when the corresponding program unit is loaded.

◈ The statement CREATE DATA creates a heap reference. All references that point to the anonymous data object or its parts are also heap references and keep the data object alive. The same applies to field symbols.

◈ When a data type is used, the instance operator NEW acts like the statement CREATE DATA dref TYPE type and can be used in general expression positions.

◈ Unlike CREATE OBJECT, CREATE DATA does not set the return code sy-subrc.

Handleable Exceptions

CX_SY_CREATE_DATA_ERROR

◈ Cause: Illegal value for the addition DECIMALS.
Runtime Error: CREATE_DATA_ILLEGAL_DECIMALS

◈ Cause: Illegal value for the addition INITIAL SIZE.
Runtime Error: CREATE_DATA_ILLEGAL_INIT_SIZE

◈ Cause: Illegal value for the addition LENGTH.
Runtime Error: CREATE_DATA_ILLEGAL_LENGTH

◈ Cause: The addition LENGTH was used for a type other than c, n, x, or p.
Runtime Error: CREATE_DATA_LEN_NOT_ALLOWED

◈ Cause: The type specified dynamically in the addition TYPE is not typed completely.
Runtime Error: CREATE_DATA_NOT_ALLOWED_TYPE

◈ Cause: The type dynamically specified in the addition TYPE is not known.
Runtime Error: CREATE_DATA_UNKNOWN_TYPE

Non-Handleable Exceptions

◈ Cause: The variable dref does not have the correct type.
Runtime Error: CREATE_DATA_REFERENCE_EXPECTED

1. CREATE DATA dref

Syntax

CREATE DATA dref [area_handle].

Effect

If neither of the additions TYPE or LIKE is specified, the data reference variable dref must be fully typed. The data object is then created with the static data type of the data reference variable.

Example

Creates an internal table and a data object of type i. The data objects are created directly before they are used and are then initialized by the reference variables and passed to the garbage collector. The data objects are accessed by dereferencing the data references.

TYPES t_itab TYPE TABLE OF i WITH NON-UNIQUE KEY table_line.

DATA: tab_ref TYPE REF TO t_itab,
      i_ref   TYPE REF TO i.

IF tab_ref IS INITIAL.
   CREATE DATA tab_ref.
ENDIF.

tab_ref->* = VALUE #( FOR j = 1 UNTIL j > 10 ( j ) ).

IF tab_ref IS NOT INITIAL.
  IF i_ref IS INITIAL.
    CREATE DATA i_ref.
  ENDIF.
  LOOP AT tab_ref->* INTO i_ref->*.
    cl_demo_output=>write( |{ i_ref->* }| ).
  ENDLOOP.
ENDIF.
cl_demo_output=>display( ).

CLEAR: tab_ref, i_ref.

2. CREATE DATA - TYPE abap_type

Syntax

CREATE DATA dref [area_handle]
                 TYPE {abap_type|(name)}
                      [LENGTH len] [DECIMALS dec].

Effect

Creates a data object with an explicitly specified data type. For the data type, all predefined data types (apart from b and s) can be used that are more specific than the static type of dref or are identical to it. The name of the type can be specified as follows:

◈ abap_type

Specified directly and statically as abap_type.

◈ (name)

Specified as the content of a character-like data object name (not case-sensitive). The following can be specified for name:

     ◈ Literal or constant

If the data object name is specified as a character literal or as a constant, it can be evaluated statically and the specified type is identified as the used object.

     ◈ Variable

If the data object name is specified as a variable, it is specified only dynamically and the content is not evaluated statically.

When the statement is executed, name is not evaluated until runtime (in both cases).
In the ABAP types c, n, p, and x, the length of the data type dtype can be determined by specifying a numeric data object len after the addition LENGTH, which, when the statement is executed, contains a value within the length range defined for the type in question. If the addition LENGTH is not specified, the standard length from the table is used. For all other ABAP types, the length is determined by the value in the table and the addition LENGTH cannot be specified.

In the ABAP type p, the number of decimal places is determined by specifying a numeric data object dec after the addition DECIMALS. If DECIMALS is specified, the same applies as in the statement TYPES. If the addition DECIMALS is not specified, no decimal places are created. Before the decimal separator can be respected for operations with packed numbers, the program attribute fixed point arithmetic has to be set. If not, the addition DECIMALS only affects output formatting on dynpros and in the statement WRITE [TO]. For all other ABAP types and when specifying name dynamically, the addition DECIMALS is not permitted.

2.1 Creating Elementary Data Objects

The example demonstrates how elementary data objects are created.

Source Code

REPORT demo_create_simple_data.

CLASS create_demo DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS main.
  PRIVATE SECTION.
    CLASS-METHODS create_data IMPORTING
                                VALUE(typ) TYPE c
                                VALUE(len) TYPE i
                                VALUE(dec) TYPE i
                              RETURNING
                                VALUE(dref) TYPE REF TO data
                              RAISING cx_sy_create_data_error.
ENDCLASS.

CLASS create_demo IMPLEMENTATION.
  METHOD main.
    DATA dref TYPE REF TO data.
    FIELD-SYMBOLS <fs> TYPE any.


    DATA: type     LENGTH 10 TYPE c,
          length   TYPE i,
          decimals TYPE i.

    cl_demo_input=>add_field( EXPORTING text  = `Builtin ABAP Type`
                              CHANGING  field = type ).
    cl_demo_input=>add_field( EXPORTING text  = `Length`
                              CHANGING  field = length ).
    cl_demo_input=>request(   EXPORTING text  = `Decimals`
                              CHANGING  field = decimals ).

    TRY.
        dref = create_data( typ = type
                            len = length
                            dec = decimals ).
        ASSIGN dref->* TO <fs>.
        DESCRIBE FIELD <fs> TYPE type
                            LENGTH length IN BYTE MODE
                            DECIMALS decimals.
        cl_demo_output=>display( |{ type } { length } { decimals }| ).
      CATCH cx_sy_create_data_error.
        cl_demo_output=>display( |Error creating { type } {
                                                   length } {
                                                   decimals }| ).
    ENDTRY.
  ENDMETHOD.
  METHOD create_data.
    TRANSLATE typ TO LOWER CASE.
    CASE typ.
      WHEN 'd' OR 'decfloat16' OR 'decfloat34' OR 'f' OR 'i'
               OR 'string' OR 't' OR 'xstring'.
        CREATE DATA dref TYPE (typ).
      WHEN 'c' OR 'n' OR 'x'.
        CREATE DATA dref TYPE (typ) LENGTH len.
      WHEN 'p'.
        CREATE DATA dref TYPE p LENGTH len DECIMALS dec.
      WHEN OTHERS.
        RAISE EXCEPTION TYPE cx_sy_create_data_error.
    ENDCASE.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  create_demo=>main( ).

Description

The method create_data creates all elementary data objects that are possible using predefined ABAP types, depending on the input parameters passed.

3. CREATE DATA - TYPE, LIKE
4. CREATE DATA - HANDLE
5. CREATE DATA - REF TO
6. CREATE DATA - TABLE OF
7. CREATE DATA - AREA HANDLE

⚫ CREATE OBJECT


Syntax Forms

Defining a Class Implicitly

1. CREATE OBJECT oref [ area_handle] [ parameter_list].

Defining a Class Explicitly

2. CREATE OBJECT oref [ area_handle]
                     TYPE { class  [parameter_list] }
                        | { (name) [ parameter_list| parameter_tables] }.

Effect

The statement CREATE OBJECT creates an instance of a class or object and assigns the object reference to the reference variable oref. The instance constructor of the class is called directly after the object is created.

By default, the object is created in the internal session (or heap) of the current program and remains there for as long as it is required. If no more heap references point to the object, the following applies:

◈ No more object references point to the object.
◈ No more data references and no more field symbols point to an instance attribute or to a part of an instance attribute.

Also, if no more methods of the object are registered as event handlers, the object is deleted by the garbage collector. The addition area_handle can be used to create the object as a shared object.

The reference variable oref must be declared as an object reference variable. Instance components of an object created using CREATE OBJECT can only be accessed using object reference variables (see Data Objects in Operand Positions).

The addition TYPE can be used to specify the class of the new object. The static type of the object reference variables must be more general than or identical to the class of the new object (in accordance with the rules for Assignments Between Object Reference Variables).

The additions parameter_list and parameter_tables must be used to fill the non-optional input parameters of the first explicitly implemented instance constructor in the path of the inheritance tree between the instantiated class and the root class object. These additions can also be used to assign return values to the non-class-based exceptions of the instance constructor.

If a handleable exception is raised for the object in the runtime environment, the object is not created and the object reference variable oref is initialized. If a handleable exception is raised when the object is created in the instance constructor of the class, the object is deleted and the object reference variable oref is initialized.

Return Value

If the statement CREATE OBJECT is executed successfully, sy-subrc is set to 0. Values other than 0 can occur when specifying EXCEPTIONS in parameter_spec when non-class-based exceptions of the instance constructor are handled.

Notes

◈ Instances of a class can be created only where permitted by the addition CREATE of the statement CLASS DEFINITION.

◈ If the reference variable oref specified after CREATE OBJECT is passed simultaneously to the instance constructor, it points to the new object when this constructor is executed. To pass a reference to an existing object to the instance constructor, a different reference variable needs to be used.

◈ The statement CREATE OBJECT creates a heap reference. All references that point to the object or its parts are also heap references and keep the object alive. The same applies to field symbols that point to instance attributes or to their parts.

◈ When a class is used, the instance operator NEW acts like the statement CREATE OBJECT oref TYPE class and can be used in general expression positions.

◈ The return code sy-subrc is set to 0 if the statement is successful because the instance constructor is called. sy-subrc is set each time a method is called.

Handleable Exceptions

CX_SY_CREATE_OBJECT_ERROR

◈ Cause: An attempt was made to instantiate an abstract class.
Runtime Error: CREATE_OBJECT_CLASS_ABSTRACT

◈ Cause: The class specified in the addition TYPE does not exist.
Runtime Error: CREATE_OBJECT_CLASS_NOT_FOUND

◈ Cause: The class specified dynamically in TYPE does not match the type of the reference variable.
Runtime Error: MOVE_OREF_NOT_CONVERTIBLE

◈ Cause: An attempt was made to instantiate a private class externally.
Runtime Error: CREATE_OBJECT_CREATE_PRIVATE

◈ Cause: An attempt was made to instantiate a protected class externally.
Runtime Error: CREATE_OBJECT_CREATE_PROTECTED

Non-Handleable Exceptions

◈ Cause: A reference must be specified as the target variable.
Runtime Error: CREATE_OBJECT_NO_REFTYPE:

1. CREATE OBJECT oref 

Syntax

CREATE OBJECT oref [ area_handle] [ parameter_list].

Effect

If the addition TYPE is not specified, the object reference variable oref must be a class reference variable. An instance of the class is created that is the static type of the object reference variable. The static type of the class reference variable cannot be an abstract class, and in particular must not be the root class object.

Example

Creates an instance of a class c1 using an implicit reference to the static type of the reference variables.

CLASS c1 DEFINITION.
  ...
ENDCLASS.

...

DATA oref TYPE REF TO c1.

...

CREATE OBJECT oref.

2. CREATE OBJECT - TYPE 

Syntax

CREATE OBJECT oref [area_handle]
                   TYPE { class  [parameter_list] }
                      | { (name) [ parameter_list| parameter_tables] }.

Effect

Creates an instance of an explicitly specified class. Any concrete class that is more specific than or identical to the static type of the object reference variable oref can be specified. oref can be a class reference variable or an interface reference variable. The name of the class can be specified as follows:

◈ class

Specified directly and statically as class.

◈ (name)

Specified as the content of a character-like data object name. The data object name must contain the name of the class in uppercase letters when the statement is executed. The class name in name can also be an absolute type name. The following can be specified for name:

     ◈ Literal or constant

If the data object name is specified as a character literal or as a constant, it can be evaluated statically and the specified class is identified as the used object.

     ◈ Variable

If the data object name is specified as a variable, it is specified only dynamically and the content is not evaluated statically.
When the statement is executed, name is not evaluated until runtime (in both cases).

Notes

◈ If the class is specified dynamically, the parameters can either be specified statically in parameter_list or dynamically in parameter_tables.

◈ When a class is used, the instance operator NEW acts like the statement CREATE OBJECT oref TYPE class and can be used in general expression positions. Dynamic specification in name is not possible here.

Security Note

If used wrongly, creating objects dynamically can present a serious security risk. Names of classes that are passed to a program from the outside must be checked thoroughly before being used in dynamic statements. The system class CL_ABAP_DYN_PRG, for example, can be used to do this.

Example

Creates an instance of a class c1 using an explicit reference to the class. The static type of the reference variable is the root class object and is therefore more general than any other class.

CLASS c1 DEFINITION.
  ...
ENDCLASS.

...

DATA oref TYPE REF TO object.

...

CREATE OBJECT oref TYPE c1.

3. CREATE OBJECT - AREA HANDLE 

Syntax

CREATE OBJECT oref AREA HANDLE handle ...

Effect

This statement creates an object as a shared object in the area instance version of the shared memory, which is bound to the area handle referenced by handle. The implicitly or explicitly specified class must be defined as a shared memory enabled class using the SHARED MEMORY ENABLED addition of the CLASS statement.

handle expects an object reference variable whose static type is CL_ABAP_MEMORY_AREA or one of its subclasses (area class). When the statement is executed, handle must point to an area handle and the area handle must be associated with an area instance version with a change lock. A reference like this can be created in one of the following ways:

◈ Inherit the return value of the methods ATTACH_FOR_WRITE or ATTACH_FOR_UPDATE of an area class created using transaction SHMA.

◈ Inherit the return value of the GET_HANDLE_BY_... method of any area class.

◈ Inherit the return value of the method GET_IMODE_HANDLE of the predefined class CL_IMODE_AREA.

The latter is a reference to an area handle for the current internal session and the statement CREATE OBJECT operates as if the addition AREA HANDLE is not specified.

Notes

◈ The only shared object that can be addressed directly from an ABAP program after a connection to an area instance version is the instance of the area root class. All other objects have to be referenced in this instance.

◈ The static attributes of a shared object are not created in the shared memory. Instead, they are created when the shared memory-enabled class is loaded in the internal session of a program, like for every class. They can thus occur more than once and independently of one another in different programs.

Exceptions

Handleable Exceptions

CX_SHM_WRONG_HANDLE

◈ Cause: The area handle does not hold any change locks.

CX_SHM_ALREADY_DETACHED

◈ Cause: The area handle is not bound to an area instance version.

CX_SHM_OUT_OF_MEMORY

◈ Cause: There is not enough memory.

CX_SHM_OBJECT_NOT_SERIALIZABLE

◈ Cause: An attempt was made to create an object that cannot be serialized in an area instance that can be displaced using backup and recovery.

Creating a Class Instance as a Shared Object

The example demonstrates how an object is created in an area instance version.

Source Code

REPORT demo_create_shared_object.

CLASS class DEFINITION
            SHARED MEMORY ENABLED.
  PUBLIC SECTION.
    DATA attr TYPE string.
    METHODS set_attr IMPORTING text TYPE string.
ENDCLASS.

CLASS class IMPLEMENTATION.
  METHOD set_attr.
    attr = text.
  ENDMETHOD.
ENDCLASS.

CLASS demo DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS main.
ENDCLASS.

CLASS demo IMPLEMENTATION.
  METHOD main.

    DATA: handle TYPE REF TO cl_demo_area,
          root   TYPE REF TO cl_demo_root,
          exc    TYPE REF TO cx_shm_attach_error,
          oref   TYPE REF TO class.

    TRY.
        handle = cl_demo_area=>attach_for_write( ).
        CREATE OBJECT root AREA HANDLE handle.
        handle->set_root( root ).
        CREATE OBJECT root->oref AREA HANDLE handle TYPE class.
        oref ?= root->oref.
        oref->set_attr( `String in shared memory` ).
        CLEAR oref.
        handle->detach_commit( ).
      CATCH cx_shm_attach_error INTO exc.
        cl_demo_output=>display_text( exc->get_text( ) ).
        LEAVE PROGRAM.
    ENDTRY.

    TRY.
        handle = cl_demo_area=>attach_for_read( ).
        oref ?= handle->root->oref.
        cl_demo_output=>display_data( oref->attr ).
        CLEAR oref.
        handle->detach( ).
      CATCH cx_shm_attach_error INTO exc.
        cl_demo_output=>display_text( exc->get_text( ) ).
        LEAVE PROGRAM.
    ENDTRY.

  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  demo=>main( ).

Description

The AREA HANDLE addition is used to create an instance of the local class class in an area instance version of area CL_DEMO_AREA as a shared object. The generically typed attribute oref of area root class CL_DEMO_ROOT is used a reference variable. The attr attribute of the object is assigned a value when its set_attr method is called.

Once write access is completed using the DETACH_COMMIT method, read access takes place, which demonstrates how the object is accessed in the shared memory. This type of access can also take place in a different program, provided that the area instance version exists in the shared memory.

4. CREATE OBJECT - parameter_list 

Syntax

... [EXPORTING  p1 = a1 p2 = a2 ...]
    [EXCEPTIONS exc1 = n1 exc2 = n2 ... [OTHERS = n_others]].

Effect

The additions EXPORTING and EXCEPTIONS are used to pass actual parameters to the instance constructor statically or to assign return values to non-class-based exceptions.

◈ When using the addition EXPORTING, the non-optional input parameters p1 p2 ... of the instance constructor of the instantiated class must be specified using the type-friendly actual parameters a1 a2 ... (the other input parameters are optional). As in regular method calls, a1, a2, ... are general expression positions. In other words, functions and expressions can be passed as actual parameters, alongside data objects. Special rules apply in this case. If a subclass does not have an instance constructor implemented explicitly, the interface of the instance constructor from the next-highest superclass that explicitly implements the instance constructor is used.

◈ The addition EXCEPTIONS can be used to assign return values to non-class-based exceptions exc1 exc2....

The syntax and semantics are the same as in the parameter list for static method calls.

Example

Creates a Control Framework (CFW) dialog box and passes input parameters to the instance constructor of the global class CL_GUI_DIALOGBOX_CONTAINER. The class is defined implicitly using the static type of the reference variable dialog_box.

DATA dialog_box TYPE REF TO cl_gui_dialogbox_container.

CREATE OBJECT dialog_box
       EXPORTING parent = cl_gui_container=>desktop
                 width  = 1000
                 height = 350.

5. CREATE OBJECT - parameter_tables 

Syntax

... [PARAMETER-TABLE ptab]
    [EXCEPTION-TABLE etab].

Effect

The additions PARAMETER-TABLE and EXCEPTION-TABLE pass actual parameters dynamically to the instance constructor or assign return values to the non-class-based exceptions.

These additions can be used only if the instantiated class is specified dynamically in name. Using the special internal tables ptab and etab, they assign actual parameters to the input parameters of the instance constructor, or return values to the non-class-based exceptions.

The syntax and semantics are the same as those that apply to dynamic method calls using the statement CALL METHOD. The internal tables ptab and etab in particular must be defined with reference to the tables ABAP_PARMBIND_TAB and ABAP_EXCPBIND_TAB from the type group ABAP.

Example

Creates a Control Framework (CFW) dialog box dynamically and passes input parameters dynamically to the instance constructor of the global class CL_GUI_DIALOGBOX_CONTAINER. The class is defined explicitly using the TYPE addition.

DATA: container TYPE REF TO cl_gui_container,
      exc_ref TYPE REF TO cx_root.

DATA: class TYPE string VALUE `CL_GUI_DIALOGBOX_CONTAINER`,
      ptab TYPE abap_parmbind_tab.

ptab = VALUE #( ( name  = 'PARENT'
                  kind  = cl_abap_objectdescr=>exporting
                  value = REF #( cl_gui_container=>desktop ) )
                ( name  = 'WIDTH'
                  kind  = cl_abap_objectdescr=>exporting
                  value = REF #( 1000 ) )
                ( name  = 'HEIGHT'
                  kind  = cl_abap_objectdescr=>exporting
                  value = REF #( 300 ) ) ).

TRY.
    CREATE OBJECT container TYPE (class)
      PARAMETER-TABLE ptab.
  CATCH cx_sy_create_object_error INTO exc_ref.
    MESSAGE exc_ref->get_text( ) TYPE 'I'.
ENDTRY.

Example

The following program extract creates an object of a class SOME_CLASS dynamically, whose instance constructor expects a reference variable of the static type ANY_CLASS. The program has correct syntax, but the object is created only in systems in which the classes exist.

CONSTANTS:
  anycls  TYPE string VALUE `ANY_CLASS`,
  somecls TYPE string VALUE `SOME_CLASS`,
  param   TYPE string VALUE `PARA`.

DATA dref TYPE REF TO data.
TRY.
    CREATE DATA dref TYPE REF TO (anycls).
    ASSIGN dref->* TO FIELD-SYMBOL(<fs>).
    CREATE OBJECT <fs> TYPE (anycls).
  CATCH cx_sy_create_data_error
        cx_sy_create_object_error.
    ...
ENDTRY.

IF <fs> IS ASSIGNED.
  DATA(ptab) = VALUE abap_parmbind_tab(
    ( name = param
      kind = cl_abap_objectdescr=>exporting
      value =  REF #( <fs> ) ) ).
ENDIF.

DATA oref TYPE REF TO object.
TRY.
    CREATE OBJECT oref TYPE (somecls) PARAMETER-TABLE ptab.
  CATCH cx_sy_create_object_error
        cx_sy_dyn_call_parameter_error INTO DATA(exc).
    ...
ENDTRY.

This program can be executed in systems in which classes are declared as follows without raising exceptions.

CLASS any_class DEFINITION.
  ...
ENDCLASS.

CLASS some_class DEFINITION.
  PUBLIC SECTION.
    METHODS constructor IMPORTING para TYPE REF TO any_class.
    ...
ENDCLASS.

CLASS some_class IMPLEMENTATION.
  METHOD constructor.
    ...
  ENDMETHOD.
  ...
ENDCLASS.

⚫ NEW - Instance Operator


Syntax

... NEW type( ... ) ...

Effect

A constructor expression with the instance operator NEW creates an anonymous data object or an instance of a class. The result is a reference variable that points to the new object. The following can be specified for type:

◈ A non-generic data type dtype.

The operator NEW works in the same way as the statement CREATE DATA dref TYPE dtype, where dref stands for the result that points to the new anonymous data object. The result is a data reference variable of the static type dtype. A constructor expression of this type cannot be continued using a component selector.

◈ A class class.

The operator NEW works in the same way as the statement CREATE OBJECT oref TYPE class, where oref stands for the result that points to the new object. The result is an object reference variable of the static type class. A constructor expression of this type can be continued at general expression positions and functional positions, like an object reference variable, using an object component selector ->, and can be used at the same operand positions. Furthermore,

    ◈ It is possible to introduce standalone method calls including chained method calls.
    ◈ A single expression, which points to an attribute of the class using exactly one following object component selector, can also be used as the target field of assignments.

◈ The # character.

If the data type required in an operand position is unique and fully recognizable, the # character can be used instead of an explicitly specified type type and the operand type is used. If the operand type is not fully identifiable, the character # cannot be used, with the following exception: The operand can be evaluated after BASE when a structure or an internal table is constructed.

The same descriptions apply as for the CREATE statements. Once an object has been created, it is provided with values using the parameters in parentheses. The syntax used in pass by parameter depends on the type used. There are specialized categories of pass by parameter for complex types.

◈ Initial value for all types
◈ Initial value for all data types
◈ Structures
◈ Internal tables
◈ Classes

When a constructor expression is assigned to a reference variable using NEW, the information in the parentheses is evaluated before the new object is bound to the target variable.

Return Value

If an instance of a class is created successfully, the instance operator NEW sets sy-subrc to 0. Non-class-based exceptions of the instance constructor cannot be handled, which means that sy-subrc is never set to a value other than 0. The return code sy-subrc is not set when anonymous data objects are created.

Notes

◈ The instance operator NEW always creates a new temporary reference variable that points to the new object. The reference variable is used as the operand of a statement and then deleted. It is deleted when the current statement is closed or after the analysis of a relational expression once the truth value is determined. The new object is passed to the garbage collector if it is not passed to a heap reference or a field symbol after the temporary reference variable is deleted.

◈ Assignments to a reference variable also always create a temporary reference variable that is only assigned to the target variable afterwards. This means that the object pointed to by the target variable before the assignment can be addressed using it throughout the entire expression. This is the difference between NEW and the value operator VALUE.

Example

Creates an anonymous data object of the type i with the value 555 and an instance of a local class cls (derived implicitly from the static type of oref). In this case, the last statement can be written just as explicitly as oref = NEW cls( ) or with inline declaration instead of the previous DATA statement as DATA(oref) = NEW cls( ).

CLASS cls DEFINITION.
  ...
ENDCLASS.

DATA: dref TYPE REF TO data,
      oref TYPE REF TO cls.

dref = NEW i( 555 ).
oref = NEW #( ).

1. NEW - Initial Value for All Types 

Syntax

... NEW dtype|class|#( ) ...

Effect

If no parameters are specified,

◈ an anonymous data object retains its type-specific initial value,
◈ no values are passed to the instance constructor of an object.

This is possible for every non-generic data type dtype. The instance constructor of a class class can either have only optional input parameters or no input parameters at all. The # symbol can stand for appropriate types.

Example

After the following program section is executed, dref points to an empty internal table with the row type T100. Both constructor expressions have the same function.

TYPES t_itab TYPE TABLE OF t100 WITH EMPTY KEY.

DATA dref TYPE REF TO t_itab.

dref = NEW #( ).
dref = NEW t_itab( ).

2. NEW - Single Value for All Data Types 

Syntax

... NEW dtype|#( [let_exp] dobj ) ...

Effect

If dtype is a non-generic elementary data type, a structured type, a table type, or a reference type or # represents a type like this, a single data object dobj can be specified as a unnamed argument, of the type dtype or convertible to this type. dobj is a general expression position. The value of dobj is assigned to the new anonymous data object. The assignment is made in accordance with the applicable assignment rules. Optionally, a LET expression let_exp can be specified before the data object to define local auxiliary fields.

Notes

◈ In particular, an expression specified for dobj can itself be a constructor expression or contain a constructor expression.
◈ When a constructor expression is assigned to a reference variable using NEW, the original reference is made available in the entire expression in the target variable. The target variable is not overwritten until the expression is closed.

Example

Constructs an anonymous data object of the type string, whose value is determined using a string expression.

PARAMETERS input TYPE c LENGTH 10 LOWER CASE DEFAULT 'World'.

DATA dref TYPE REF TO string.

dref =  NEW string( `Hello ` && ` ` && input && `!` ).

MESSAGE dref->* TYPE 'I'.

Example

For each row read, a structured anonymous data object is created in a SELECT loop. The content of the row is assigned to this data object. The object is created in the general expression position of the statement APPEND and the new data reference is appended directly to an internal table with the appropriate row type. The result is a table that references all new anonymous data objects.

DATA dref_tab LIKE TABLE OF REF TO t100 WITH EMPTY KEY.

DATA wa TYPE t100.

SELECT *
       FROM t100
       WHERE sprsl = @sy-langu
       INTO @wa.
  APPEND NEW #( wa ) TO dref_tab.
ENDSELECT.

3. NEW - Structures 

Syntax

... NEW dtype|#( [let_exp]
                 [BASE dobj]
                 comp1 = dobj1 comp2 = dobj2 ... ) ...

Effect

If dtype is a structured data type or # represents a type like this, the individual components can be specified as named arguments comp1, comp2, ... Each component of the new anonymous data object can be assigned a data object with the same data type as the component (or whose data type can be converted to this data type). This assignment is made for all data types in accordance with the appropriate assignment rules.

An addition BASE can be specified in front of the individual component assignments, followed by a data object dobj. dobj is a functional operand position. The type of dobj must be convertible to the type of the anonymous data object. If BASE is specified, the content of dobj is assigned to the anonymous data object before the individual components are assigned. If the character # is specified for the type of the anonymous data object and the type cannot be determined from the operand position of the VALUE expression, the type of dobj is used for this expression (if identifiable and structured).

dobj1, dobj2, ... are general expression positions. An optional LET LET expression let_exp can be specified before the assignments to define local auxiliary fields that can be used on the right side of the assignments.

If a component is itself structured, either a suitable data object can be assigned to the entire substructure or its components can be specified using the structure component selector (-). Non-specified components are ignored and keep their type-specific initial value or the value assigned using BASE. It is not possible to assign multiple values to a component, regardless of how the component is addressed. If the addition BASE is used, at least one component must be specified.

Notes

◈ The assignments can be specified in any order within the parentheses.

◈ If a component with a complex data type is constructed in an argument position, the value operator VALUE can be used. This affects tabular components, for example. This is also possible for structured components but is not necessary since the subcomponents can be addressed using the structure component selector.

◈ When a constructor expression is assigned to a reference variable using NEW, the original reference is made available in the entire expression in the target variable. The target variable is not overwritten until the expression is closed. In the case of the value operator VALUE, however, the target variable can only be assigned to an auxiliary variable using LET and is then no longer available.

Example

Constructs an anonymous data object with a nested structure type and tabular components. The subcomponents of col2 are addressed directly using the structure component selector. VALUE must be used to construct the tabular component col3. This is because the syntax used to construct internal tables cannot be specified directly as an argument.

TYPES: t_itab TYPE TABLE OF i WITH EMPTY KEY,
       BEGIN OF t_struct,
         col1 TYPE i,
         BEGIN OF col2,
           col1 TYPE i,
           col2 TYPE t_itab,
         END OF col2,
         col3 TYPE t_itab,
       END OF t_struct.

DATA itab TYPE t_itab.

DATA dref TYPE REF TO data.

dref = NEW t_struct( col1 = 1
                     col2-col1 = 2
                     col2-col2 = itab
                     col3 = VALUE #( ( 1 )
                                     ( 2 )
                                     ( 3 ) ) ).

Example

Uses BASE. The type of the return value of base1 is applied in the construction of ref1. This is not possible in the construction of ref2, since base2 is not structured. In both results, col1 and col3 have the values xx or zz assigned using BASE, whereas col2 has the directly assigned value BB.

TYPES:
  BEGIN OF struct,
    col1 TYPE c LENGTH 2,
    col2 TYPE c LENGTH 2,
    col3 TYPE c LENGTH 2,
  END OF struct.

DATA(base1)   = VALUE struct( col1 = 'xx' col2 = 'yy' col3 = 'zz' ).
DATA(ref1)  = NEW #( BASE base1 col2 = 'BB' ).

DATA(base2)   = `xxyyzz`.
DATA(ref2)  = NEW struct( BASE base2 col2 = 'BB' ).

cl_demo_output=>write(   ref1->* ).
cl_demo_output=>display( ref2->* ).

4. NEW - Internal Tables 

Syntax

... NEW dtype|#( [let_exp]
                 [BASE itab]
                 [FOR for_exp1
                  FOR for_exp2
                  ... ]
                 ( line_spec1 )
                 ( line_spec2 )
                   ... ) ...

Additions

1. ... BASE itab

2. ... FOR for_exp

Effect

If dtype is a tabular data type or # stands for a type like this, the table rows of the constructed table are created as follows:

◈ Firstly, an optional LET expression let_exp can be specified to define local auxiliary fields whose values can be used to construct the table rows.
◈ An optional start value for the content can be specified for the content of the internal table after BASE (see below).
◈ One more optional consecutive iteration expressions can then be specified using FOR (see below).
◈ Then the table rows are constructed in one or more internal parentheses by specifying line_spec. Each inner parenthesis constructs one or more rows in accordance with the information in line_spec and inserts them into the new internal table in accordance with the rules for the statement INSERT ... INTO TABLE. The rows are inserted in the order of the parentheses.

The constructed rows must meet the requirements of the statement INSERT for inserting work areas using table keys and therefore be compatible with the row type. There is one exception to this: When constructing a standard table, where the rows are only appended, the value can be shorter than the row length (for row types c and x), in which case it is padded on the right with blanks or hexadecimal 0.

Notes

◈ When a constructor expression is assigned to a reference variable using NEW, the original reference is made available in the entire expression in the target variable. The target variable is not overwritten until the expression is closed. In the case of the value operator VALUE, however, the target variable can only be assigned to an auxiliary variable using LET and is then no longer available.

◈ The operand type for line_spec in the inner parentheses is the row type of the table type specified using dtype or #, which means it is always uniquely identifiable. Constructor expressions in this place can therefore always derive the required data type using #.

Addition 1

... BASE itab

Effect

An addition, BASE, followed by an internal table, itab, can be specified in front of the lines that you want to insert. This is a functional operand position. The row type of itab must be convertible to the row type of the return value. If BASE is specified, the content of itab is assigned to the return value before the individual rows are inserted. If the character # is specified for the type of the return value and the type cannot be determined from the operand position of the constructor expression, the type of itab is used for this expression (if identifiable).

Addition 2

... FOR for_exp

Effect

If one or more iteration expressions are specified one after the other using FOR, this means that the lines constructed in line_spec for every iteration of the last FOR expression are inserted into the target table. When constructing table rows in line_spec, the visible local work areas and field symbols of the iteration expressions can also be used.

◈ If conditional iterations are used, the new table rows created in freely defined iteration steps.
◈ If table iterations are used, the rows of existing internal tables are evaluated. This is known as table comprehensions, since new table rows can be constructed from the rows of existing internal tables.

Notes

◈ The term "table comprehension" is derived from similar concepts used in many other languages, where it is also known as "list comprehension".
◈ Table filtering can be implemented more efficiently using the filter operator FILTER.
◈ Conditional iterations and table comprehensions are also possible with FOR expressions for mesh paths.

Example

Constructs three anonymous internal tables with an elementary row type. The first table is filled with three rows. The second row is initial. The second and third tables are filled with the rows of the first table and three further rows. Using BASE and LINES OF here has the same effect.

TYPES t_itab TYPE TABLE OF i WITH EMPTY KEY.

DATA(dref1) = NEW t_itab( ( 1 ) (  ) ( 3 ) ).

DATA(dref2) = NEW t_itab( BASE dref1->*
                          (   ) ( 5 ) (  ) ).

DATA(dref3) = NEW t_itab( ( LINES OF dref1->* )
                          (   ) ( 5 ) (  ) ).

cl_demo_output=>write(   dref1->* ).
cl_demo_output=>write(   dref2->* ).
cl_demo_output=>display( dref3->* ).

Example

Constructs an anonymous internal table with a structure row type with substructures and tabular components.

TYPES: BEGIN OF t_struct1,
         col1 TYPE i,
         col2 TYPE i,
       END OF t_struct1,
       BEGIN OF t_struct2,
         col1 TYPE i,
         col2 TYPE t_struct1,
         col3 TYPE TABLE OF t_struct1 WITH EMPTY KEY,
       END OF t_struct2,
       t_itab TYPE TABLE OF t_struct2 WITH EMPTY KEY.

DATA dref TYPE REF TO data.

dref = NEW t_itab( ( col1 = 1
                     col2-col1 = 1
                     col2-col2 = 2
                     col3 = VALUE #( ( col1 = 1 col2 = 2 )
                                     ( col1 = 3 col2 = 4 ) ) )
                   ( col1 = 2
                     col2-col1 = 2
                     col2-col2 = 4
                     col3 = VALUE #( ( col1 = 2 col2 = 4 )
                                     ( col1 = 6 col2 = 8 ) ) ) ).

4.1 NEW - line_spec 

Syntax

... line
  | {LINES OF itab [FROM idx1] [TO idx2] [USING KEY keyname]} ...

Alternatives:

1. ... line

2. ... LINES OF jtab [FROM idx1] [TO idx2] [USING KEY keyname]

Effect

Specifies one or more rows to be inserted when constructing an internal table with the instance operator NEW.

Alternative 1

... line

Effect

Specifies a row. line can be specified in exactly the same way as in the parenthesis of an expression NEW line_type( ... ), with one exception. Here, line_type is the row type of the internal table and a corresponding row is constructed.

The exception to this rule are tabular row types. The syntax in the inner parenthesis does not allow further parentheses to be nested directly.

Short Form for Structured Row Types

If the row type of the internal table is a structured type, the following short form can be used:

NEW dtype|#( [let_exp]
             [BASE itab]
             col1 = dobj11 ... ( col2 = dobj12 col3 = dobj13 ... )
                               ( col2 = dobj22 col3 = dobj23 ... )
                               ...
             col1 = dobj31 col2 = dobj32 ... ( col3 = dobj33 ... )
                                             ( col3 = dobj43 ... )
             ... ).

This has the same semantics as the following:

NEW dtype|#( [let_exp]
             [BASE itab]
             ( col1 = dobj11 ... col2 = dobj12 col3 = dobj13 ... )
             ( col1 = dobj11 ... col2 = dobj22 col3 = dobj23 ... )
             ...
             ( col1 = dobj31 col2 = dobj32 ... col3 = dobj33 ... )
             ( col1 = dobj31 col2 = dobj32 ... col3 = dobj43 ... )
             ... ).

Values can be assigned to individual structure components outside of the inner parentheses. An assignment of this type applies to all following inner parentheses until the next assignment is made to the component in question. Assignments outside of the inner parentheses must be followed by at least one inner parenthesis. A component cannot be assigned a value more than once in the construction of a structure, which means that a component assigned a value outside of the inner parentheses can no longer be specified in an inner parenthesis. A component can be specified again outside the inner parentheses and any components previously specified in an inner parenthesis can also be listed outside the parenthesis.

Notes

◈ The restriction that the content of tabular row types cannot be constructed directly in the inner parentheses applies for reasons of legibility (human and machine) and is not a functional restriction. The expression VALUE line_type( ... ) can be specified to construct the content of a tabular row, where line_type is the tabular row type.
◈ Specifying CONV line_type( ... ) for the inserted values is also a way of meeting the compatibility requirement with the row type.
◈ The short form for structured row types enables columns of internal tables that are to be given an identical value in blocks to be filled more easily.

Alternative 2

... LINES OF jtab [FROM idx1] [TO idx2] [USING KEY keyname]


Effect

Specifies multiple rows. The rows are taken from the internal table jtab and inserted into the target table as a block. The same applies to jtab and the additions FROM, TO, and USING KEY as to the addition LINES OF of the statement INSERT and the block is inserted in accordance with these rules. jtab is a functional operand position.

Notes

◈ The rows from jtab are inserted into the target table using the table key only, which means that jtab must be compatible with the target type.

◈ If there is a conflict with an existing unique table key, a non-handleable exception is always raised when inserting multiple rows from an internal table using the statement INSERT.

◈ When standard tables are created, the rows of the table jtab are appended to the target table in the same way as with the statement APPEND LINES OF.

Example

Constructs an internal table itab containing the first and last three rows of the previously constructed table alpha.

DATA:
  alpha TYPE TABLE OF string WITH EMPTY KEY,
  itab  LIKE REF TO alpha.

alpha = VALUE #(  FOR j = 0 UNTIL j >= strlen( sy-abcde )
                  ( substring( val = sy-abcde
                               off = j
                               len = 1  ) ) ).

itab = NEW #( ( LINES OF alpha FROM 1 to 3 )
              ( `-` )
              ( LINES OF alpha FROM lines( alpha ) - 2
                               TO   lines( alpha ) ) ).
cl_demo_output=>display( itab->* ).

5. NEW - Classes 

Syntax

... NEW class|#( [let_exp] p1 = a1 p2 = a2 .. ) ...

Effect

If a class class is specified or # stands for a class like this, the non-optional input parameters p1 p2 ... of the instance constructor of the instantiated class must be filled using the type-friendly actual parameters a1 a2 .... The optional input parameters do not need to be filled. The description of the statement CREATE OBJECT specifies how values are passed by parameter and which classes can be used. No parameters are passed for a class without an explicit instance constructor A LET expression let_exp can be specified (optional) before the parameter to define local auxiliary fields.

Like an object reference variable of the type class, a constructor expression NEW class( ... ) can be specified before the object component selector -> and in chained attribute accesses and chained method calls. A chained method call of this type can be specified as a standalone statement. This persists the result for the duration of the statement. Even a single expression without a following object component selector can be specified as a standalone statement. In this case, the only constructor executed is the constructor that needs to save a reference to the new object elsewhere (if it needs to be persisted).

The following applies in particular to an attribute access NEW class( ... )->attr:

◈ it can be specified as a writable expression in a result position.
◈ A specified offset/length +off(len) can be appended (if the data type is suitable), except if the chaining uses the statement ASSIGN as a memory area.

Method chainings cannot be specified between the constructor expression and the attribute here.

Notes

◈ This can be seen as a functional call of the instance constructor. As with function calls of functional methods, no non-class-based exceptions can be handled.
◈ When the instance constructor is called, the return code sy-subrc is set to 0. Values other than 0 are not possible, since non-class-based exceptions cannot be handled.

Example

Constructs an instance of the class c1 when the method m2 of the class c2. Here, an input parameter of the type in question is expected.

CLASS c1 DEFINITION.
  PUBLIC SECTION.
    METHODS constructor IMPORTING p1 TYPE i p2 TYPE i.
ENDCLASS.

CLASS c1 IMPLEMENTATION.
  METHOD constructor.
    ...
  ENDMETHOD.
ENDCLASS.

CLASS c2 DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS m2 IMPORTING oref TYPE REF TO c1.
ENDCLASS.

CLASS c2 IMPLEMENTATION.
  METHOD m2.
    ...
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  c2=>m2( NEW #( p1 = 1 p2 = 2 ) ).

Example

Uses a constructor expression with NEW in various positions. The temporary reference variable created using NEW is persisted during each statement.

CLASS c1 DEFINITION.
  PUBLIC SECTION.
    DATA     a1 TYPE i.
    METHODS: m1 RETURNING value(p) TYPE i,
             m2.
ENDCLASS.

CLASS c1 IMPLEMENTATION.
  METHOD m1.
    ...
  ENDMETHOD.
  METHOD m2.
    ...
  ENDMETHOD.
ENDCLASS.

DATA num TYPE i.

START-OF-SELECTION.

  num = NEW c1( )->a1.
  NEW c1( )->a1 = num.
  num = NEW c1( )->m1( ).
  NEW c1( )->m2( ).
  NEW c1( ).

Example

Displays a time stamp created in a constructor that only exists while the statement is being executed.

CLASS utc DEFINITION.
  PUBLIC SECTION.
    DATA ts TYPE timestamp.
    METHODS constructor.
ENDCLASS.

CLASS utc IMPLEMENTATION.
  METHOD constructor.
    GET TIME STAMP FIELD ts.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  cl_demo_output=>display_text(
    |{ NEW utc( )->ts TIMESTAMP = ISO }| ).

Example

Constructor expression with NEW on the left side of an expression. The temporary reference variable created using NEW exists only while the statement is being executed, however the reference to the object is assigned to the reference variable oref of the class class. This persists the object.

CLASS class DEFINITION.
  PUBLIC SECTION.
    DATA attr TYPE string.
    METHODS constructor.
ENDCLASS.

DATA oref TYPE REF TO class.

CLASS class IMPLEMENTATION.
  METHOD constructor.
    oref = me.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  NEW class( )->attr = 'foo'.
  cl_demo_output=>display( oref->attr ).

⚫ VALUE - Value Operator


Syntax

... VALUE type( ... ) ...

Effect

A constructor expression with the value operator VALUE creates a result of a data type specified using type. The following can be specified for type:

● A non-generic data type dtype.
● Exceptions to this rule are:
    ● When an initial value VALUE #( ) is passed to a generically typed formal parameter, the type is derived from the generic type.
    ● The operand can be evaluated after BASE when a structure or an internal table is constructed.
    ● When used for a single table expression VALUE #( table_expo ).

The operator

● creates initial values for any non-generic data types
● constructs the content of
    ● structured types
    ● table types
● controls the type of the result of table expressions and so enables a default value to be specified for unfound rows

The content of the result is determined by the parameters specified in parentheses. The syntax used in pass by parameter depends on the type used when the value was constructed. There are specialized categories of pass by parameter for each possible type.

● Pass by parameter when constructing values:
    ● Initial value for all types
    ● Structures
    ● Internal tables
● If a single table expression is specified as a parameter, VALUE does not construct a value. Instead it controls the type of the result.

In an assignment of a constructor expression to a data object using VALUE, the data object is used directly. It is overwritten in full with an initial value or start value before being assigned the values specified in the parentheses.

Notes

● Elementary data types and reference types cannot be specified explicitly with VALUE for constructing values, except when an initial value is created. Unlike when using the instance operator NEW, the correct result can be achieved by using direct assignments. For this reason, it is not necessary to specify unnamed arguments as single values when using NEW (and also not allowed). The use of VALUE to control table expressions is not affected by this, since any valid data type can be specified here.

● Arithmetic calculations with the results of VALUE for constructing values are not possible (except when creating an initial value). This means that constructor expressions of this type cannot be specified directly in the operand positions of arithmetic expressions. Constructor expressions using VALUE used to control table expressions are not affected by this, if the table expressions can be used for calculations using valid results.

● The conversion operator CO closes the gap where no elementary data objects can be constructed in operand positions using VALUE.

● If a constructor expression with VALUE is not used as the source of an assignment to a data object, the value operator VALUE creates a new temporary data object whose data type is determined by the specified type and whose content is determined by the parameters passed. This data object is used as the operand of a statement and then deleted. It is deleted when the current statement is closed or after the analysis of a relational expression once the truth value is determined.

● In assignments to a data object, the target variable is used directly and no temporary data object is created. This variable is initialized or overwritten in full before the assignment of the values specified in the parentheses. Its original value, however, is still available in an optional LET expression. This is the difference between VALUE and the instance operator NEW.

Example

Constructs the values of a structure of type TB declared inland.

DATA(WA) = VALUE td( spryly = 'ER'
                       AR = 'DEMO'
                       ms = '111'
                       text = '...' ).

1. VALUE - Initial Value for All Types

Syntax

... VALUE dtype|#( ) ...

Effect

If no parameters are specified in the parentheses, the return value is set to its type-specific initial value. This is possible for any non-generic data types dtype. The # character can stand for appropriate statically identifiable operand types. The type is still derived as follows from the generic type if the parameter when VALUE #( ) is passed to a generically typed formal parameter:

◈ string for csequence and clike
◈ xstring for xsequence
◈ decfloat34 for numeric and decfloat
◈ p with the length 8 and no decimal places if p is generic
◈ The standard key for a standard table type with generic primary table key

Other generic data types (except for table types) that are explicitly generic with respect to their secondary table keys cannot be made more concrete and produce a syntax error. More specifically, this applies to the types c, n, and x with generic lengths.

Notes

◈ VALUE with pass by value is used only to construct certain complex values (structures, internal tables). VALUE without pass by value, on the other hand, is a general method for creating type-compliant initial values in any operand positions.

◈ Rules apply when deriving the type in cases where # is specified for actual parameters that can be passed to generically typed formal parameters. These rules prevent syntax errors in programs that call a procedure and the procedure makes the full typing of a formal parameter type more general by switching to a generic type.

Example

Creates a suitable initial structure for a non-optional input parameter of a method.

CLASS c1 DEFINITION.
  PUBLIC SECTION.
    TYPES: BEGIN OF t_struct,
             col1 TYPE i,
             col2 TYPE i,
           END OF t_struct.
    CLASS-METHODS m1 IMPORTING p TYPE t_struct.
ENDCLASS.

CLASS c1 IMPLEMENTATION.
  METHOD m1.
    ...
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  c1=>m1( VALUE #( ) ).

1.1 Value Operator, Type Inference 

This example demonstrates a type inference for the value operator VALUE.

Source Code

REPORT demo_value_type_inference.

CLASS demo DEFINITION.
  PUBLIC SECTION.
    TYPES c10 TYPE c LENGTH 10.
    CLASS-METHODS:
      main,
      meth1 IMPORTING p TYPE c10,
      meth2 IMPORTING p TYPE c,
      meth3 IMPORTING p TYPE csequence,
      descr IMPORTING p TYPE any.
ENDCLASS.

CLASS demo IMPLEMENTATION.
  METHOD main.
    demo=>meth1( p = VALUE #(  ) ).
    cl_demo_output=>line( ).

   "demo=>meth2( p = value #(  ) ). "not possible
    cl_demo_output=>line( ).

    demo=>meth3( p = VALUE #(  ) ) ##type.
    cl_demo_output=>display( ).
  ENDMETHOD.
  METHOD meth1.
    descr( p ).
  ENDMETHOD.
  METHOD meth2.
    descr( p ).
  ENDMETHOD.
  METHOD meth3.
    descr( p ).
  ENDMETHOD.
  METHOD descr.
    DATA type   TYPE string.
    DATA length TYPE i.
    DESCRIBE FIELD p TYPE type.
    IF type = 'g'.
      type = 'STRING'.
      length = strlen( p ).
    ELSE.
      DESCRIBE FIELD p LENGTH length IN CHARACTER MODE.
    ENDIF.
    cl_demo_output=>write( |{ type } { length }| ).
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  demo=>main( ).

Description

Passes constructor expressions with the value operator VALUE for initial values to differently typed formal parameters of methods.

◈ Fully typed formal parameter
When the method meth1 is called with a fully typed formal parameter, the operand type for # is identified using this parameter and the result of the value operator is an initial field of type c with length 10.
◈ Formal parameter typed generically with c
No call is possible here, since there is no inference rule for the generic type c.
◈ Formal parameter typed generically with csequence
In accordance with the inference rule for csequence, the result of the value operator is an initial field of type string. This is indicated by a syntax check warning.

2. VALUE - Structures

Syntax

... VALUE dtype|#( [let_exp]
                   [BASE dobj]
                   comp1 = dobj1 comp2 = dobj2 ... ) ...

Effect

If dtype is a structured data type or # represents a type like this, the individual components can be specified as named arguments comp1, comp2, ... Each component of the return value can be assigned a data object with the same data type as the component (or whose data type can be converted to this data type). This assignment is made for all data types in accordance with the appropriate assignment rules.

An addition BASE can be specified in front of the individual component assignments, followed by a data object dobj. dobj is a functional operand position. The type of dobj must be convertible to the type of the return value. If BASE is specified, the content of dobj is assigned to the return value before the individual component are assigned. If the character # is specified for the type of the return value and the type cannot be determined from the operand position of the VALUE expression, the type of dobj is used for this expression (if identifiable and structured).

dobj1, dobj2, ... are general expression positions. An optional LET expression let_exp can be specified before the assignments to define local auxiliary fields that can be used on the right side of the assignments.

If a component is itself structured, either a suitable data object can be assigned to the entire substructure or its components can be specified using the structure component selector (-). Non-specified components are ignored and keep their type-specific initial value or the value assigned using BASE. It is not possible to assign multiple values to a component, regardless of how the component is addressed. If the addition BASE is used, at least one component must be specified.

If the VALUE operator is used as the source of an assignment to a structure, this structure is first initialized after any LET expressions are evaluated or the structure is first assigned the data object dobj after BASE. The assignments are then executed directly in the parenthesis, with the structure components as target fields.

Notes

◈ The assignments can be specified in the parenthesis after the optional additions LET ... IN and BASE, in any order.
◈ If a component with a complex data type is constructed in an argument position, the value operator VALUE can be used again. This affects tabular components, for example. This is also possible for structured components but is not necessary since the subcomponents can be addressed using the structure component selector.
◈ The rule that a target structure of an assignment is first overwritten in full and then edited directly can produce unexpected results if structure components on the left side are specified as data objects pending assignment on the right side. Instead of the assignments on the right side being evaluated and assigned first, the current value is used in every assignment. If the entire structure or structure components from the left side are needed on the right side, however, they can be saved in local auxiliary variables using a LET expression, since this expression is evaluated first.
◈ If the target table is specified as dobj after BASE in an assignment to an existing structure, no assignment takes place before the component assignments are evaluated, and the target structure just keeps its value instead.

Example

Three different ways of filling a nested structure struct with values. The structure is given the same values each time.

TYPES:  BEGIN OF t_col2,
           col1 TYPE i,
           col2 TYPE i,
        END OF t_col2.

TYPES: BEGIN OF t_struct,
         col1 TYPE i,
         col2 TYPE t_col2,
       END OF t_struct.

DATA: struct TYPE t_struct,
      col2 TYPE t_col2.

struct = VALUE t_struct( col1 = 1
                         col2-col1 = 1
                         col2-col2 = 2 ).

col2   = VALUE   t_col2( col1 = 1
                         col2 = 2 ).
struct = VALUE t_struct( col1 = 1
                         col2 = col2 ).

struct = VALUE t_struct( col1 = 1
                         col2 = VALUE #( col1 = 1
                                         col2 = 2 ) ).

Example

This example displays the effects produced if components of a target structure are used as assignment sources. After the assignment to struct1, col1 and col2 have the value 0 and col3 and col4 have the value 5. The original values of col1 and col2 are not switched and col3 is not given the original value of col4. The assignment to struct2 demonstrates how the behavior can be changed by saving the target object to an auxiliary variable x and using this object. In struct2, the original values of col1 and col2 are switched and col3 is given the original value of col4.

DATA:
  BEGIN OF struct,
    col1 TYPE i VALUE 1,
    col2     TYPE i VALUE 2,
    col3 TYPE i VALUE 3,
    col4 TYPE i VALUE 4,
  END OF struct,
  struct1 LIKE struct,
  struct2 LIKE struct.

struct1 = struct2 = struct.

struct1 = VALUE #( col1 = struct1-col2
                   col2 = struct1-col1
                   col4 = 5
                   col3 = struct1-col4 ).

cl_demo_output=>write( struct1 ).

struct2 = VALUE #( LET x = struct2 IN
                   col1 = x-col2
                   col2 = x-col1
                   col4 = 5
                   col3 = x-col4 ).

cl_demo_output=>display( struct2 ).

Example

Uses BASE. The type of the return value of base1 is applied in the construction of struct1. This is not possible in the construction of struct2, since base2 is not structured. In both results, col1 and col3 have the values xx or zz assigned using BASE, whereas col2 has the directly assigned value BB.

TYPES:
  BEGIN OF struct,
    col1 TYPE c LENGTH 2,
    col2 TYPE c LENGTH 2,
    col3 TYPE c LENGTH 2,
  END OF struct.

DATA(base1)   = VALUE struct( col1 = 'xx' col2 = 'yy' col3 = 'zz' ).
DATA(struct1) = VALUE #( BASE base1 col2 = 'BB' ).

DATA(base2)   = `xxyyzz`.
DATA(struct2) = VALUE struct( BASE base2 col2 = 'BB' ).

cl_demo_output=>write( struct1 ).
cl_demo_output=>display( struct2 ).

Example

Uses BASE with a CORRESPONDING expressions for an assignment between two incompatible structures. struct1 is first assigned the identically named components of struct2 and then the remaining components are filled explicitly. The same can be done for the columns of an internal table by performing an appropriate assignment within an iteration using FOR.

DATA:
  BEGIN OF struct1,
    col1 TYPE i,
    col2 TYPE i,
    col3 TYPE i,
    col4 TYPE i,
    col5 TYPE i,
  END OF struct1,
  BEGIN OF struct2,
    col1 TYPE i VALUE 1,
    col2     TYPE i VALUE 2,
    col3 TYPE i VALUE 3,
  END OF struct2.

struct1 = VALUE #( BASE CORRESPONDING #( struct2 ) col4 = 4 col5 = 5 ).

3. VALUE - Internal Tables

Syntax

... VALUE dtype|#( [let_exp]
                   [BASE itab]
                   [FOR for_exp1
                    FOR for_exp2
                    ... ]
                   ( line_spec1 )
                   ( line_spec2 )
                     ... ) ...

Additions

1. ... BASE itab

2. ... FOR for_exp

Effect

If dtype is a tabular data type or # stands for a type like this, the table rows of the constructed table are created as follows:

◈ Firstly, an optional LET expression let_exp can be specified to define local auxiliary fields whose values can be used to construct the table rows.
◈ An optional start value for the content can be specified for the content of the internal table after BASE.
◈ One more optional consecutive iteration expressions can then be specified using FOR (see below).
◈ Then the table rows are constructed in one or more internal parentheses by specifying line_spec. Each inner parenthesis constructs one or more rows in accordance with the information in line_spec and inserts them into the new internal table in accordance with the rules for the statement INSERT ... INTO TABLE. The rows are inserted in the order of the parentheses.

The constructed rows must meet the requirements of the statement INSERT for inserting work areas using table keys and therefore be compatible with the row type. There is one exception to this: When constructing a standard table, where the rows are only appended, the value can be shorter than the row length (for row types c and x), in which case it is padded on the right with blanks or hexadecimal 0.

If the VALUE operator is used as the source of an assignment to an internal table, this table is first initialized after the evaluation of the LET expression (if available) or is assigned the content of itab. The line_spec data is then evaluated and inserted directly in the target table.

Notes

◈ In an assignment of the constructor expression to an internal table, its existing rows cannot be used directly as an argument in line_spec. This is because this table is deleted before line_spec is evaluated or overwritten by the content of itab. If the entire internal table or rows from the left side are needed on the right side, however, they can be saved in local auxiliary variables using a LET expression, since this expression is evaluated first.
◈ The operand type for line_spec in the inner parentheses is the row type of the table type specified using dtype or #, which means it is always uniquely identifiable. Constructor expressions in this place can therefore always derive the required data type using #.

Addition 1

... BASE itab

Effect

An addition, BASE, followed by an internal table, itab, can be specified in front of the lines that you want to insert. This is a functional operand position. The row type of itab must be convertible to the row type of the return value. If BASE is specified, the content of itab is assigned to the return value before the individual rows are inserted. If the character # is specified for the type of the return value and the type cannot be determined from the operand position of the constructor expression, the type of itab is used for this expression (if identifiable).

Notes

◈ If the addition BASE is not specified, only new content of tables can be constructed with the value operator and not enhanced. If the same table is specified after BASE to which the constructor expression is assigned, further rows can be inserted in this table.
◈ If the target table is specified as itab after BASE in an assignment to an existing internal table, no assignment takes place before line_spec is evaluated, and the target table just keeps its value instead.

Addition 2

... FOR for_exp

Effect

If one or more iteration expressions are specified one after the other using FOR, this means that the lines constructed in line_spec for every iteration of the last FOR expression are inserted into the target table. When constructing table rows in line_spec, the visible local work areas and field symbols of the iteration expressions can also be used.

If conditional iterations are used, the new table rows created in freely defined iteration steps.
If table iterations are used, the rows of existing internal tables are evaluated. This is known as table comprehensions, since new table rows can be constructed from the rows of existing internal tables.

Notes

◈ The term "table comprehension" is derived from similar concepts used in many other languages, where it is also known as "list comprehension".
◈ Table filtering can be implemented more efficiently using the filter operator FILTER.
◈ Conditional iterations and table comprehensions are also possible with FOR expressions for mesh paths.
◈ For tasks that can be solved with table comprehensions and also with special assignments for components (in particular the component operator CORRESPONDING), it is best to use assignments (see example).
◈ If the VALUE operator is used, it should be noted that assignments to internal tables are also initialized (or given the content of itab after base) even in the case of table comprehensions after the evaluation of a LET expressions. The target table is then used directly. The original table can therefore not be used directly in the FOR expressions (unless it is assigned to an auxiliary variable after LET).

Example

Constructs an internal table with an elementary row type. jtab is filled with three rows and itab with six rows. The first row inserted in itab is initial and the last three rows are taken from the table jtab filled previously.

TYPES t_itab TYPE TABLE OF i WITH EMPTY KEY.

DATA(jtab) = VALUE t_itab( ( 10 ) ( 20 ) ( 30 ) ).

DATA(itab) = VALUE t_itab( ( ) ( 1 ) ( 2 ) ( LINES OF jtab ) ).

cl_demo_output=>display( itab ).

Example

Constructs an internal table with an elementary row type of type string and fills it with three rows. The result is a table that is given the previous day, current day, and next day formatted for the current language environment. Today's date is produced using a method. To make sure that the method is called only once, the return value is assigned to a local auxiliary field in a LET expression.

CLASS date DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS get RETURNING VALUE(d) TYPE d.
ENDCLASS.

CLASS date IMPLEMENTATION.
  METHOD get.
    d = sy-datlo.
  ENDMETHOD.
ENDCLASS.

TYPES t_date_tab TYPE TABLE OF string  WITH EMPTY KEY.

DATA date_tab TYPE t_date_tab.

START-OF-SELECTION.

  date_tab = VALUE #(
               LET d = date=>get( ) IN
               ( |{ CONV d( d - 1 ) DATE = ENVIRONMENT }| )
               ( |{         d       DATE = ENVIRONMENT }| )
               ( |{ CONV d( d + 1 ) DATE = ENVIRONMENT }| ) ).

Example

Constructs an internal table with a structured row type and fills it with two rows. The structures are filled with values component by component.

TYPES: BEGIN OF t_struct,
         col1 TYPE i,
         col2 TYPE i,
       END OF t_struct,
       t_itab TYPE TABLE OF t_struct WITH EMPTY KEY.

DATA itab TYPE t_itab.

itab = VALUE #( ( col1 = 1 col2 = 2 )
                ( col1 = 3 col2 = 4 ) ).

Example

Constructs a ranges table and fills it with four rows while using the short form for structured row types.

DATA itab TYPE RANGE OF i.

itab = VALUE #( sign = 'I'  option = 'BT' ( low = 1  high = 10 )
                                          ( low = 21 high = 30 )
                                          ( low = 41 high = 50 )
                            option = 'GE' ( low = 61 )  ).

Example

Constructs an internal table with a tabular row type and fills it with two rows. The first row is assigned a table that is already filled. The second row is constructed using VALUE.

TYPES: t_itab1 TYPE TABLE OF i       WITH EMPTY KEY,
       t_itab2 TYPE TABLE OF t_itab1 WITH EMPTY KEY.

DATA itab1 TYPE t_itab1.
DATA itab2 TYPE t_itab2.

itab1 = VALUE #( ( 1 ) ( 2 ) ( 3 ) ).
itab2 = VALUE #( ( itab1 )
                 ( VALUE t_itab1( ( 4 ) ( 5 ) ( 6 ) ) ) ).

Example

Uses BASE. The table type of base1 or base2 is applied in the construction of tab1 and tab2. This is not possible in the construction of tab3 since the row type of base2 is not structured and suitable for specifying individual components in the following parentheses. The type itab2 is specified explicitly for tab3. This is possible since the row type of base2 can be converted into this row type Sorted tables are constructed, which means that the rows in the results are also sorted.

TYPES:
  itab1 TYPE SORTED TABLE OF string WITH UNIQUE KEY table_line,
  BEGIN OF struct,
    col1 TYPE c LENGTH 2,
    col2 TYPE c LENGTH 2,
    col3 TYPE c LENGTH 2,
  END OF struct,
  itab2 TYPE SORTED TABLE OF struct WITH UNIQUE KEY col1 col2 col3.

DATA(base1) = VALUE itab1(
                ( `x1y1z1` )
                ( `x2y2z2` )
                ( `x3y3z3` ) ).
DATA(base2) = VALUE itab2(
                ( col1 = 'x1' col2 = 'y1' col3 = 'z1' )
                ( col1 = 'x2' col2 = 'y2' col3 = 'z2' )
                ( col1 = 'x3' col2 = 'y3' col3 = 'z3' ) ).

DATA(tab1) = VALUE #( BASE base1
               ( `A1B1B1` )
               ( `A2B2B2` ) ).

DATA(tab2)  = VALUE #(
                BASE base2
                ( col1 = 'A1' col2 = 'B1' col3 = 'C1' )
                ( col1 = 'A2' col2 = 'B2' col3 = 'C2' ) ).

DATA(tab3) = VALUE itab2( BASE base1
               ( col1 = 'A1' col2 = 'B1' col3 = 'C1' )
               ( col1 = 'A2' col2 = 'B2' col3 = 'C2' ) ).

cl_demo_output=>write(   tab1  ).
cl_demo_output=>write(   tab2 ).
cl_demo_output=>display( tab3 ).

Example

Uses BASE to append rows to existing rows in an internal table.

TYPES itab TYPE TABLE OF string WITH EMPTY KEY.

DATA(itab) =
  VALUE itab(
    ( `a` ) ( `b` ) ( `c` ) ).

...

itab =
  VALUE #(
    BASE itab
    ( `d` ) ( `e` ) ( `f` ) ).

cl_demo_output=>display( itab ).

Example

Uses BASE to append rows to an internal table in a loop. After the output, it possible to see how the same function can be applied using an iteration expression with FOR.

DATA itab TYPE TABLE OF i WITH EMPTY KEY.

DO 10 TIMES.
  itab = VALUE #( BASE itab ( ipow( base = sy-index exp = 2 ) ) ).
ENDDO.

cl_demo_output=>display( itab ).

DATA jtab LIKE itab.
jtab = VALUE #( FOR j = 1 UNTIL j > 10
                ( ipow( base = j exp = 2 ) ) ).
ASSERT jtab = itab.

3.1 VALUE - line_spec 

Syntax

... line
  | {LINES OF itab [FROM idx1] [TO idx2] [USING KEY keyname]} ...

Alternatives:

1. ... line

2. ... LINES OF jtab [FROM idx1] [TO idx2] [USING KEY keyname]

Effect

Specifies one or more rows to be inserted when constructing an internal table with the value operator VALUE.

Note

If rows from the target table or the entire target table are used in line_spec in an assignment of a constructor expression using the value operator VALUE to an internal table, these rows are deleted or overwritten by a start value before both variants of line_spec are evaluated. The target table must therefore be saved in an auxiliary variable first. A LET expression can be used to do this.

Alternative 1

... line

Effect

Specifies a row. line can be specified in exactly the same way as in the parenthesis of an expression NEW line_type( ... ), with one exception. Here, line_type is the row type of the internal table and a corresponding row is constructed.

The exception to this rule are tabular row types. The syntax in the inner parenthesis does not allow further parentheses to be nested directly.

Short Form for Structured Row Types

If the row type of the internal table is a structured type, the following short form can be used:

VALUE dtype|#( [let_exp]
               [BASE itab]
               col1 = dobj11 ... ( col2 = dobj12 col3 = dobj13 ... )
                                 ( col2 = dobj22 col3 = dobj23 ... )
                                 ...
               col1 = dobj31 col2 = dobj32 ... ( col3 = dobj33 ... )
                                               ( col3 = dobj43 ... )
               ... ).
This has the same semantics as the following:

VALUE dtype|#( [let_exp]
               [BASE itab]
               ( col1 = dobj11 ... col2 = dobj12 col3 = dobj13 ... )
               ( col1 = dobj11 ... col2 = dobj22 col3 = dobj23 ... )
               ...
               ( col1 = dobj31 col2 = dobj32 ... col3 = dobj33 ... )
               ( col1 = dobj31 col2 = dobj32 ... col3 = dobj43 ... )
               ... ).

Values can be assigned to individual structure components outside of the inner parentheses. An assignment of this type applies to all following inner parentheses until the next assignment is made to the component in question. Assignments outside of the inner parentheses must be followed by at least one inner parenthesis. A component cannot be assigned a value more than once in the construction of a structure, which means that a component assigned a value outside of the inner parentheses can no longer be specified in an inner parenthesis. A component can be specified again outside the inner parentheses and any components previously specified in an inner parenthesis can also be listed outside the parenthesis.

Notes

◈ The restriction that the content of tabular row types cannot be constructed directly in the inner parentheses applies for reasons of legibility (human and machine) and is not a functional restriction. The expression VALUE line_type( ... ) can be specified to construct the content of a tabular row, where line_type is the tabular row type.
◈ Specifying CONV line_type( ... ) for the inserted values is also a way of meeting the compatibility requirement with the row type.
◈ The short form for structured row types enables columns of internal tables that are to be given an identical value in blocks to be filled more easily.
◈ As in VALUE, the table rows are constructed in accordance with the rules for the instance operator NEW, since new table rows are created here too and the restriction for VALUE dictating that no values of elementary data objects can be constructed cannot be applied.

Alternative 2

... LINES OF jtab [FROM idx1] [TO idx2] [USING KEY keyname]

Effect

Specifies multiple rows. The rows are taken from the internal table jtab and inserted into the target table as a block. The same applies to jtab and the additions FROM, TO, and USING KEY as to the addition LINES OF of the statement INSERT and the block is inserted in accordance with these rules. jtab is a functional operand position.

Notes

◈ The rows from jtab are inserted into the target table using the table key only, which means that jtab must be compatible with the target type.
◈ If there is a conflict with an existing unique table key, a non-handleable exception is always raised when inserting multiple rows from an internal table using the statement INSERT.
◈ When standard tables are created, the rows of the table jtab are appended to the target table in the same way as with the statement APPEND LINES OF.

Example

Effects when using the left side of an assignment in specified rows.

◈ In the construction of itab1, the left side is used after BASE. Here, the original three rows are passed as a start value before the specified rows are evaluated. Two single rows are then appended to this start value.

◈ In the construction of itab2, the left side is initialized before the specified rows are evaluated. This is why no rows are inserted by LINES OF itab2 and the table contains only two single rows.

◈ In the construction of itab3, the left side is given its original three rows as a start row using BASE. These rows are then appended again using LINES OF, before the two single rows are appended.

◈ In the construction of itab4, the left side is saved in the auxiliary variable x before it is initialized. It is then used in LINES OF. The result is the same as when the left side is used after BASE.
TYPES itab TYPE STANDARD TABLE OF i WITH EMPTY KEY.

DATA(itab) = VALUE itab( ( 1 ) ( 2 ) ( 3 ) ).

data(itab1) = itab.
itab1 = VALUE #(  BASE itab1
                 ( 4 )
                 ( 5 ) ).
cl_demo_output=>write( itab1 ).

data(itab2) = itab.
itab2 = VALUE #( ( LINES OF itab2 )
                  ( 4 )
                  ( 5 ) ).
cl_demo_output=>write( itab ).

data(itab3) = itab.
itab3 = VALUE #( BASE itab3
                 ( LINES OF itab3 )
                 ( 4 )
                 ( 5 ) ).
cl_demo_output=>write( itab3 ).

data(itab4) = itab.
itab4 = VALUE #( LET x = itab4 IN
                 ( LINES OF x )
                 ( 4 )
                 ( 5 ) ).
cl_demo_output=>write( itab4 ).

cl_demo_output=>display( ).

⚫ Shared Objects


Shared objects are objects in areas of shared memory. These areas are accessed using area handles.

◎ Overview
◎ Areas
◎ Area instance versions
◎ Objects
◎ Classes and interfaces
◎ Restrictions

1. Shared Objects - Overview

Shared objects are instances of classes or anonymous data objects in shared memory. Named data objects can be stored as attributes of classes. The memory area of the shared memory for shared objects is the shared object memory. Its size is determined by the profile parameter abap/shared_objects_size_MB.

Shared objects are managed using areas. Areas and their properties can be created and edited using transaction SHMA.

Shared Memory-Enabled Classes

The prerequisite for storing an instance of a class in the shared memory is that the class of the object has to be defined with the SHARED MEMORY ENABLED addition of the CLASS statement, or that the property Shared memory-enabled has to be selected in Class Builder. Each area is linked to a global area root class, which can contain separate data and references to other instances of shared memory-enabled classes or to anonymous data objects in its attributes.

Areas and Area Instances

An area is the template for area instances in the shared memory. Multiple area instances with different names can be created from one area instance. In addition, there can be multiple versions of an area instance (area instance versions). Version IDs are used to distinguish between the versions. All area instance versions of the same area instance name make up an area instance. In the simplest case (without versioning), an area instance consists of a single area instance version.

Area Classes and Area Handles

When an area is defined in transaction SHMA, a global and final area class (with the same name) is generated as a subclass of CL_SHM_AREA. Class CL_SHM_AREA itself is a direct subclass of CL_ABAP_MEMORY_AREA. In an ABAP program, an area is accessed exclusively using the methods of the generated area class. There are static methods for binding an ABAP program (or its internal session) to area instances in the shared memory (attach methods). Binding creates an instance of the area class as an area handle, and creates an area lock at the same time. The ABAP program can access the bound area instance version using the area handle and thus access the shared objects that are stored there. The area handle also contains the methods for deleting the connection or the lock (detach methods).

Access to Objects

The shared objects in an area instance version are addressed by references, which are obtained using the area handle. The shared objects within an area instance version can refer to each other without any restrictions. An ABAP program can contain references to shared objects provided that it is bound to an area instance version. Area instances themselves are self-contained so that they cannot contain any references to other area instance versions or be contained in an internal session. There is one exception to this rule, provided that an area instance is bound to an internal session for writing or updating. During this time, there can be references in the area instance to objects in the internal session or to other area instances that are similarly bound.

Note

Do not confuse area instances or area instance versions with instances of classes. In particular, an area instance is not an instance of an area class. Area instances are managed areas (the actual areas) in the shared memory in which shared objects can be stored, and that are addressed by area handles.

2. Shared Objects - Areas

An area is a repository object for storing shared objects. It is the template for area instance versions in the shared memory. An identically named area class and any area root class are assigned to each area. Areas are created and managed in transaction SHMA. Various properties can be assigned to an area in transaction SHMA. From a technical point of view, the properties are taken into consideration when the area class is generated, or they are stored automatically in the attributes of the area class when an area handle is created.

2.1 Areas - Basic Properties 

An area has the following basic properties:

◈ Area Name

The name of an area. This is also the name of the generated global area class and is therefore unique across the system. It is advisable to follow the naming conventions for global classes in the current system and use the prefix "CL_".

◈ Area Root Class

The area root class is a global shared memory-enabled class that has to be assigned to an area when it is defined. A non-empty area instance version has to contain at least one instance of the area root class as a root object that the other objects are referenced from. The ROOT attribute of a corresponding area handle is generated as a reference variable with the static type of the area root class.

◈ Client-Specific Area

An area can be identified as client-specific. In this case, an area instance of the area is identified by a client identifier and by its name. In client-specific areas, the area class methods refer to accessing an area instance on the current client. In client-specific areas, these methods have the additional input parameter CLIENT, which enables explicit access to other clients. Note the restriction that it is not possible to set locks by specifying the client explicitly if automatic area building is possible. For methods where this makes sense, the value of constant CL_SHM_AREA=>ALL_CLIENTS can be passed to CLIENT to execute it on all clients. In the standard setting, the runtime-dependent area properties are client-specific. There is no check to see whether a specified client actually exists in the system.

◈ Automatic Area Building

If this property is set, a new area instance is created automatically at the time selected in the area build type. If this property is to be set, an area constructor class must be specified in the dynamic area properties, and the area has to be bound to the application server.

◈ Transactional Area

An area instance version of a transactional area is not active immediately after a change lock is removed using method DETACH_COMMIT of the area handle. It becomes active after the next database commit instead. Between the time when the lock is removed and the database commit, the area instance version appears as in the structure. No new change locks can be set on the area instance, and shared locks access the previous active version. In non-transactional areas, the state of the area instance version is set to active as soon as method DETACH_COMMIT is executed.

With transactional areas, methods FREE_AREA, FREE_INSTANCE, INVALIDATE_AREA and INVALIDATE_INSTANCE of the area class have a parameter called AFFECT_SERVER that can be used to control the cross-server invalidation.

Transactional areas enable data or objects in the area instance versions to join such areas to database contents. To ensure that the reference between database content and shared objects is not damaged, changes to the shared objects should be made only in contexts in which the database changes were also made in the current application. During updating for example, changes to the shared objects should only be made while the corresponding update functional module is being executed.

2.2 Areas - Fixed Area Properties 

Like basic properties, fixed properties of an area can be only be changed by developers. When the fixed properties of an area are changed during operation, all area instances of the area are set to status expired. The area class does not have to be regenerated however.

◈ Area Binding

The context specified for this property defines the visibility and lifetime of the area instance version of the instance. Possible contexts are:
   
     ◈ Application server

Area instance versions exist until the application server is shut down.
 
      ◈ User session

Area instances exist until the last ABAP session of the current user session ends. For area binding, every user logon to an AS ABAP counts individually. This also applies in particular when users log on using external interfaces such as RFC or ICF.

     ◈ Top level transaction

The top level transaction is the first program in a call sequence. These area instances exist for as long as the ABAP memory assigned to a call sequence is loaded, in other words for as long as the internal session of the top level transaction is loaded.

◈ Area Instance Versioning

This property defines whether there can be only one or more than one area instance version of an area instance. Without versioning, there is only one version and the area instance is equivalent to this area instance version. With versioning, there can be multiple versions in different states, and an area instance is the quantity of all area instance versions with the same area instance name.

Without versioning, multiple readers from different internal sessions can access an area instance after it has been built. Writes are only possible if no shared locks are in force. With versioning, a change lock can be set on an area instance that still has shared locks.

The maximum number of versions of an area instance can be specified in the runtime-dependent area properties.

2.3 Areas - Dynamic Area Properties 

The dynamic properties of an area are not respected when the area class is generated. These properties can be changed by developers only. When the dynamic properties of an area are changed dynamically during operation, the current area instance versions (versions that are being built, active or obsolete) are not affected. The new dynamic properties are not used until the next change lock is set in the corresponding version that is being built.

◈ Area Constructor Class

Any global class that implements the interface SHM_IF_SHM_BUILD_INSTANCE can be specified as an area constructor class. The implementation of the interface method IF_SHM_BUILD_INSTANCE~BUILD is used as the area constructor.

An area constructor class has to be specified if automatic area building is activated in the basic properties. The interface method IF_SHM_BUILD_INSTANCE~BUILD of the specified class is called implicitly in a separate ABAP session when an area is built automatically.

An area constructor class can be specified if automatic area building is not activated in the basic properties. The interface method IF_SHM_BUILD_INSTANCE~BUILD of the current area constructor class can be called explicitly in the current internal session (using the method BUILD generated in every area class).

An example of how to implement the interface method IF_SHM_BUILD_INSTANCE~BUILD in an area constructor class can be found under Area Constructor Class.

◈ Displacement Type

This property determines whether and how instances of the area can be displaced. Displacement may be necessary if the available addressing area of the shared memory is not sufficient for all area instance versions. This may be the case in 32-bit systems, but should not be an issue for 64-bit systems. Possible displacement types are:

     ◈ Displacement Not Possible

Area instance versions cannot be displaced. If the addressing area is no longer sufficient for all area instance versions, a runtime error occurs.
     ◈ Displacement Possible

Area instance versions can be displaced. The content is lost (complete displacement). Displacement only takes place if no area handle is bound to the area instance at the same time, or if there are no locks on the area instance. This means that only those area instances can be displaced that have exactly one version (the active version) with no shared lock at the time of displacement.

2.4 Areas - Runtime-Dependent Area Properties 

The same points apply to runtime-dependent properties of an area as to dynamic area properties, with the difference that they can be given default values by a developer and can also be changed without a developer key, by administrators for example, during Customizing or operation.

With client-dependent areas, the runtime-dependent area properties can be set individually for each client. The default values are used if no separate runtime-dependent area properties are specified for a client.

◈ Area Build Type

This property specifies when area instance versions of the area should be built automatically using the area constructor that is implemented in the area constructor class. Possible values are:

     ◈ No Autostart

Area instance versions are not built automatically. The basic property automatic area building must not be activated with this setting.

     ◈ Autostart for Read Request

A new area instance version is built automatically if there is a read access and no active area instance version is available. The basic property automatic area building must be activated.

     ◈ Autostart for Read Request and Every Invalidation

Automatic area building as is the case with Autostart for Read Request, and additionally with read access of a displaced or expired area instance version. The basic property automatic area building must be activated.

◈ Size of an Area Instance Version

This property determines the maximum permitted size of an individual area instance version. Possible values are:

     ◈ No limit

No restriction on size.

     ◈ Maximum ... KB

Size restriction up to a specified number of kilobytes. If the maximum size is less than the current size of an area instance version during operation, read access is still possible, but change access is not. Change access is not possible again until the size of the current area instance version falls below the maximum size.

◈ Number of Versions of an Area Instance

This property specifies the maximum number of versions of an area instance. Possible values are:

     ◈ No limit

No restriction.

     ◈ Maximum ...

Restriction up to the number you specify. If you want to specify a number, the fixed area property area instance versioning must have been activated. If the maximum number of area instance versions during operation is less than the current number of area instance versions, no versions can be deleted although new versions can be created once the number is below the maximum number permitted.

◈ Lifetime of an Area Instance

This property controls the lifetime of area instance versions. Possible values are:

     ◈ No specification

The lifetime is not restricted.

     ◈ Expires after ... minutes

If a number is specified here, an area instance version becomes obsolete this number of minutes after a change lock is released.

     ◈ Refresh after ... minutes

If a number is specified here, the area constructor in the constructor class is called this number of minutes after a change lock is released. The prerequisite for this is that the basic property automatic area building is activated.

      ◈ Without read access ... minutes

If a number is specified here, an area instance version becomes obsolete this number of minutes after a read or change lock is released.

3. Shared Objects - Area Instance Versions

Shared objects are stored and managed in area instance versions. In an ABAP program, area instance versions and thus shared objects are accessed exclusively by means of area handles. Area locks are set and area instance versions can acquire different states.

◈ Area Handles
◈ Area Locks
◈ States of Area Instance Versions

The transaction SHMM provides an overview of the area instances in the shared objects memory of the current application server, the corresponding locks, and the states of the area instance versions. The class CL_SHM_UTILITIES is used to query the attributes of area instances in programs.

3.1 Shared Objects - Area Handles

Creating Area Handles

Area handles are instances of the area class of an area. An individual area handle is created using one of the following static methods from the area class. During this process, a corresponding area lock is set:

◈ ATTACH_FOR_WRITE
◈ ATTACH_FOR_UPDATE
◈ ATTACH_FOR_READ

There is also a MULTI_ATTACH method for creating multiple area handles at once. The methods return a reference to the area handle that is created. Each area handle is bound to exactly one area instance version. This area instance version has a certain state, depending on the method.

Binding an area handle to an area instance version has the same effect as setting one of the following area locks on the area instance:

◈ ATTACH_FOR_WRITE and ATTACH_FOR_UPDATE create an exclusive lock
◈ ATTACH_FOR_READ creates a shared lock

Creating Area Instance Versions

Method ATTACH_FOR_WRITE creates a new area instance version if the existing locks permit this. Specifying a name makes it possible to create multiple area instances of an area, each with its own versioning. If no name is specified, the content of constant CL_SHM_AREA=>DEFAULT_INSTANCE is used as the default value. It is advisable to always work with explicit and unique names. Until the binding is removed, changes can be performed in the current internal session on the bound area instance version.

Changing Area Instance Versions

Method ATTACH_FOR_UPDATE is created if existing locks allow this,

◈ Creates a new version as a copy of the active area instance version, in the case of areas with versioning, or
◈ Binds the area handle to an existing active area instance version in the case of areas without versioning.

Specify a name to select an area instance. If no name is specified, the content of constant CL_SHM_AREA=>DEFAULT_INSTANCE is used as the default value. Until the binding is removed, changes can be performed in the current internal session on the bound area instance version.

Reading Area Instance Versions

Method ATTACH_FOR_READ binds the area handle to an existing area instance version if existing locks allow this. Specify a name to select an area instance. If no name is specified, the content of constant CL_SHM_AREA=>DEFAULT_INSTANCE is used as the default value. Until the binding is removed, reads can be performed in the current internal session on the bound area instance version.

Deactivating Area Handles

The following instance methods of the area class removes the binding of individual area handles:

◈ DETACH removes a shared lock.
◈ DETACH_COMMIT removes an exclusive lock and confirms the changes that have been made.
◈ DETACH_ROLLBACK removes an exclusive lock without confirming the changes that have been made.

Two other static methods DETACH_AREA and DETACH_ALL_AREAS are used to remove multiple bindings at once. Once the binding between an area handle and the area instance version has been removed, the area handle is inactive and can no longer be used. Removing a binding also removes the corresponding area lock and might change the state of the relevant area instance version.

Additional Methods

The methods of area handles listed above are normally used when working with shared objects. There are also additional methods for special applications. Transaction SHMM provides a program-independent user interface for these methods.

◈ Invalidating Versions

Methods INVALIDATE_INSTANCE or INVALIDATE_AREA can be used to set one or more active area instance versions to "obsolete". This prevents new shared locks from being set for this version, although existing shared locks continue to exist.

◈ Deleting Versions

Methods FREE_INSTANCE or FREE_AREA can be used to set one or more active or obsolete area instance versions to "expired". This removes all shared locks and no new shared locks can be set on these versions.

◈ Information About Area Instances

Method GET_INSTANCE_INFOS returns information about all of the area instances of an application server in an internal table.

◈ Information About Area Handles

The methods GET_LOCK_KIND, IS_VALID, IS_ACTIVE_VERSION, IS_SHARED, HAS_ACTIVE_PROPERTIES, and GET_DETACH_INFO provide information about locks and the state of an area handle.

◈ Explicit Call of the Area Constructor

The method BUILD can be used to call the area constructor of an area explicitly in the current internal session. This method is a standardized mechanism for building area instances.

3.2 Shared Objects - Area Locks

An area lock is set on the area instance version each time an area instance version is accessed, that is, each time an area handle is bound. The lock exists as long as an area handle is bound to an area instance version and rejects any attempts made to bind other area handles to the area instance. As long as no lock is set, a program cannot access area instances.

Shared Locks

A shared lock is set when an area handle is bound to an area instance version using the method ATTACH_FOR_READ. There can be a maximum of one shared lock on an area instance within an internal session. Across multiple sessions, there can be multiple shared locks on an area instance version.

Once a shared lock is set in an internal session, reads can be performed on the corresponding area instance version and its objects until the method DETACH is executed.

Note

If a shared lock is always set immediately before an access and is then deleted again afterwards, note that the same version may not necessarily be accessed the next time. A shared lock is always set on the active area instance version.

Exclusive Locks

An change lock is either an exclusive lock or an update lock. An exclusive lock is set if an area handle is bound to an area instance version using the method ATTACH_FOR_WRITE, and an update lock is set if an area handle is bound using the method ATTACH_FOR_UPDATE.

On an application server, there can be a maximum of one exclusive lock on an area instance. An exclusive lock locks an area instance exclusively, that is, no parallel shared locks are possible on this version. Parallel reads are possible on the same area instance if area instance versioning is activated.

Once an exclusive lock has been set in an internal session, reads and changes on the area instance version and its objects are possible until the methods DETACH_COMMIT or DETACH_ROLLBACK are executed.

◈ A new, empty area instance version is created when writes are performed.
◈ The update:
     ◈ Binds the existing active version for changing in the case of areas without versioning
     ◈ Creates a copy of the active area instance version and binds it for changing in the case of areas with versioning

Within an internal session, a maximum of one exclusive lock can be set for an area instance, using ATTACH_FOR_WRITE and ATTACH_FOR_UPDATE. These methods cannot be used to set an exclusive lock if an exclusive lock already exists within the same internal session for any area instance version; attempting to do so raises the exception CX_SHM_CHANGE_LOCK_ACTIVE. On the other hand, the method MULTI_ATTACH can be used to set multiple parallel exclusive locks on multiple area instance versions.

Releasing Locks

Unless the method DETACH is used, shared locks are released automatically when an internal session ends. Exclusive locks must always be released explicitly using DETACH_COMMIT or DETACH_ROLLBACK. In the following situations, there must not be any exclusive locks for an area instance version, since this would produce the runtime error SYSTEM_SHM_CHANGE_LOCK_ACTIVE:

◈ Closing of an internal session (except when using the statement LEAVE TRANSACTION (or function "/n")). The statement LEAVE TRANSACTION releases all exclusive locks using the method DETACH_ROLLBACK.
◈ Database commit in the case of transactional areas.
◈ Program calls with SUBMIT AND RETURN and CALL TRANSACTION in the case of transactional areas.

If all reference variables to an area handle are initialized and the area handle is then deleted by the garbage collector while it holds a lock, the lock remains and is not deleted. The area instance version can still be accessed, although exclusive locks can no longer be released. This produces the runtime error above.

Note: In transactional areas, note that an exclusive lock released using the method DETACH_COMMIT has to be released finally with a database commit before an internal session or program call (SUBMIT, CALL TRANSACTION, or LEAVE TO TRANSACTION) is closed.

3.3 Shared Objects - States of Area Instance Versions

Area instance versions can have the following states.

"Building"

An area instance version that has a change lock is being built. Change locks automatically create a building version.

"Active"

The area instance version whose build or update was last released using the DETACH_COMMIT method (and a database commit in the case of transactional areas) is active. All shared locks are set automatically to the current active version.

"Obsolete"

If a new version becomes complete when reads are performed on the currently active version of the build, the new version becomes active and the version that was previously active becomes obsolete. The shared locks on the obsolete version remain until the read process is complete; new shared locks for the area instance are always set on the active version, however.

"Expired"

Once the last shared lock on an obsolete version is removed, the version expires (it is deleted by the garbage collector). No locks can be set on expired versions and they are ignored when the version number is determined.

In an area without area instance versioning, there is always only one area instance version, which is available in one of the states mentioned above. In an area with versioning, there can be different states in an area instance at the same time:

◈ Since there can be a maximum of one change lock on an area instance, there is a maximum of one building version for each area instance at any given time.
◈ There is a maximum of one active version for each area instance.
◈ Depending on the maximum version number, multiple obsolete versions can exist in parallel.

Note: If there are a large number of obsolete area instance versions for an area that still have shared locks, but there is an updated version in an active state, this can indicate a problem with the use of shared objects.

Example

In a simple case with a maximum of two version, there can be a maximum of:

◈ One active version and one building version
◈ One active version and one obsolete version
◈ One building version and one obsolete version

4. Shared Objects - Objects

Objects in the shared objects memory, that is, the actual shared objects, are instances of shared memory-enabled classes or anonymous data objects that are addressed using references.

A shared-memory-enabled class is declared with the addition SHARED MEMORY ENABLED of the statement CLASS, or has the property Shared Memory Enabled activated in Class Builder. Only instances of shared-memory-enabled classes can be stored in the shared objects memory. The static attributes of a shared memory-enabled class, on the other hand, are not saved in the shared memory but in the internal session of a program. If different programs access the same shared objects, the static attributes of the corresponding classes exist multiple times and independently from each other in the programs.

Since area instances are self-contained without existing area locks, a root object of a shared memory-enabled class is required for the initial access.

◈ References to Shared Objects
◈ Root Object
◈ Object Creation
◈ Memory Bottlenecks

4.1  Shared Objects - References

Objects in area instance versions are instances of classes or anonymous data objects and therefore they can only really be addressed using heap references.

Access to Shared Objects

To use a reference of this type to read or write to objects in area instances of the shared memory from within an internal session, it is necessary to connect an area handle to an area instance version, to set a suitable area lock. The root object that can reference additional objects is used for the initial access to the objects in an area instance version.

References from the area instance version to internal session objects can exist and objects of the area instance version can be used in the internal session (but only if an area handle exists for an area instance version in an internal session). As long as an area lock exists, the references can be used as usual, with the restriction that the type of lock determines whether or not the referenced objects of the area instance version can be changed. If a read or write is performed on the content of an object of the area instance version, a runtime error occurs although there is no corresponding lock.

Note: 

The static methods GET_HANDLE_BY_OREF, GET_HANDLE_BY_DREF, and GET_HANDLE_BY_DATA can be used to obtain a reference to the area handle of an object. The corresponding return value is of general type CL_ABAP_MEMORY_AREA, which is why this sort of reference is really only suitable for creating objects.

Completed Area Instance Versions

Area instances that are not bound to any area handles are self-contained. If the lock is released using the method DETACH_COMMIT of the area handle after change accesses, no references from an area instance version are allowed to point to anything external. After the method DETACH_COMMIT, any external references that refer to objects of the area instance version can no longer be used to access these objects. Links between the shared objects of a completed area instance version can be created by using object references and data references.

A special restriction applies to data references in completed area instance versions: the dynamic type of these references must be a known type when a program is loaded in an internal session. The data types that cannot be used to create anonymous data objects as shared objects are listed under the addition AREA HANDLE of statement CREATE DATA.

4.2 Shared Objects - Root Object

Each area instance version contains an instance of the area root class that is identified as the root object.

The figure below shows how shared objects are accessed using the root object. The shared objects of an area instance version are accessed initially from an internal session, always by using the reference variable ROOT of the area handle that points to the root object.

SAP ABAP Tutorials and Materials, SAP ABAP Development, SAP ABAP Learning

The root object has to be defined with the instance method SET_ROOT of the area handle before the lock is released with the method DETACH_COMMIT of the area handle after writes.

Once an area handle has been bound to an existing area instance version, a reference to the root object can be obtained by reading the attribute ROOT (or even using the instance method GET_ROOT) of the area handle. The root object can then contain object and data references to further shared objects of the area instance version and also return them.

4.3 Shared Objects - Creating Objects

A shared object in an area instance version of the shared memory is created with the following statements:

◈ CREATE OBJECT oref AREA HANDLE handle ...
◈ CREATE DATA dref AREA HANDLE handle ...

handle is an object reference variable that points to an area handle, which is connected by a change lock to an area instance version currently being built. The created object is stored in this area instance version and oref or dref refer to the object. When the class instance is created, it must be shared-memory-enabled.

Before the area instance version is built with the DETACH_COMMIT method, the SET_ROOT method of the area handle must be used to define the root object. Once the area instance version has been built with the DETACH_COMMIT method, no references from the area instance version are allowed to point to anything external.

The treatable exceptions listed for the above statements can occur when objects are created.

4.4 Shared Objects - Memory Bottlenecks

The shared memory of an application server is a limited resource. The ABAP runtime environment uses it to store programs, program data, buffers etc. Explicit ABAP programming can access either data clusters in cross-transaction application buffers or shared objects in the shared objects memory.

The maximum amount of shared memory that can be occupied by the different users is defined statically using profile parameters. Transaction ST02 shows the current utilization of the shared memory and the related profile parameters.

If the amount of memory allocated to the shared objects memory (by the profile parameter abap/shared_objects_size_MB) is exceeded when shared objects are used, a handleable exception of class CX_SHM_OUT_OF_MEMORY is raised. This exception can occur in different situations:

◈ When shared objects are created or changed in the shared memory
◈ When locks are removed with DETACH_COMMIT
◈ When locks are created with ATTACH_FOR_WRITE, ATTACH_FOR_UPDATE, and even with ATTACH_FOR_READ (if there is no longer sufficient space for the administration information)

For this reason, it is best to handle the exception CX_SHM_OUT_OF_MEMORY each time the shared objects memory is accessed. The easiest way to do this is when all accesses to shared objects (in an ideal situation, these only occur within one wrapper class) also take place in only one single TRY control structure, in which this exception is handled. If an exclusive lock on the area still exists when the exception is handled (this can be identified using the method GET_LOCK_KIND of the area handle), it should be removed using DETACH_ROLLBACK.

Note

To handle the exception CX_SHM_OUT_OF_MEMORY, a suitable fallback strategy should be implemented, for example a strategy to create the required objects in the internal session and copy the previous content from the shared memory to these objects.

5. Shared Objects - Classes and Interfaces

The hierarchy of global classes that are involved when working with shared objects is as follows:

CL_ABAP_MEMORY_AREA
  |
  |--CL_SHM_AREA
  |    |
  |    |--Area Classes
  |
  |--CL_IMODE_AREA

Meaning of the three predefined system classes:

◈ CL_ABAP_MEMORY_AREA is the superclass of all area classes.
◈ CL_SHM_AREA is the superclass of all self-defined area classes.
◈ CL_IMODE_AREA is a predefined area class for the internal session.

There is also a system interface, which must be implemented by the class for the optional area constructor:

IF_SHM_BUILD_INSTANCE
  |
  |--Area Constructor Class

5.1 Shared Objects - CL_ABAP_MEMORY_AREA

The CL_ABAP_MEMORY_AREA class is the common superclass of all area classes. It contains general methods for area handles.
  • Static Methods
    • GET_HANDLE_BY_OREF
Gets the area handle for an instance of a class. The instance can be in the shared memory or in the internal session.

Input Parameter

◈ OREF of type REF TO object

Reference to the instance of a class.

Return Value

◈ HANDLE of type REF TO cl_abap_memory_area

Reference to the area handle of the corresponding area instance version. Typing means that essentially this reference is only suitable for creating objects.
    • GET_HANDLE_BY_DREF
Gets the area handle for a data object. The data object can be in the shared memory or in the internal session.

Input Parameter

DREF of type REF TO data

Reference to a data object in the shared memory.

Return Value

◈ HANDLE of type REF TO cl_abap_memory_area

Reference to the area handle of the corresponding area instance version. Typing means that essentially this reference is only suitable for creating objects.
    • GET_HANDLE_BY_DATA
Gets the area handle for a data object. The data object can be in the shared memory or in the internal session.

Input Parameter

◈ DATAOBJECT of type any

Data object in the shared memory. This can be specified as a field symbol, for example, which refers to a dereferenced data object in the shared memory.

Return Value

◈ HANDLE of type REF TO cl_abap_memory_area

Reference to the area handle of the corresponding area instance version. Typing means that essentially this reference is only suitable for creating objects.
  • Instance Methods
    • IS_SHARED
Checks whether the area handle represents an area instance version in the shared memory, or whether it represents the current internal session.

Return Value

◈ SHARED of type ABAP_BOOL

ABAP_TRUE if an area instance version is represented in the shared objects memory, and ABAP_FALSE if the current internal session is represented.
    • IS_VALID
Checks whether the area handle can be used to access an area instance version in the shared memory, or whether the current internal session is accessed.

Return Value

◈ VALID of type ABAP_BOOL

ABAP_TRUE if the area handle is used to access an area instance version or the current internal session; otherwise ABAP_FALSE.
    • IS_ACTIVE_VERSION
Checks whether the area handle refers to the active area instance version.

Return Value

◈ ACTIVE_VERSION of type ABAP_BOOL

ABAP_TRUE if the current area instance version or the internal session is represented. ABAP_FALSE if an obsolete area instance version is represented, the area handle was already released, or if it is a change handle.
    • HAS_ACTIVE_PROPERTIES
Checks whether the area’s current dynamic properties match the properties of the area instance version that is represented:

Return Value

◈ ACTIVE_PROPERTIES of type ABAP_BOOL

ABAP_TRUE if the dynamic attributes of the area have not been changed since the current area instance version was built, or if the current internal session is represented. Otherwise, or if the area handle was already released, ABAP_FALSE.
    • GET_DETACH_INFO
Determines the reason for an invalid area handle.

Return Value

DETACH_INFO of type SHM_DETACH_INFO
The return value can be compared with one of the following constants of class CL_ABAP_MEMORY_AREA.

◈ DETACH_INFO_NOT_DETACHED 

The area handle is still valid. This value is also returned if a commit fails but no rollback has yet been performed. This value is also returned if the current internal session is represented.

◈ DETACH_INFO_HANDLE 

The shared lock or exclusive lock was released explicitly using one of the methods DETACH_COMMIT or DETACH_ROLLBACK.

◈ DETACH_INFO_AREA 

The shared lock or exclusive lock was released by one of the DETACH_AREA or DETACH_ALL_AREAS methods.

◈ DETACH_INFO_ATTACH 

The shared lock was released by the ATTACH_FOR_WRITE method, and the constant CL_SHM_AREA=>ATTACH_MODE_DETACH_READER was passed to the ATTACH_MODE parameter.

◈ DETACH_INFO_INVALIDATE 

The shared lock was released using an INVALIDATE_... method, and the ABAP_TRUE constant was passed to the TERMINATE_CHANGER parameter.

◈ DETACH_INFO_PROPAGATE 

The change lock was released by a PROPAGATE_... method.

◈ DETACH_INFO_FREE 

The shared lock or exclusive lock was released using a FREE_... method.

5.1.1 Shared Objects - CL_SHM_AREA

The class CL_SHM_AREA is a subclass of CL_ABAP_MEMORY_AREA and the superclass of all area classes that are generated when an area is created using transaction SHMA. This class contains general attributes and methods for the corresponding area handles.
  • Instance Attributes
    • PROPERTIES
Structure of type SHM_PROPERTIES with the READ-ONLY property. The components in the structure contain area properties that are generally set using transaction SHMA. The components in the structure are:

AUTO_BUILD

If the value is ABAP_TRUE, the area instance versions of an area can be built automatically. The prerequisite for the value ABAP_TRUE is that the component AUTO_BUILD_CLASS is not initial. If the value is ABAP_FALSE, the area instance versions of an area cannot be built automatically.

AUTO_BUILD_CLASS

Contains the name of the area constructor class, which implements the BUILD constructor using the IF_SHM_BUILD_INSTANCE interface to build area instance versions automatically. This component is only filled if the area handle is bound by an exclusive lock to an area instance version, and is otherwise initial.

BUILD_KIND

Specifies when area instance versions of the area are built automatically using the area constructor in the area constructor class: If the value is CL_SHM_AREA=>BUILD_KIND_NONE, area instances versions are not built automatically. This is always the case if the component AUTO_BUILD has the value ABAP_FALSE. If the component AUTO_BUILD has the value ABAP_TRUE, the component BUILD_KIND can have the values CL_SHM_AREA=>BUILD_KIND_DUE_TO_READ_REQUEST or CL_SHM_AREA=>BUILD_KIND_DUE_TO_INVALIDATION. If the component has the value CL_SHM_AREA=>BUILD_KIND_DUE_TO_READ_REQUEST and no active area instance versions exist, the area constructor is called automatically when a read is performed. If the component has the value CL_SHM_AREA=>BUILD_KIND_DUE_TO_INVALIDATION, the area constructor is called in the same way as with the CL_SHM_AREA=>BUILD_KIND_DUE_TO_READ_REQUEST value. The constructor is still called during the transition from an active version to an obsolete or expired version, without creating an active area instance version.

CLIENT_DEPENDENT

If the value is ABAP_TRUE, the area is client-specific. With area instance versions of the same area, the version names and the current client identifier in the CLIENT attribute are used to distinguish the versions. If the component has the value ABAP_FALSE (default setting), the area is not client-specific and CLIENT is initial.

DISPLACE_KIND

Controls whether area instance versions of the area may be displaced. If the value is CL_SHM_AREA=>DISPLACE_KIND_NONE, they are not displaceable (default setting). If the value is CL_SHM_AREA=>DISPLACE_KIND_SERIALIZABLE, they are displaceable. Before displacements, the content is serialized and is saved persistently. It is reloaded into the shared memory using a read or update on the area instance version. The prerequisite for this is that each class instantiated in the area instance has to implement the IF_SERIALIZABLE_OBJECT interface. If the component has the value CL_SHM_AREA=>DISPLACE_KIND_DISPLACABLE, the area instance versions are displaceable, and the content is lost with a displacement (complete displacement). Displacement takes place as long as no area handle is bound to an area instance version of the displaceable area instance at the same time.

HAS_VERSIONS

If the value is ABAP_TRUE, the area supports versioning. If the value is ABAP_FALSE, there is a maximum of one single area instance version.

IDLE_TIME

Specifies how many minutes an area instance version remains in the shared memory (after an exclusive or shared lock has been released) before it is automatically deleted. If the value is 0 (default setting), the area instance version is not deleted automatically. Values other than 0 are only possible if the components INVALIDATE_TIME and REFRESH_TIME both have the value 0. In the case of transactional areas, time measurement begins with the first database commit after a lock is released using the method DETACH_COMMIT.

INVALIDATE_TIME

Specifies after how many minutes an area instance version becomes obsolete after an exclusive lock has been released. If the value is 0 (default setting), an area instance version never becomes obsolete. Values other than 0 are only possible if the components IDLE_TIME and REFRESH_TIME both have the value 0. With transactional areas, time measurement begins with the first database commit after a lock is released using the method DETACH_COMMIT.

LIFE_CONTEXT

Sets the visibility and lifetime of the area instance versions of the area. If this method has the value CL_SHM_AREA=>LIFE_CONTEXT_APPSERVER, the area instance versions exist until the application server is shut down (default value). If it has the value CL_SHM_AREA=>LIFE_CONTEXT_SESSION, the area instances exist until the current user’s last ABAP session ends. If it has the value CL_SHM_AREA=>LIFE_CONTEXT_MODE, the area instances exist for as long as the current ABAP session is active. If it has the value CL_SHM_AREA=>LIFE_CONTEXT_MEMORY, the area instances exist for as long as the data exists in the ABAP memory of the current call sequence.

MAX_AREA_SIZE

Specifies the maximum permitted size of an area in KB. The size of an area corresponds to the total memory requirement for all area instance versions. The default value is currently 0 and does not restrict the size.

MAX_VERSION_SIZE

Specifies the maximum permitted size of an area in KB. The size of an area corresponds to the total memory requirement for all area instance versions. The default value is currently 0 and does not restrict the size.

MAX_VERSIONS

Specifies the maximum number of area instance versions for an area instance of an area. Obsolete areas are not counted. The default value is 0 and does not restrict the size. If the component HAS_VERSIONS has the value ABAP_FALSE, MAX_VERSIONS is always 1. Otherwise, MAX_VERSIONS can be any non-negative number that is not 1.

REFRESH_TIME

Specifies after how many minutes an area instance version is built by the automatic call of the area constructor. If the value is 0 (default setting), an area instance version is never built automatically. Values other than 0 are only possible if the components IDLE_TIME and INVALIDATE_TIME both have the value 0. In the case of transactional areas, time measurement begins with the first database commit after a lock is released using the method DETACH_COMMIT. The prerequisite is that an active version of the area instance version is present at the start of the build. If the method DETACH_COMMIT was not successful, the preceding area instance version is preserved (if area are versioned) and the automatic rebuild raises appropriate exceptions. The area constructor can catch the exceptions CATCH CX_SHM_ERROR and CX_SHM_FAILURE itself and, for example, call the method INVALIDATE_INSTANCE of the area class to delete a preceding area instance version explicitly. If an automatic area build fails due to the failure of the method DETACH_COMMIT, no automatic rebuilds take place until the method is executed successfully.

TRANSACTIONAL

If the value is ABAP_TRUE, the area is transactional (default setting). Changes to the area instance versions of the area do not become active until after the method DETACH_COMMIT is executed with the next database commit. If the value is ABAP_FALSE, the area is not transactional and changes become active immediately after the method DETACH_COMMIT is executed.
    • INST_NAME
Text field of type SHM_INST_NAME with the READ-ONLY property. This attribute contains the name of the current area instance. This attribute is set when an area instance is created using the method ATTACH_FOR_WRITE of the area class.
    • CLIENT
Text field of type MANDT with the READ-ONLY property. In client-specific areas (the component CLIENT_DEPENDENT of the structure PROPERTIES has the value ABAP_TRUE), this attribute contains the current client identifier of the area instance. The attribute is initial in a cross-client area.
  • Static Methods
    • MULTI_ATTACH
Enables shared, exclusive, or update locks to be set at the same time on multiple area instances of one or more areas. The method MULTI_ATTACH is the only way to have change access to multiple area instances at the same time or in other words, set multiple exclusive locks at once.

Input/Output Parameters

ATTACH_TAB of type SHM_ATTACH_TAB

Internal table whose rows contain information about the individually requested locks. The components of the rows are:

◈ AREA_NAME of type SHM_AREA_NAME 

Area name

◈ INST_NAME of type SHM_INST_NAME 

Name of the area instance. If the area instance should be accessed with the default name, the value CL_SHM_AREA=>DEFAULT_INSTANCE must be passed.

◈ CLIENT of type MANDT 

Client identifier for client-specific areas. If the area instance should be accessed with the current client identifier, the current client must also be passed. The component must be initial in the case of cross-client areas.

◈ LOCK_KIND of type SHM_LOCK_KIND 

Access type, possible values: CL_SHM_AREA=>LOCK_KIND_READ, CL_SHM_AREA=>LOCK_KIND_WRITE or CL_SHM_AREA=>LOCK_KIND_UPDATE.

◈ ATTACH_MODE of type SHM_ATTACH_MODE 

Behavior for change accesses. Possible values: CL_SHM_AREA=>ATTACH_MODE_DEFAULT, CL_SHM_AREA=>ATTACH_MODE_DETACH_READER or CL_SHM_AREA=>ATTACH_MODE_WAIT.

◈ LEVEL of type i 

Order in which the locks are set. Table rows with smaller values in the column are evaluated before table rows with larger values. If the values are equal, the order of the rows in the table is used as the deciding factor.

◈ HANDLE of type REF TO cl_shm_area 

This column returns a reference to an area handle for the area instance version for which the lock was requested (provided that this was successful). If an exception is raised, the value of the column is initial for either all rows or for the affected rows (depending on the value of the input parameter IGNORE_ERRORS).

◈ EXCEPTION of type REF TO cx_root 

If an exception is raised, this column returns a reference to the exception object for either one or all relevant rows (depending on the value of IGNORE_ERRORS). In addition to the exceptions of ATTACH methods for setting individual locks in the area class, the exception CX_SHM_MULTI_ATTACH_ERROR can also be raised if: An exclusive and update lock is requested at the same time on an area instance version (exception text: DUPLICATE_CHANGE_LOCK), a lock for a client other than the current client is requested on an area instance version with automatic area building (exception text: ILLEGAL_AUTO_BUILD_CLIENT), a client identifier is specified for a cross-client area (exception text: ILLEGAL_CLIENT_FOR_AREA), in success cases, the column is initial..

Input Parameters

IGNORE_ERRORS of type ABAP_BOOL

Controls error handling of methods. Possible values are ABAP_TRUE and ABAP_FALSE.

If ABAP_TRUE is passed, the system attempts to set the remaining locks following an exception when the lock was set. In the rows of the ATTACH_TAB parameter where an error occurred, the reference to the area handle in the HANDLE column is initialized and the reference in the EXCEPTION column is set to the corresponding exception object.

If ABAP_FALSE is passed, the method is terminated following an exception while trying to set a lock. The HANDLE column is initialized in all rows of the ATTACH_TAB parameter. The reference in the EXCEPTION column to the corresponding exception object is set in the row where the error occurred.

All area instances for which an error occurred in the method MULTI_ATTACH , have the same state after the method ends as they did before the method was called. This means the previous locks and the statuses remain the same.

WAIT_TIME of type i

Specifies the wait time in milliseconds for all rows of the ATTACH_TAB parameter, where the value CL_SHM_AREA=>ATTACH_MODE_WAIT is specified in the ATTACH_MODE column. The wait time must be greater than or equal to 0 and is distributed to the relevant lock requests. If multiple exclusive locks are to be set and the first lock can be set in the wait time, the remaining wait time is left over for the other locks. The time available for the remaining rows is therefore reduced by the wait time used each time a row of this type is evaluated.

Caution

For change locks with a wait time that are set with MULTI_ATTACH, the same mutual exclusions apply as to methods ATTACH_FOR_WRITE and ATTACH_FOR_UPDATE of the area class. This may prevent locks from being set in certain cases. For example, if a MULTI_ATTACH with a wait time is executed in parallel in two programs, where program 1 first sets exclusive lock A and an exclusive lock B, and program 2 does this in reverse order and lock A is set in program 1 and lock B is set in program 2, at least one second lock cannot be set. If there is a lock request for the second lock (lock B in program 1 and lock A in program 2), each program has to wait for the other program’s wait time to expire.

Output Parameters

◈ ERROR_FLAG of type ABAP_BOOL

Specifies whether one or more exceptions were raised during the method. If ERROR_FLAG has the value ABAP_FALSE, this means all locks were set successfully. If ERROR_FLAG has the value ABAP_TRUE, not all locks could be set. The locks contain references to the exception object(s) for either one or more rows (depending on the value of the IGNORE_ERRORS input parameter) of the EXCEPTION column of the ATTACH_TAB parameters.
    • DETACH_ALL_AREAS
Releases all of the locks of the current internal session on any area instance versions of any areas, which deactivates all of the area handles of the internal session. If an exclusive or update lock is released, this rejects any changes that were made up to then to area instance versions.

Return Value

RC of type SHM_RC

Possible values:

◈ CL_SHM_AREA=>RC_DONE if all locks were released.
◈ CL_SHM_AREA=>RC_NOTHING_TO_BE_DONE, if no locks were released because no locks existed in the first place.

Note

The method DETACH_ALL_AREAS does not require any input parameters for the client identifier, since it accesses both client-specific and cross-client area instances independently of the client. To delete all locks in a special client, the corresponding area handles must be accessed individually. These can be managed in an internal table.
  • Instance Methods
    • DETACH
Releases the lock on the current area handle. The area handle is then inactive.

Exceptions

◈ CX_SHM_WRONG_HANDLE

An exclusive lock was active and not a shared lock (exception text: READ_HANDLE_REQUIRED)

◈ CX_SHM_ALREADY_DETACHED

No exclusive lock was active.
    • DETACH_COMMIT
Releases a change lock (exclusive or update lock) on the current area handle and confirms the changes that were made. The area handle is then inactive. The prerequisite for this is that the current area instance version must contain an instance of the area root class (root object). In addition, there must not be any references from the area instance version to a different area instance of the shared objects memory, or to the internal session.

If an exception is raised when the method is executed, the change lock is not released correctly. Although it remains, the lock cannot be released a second time using the method DETACH_COMMIT. The DETACH_ROLLBACK can be used instead.

In the case of non-transactional areas (the component TRANSACTIONAL of the structure PROPERTIES has the value ABAP_FALSE), changes to the current area instance version become active immediately after the method DETACH_COMMIT is executed. In the case of transactional areas (the component TRANSACTIONAL of the structure PROPERTIES has the value ABAP_TRUE), the changes that are completed when the method DETACH_COMMIT is executed are not active until the next database commit. The following rules apply during the time between the completion of the method DETACH_COMMIT and the next database commit:

◈ With transactional areas with versioning, all requested shared locks access the previous version.
◈ No reads are possible for transactional areas without versioning.
◈ It is not possible to set a new change lock for areas with or without versioning.

When the method DETACH_COMMIT is called, the event SHM_COMMIT_EVENT of the generated area class is triggered automatically.

Exceptions

◈ CX_SHM_WRONG_HANDLE

A shared lock was active instead of an exclusive lock (exception text: WRITE_HANDLE_REQUIRED)

◈ CX_SHM_ALREADY_DETACHED

No change lock was active.

◈ CX_SHM_COMPLETION_ERROR

Subclasses:

◈ CX_SHM_ROOT_OBJECT_INITIAL 

No root object was assigned to the area instance version.

◈ CX_SHM_EXTERNAL_REFERENCE 

There are still references from the current area instance version to a different area instance of the shared objects memory, or to the internal session.

◈ CX_SHM_EVENT_EXECUTION_FAILED 

An exception was raised when an event handler was executed for SHM_COMMIT_EVENT. The exception raised can be read using the attribute PREVIOUS.

◈ CX_SHM_SECONDARY_COMMIT

An attempt was made to release a change lock again (release attempt had already failed previously) using DETACH_COMMIT instead of DETACH_ROLLBACK.
CX_SHM_COMPLETION_ERROR and CX_SHM_SECONDARY_COMMIT are subclasses of CX_SHM_DETACH_ERROR.
    • DETACH_ROLLBACK
Releases a change lock (exclusive or update lock) on the current area handle and discards the changes that were made. The area handle is then inactive.

For areas without versioning, no active version of the area is available once the method has been executed. The previous version is still available for areas with versioning. With transactional areas, a new exclusive lock can be set on the relevant area instance (even before the next database commit) once the method DETACH_ROLLBACK has been executed.

When the method DETACH_ROLLBACK is called, the event SHM_ROLLBACK_EVENT is raised automatically before it is executed.

Exceptions

◈ CX_SHM_WRONG_HANDLE

A shared lock was active instead of an exclusive lock (exception text: WRITE_HANDLE_REQUIRED)

◈ CX_SHM_ALREADY_DETACHED

No change lock was active.

◈ CX_SHM_EVENT_EXECUTION_FAILED

An exception was raised when an event handler was executed for SHM_ROLLBACK_EVENT. The exception raised can be read using the attribute PREVIOUS.

CX_SHM_EVENT_EXECUTION_FAILED is a subclass of CX_SHM_COMPLETION_ERROR, which is a subclass of CX_SHM_DETACH_ERROR.
    • GET_LOCK_KIND
Returns the type of the current lock for an area handle.

Return Value

◈ LOCK_KIND of type SHM_LOCK_KIND

Possible values:

◈ CL_SHM_AREA=>LOCK_KIND_READ if the area handle holds a shared lock.
◈ CL_SHM_AREA=>LOCK_KIND_WRITE if the area handle holds an exclusive lock.
◈ CL_SHM_AREA=>LOCK_KIND_UPDATE if the area handle holds an update lock.
◈ CL_SHM_AREA=>LOCK_KIND_COMPLETION_ERROR, if the area handle holds a change lock, after the method DETACH_COMMIT was ended with an exception.
◈ CL_SHM_AREA=>LOCK_KIND_DETACHED, if the area handle does not hold any locks or if it is not bound to an area instance version.
    • GET_ROOT
Returns a reference to the root object (instance of the area root class) for an area handle. The method is intended for the unlikely case where multiple handles need to be handled for different areas with different area root classes. Otherwise the attribute ROOT of the area class can be accessed directly.

Return Value

◈ ROOT of type REF TO object

Exceptions

◈ CX_SHM_ALREADY_DETACHED

The area handle is not bound to an area instance version.
  • Instance Events
    • SHM_COMMIT_EVENT
This event is raised by the area handle automatically when the method DETACH_COMMIT is called.
    • SHM_ROLLBACK_EVENT
This event is raised by the area handle automatically when the method DETACH_ROLLBACK is called.

5.1.1.1 Shared Objects - Area Classes

An area class is generated as a subclass of class CL_SHM_AREA when an area is created using transaction SHMA. Its instances are used as area handles for the area instance versions of this area. The name of an area class is the same as the name of the area, which should therefore start with CL_.

Area classes can be displayed in Class Builder, although they cannot be changed there. The structure of an area class depends on the definition of the area in transaction SHMA. After the properties of an area have been changed, the area class is regenerated if necessary.
  • Static Attributes
    • AREA_NAME
Constant of type SHM_AREA_NAME: Contains the name of the current class or area.
  • Instance Attributes
    • ROOT
Reference variable of type REF TO area_root_class, where area_root_class is the area root class of the area. This attribute has the READ-ONLY property and is used for direct reads of the root object of an area instance version. Access using the GET_ROOT method is necessary in exceptional cases only, such as when using generic programming.
  • Static Methods
    • ATTACH_FOR_READ
Creates an area handle with a shared lock for an area instance version and returns a reference to the area handle.

Input Parameters

◈ INST_NAME of type SHM_INST_NAME

Name of the area instance version. The name is optional. The default value is CL_SHM_AREA=>DEFAULT_INSTANCE.

◈ CLIENT of type SHM_CLIENT

Client ID if the area is client-specific. The client ID is optional. The default value is the ID of the current client.

Return Code

◈ HANDLE of type REF TO area_class.

Reference to the new area handle, where area_class is the current area class.

Exceptions

◈ CX_SHM_INCONSISTENT

The type of an object saved in the area instance does not match the definition of the object with the same name in the current internal session. If the time stamp for the type of the shared objects is newer than the time stamp in the internal session, the application should be restarted, to ensure the internal session also uses the current version of the type. If the time stamp of the type in the internal session is newer than the time stamp of the shared object, a new area instance version should be constructed, so that the current type is used there.

◈ CX_SHM_NO_ACTIVE_VERSION

This exception is raised in the following cases:

    ◈ The area instance version does not exist and an automatic build is not possible because there is no area constructor or displaced version (exception text: NEITHER_BUILD_NOR_LOAD).
    ◈ The area instance version does not exist and the area constructor was called (exception text: BUILD_STARTED). The system does not wait for the automatic area build to be terminated when the exception is caught. If this exception is raised twice in succession with this exception text, the area constructor was not ended correctly.
    ◈ The area instance version does not exist although the area constructor is already being executed (exception text: BUILD_NOT_FINISHED).
    ◈ The area instance version is not available and a displaced version was started (exception text: LOAD_STARTED).
    ◈ The area instance version does not exist but a displaced version is already being loaded (exception text: LOAD_NOT_FINISHED).

◈ CX_SHM_READ_LOCK_ACTIVE

The area instance version is already locked for reading in the same internal session.

◈ CX_SHM_EXCLUSIVE_LOCK_ACTIVE

This exception is raised in the following cases:

    ◈ The area instance does not support versioning and is already locked against changes (exception text: LOCKED_BY_ACTIVE_CHANGER).

    ◈ The area instance does not support versioning and a user is waiting for an exclusive lock (exception text: LOCKED_BY_PENDING_CHANGER).

    ◈ The area instance is transactional, does not support versioning, and an exclusive lock was released, but the database commit has not yet taken place (exception text: WAITING_FOR_DB_COMMIT).

◈ CX_SHM_PARAMETER_ERROR

The value of CL_SHM_AREA=>ALL_CLIENTS was specified for the input parameter CLIENT.
The first four exception classes are subclasses of CX_SHM_ATTACH_ERROR.
    • ATTACH_FOR_WRITE
Creates an area handle with an exclusive lock for an area instance version and returns a reference to the area handle.

Input Parameters

◈ INST_NAME of type SHM_INST_NAME

Name of the area instance version. The name is optional. The default value is CL_SHM_AREA=>DEFAULT_INSTANCE.

◈ CLIENT of type SHM_CLIENT

Client ID if the area is client-specific. The client ID is optional. The default value is the ID of the current client. In tenant-isolation systems, the CLIENT parameter cannot be passed in application clients.

◈ ATTACH_MODE of type SHM_ATTACH_MODE

Controls the lock mode. This information is optional. The default value is CL_SHM_AREA=>ATTACH_MODE_DEFAULT. Possible values are:

    ◈ CL_SHM_AREA=>ATTACH_MODE_DEFAULT 

If there are shared locks on the area instance of the specified name, these are not released. For areas with versioning, the system attempts to create a new version. In the case of areas without versioning, the exception CX_SHM_VERSION_LIMIT_EXCEEDED is raised.

    ◈ CL_SHM_AREA=>ATTACH_MODE_DETACH_READER 

For areas with versioning, if there are shared locks on all area instance versions of the specified name, the shared locks on the oldest version are released. This deactivates them so that a new version can be created. All shared locks are released for areas without versioning.

    ◈ CL_SHM_AREA=>ATTACH_MODE_WAIT 

If the exclusive lock cannot be set, the program waits for the time specified in the WAIT_TIME parameter and tries to set the lock again before the exception CX_SHM_VERSION_LIMIT_EXCEEDED is raised. For an area without versioning, no further shared locks can be set on the area instance during the wait time. It is still possible to set shared locks for an area with versioning.

◈ WAIT_TIME of type i

Wait time in milliseconds, if the value CL_SHM_AREA=>ATTACH_MODE_WAIT is passed for ATTACH_MODE. If a value not equal to 0 is passed for WAIT_TIME, if the value CL_SHM_AREA=>ATTACH_MODE_WAIT is not passed to ATTACH_MODE, or if a negative value is specified for WAIT_TIME, the exception CX_SHM_PARAMETER_ERROR is raised.

An attempt is made to set an exclusive lock again in the wait time. Only one program with the parameter WAIT_TIME can wait for an area instance at any one time. If a different program tries to set another exclusive lock with the parameter WAIT_TIME, this raises the exception CX_SHM_EXCLUSIVE_LOCK_ACTIVE directly (exception text LOCKED_BY_PENDING_CHANGER).

If the exclusive lock can be set within the wait time, the program flow continues. Note that there may be a delay until the waiting program can be restarted. During this delay, no other program can set an exclusive lock. This guarantees that the waiting program is given the exclusive lock next.

If the exclusive lock cannot be set within the wait time, the exception CX_SHM_EXCLUSIVE_LOCK_ACTIVE is raised after the wait time (exception text:. LOCKED_BY_ACTIVE_CHANGER).

Return Code

◈ HANDLE of type REF TO area_class.

Reference to the new area handle, where area_class is the current area class.

Exceptions

◈ CX_SHM_VERSION_LIMIT_EXCEEDED

The exclusive lock could not be set since there was already a shared lock on the area instance version and no new version could be created because this would overwrite the maximum number of possible versions.

◈ CX_SHM_CHANGE_LOCK_ACTIVE

An area instance version is already locked for changing in the same internal session. If a previous exclusive lock was released in a transactional area, but there has been no database commit yet, this raises the exception with the exception text WAITING_FOR_DB_COMMIT.

◈ CX_SHM_EXCLUSIVE_LOCK_ACTIVE

This exception is raised in the following cases:

    ◈ The area instance is already locked for changes in a different internal session (exception text: LOCKED_BY_ACTIVE_CHANGER).

    ◈ A user in a different internal session is waiting for an exclusive lock (exception text: LOCKED_BY_PENDING_CHANGER).

    ◈ The area instance is transactional and an exclusive lock was released in a different internal session, but the database commit has not yet taken place (exception text: WAITING_FOR_DB_COMMIT).

◈ CX_SHM_PENDING_LOCK_REMOVED

This exception is raised if the value CL_SHM_AREA=>ATTACH_MODE_WAIT is passed for ATTACH_MODE, but the lock was deleted in transaction SHMM during a wait period.

◈ CX_SHM_PARAMETER_ERROR

This exception is raised in the following cases:

    ◈ An invalid value was passed for the input parameter ATTACH_MODE.
    ◈ A negative number was passed for the input parameter WAIT_TIME .
    ◈ The value of CL_SHM_AREA=>ALL_CLIENTS was specified for the input parameter CLIENT.

The first four exception classes are subclasses of CX_SHM_ATTACH_ERROR.
    • ATTACH_FOR_UPDATE
Creates an area handle with an update lock for an area instance version and returns a reference to the area handle.

Input Parameters

◈ INST_NAME of type SHM_INST_NAME

Name of the area instance version. The name is optional. The default value is CL_SHM_AREA=>DEFAULT_INSTANCE.

◈ CLIENT of type SHM_CLIENT

Client ID if the area is client-specific. The client ID is optional. The default value is the ID of the current client. In tenant-isolation systems, the CLIENT parameter cannot be passed in application clients.

◈ ATTACH_MODE of type SHM_ATTACH_MODE

Controls the lock mode. This information is optional. The default value is CL_SHM_AREA=>ATTACH_MODE_DEFAULT. Possible values are:

    ◈ CL_SHM_AREA=>ATTACH_MODE_DEFAULT 

If there are shared locks on the area instance of the specified name, these are not released. For areas with versioning, the system attempts to create a new version. In the case of areas without versioning, the exception CX_SHM_VERSION_LIMIT_EXCEEDED is raised.

    ◈ CL_SHM_AREA=>ATTACH_MODE_DETACH_READER 

For areas with versioning, if there are shared locks on all area instance versions of the specified name, the shared locks on the oldest version are released. This deactivates them so that a new version can be created. All shared locks are released for areas without versioning.

    ◈ CL_SHM_AREA=>ATTACH_MODE_WAIT 

If the update lock cannot be set, the program waits for the time specified in the WAIT_TIME parameter and tries to set the lock again before the exception CX_SHM_VERSION_LIMIT_EXCEEDED is raised. For an area without versioning, no further shared locks can be set on the area instance during the wait time. It is still possible to set shared locks for an area with versioning.

◈ WAIT_TIME of type i

Wait time in milliseconds, if the value CL_SHM_AREA=>ATTACH_MODE_WAIT is passed for ATTACH_MODE. If a value not equal to 0 is passed for WAIT_TIME, if the value CL_SHM_AREA=>ATTACH_MODE_WAIT is not passed to ATTACH_MODE, or if a negative value is specified for WAIT_TIME, the exception CX_SHM_PARAMETER_ERROR is raised.

An attempt is made to set an update lock again in the wait time. Only one program with the parameter WAIT_TIME can wait for an area instance at any one time. If a different program tries to set another exclusive lock with the parameter WAIT_TIME, this raises the exception CX_SHM_EXCLUSIVE_LOCK_ACTIVE directly (exception text LOCKED_BY_PENDING_CHANGER).

If the update lock can be set within the wait time, the program flow continues. Note that there may be a delay until the waiting program can be restarted. During this delay, no other program can set an exclusive lock. This guarantees that the waiting program receives the update lock next.

If the update lock cannot be set within the wait time, the exception CX_SHM_EXCLUSIVE_LOCK_ACTIVE is raised after the wait time (exception text:. LOCKED_BY_ACTIVE_CHANGER).

Note: Since an active area instance version is required for setting an update lock, an area constructor called automatically is started when the ATTACH_FOR_UPDATE method is called. The following applies when using the parameter WAIT_TIME: If the area constructor can be started, there is a wait period. If the area constructor ends before the end of the wait time, the update lock is set. If the area constructor ends without being able to construct an active version, the wait is terminated before the end of the wait time. If the area constructor does not end within the wait time, the exception CX_SHM_NO_ACTIVE_VERSION is raised (exception text: BUILD_NOT_FINISHED).

Return Code

◈ HANDLE of type REF TO area_class.

Reference to the new area handle, where area_class is the current area class.

Exceptions

◈ CX_SHM_INCONSISTENT

The type of an object saved in the area instance does not match the definition of the object with the same name in the current program.

◈ CX_SHM_NO_ACTIVE_VERSION

This exception is raised in the following cases:

◈ The area instance version does not exist and an automatic build is not possible because an area constructor or a displaced version does not exist (exception text: NEITHER_BUILD_NOR_LOAD).

◈ The area instance version does not exist and the area constructor was called (exception text: BUILD_STARTED).

◈ The area instance version does not exist although the area constructor is already being executed (exception text: BUILD_NOT_FINISHED).

◈ The area instance version is not available and a displaced version was started (exception text: LOAD_STARTED).

◈ The area instance version does not exist but a displaced version is already being loaded (exception text: LOAD_NOT_FINISHED).

◈ CX_SHM_VERSION_LIMIT_EXCEEDED

The update lock could not be set since there was already a shared lock on the area instance version and no new version could be created because this would overwrite the maximum number of possible versions.

◈ CX_SHM_CHANGE_LOCK_ACTIVE

An area instance version is already locked for changing in the same internal session. If a previous exclusive lock was released in a transactional area, but there has been no database commit yet, this raises the exception with the exception text WAITING_FOR_DB_COMMIT.

◈ CX_SHM_EXCLUSIVE_LOCK_ACTIVE

This exception is raised in the following cases:

    ◈ The area instance is already locked for changes in a different internal session (exception text: LOCKED_BY_ACTIVE_CHANGER).
    ◈ A user in a different internal session is waiting for an exclusive lock (exception text: LOCKED_BY_PENDING_CHANGER).
    ◈ The area instance is transactional and an exclusive lock was released in a different internal session, but the database commit has not yet taken place (exception text: WAITING_FOR_DB_COMMIT).

◈ CX_SHM_PENDING_LOCK_REMOVED

This exception is raised if the value CL_SHM_AREA=>ATTACH_MODE_WAIT is passed for ATTACH_MODE, but the lock was deleted in transaction SHMM during a wait period.

◈ CX_SHM_PARAMETER_ERROR

This exception is raised in the following cases:

    ◈ An invalid value was passed for the input parameter ATTACH_MODE.
    ◈ A negative number was passed for the input parameter WAIT_TIME .
    ◈ The value of CL_SHM_AREA=>ALL_CLIENTS was specified for the input parameter CLIENT.

The first six exception classes are subclasses of CX_SHM_ATTACH_ERROR.
    • DETACH_AREA
Releases all locks of the current internal session on the area instances versions of the associated area. This deactivates all of the area handles in the current internal session. If an exclusive lock or an update lock is released, this rejects any changes that were made to the area instance versions up to then.

Input Parameters

◈ CLIENT of type SHM_CLIENT

Optional client ID if the area is client-specific. The default value is the ID of the current client. In tenant-isolation systems, the CLIENT parameter cannot be passed in application clients.
Return Code

◈ RC of type SHM_RC

Possible values:

    ◈ CL_SHM_AREA=>RC_DONE if all locks were released.
    ◈ CL_SHM_AREA=>RC_NOTHING_TO_BE_DONE if no locks were released because no locks existed in the current session.
    • INVALIDATE_INSTANCE
For non-transactional areas, this method immediately sets the state of the active area instance version of the area instance of the name passed to obsolete. For transactional areas, this is done using the next database commit. No new locks can be set on this area instance version afterwards. Any existing shared locks are not released. How existing exclusive locks are handled depends on the input parameter TERMINATE_CHANGER.

Input Parameters

◈ INST_NAME of type SHM_INST_NAME

Name of the area instance version. The name is optional. The default value is the value of constant 
CL_SHM_AREA=>DEFAULT_INSTANCE.

◈ CLIENT of type SHM_CLIENT

Client ID if the area is client-specific. The default value is the ID of the current client. In tenant-isolation systems, the CLIENT parameter cannot be passed in application clients.

◈ TERMINATE_CHANGER of type ABAP_BOOL

Controls the handling of exclusive locks. Possible values are:

    ◈ ABAP_TRUE (existing exclusive locks are released (default setting)).
    ◈ ABAP_FALSE (existing exclusive locks are not released).

◈ AFFECT_SERVER of type SHM_AFFECT_SERVER (for transactional areas only)

Controls cross-server invalidation. Possible values are:

    ◈ CL_SHM_AREA=>AFFECT_LOCAL_SERVER (only the area instance versions of the current application server are invalidated (default setting)).
    ◈ CL_SHM_AREA=>AFFECT_ALL_SERVERS (the area instance versions of all application servers are invalidated).
    ◈ CL_SHM_AREA=>AFFECT_ALL_SERVERS_BUT_LOCAL (the area instance versions of all application servers are invalidated, apart from the current application server). This enables changes to be made to areas of the current application server directly, without the database having to create the entire area again.

Caution

Once this method is executed and ABAP_TRUE is passed to TERMINATE_CHANGER, all programs where there is still an exclusive lock for the invalidated area instance are terminated with the runtime error SYSTEM_SHM_AREA_OBSOLETE.

Return Code

◈ RC of type SHM_RC

Possible values in non-transactional areas:

    ◈ CL_SHM_AREA=>RC_DONE if the active area instance version was set to obsolete. If the value ABAP_TRUE was passed to TERMINATE_CHANGER (even if an exclusive lock was released).

    ◈ CL_SHM_AREA=>RC_NOTHING_TO_BE_DONE if no active area instance version is available and (if the value ABAP_TRUE was passed to TERMINATE_CHANGER) if no exclusive lock exists .

    ◈ CL_SHM_AREA=>RC_INSTANCE_NAME_NOT_FOUND if no area instance of the specified name exists.

In transactional areas, RC always has the value CL_SHM_AREA=>RC_NOTHING_TO_BE_DONE.

Exceptions

CX_SHM_PARAMETER_ERROR

An invalid value was passed for the input parameter TERMINATE_CHANGER.
    • INVALIDATE_AREA
In non-transactional areas, this method immediately sets the state of all active area instance versions of the area in the current internal session to obsolete. For transactional areas this is done by the next database commit. No new locks can be set on these area instance versions afterwards. Any existing shared locks are not released. How existing exclusive locks are handled depends on the input parameter TERMINATE_CHANGER.

Input Parameters

◈ CLIENT of type SHM_CLIENT

Client ID if the area is client-specific. The default value is the ID of the current client. In tenant-isolation systems, the CLIENT parameter cannot be passed in application clients.

◈ TERMINATE_CHANGER of type ABAP_BOOL

Controls the handling of exclusive locks. Possible values are:

    ◈ ABAP_TRUE (existing exclusive locks are released (default setting)).
    ◈ ABAP_FALSE (existing exclusive locks are not released).

◈ AFFECT_SERVER of type SHM_AFFECT_SERVER (for transactional areas only)
Controls cross-server invalidation. Possible values are:

    ◈ CL_SHM_AREA=>AFFECT_LOCAL_SERVER (only the area instance versions of the current application server are invalidated (default setting)).
    ◈ CL_SHM_AREA=>AFFECT_ALL_SERVERS (the area instance versions of all application servers are invalidated).
    ◈ CL_SHM_AREA=>AFFECT_ALL_SERVERS_BUT_LOCAL (the area instance versions of all application servers are invalidated, apart from the current application server). This enables changes to be made to areas of the current application server directly, without the database having to create the entire area again.

Caution

Once this method is executed and ABAP_TRUE is passed to TERMINATE_CHANGER, all programs where there are still exclusive locks for the invalidated area instance versions are terminated with the runtime error SYSTEM_SHM_AREA_OBSOLETE.

Return Code

◈ RC of type SHM_RC

Possible values in non-transactional areas:

    ◈ CL_SHM_AREA=>RC_DONE if at least one active area instance version was set to obsolete. If the value ABAP_TRUE was passed to TERMINATE_CHANGER (even if one or more exclusive locks were released).
    ◈ CL_SHM_AREA=>RC_NOTHING_TO_BE_DONE if no active area instance version exists and (if the value ABAP_TRUE was passed to TERMINATE_CHANGER) if no exclusive lock exists.

In transactional areas, RC always has the value CL_SHM_AREA=>RC_NOTHING_TO_BE_DONE.

Exceptions

◈ CX_SHM_PARAMETER_ERROR

An invalid value was passed for the input parameter TERMINATE_CHANGER.
    • FREE_INSTANCE
This method sets the state of all (active and obsolete) area instance versions of the area instance for the name passed to "expired", and all shared locks are released. No new shared locks and update locks can be set on this area instance version afterwards. How existing exclusive locks are handled depends on the input parameter TERMINATE_CHANGER. In non-transactional areas, the state of the area instance version is changed immediately; in transactional areas, the state changes after the next database commit.

Caution

After this method has been executed, all programs in which area handles still exist for the released area instance versions terminate with the runtime error SYSTEM_SHM_AREA_OBSOLETE.

Input Parameters

◈ INST_NAME of type SHM_INST_NAME

Name of the area instance version. The name is optional. The default value is the value of constant CL_SHM_AREA=>DEFAULT_INSTANCE.

◈ CLIENT of type SHM_CLIENT

Client ID if the area is client-specific. The default value is the ID of the current client. In tenant-isolation systems, the CLIENT parameter cannot be passed in application clients.

◈ TERMINATE_CHANGER of type ABAP_BOOL

Controls the handling of exclusive locks. Possible values are:

    ◈ ABAP_TRUE (existing exclusive locks are released (default setting)).
    ◈ ABAP_FALSE (existing exclusive locks are not released).

◈ AFFECT_SERVER of type SHM_AFFECT_SERVER (for transactional areas only)

Controls cross-server invalidation. Possible values are:

◈ CL_SHM_AREA=>AFFECT_LOCAL_SERVER (only the area instance versions of the current application server are invalidated (default setting)).

◈ CL_SHM_AREA=>AFFECT_ALL_SERVERS (the area instance versions of all application servers are invalidated).

◈ CL_SHM_AREA=>AFFECT_ALL_SERVERS_BUT_LOCAL (the area instance versions of all application servers are invalidated, apart from the current application server). This enables changes to be made to areas of the current application server directly, without the database having to create the entire area again.

Return Code

◈ RC of type SHM_RC

Possible values in non-transactional areas:

    ◈ CL_SHM_AREA=>RC_DONE if an active or an obsolete area instance version was set to expired. If the value ABAP_TRUE was passed to TERMINATE_CHANGER (even if an exclusive lock was released).
    ◈ CL_SHM_AREA=>RC_NOTHING_TO_BE_DONE, if no active or obsolete area instance versions exist and (if the value ABAP_TRUE was passed to TERMINATE_CHANGER) if no exclusive lock exists.
    ◈ CL_SHM_AREA=>RC_INSTANCE_NAME_NOT_FOUND if no area instance of the specified name exists.

In transactional areas, RC always has the value CL_SHM_AREA=>RC_NOTHING_TO_BE_DONE.

Exceptions

◈ CX_SHM_PARAMETER_ERROR

An invalid value was passed for the input parameter TERMINATE_CHANGER.
    • FREE_AREA
This method sets the state of all (active and obsolete) area instance versions of the area to "expired", and all shared locks are released. No new locks can be set on these area instance versions afterwards. How existing exclusive locks are handled depends on the input parameter TERMINATE_CHANGER. In non-transactional areas, the change takes place immediately; in transactional areas, the change takes place after the next database commit.

Input Parameters

◈ CLIENT of type SHM_CLIENT

Client ID if the area is client-specific. The default value is the ID of the current client. In tenant-isolation systems, the CLIENT parameter cannot be passed in application clients.

◈ TERMINATE_CHANGER of type ABAP_BOOL

Controls the handling of exclusive locks. Possible values are:

    ◈ ABAP_TRUE (existing exclusive locks are released (default setting)).
    ◈ ABAP_FALSE (existing exclusive locks are not released).

◈ AFFECT_SERVER of type SHM_AFFECT_SERVER (for transactional areas only)

Controls cross-server invalidation. Possible values are:

    ◈ CL_SHM_AREA=>AFFECT_LOCAL_SERVER (only the area instance versions of the current application server are invalidated (default setting)).
    ◈ CL_SHM_AREA=>AFFECT_ALL_SERVERS (the area instance versions of all application servers are invalidated).
    ◈ CL_SHM_AREA=>AFFECT_ALL_SERVERS_BUT_LOCAL (the area instance versions of all application servers are invalidated, apart from the current application server). This enables changes to be made to areas of the current application server directly, without the database having to create the entire area again.

Return Code

◈ RC of type SHM_RC
◈ Possible values in non-transactional areas:

    ◈ CL_SHM_AREA=>RC_DONE if at least one active or obsolete area instance version was set to "expired". If the value ABAP_TRUE was passed to TERMINATE_CHANGER (even if one or more exclusive locks were released).
    ◈ CL_SHM_AREA=>RC_NOTHING_TO_BE_DONE if no active or obsolete area instance versions exist and (if the value ABAP_TRUE was passed to TERMINATE_CHANGER) if no exclusive lock exists.

In transactional areas, RC always has the value CL_SHM_AREA=>RC_NOTHING_TO_BE_DONE.

Exceptions

◈ CX_SHM_PARAMETER_ERROR

An invalid value was passed for the input parameter TERMINATE_CHANGER.

Caution

After this method has been executed, all programs in which area handles still exist for the released area instance versions terminate with the runtime error SYSTEM_SHM_AREA_OBSOLETE.
    • GET_INSTANCE_INFOS
Returns the names of all instances of the area on the current application server that are currently being built, are active, or are obsolete.

Input Parameters

◈ CLIENT of type SHM_CLIENT

Client ID if the area is client-specific. The default value is the ID of the current client. In tenant-isolation systems, the CLIENT parameter cannot be passed in application clients.

Return Code

◈ INFOS of type SHM_INST_INFOS

SHM_INST_INFOS is an internal table of row type SHM_INST_INFO with the following components:

◈ CLIENT of type MANDT. The client ID if areas are client-specific. Initial if areas are cross-client.
◈ NAME of type SHM_INST_NAME (area name). This name is ◈ CL_SHM_AREA=>DFAULT_INSTANCE for areas with the default name.
◈ VERSIONS_IN_BUILD of type SHM_VERS_CNT. The number of area instance versions that are currently being built. Possible values are 0 or 1.
◈ VERSIONS_ACTIVE of type SHM_VERS_CNT. The number of currently active area instance versions. Possible values are 0 or 1.
◈ VERSIONS_OBSOLETE of type SHM_VERS_CNT. The number of obsolete area instance versions. Possible values range from 0 to the maximum number of area instance versions (component MAX_VERSIONS of the PROPERTIES attribute of the CL_SHM_AREA class).

An empty table is returned if there are no area instances for the area. The number of expired area instance versions is ignored.
    • BUILD
Calls the area constructor explicitly . The area constructor is executed in the current internal session. If the areas are client-specific, the area of the current client is built.

Input Parameters

◈ INST_NAME of type SHM_INST_NAME

Name of the area instance version. The name is optional. The default value is the value of constant CL_SHM_AREA=>DEFAULT_INSTANCE.

Exceptions

◈ CX_SHM_BUILD_FAILED
An error occurred when the area constructor was executed.
◈ CX_SHMA_NOT_CONFIGURED
No area constructor class is bound to the area class.
◈ CX_SHMA_INCONSISTENT
The area class has to be generated again.
    • PROPAGATE_INSTANCE (obsolete)
This method is only available if the area is transactional. It has the same effect as executing the INVALIDATE_INSTANCE method and passing the value of ABAP_TRUE to the input parameter TERMINATE_CHANGER on all application servers in the current AS ABAP. This propagation takes place after the next database commit.

Caution

Do not use this method any more. Instead, use the parameter AFFECT_SERVER of the FREE_AREA, FREE_INSTANCE, INVALIDATE_AREA, and INVALIDATE_INSTANCE methods.

Input Parameters

    ◈ INST_NAME of type SHM_INST_NAME
Name of the area instance version. The name is optional. The default value is the value of constant CL_SHM_AREA=>DEFAULT_INSTANCE.
    ◈ CLIENT of type SHM_CLIENT
Client ID if the area is client-specific. The default value is the ID of the current client. In tenant-isolation systems, the CLIENT parameter cannot be passed in application clients.
    ◈ AFFECTING_LOCAL_SERVER of type ABAP_BOOL

Controls whether the change in state is also performed on the current application server. Possible values are:

    ◈ ABAP_TRUE. The active area instance version is set to obsolete on the current application server. This setting can be used if the content of the area instance is to be changed using the area constructor, after the database content has been changed.
    ◈ ABAP_FALSE. The active area instance version is not set to obsolete on the current application server (default setting). This means that a new version can be preserved on an application server while only the current versions on other servers are invalidated.

Exceptions

◈ CX_SHM_PARAMETER_ERROR

An invalid value was passed for the input parameter AFFECTING_LOCAL_SERVER.
    • PROPAGATE_AREA (obsolete)
This method is only available if the area is transactional. It has the same effect as executing the INVALIDATE_AREA method and passing the value of ABAP_TRUE to the input parameter TERMINATE_CHANGER on all application servers in the current AS ABAP. This propagation takes place after the next database commit.

Caution

Do not use this method any more. Instead, use the parameter AFFECT_SERVER of the FREE_AREA, FREE_INSTANCE, INVALIDATE_AREA, and INVALIDATE_INSTANCE methods.

Input Parameters

◈ CLIENT of type SHM_CLIENT

Client ID if the area is client-specific. The default value is the ID of the current client. In tenant-isolation systems, the CLIENT parameter cannot be passed in application clients.

◈ AFFECTING_LOCAL_SERVER of type ABAP_BOOL

Controls whether the change in state is also performed on the current application server. Possible values are:
    ◈ ABAP_TRUE. The active area instance versions are set to obsolete on the current application server.
    ◈ ABAP_FALSE. The active area instance versions are not set to obsolete on the current application server (default setting).

Exceptions

◈ CX_SHM_PARAMETER_ERROR

An invalid value was passed for the input parameter AFFECTING_LOCAL_SERVER.
  • Instance Methods
    • SET_ROOT
This method defines the root object (instance of the area root class) of the area instance version. Before an exclusive lock can be released using the DETACH_COMMIT method, the root object has to be reset at least once using SET_ROOT. Updates are possible. The SET_ROOT method can only be called in area handles with exclusive locks.

Input Parameters

◈ REF TO of type area_root_class, where area_root_class is the area root class of the area.

Exceptions

◈ CX_SHM_WRONG_HANDLE
The method was called using an area handle with a shared lock or an area handle in which the DETACH_COMMIT method failed.
◈ CX_SHM_INITIAL_REFERENCE
The reference variable passed to ROOT is initial.

5.1.2 Shared Objects - CL_IMODE_AREA

The class CL_IMODE_AREA is a subclass of CL_ABAP_MEMORY_AREA and a predefined area class that enables the current internal session to be handled as an area instance version. There can be exactly one instance of the class CL_IMODE_AREA (singleton) in an internal session. This instance is an area handle for the current internal session.

Static Methods

GET_IMODE_HANDLE

Returns a reference to the area handle for the current internal session.

Return Value
  • HANDLE of type REF TO cl_imode_area
5.2 Shared Objects - IF_SHM_BUILD_INSTANCE

Interface IF_SHM_BUILD_INSTANCE must be included by an area constructor class that implements an area's optional area constructor.

Static Methods

BUILD

Interface method for implementing the area constructor of an area.

input parameter

◈ INST_NAME of type SHM_INST_NAME

Name of the area instance version. Entering a name is optional. The default value is the value of constant CL_SHM_AREA=>DEFAULT_INSTANCE.

◈ INVOCATION_MODE of type i

This parameter can be used to determine the type of call in the area constructor. The default value CL_SHM_AREA=>INVOCATION_MODE_EXPLICIT is used for the explicit call. CL_SHM_AREA=>INVOCATION_MODE_AUTO_BUILD is passed with the automatic call.

Exceptions

◈ CX_SHM_BUILD_FAILED

An error has occurred while executing the area constructor.

Note: The BUILD method does not have an input parameter for the client identifier. The area is built in the current client when the method is called.

5.2.1 Shared Objects - Area Constructor Class

An area constructor class is a global class with a freely selectable name, which implements the interface IF_SHM_BUILD_INSTANCE. An area constructor can be implemented in the interface method BUILD.

An area constructor class can be assigned to an area in transaction SHMA. This is always necessary if the area is to be built automatically by calling the area constructor, in other words if the BUILD_KIND and REFESH_TIME components of the PROPERTIES structure of class CL_SHM_AREA are filled accordingly. If an area is not to be built automatically, an area constructor class can be specified for the explicit area constructor call using the method BUILD of the area class.

Structure of an Area Constructor

The following structure is recommended for the area constructor implemented in the interface method BUILD:

1. First, the area constructor has to use the method ATTACH_FOR_WRITE to create an area handle with an exclusive lock for the area instance that is passed in the parameter INST_NAME. Since the automatic area constructor call cannot ensure that the exclusive lock can be set either, all exceptions have to be intercepted and forwarded to the caller of the constructor by raising the interface exception CX_SHM_BUILD_FAILED. This should pass the original exception to the parameter PREVIOUS of the constructor of CX_SHM_BUILD_FAILED.
2. Just like whenever a new area instance version is created, a root object also has to be defined in the area constructor using the method SET_ROOT.
3. The area instance version can then be built, that is, objects are stored in the shared memory.
4. The area handle that is created has to be released again using the method DETACH_COMMIT.
5. If the area constructor was called automatically, a database commit has to be triggered when a transactional area is built.

In an area constructor, no statements can be used that exit the current internal session (such as SUBMIT, CALL TRANSACTION, CALL SCREEN, MESSAGE for message types "W", "I", "E", and so on).

Example

The following implementation can be used as a template for new implementations.

CLASS area_constructor IMPLEMENTATION.

  METHOD if_shm_build_instance~build.

    DATA:
      my_handle TYPE REF TO area
      my_data   TYPE REF TO area_root_class
      my_except TYPE REF TO cx_root.

    TRY.
        my_handle = cl_my_area=>attach_for_write( inst_name ).
      CATCH cx_shm_error INTO my_except.
        RAISE EXCEPTION TYPE cx_shm_build_failed
                        EXPORTING previous = my_except.
    ENDTRY.

    CREATE OBJECT my_data AREA HANDLE my_handle.
    my_handle->set_root( my_data ).

    ... " code to build the area instance

    TRY.
        my_handle->detach_commit( ).
      CATCH cx_shm_error INTO my_except.
        RAISE EXCEPTION TYPE cx_shm_build_failed
                        EXPORTING previous = my_except.
    ENDTRY.

    IF invocation_mode = cl_shm_area=>invocation_mode_auto_build.
      CALL FUNCTION 'DB_COMMIT'.
    ENDIF.

  ENDMETHOD.

ENDCLASS.

6. Shared Objects - Restrictions

At present, the following restrictions apply to shared objects:

◈ On 32-bit systems, only a limited amount of memory space is available for storing shared objects, due to the restricted address space. For this reason, shared objects can only be used on 32-bit systems under certain conditions.

◈ When data objects that are referenced using data references are stored, there is also the restriction that the dynamic type cannot be created at program runtime. A direct reference to data elements and table types belonging to ABAP Dictionary is possible however.

◈ The memory consumption of shared objects in the shared memory cannot be monitored using Memory Inspector.

◈ Memory bottlenecks can occur in the shared objects memory, but they can be dealt with. The associated exception class is CX_SHM_OUT_OF_MEMORY.

◈ There is no memory restriction for logical areas, which generally consist of multiple area instances. There are currently only memory restrictions for individual area instances.

◈ The lifetime of area instances cannot be bound to that of user sessions, ABAP sessions, or transactions. Area instances currently exist as long as the application server instance.

7. Shared Objects

This example demonstrates the use of shared objects.

Source Code

REPORT demo_shared_objects.

CLASS demo_flight_list_handler DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-DATA flight_list_handler
    TYPE REF TO demo_flight_list_handler.
    CLASS-METHODS class_constructor.
    METHODS get_flight_list
      RETURNING
        VALUE(flights) TYPE REF TO spfli_tab
      RAISING
       cx_no_flights.
  PRIVATE SECTION.
    DATA area_handle TYPE REF TO cl_demo_flights.
    METHODS create_flight_list
      RAISING
        cx_shm_attach_error
        cx_no_flights.
ENDCLASS.

CLASS demo_flight_list_handler IMPLEMENTATION.
  METHOD class_constructor.
    CREATE OBJECT flight_list_handler.
  ENDMETHOD.
  METHOD get_flight_list.
    DATA flight_list TYPE REF TO cl_demo_flight_list.
    IF area_handle IS INITIAL.
      TRY.
          area_handle = cl_demo_flights=>attach_for_read( ).
        CATCH cx_shm_attach_error.
          TRY.
              me->create_flight_list( ).
              area_handle = cl_demo_flights=>attach_for_read( ).
            CATCH cx_shm_attach_error.
              CREATE OBJECT flight_list.
              flight_list->set_flight_list( ).
          ENDTRY.
      ENDTRY.
    ENDIF.
    IF area_handle IS NOT INITIAL.
      flights = REF #( area_handle->root->flight_list ).
    ELSEIF flight_list IS NOT INITIAL.
      flights = REF #( flight_list->flight_list ).
    ELSE.
      RAISE EXCEPTION TYPE cx_no_flights.
    ENDIF.
  ENDMETHOD.
  METHOD create_flight_list.
    DATA: flight_list  TYPE REF TO cl_demo_flight_list,
          exc_ref      TYPE REF TO cx_no_flights.
    DATA(area_handle) = cl_demo_flights=>attach_for_write( ).
    CREATE OBJECT flight_list AREA HANDLE area_handle.
    area_handle->set_root( flight_list ).
    TRY.
        flight_list->set_flight_list( ).
      CATCH cx_no_flights INTO exc_ref.
        area_handle->detach_rollback( ).
        RAISE EXCEPTION exc_ref.
    ENDTRY.
    area_handle->detach_commit( ).
  ENDMETHOD.
ENDCLASS.

CLASS shm_demo DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS main.
ENDCLASS.
CLASS shm_demo IMPLEMENTATION.
  METHOD main.
    DATA: flight_list_handler TYPE REF TO demo_flight_list_handler,
          flight_list TYPE REF TO spfli_tab.
    flight_list_handler =
      demo_flight_list_handler=>flight_list_handler.
    TRY.
        flight_list = flight_list_handler->get_flight_list( ).
      CATCH cx_no_flights.
         cl_demo_output=>display_text( 'No flight list available' ).
        RETURN.
    ENDTRY.
    cl_demo_output=>display_data( flight_list->* ).
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  shm_demo=>main( ).

Description

Area Root Class

The global class CL_DEMO_FLIGHT_LIST is used as an area root class. It contains the internal table FLIGHT_LIST (of type SPFLI_TAB from ABAP Dictionary) as a public attribute, which is filled by the method SET_FLIGHT_LIST. This table represents the non-modifiable data that is accessed from different programs.

Area

CL_DEMO_FLIGHTS is used as an area, whose properties are edited in transaction SHMA. The default values were applied apart from two exceptions:

◈ Versioning is deactivated because the data in the area instance should not be changed during the program runtime.
◈ The lifetime after the last access is restricted to five minutes. This prevents memory space from being occupied in the shared memory without a program requiring the memory.

Brokers and Loaders

The class demo_flight_list_handler encapsulates the access to the area before the consumer (in the real world, this would be a global class). The static constructor creates one instance of this class (singleton). The method get_flight_list is used as a broker. It attempts to set a shared lock for an area instance. Within an internal session, only one shared lock is possible for an area instance. Therefore the system first queries whether an area handle area already exists. The alternative would have been to handle the exception CX_SHM_READ_LOCK_ACTIVE. However, this would have been less effective in this example. If the operation is not successful, the method create_flight_list is called, which acts as a loader. This attempts to set a exclusive lock and to build an area instance with a root object. Any exceptions that occur are propagated to the calling method. A DETACH_ ROLLBACK is executed before any possible CX_NO_FLIGHTS exceptions from SET_FLIGHT_LIST are forwarded to the calling program. If the change lock is not removed explicitly, the program is terminated at the end of the current internal session or possibly even beforehand.

If the area was built, get_flight_list attempts to set a shared lock again. If the area instance could not be built, get_flight_list creates an object of class ZCL_FLIGHT_LIST (as an emergency measure) in the current internal session and fills the internal table flight_list. Finally, a data reference to the flight list is assigned to the return value of the method (either in the root object of the shared object or in the local object).

The exclusive lock in create_flight_list is closed explicitly, whereas a shared lock in get_flight_list is persisted until the end of the internal session. The latter point (shared lock) is only possible for areas without versioning, if no more modifying accesses are expected once an area has been built.

Consumers

The class shm_demo demonstrates a consumer. The method main creates an object of the class demo_flight_list_handler and attempts to read a reference to the flight list. If the access is successful, the flight list is displayed in the display method. It is not important for the consumer whether the data is actually contained in the shared memory or (if an error occurs) in a local object of class CL_DEMO_FLIGHT_LIST. If no data can be read from the database, a message is displayed.

After the program call, the area instance version can be examined using transaction SHMM.


⚫ Parameters in the User Memory 


1. SPA/GPA Parameters

The user memory is a user-specific memory area of the current application server, which is accessed by all ABAP sessions of a user session at once. ABAP programs have access to SPA/GPA parameters stored in the user memory (also called SET/GET parameters).

Each SPA/GPA parameter is identified by an ID of up to 20 characters. SPA/GPA parameters can either be created explicitly using the statement SET PARAMETER, or implicitly in a PAI event. Once they have been saved in the user memory, they are available to any programs and any sessions throughout the whole duration of a user session. SPA/GPA parameters are usually evaluated by the ABAP runtime environment. In ABAP programs, the parameters can be read using the statement GET PARAMETER.

Example

One example of a program that uses SPA/GPA parameters is user maintenance (transaction SU01). In this transaction, on the Parameters tab page, you can enter user-specific parameters, which are then set when the user logs on to the AS ABAP, and are evaluated by other programs.

2. SPA/GPA Parameters and ABAP Programs

The statements SET PARAMETER and GET PARAMETER of a program do not directly access the SPA/GPA parameters of the user memory.

◈ Instead, as soon as an ABAP program is rolled in to the memory, all of the SPA/GPA parameters of the user memory are copied to the roll area of the program. The statements SET PARAMETER and GET PARAMETER of a program work with the local SPA/GPA parameters of the roll area.
◈ As soon as a program is rolled out of the memory, all the local SPA/GPA parameters are copied to the cross-session SAP memory, where they replace all SPA/GPA parameters. Any SPA/GPA parameters that do not exist in the roll area will not exist in the user memory afterwards. A roll out is performed for various reasons, such as:
    ◈ When quitting a program.
    ◈ When calling a new program using SUBMIT, CALL TRANSACTION or LEAVE TO TRANSACTION.
    ◈ During any work process change A work process change results from the same situations that cause an implicit database commit.
    ◈ In the statement COMMIT WORK.

Note:

ABAP programs cannot access the user memory directly. Instead, all SPA/GPA parameters have to be imported or exported implicitly at given times like a file. This has consequences for programs that one and the same user can run in parallel sessions:

◈ If a program sets a SPA/GPA parameter with SET PARAMETER, a program in a parallel ABAP session cannot be started until rolling out the setting program has been started if it should have access to the changed parameter.
◈ If a program sets a SPA/GPA parameter using SET PARAMETER while another program in a parallel ABAP session is active, and the latter has been running longer than the setting program, these changes will be overwritten when the program that has been running longer is rolled out.

Premature rollouts can be forced by statements such as WAIT UP TO, but the fact that the state of the user memory is always determined by the program that was last rolled out creates a serious obstacle for cross-session use of SPA/GPA parameters in programs that are running in parallel. This type of programming is therefore not recommended.

3. Managing SPA/GPA Parameters

The names of SPA/GPA parameters are edited in database table TPARA. In the Object Navigator in ABAP Workbench, the names of SPA/GPA parameters are created in uppercase in database table TPARA and are linked to packages. Database table TPARA acts as a reservation table for SPA/GPA parameters. If SPA/GPA parameters are used in a program, the name of the parameter must be contained in the PARAMID column in the database table TPARA. Be careful not to overwrite SPA/GPA parameters from other applications.

Note

If a name exists in database table TPARA, this does not automatically mean that the corresponding parameter also exists in the user memory. SPA/GPA parameters are exclusively created during execution of an ABAP program.

4. SPA/GPA Parameters and Dynpro Errors

When defining input fields, dynpro fields can be associated with SPA/GPA parameters by entering the name of an SPA/GPA parameter from the database table TPARA as an attribute PARAMETER ID. If the corresponding parameter GET PARAMETER is set and no other value is assigned to the input field, the input field is filled with the value of the SPA/GPA parameter when the screen is sent. If the corresponding attribute SET PARAMETER is set, the content of the input field is assigned to the SPA/GPA parameter at the PAI event. If the parameter does not yet exist in the user memory, it is created implicitly in the PAI event. In selection screens, this associated can be created by using the addition MEMORY ID of the statements PARAMETERS and SELECT-OPTIONS.

Notes

1. A data transport between a dynpro field and an SPA/GPA parameter in the user memory only takes place if a global data object with the same name as the dynpro field is declared in the corresponding ABAP program.
2. If the PAI event is raised using a function of type "E", no values are assigned to the SPA/GPA parameters that are associated with the dynpro, and no parameters are created in the user memory.

1. SET PARAMETER

Syntax

SET PARAMETER ID pid FIELD dobj.

Effect

This statement sets the content of the SPA/GPA parameter specified in pid user memory to the content of the data object dobj. The ID pid must be a flat character-like field that contains no more than 20 characters and does not consist solely of blanks. pid is case-sensitive. dobj expects a flat character-like field whose binary content is passed in an unconverted format.

The statement GET PARAMETER does not access the user memory directly. Instead, it accesses a local mapping of the SPA/GPA parameter in the roll area, which is loaded when rolled in and saved in the user memory when rolled out (see SPA/GPA Parameters and ABAP Programs). If the SPA/GPA parameter specified for the current user in pid does not yet exist in the user memory, it is created. If the SPA/GPA parameter has already been created for the current user, its value is overwritten.

In a program, SPA/GPA parameters can only be created or assigned values if a name exists for them in the table TPARA. If it can be determined statically that an ID pid is not in the database table TPARA, the extended program check reports an error.

Notes

◈ An SPA/GPA parameter specified in pid can match a name in the database table TPARA only if it is entered in uppercase letters.

◈ The statements SET PARAMETER and GET PARAMETER do not work directly with the SPA/GPA parameters of the user memory, which means that they are only suitable for passing data within a single ABAP session and not for passing data between two main sessions in parallel This is because programs that run in parallel can change the state of the parameters unpredictably.

Example

If the user selects a flight displayed in the basic list, when the event ATLINE-SELECTION takes place, the SPA/GPA parameters CAR and CON are set to the ID of the airline and the connection number. The names of both parameters are defined in the table TPARA for this purpose. In the initial dynpro of the transaction DEMO_TRANSACTION, two input fields are associated with these SPA/GPA parameters and are displayed with the selected values as start values.

DATA: carrier     TYPE spfli-carrid,
      connection  TYPE spfli-connid.

START-OF-SELECTION.
  SELECT carrid, connid
         FROM spfli
         INTO (@carrier, @connection).
    WRITE: / carrier HOTSPOT, connection HOTSPOT.
    HIDE:  carrier, connection.
  ENDSELECT.

AT LINE-SELECTION.
  SET PARAMETER ID: 'CAR' FIELD carrier,
                    'CON' FIELD connection.
  CALL TRANSACTION 'DEMO_TRANSACTION'.

Exceptions

Non-Handleable Exceptions

◈ Cause:: Key only contains blank characters
Runtime Error: SET_PARAMETER_ID_SPACE

◈ Cause: Key is longer than 20 characters
Runtime Error: SET_PARAMETER_ID_TOO_LONG

◈ Cause: Value is longer than 255 characters
Runtime Error: SET_PARAMETER_VALUE_TOO_LONG

◈ Cause: Memory limit of the user memory was reached
Runtime Error: SET_PARAMETER_MEMORY_OVERFLOW

2. GET PARAMETER

Syntax

GET PARAMETER ID pid FIELD dobj.

Effect

This statement sets the content of the data object dobj to the content of the SPA/GPA parameter specified in pid in the user memory. The identification pid must be a flat character-like field that contains no more than 20 characters and does not consist solely of blanks. The field is case-sensitive. The binary content of the SPA/GPA parameter is passed to dobj without being converted. The following can be specified for dobj:

◈ An existing flat character-like variable.
◈ An inline declaration DATA(var), where a variable of type XUVALUE is declared.

The statement GET PARAMETER does not access the user memory directly. Instead, it accesses a local mapping of the SPA/GPA parameter in the roll area, which is loaded when rolled in and saved in the user memory when rolled out (see SPA/GPA Parameters and ABAP Programs). If the SPA/GPA parameter specified in pid does not yet exist in the user memory for the current user, the data object dobj is initialized and sy-subrc is set to 4.

A program can only read those SPA/GPA parameters for which there is a name in the table TPARA. If it can be determined statically that an ID pid is not in the database table TPARA, the extended program check reports an error.

System Fields

sy-subrc Meaning
0 The SPA/GPA parameter specified in pid exists for the current user in the user memory and its value was passed to the target field. 
The SPA/GPA parameter specified in pid does not exist for the current user in the user memory. 

Notes

◈ An SPA/GPA parameter that is readable using GET PARAMETER can either have been created previously in the user memory using the SET PARAMETER statement or created automatically in the event PAI of a dynpro or selection screen. 

◈ An SPA/GPA parameter specified in pid can match a name in the database table TPARA only if it is entered in uppercase letters. 

◈ The statements SET PARAMETER and GET PARAMETER do not work directly with the SPA/GPA parameters of the user memory, which means that they are only suitable for passing data within a single ABAP session and not for passing data between two main sessions in parallel This is because programs that run in parallel can change the state of the parameters unpredictably. 

Example

In this example, the current value of the SPA/GPA parameter RID is read from the user memory to the data object prog. In the dynpros in ABAP Workbench, this parameter is associated with the input fields for a program name. When an ABAP Workbench tool in which an ABAP program is processed, is first called, the parameter is created in the event PAI and assigned the name of the program specified there. If, in the same user session, no dynpro is processed that sets the parameter RID and no corresponding SET PARAMETER statement was executed beforehand, RID is not found in the user memory.

DATA: para TYPE tpara-paramid VALUE 'RID', 
      prog TYPE sy-repid. 

GET PARAMETER ID para FIELD prog. 

IF sy-subrc <> 0. 
  MESSAGE 'Parameter not found' TYPE 'I'. 
ENDIF.

«« Previous
Next »»

No comments:

Post a Comment