Showing posts with label SAP NetWeaver Application Server for ABAP. Show all posts
Showing posts with label SAP NetWeaver Application Server for ABAP. Show all posts

Wednesday, 4 October 2017

Dynamic Programming in ABAP: Part 3 – An Example – ABAP RTTS

In my last blog I explained about the significance of field symbol and data references in dynamic programming.

https://saponlineguides.blogspot.in/2017/09/dynamic-programming-in-abap-part-1-introduction-to-field-symbols.html

https://saponlineguides.blogspot.in/2017/09/dynamic-programming-in-abap-part-2-introduction-to-data-reference.html

SAP ABAP RTTS, SAP Guides, SAP ABAP Learning, SAP Certifications

Now here we will see one example of dynamic programming approach and also a brief introduction to ABAP RTTS.

ABAP Runtime Type Services (RTTS) consists of two components:

◉ Runtime Type Identification (RTTI) – Provides the methods to get the type definition of data objects at runtime.

◉ Runtime Type Creation (RTTC) – Provides the methods to create the data objects at runtime with any type definition.

Basically, ABAP RTTS provides a set of classes, whose methods can be used for runtime type identification and runtime type creation. To know more about ABAP RTTS you can follow below link:

https://wiki.scn.sap.com/wiki/pages/viewpage.action?pageId=42965


An example of dynamic programming:


Requirement: As an ABAP developer, very often we get the situation where we need to write data from an internal table to a file on application server.

Solution: We will build one class having a method which will take any internal table as input and write its content in a file on application server.

Class Definition:

CLASS cl_appserver_writer DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: write IMPORTING
                           iv_filename  TYPE string
                           it_data      TYPE ANY TABLE
                           write_header TYPE abap_bool DEFAULT space
                         EXPORTING
                           ev_message   TYPE string.
ENDCLASS.

Here importing parameter it_data is of TYPE ANY TABLE so that it can receive any internal table.

Class Implementation:

CLASS cl_appserver_writer IMPLEMENTATION.
  METHOD write.
    TYPES: BEGIN OF ty_comp_detail,
             name  TYPE abap_compname,
             descr TYPE scrtext_m,
           END OF ty_comp_detail.
    DATA: lo_type_def    TYPE REF TO cl_abap_typedescr.
    DATA: lo_struct_def  TYPE REF TO cl_abap_structdescr.
    DATA: lo_table_def   TYPE REF TO cl_abap_tabledescr.
    DATA: lo_data_def    TYPE REF TO cl_abap_datadescr.
    DATA: lo_element_def TYPE REF TO cl_abap_elemdescr.
    DATA: lt_components  TYPE abap_compdescr_tab.
    DATA: wa_components  LIKE LINE OF lt_components.
    DATA: lv_str         TYPE string.
    DATA: lv_filerow     TYPE string.
    DATA: lv_counter     TYPE i VALUE 0.
    DATA: lw_field_info  TYPE dfies.
    DATA: ls_comp_detail TYPE ty_comp_detail.
    DATA: lt_comp_detail TYPE TABLE OF ty_comp_detail.

    FIELD-SYMBOLS: <row> TYPE any.
    FIELD-SYMBOLS: <field_value> TYPE any.

* Using RTTS to get the runtime type information of the internal table
    lo_type_def  = cl_abap_tabledescr=>describe_by_data( it_data ).
    lo_table_def ?= lo_type_def.
    lo_data_def = lo_table_def->get_table_line_type( ).
    lo_struct_def ?= lo_data_def.

* Get the components of the structure
    lt_components = lo_struct_def->components.

    CLEAR: lo_data_def.

* If the WRITE_HEADER is ABAP_TRUE then fetch the label
* of data element associated to each component of the
* line type structure of internal table, if no data element
* is associated then use component name as the header text
    IF write_header EQ abap_true.
      LOOP AT lt_components INTO wa_components.
        lo_data_def = lo_struct_def->get_component_type( wa_components-name ).
        lo_element_def ?= lo_data_def.
        lw_field_info = lo_element_def->get_ddic_field( ).
        ls_comp_detail-name = lw_field_info-rollname.  "Get the data element name

* Calling FM to get data element text
        CALL FUNCTION 'WCGW_DATA_ELEMENT_TEXT_GET'
          EXPORTING
            i_data_element = lw_field_info-rollname
            i_language     = sy-langu
          IMPORTING
            e_scrtext_m    = ls_comp_detail-descr
          EXCEPTIONS
            error          = 1.
        IF ls_comp_detail-descr IS INITIAL.
          ls_comp_detail-descr = wa_components-name.
        ENDIF.
        APPEND ls_comp_detail TO lt_comp_detail.
        CLEAR: ls_comp_detail.
      ENDLOOP.
    ENDIF.

    OPEN DATASET iv_filename FOR OUTPUT IN TEXT MODE ENCODING DEFAULT.
    IF sy-subrc EQ 0.
* Writing header text for each column separated by comma
      IF write_header EQ abap_true.
        LOOP AT lt_comp_detail INTO ls_comp_detail.
          lv_counter = lv_counter + 1.
          IF lv_counter EQ 1.
            lv_filerow = ls_comp_detail-descr.
          ELSE.
            CONCATENATE lv_filerow ',' ls_comp_detail-descr INTO lv_filerow.
          ENDIF.
        ENDLOOP.
        TRANSFER lv_filerow TO iv_filename.
        CLEAR: lv_filerow, lv_counter.
      ENDIF.

* Writing internal table content separated by comma
      LOOP AT it_data ASSIGNING <row>.
        LOOP AT lt_components INTO wa_components.
          lv_counter = lv_counter + 1.
          ASSIGN COMPONENT wa_components-name OF STRUCTURE <row> TO <field_value>.
          IF <field_value> IS ASSIGNED.
            lv_str = <field_value>.
            IF lv_counter EQ 1.
              lv_filerow = lv_str.
            ELSE.
              CONCATENATE lv_filerow ',' lv_str INTO lv_filerow.
            ENDIF.
            UNASSIGN <field_value>.
          ENDIF.
        ENDLOOP.
        TRANSFER lv_filerow TO iv_filename.
        CLEAR: lv_filerow, lv_counter.
      ENDLOOP.
      CLOSE DATASET iv_filename.
      ev_message = 'Success'.
    ELSE.
      ev_message = 'Failure'.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

Here the classes CL_ABAP_*DESCR are provided by the ABAP RTTS and used to get the type definition of data objects at runtime. Also we have extracted the data element name of each component of line type structure of internal table it_data using RTTS classes. Then we fetched the data element label using the FM WCGW_DATA_ELEMENT_TEXT_GET. This label is used to write the header for each column of internal table it_data if WRITE_HEADER parameter of class is provided with ABAP_TRUE.

Using the Class – The above designed class can be used as:

DATA: lt_data  TYPE STANDARD TABLE OF mara.
  DATA: lv_filename TYPE string.
  DATA: lv_message  TYPE string.

  SELECT * FROM mara INTO TABLE lt_data UP TO 5 ROWS.

  cl_appserver_writer=>write(
    EXPORTING
      iv_filename  = 'D:\usr\sap\testdata.csv'
      it_data      = lt_data
      write_header = abap_true
    IMPORTING
      ev_message   = lv_message
  ).

  WRITE: / lv_message.

Here we are passing one internal table of structure MARA to the class, and subsequently its content will be written on application server as comma separated values. However, we can pass internal table of any structure. This file can also be downloaded from application server to an excel spreadsheet.

So this is how field symbol, data reference, generic data type, RTTS helps in dynamic programming approach.

The complete code:


App Server Writer.txt

REPORT zwrite_appserver.

CLASS cl_appserver_writer DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: write IMPORTING
                           iv_filename  TYPE string
                           it_data      TYPE ANY TABLE
                           write_header TYPE abap_bool DEFAULT space
                         EXPORTING
                           ev_message   TYPE string.
ENDCLASS.

CLASS cl_appserver_writer IMPLEMENTATION.
  METHOD write.
    TYPES: BEGIN OF ty_comp_detail,
             name  TYPE abap_compname,
             descr TYPE scrtext_m,
           END OF ty_comp_detail.
    DATA: lo_type_def    TYPE REF TO cl_abap_typedescr.
    DATA: lo_struct_def  TYPE REF TO cl_abap_structdescr.
    DATA: lo_table_def   TYPE REF TO cl_abap_tabledescr.
    DATA: lo_data_def    TYPE REF TO cl_abap_datadescr.
    DATA: lo_element_def TYPE REF TO cl_abap_elemdescr.
    DATA: lt_components  TYPE abap_compdescr_tab.
    DATA: wa_components  LIKE LINE OF lt_components.
    DATA: lv_str         TYPE string.
    DATA: lv_filerow     TYPE string.
    DATA: lv_counter     TYPE i VALUE 0.
    DATA: lw_field_info  TYPE dfies.
    DATA: ls_comp_detail TYPE ty_comp_detail.
    DATA: lt_comp_detail TYPE TABLE OF ty_comp_detail.

    FIELD-SYMBOLS: <row> TYPE any.
    FIELD-SYMBOLS: <field_value> TYPE any.

* Using RTTS to get the runtime type information of the internal table
    lo_type_def  = cl_abap_tabledescr=>describe_by_data( it_data ).
    lo_table_def ?= lo_type_def.
    lo_data_def = lo_table_def->get_table_line_type( ).
    lo_struct_def ?= lo_data_def.
    lt_components = lo_struct_def->components.

    CLEAR: lo_data_def.

* If the WRITE_HEADER is ABAP_TRUE then fetch the label
* of data element associated to each component of the
* line type structure of internal table, if no data element
* is associated then use component name as the header text
    IF write_header EQ abap_true.
      LOOP AT lt_components INTO wa_components.
        lo_data_def = lo_struct_def->get_component_type( wa_components-name ).
        lo_element_def ?= lo_data_def.
        lw_field_info = lo_element_def->get_ddic_field( ).
        ls_comp_detail-name = lw_field_info-rollname.

* Calling FM to get data element text
        CALL FUNCTION 'WCGW_DATA_ELEMENT_TEXT_GET'
          EXPORTING
            i_data_element = lw_field_info-rollname
            i_language     = sy-langu
          IMPORTING
            e_scrtext_m    = ls_comp_detail-descr
          EXCEPTIONS
            error          = 1.
        IF ls_comp_detail-descr IS INITIAL.
          ls_comp_detail-descr = wa_components-name.
        ENDIF.
        APPEND ls_comp_detail TO lt_comp_detail.
        CLEAR: ls_comp_detail.
      ENDLOOP.
    ENDIF.


    OPEN DATASET iv_filename FOR OUTPUT IN TEXT MODE ENCODING DEFAULT.
    IF sy-subrc EQ 0.
* Writing header text for each column separated by comma
      IF write_header EQ abap_true.
        LOOP AT lt_comp_detail INTO ls_comp_detail.
          lv_counter = lv_counter + 1.
          IF lv_counter EQ 1.
            lv_filerow = ls_comp_detail-descr.
          ELSE.
            CONCATENATE lv_filerow ',' ls_comp_detail-descr INTO lv_filerow.
          ENDIF.
        ENDLOOP.
        TRANSFER lv_filerow TO iv_filename.
        CLEAR: lv_filerow, lv_counter.
      ENDIF.

* Writing internal table content separated by comma
      LOOP AT it_data ASSIGNING <row>.
        LOOP AT lt_components INTO wa_components.
          lv_counter = lv_counter + 1.
          ASSIGN COMPONENT wa_components-name OF STRUCTURE <row> TO <field_value>.
          IF <field_value> IS ASSIGNED.
            lv_str = <field_value>.
            IF lv_counter EQ 1.
              lv_filerow = lv_str.
            ELSE.
              CONCATENATE lv_filerow ',' lv_str INTO lv_filerow.
            ENDIF.
            UNASSIGN <field_value>.
          ENDIF.
        ENDLOOP.
        TRANSFER lv_filerow TO iv_filename.
        CLEAR: lv_filerow, lv_counter.
      ENDLOOP.
      CLOSE DATASET iv_filename.
      ev_message = 'Success'.
    ELSE.
      ev_message = 'Failure'.
    ENDIF.
  ENDMETHOD.
ENDCLASS.


START-OF-SELECTION.
  DATA: lt_data  TYPE STANDARD TABLE OF mara.
  DATA: lv_filename TYPE string.
  DATA: lv_message  TYPE string.

  SELECT * FROM mara INTO TABLE lt_data UP TO 5 ROWS.

  cl_appserver_writer=>write(
    EXPORTING
      iv_filename  = 'D:\usr\sap\testdata.csv'
      it_data      = lt_data
      write_header = abap_true
    IMPORTING
      ev_message   = lv_message
  ).

  WRITE: / lv_message.

Tuesday, 12 September 2017

Dynamic Programming in ABAP: Part 2 - Introduction to Data Reference

In my last blog I explained about field symbols, below is the link for same:

Dynamic Programming in ABAP: Part 1 - Introduction to Field Symbols

In this blog I am going to explain about data references and its significance in dynamic programming.

According to SAP documentation, Data references can point to any data objects or to their parts (components, rows of internal tables, or sections specified by offsets and lengths).

SAP ABAP, SAP ABAP Certifications, SAP ABAP Live, ABAP Learning, SAP ABAP Tutorials and Materials

So data references are nothing but pointers. It stores the memory address of any data object. But to access the actual data object which data reference is pointing to, we first need to deference it using dereferencing operator ->*.

Difference between field symbol and data reference:

Field symbol is a placeholder for data object to which it is assigned and points to the content of data object hence it can be used at any operand position (no need to dereference it) and works with the content of the referenced memory area (value semantics).

Data references are pointers to data objects and it contains the memory address of data object (reference semantics). Data reference cannot be used at operand position directly; it should be dereferenced first.

Working with data reference:

There can be two types of data references:

◉ Typed Data Reference
◉ Generic Data Reference


1. Typed Data Reference:


Typed data reference variable can be declared as:

DATA lr_num TYPE REF TO i.
CREATE DATA lr_num.

Here first statement declares a reference variable lr_num which can point to any data object of type “i”. And second statement creates an anonymous data object of type “i” and assigns the reference of this data object to lr_num. Now if we want to change the value of data object, then it can be done by dereferencing lr_num by using dereference operator ->* as shown below:

DATA lr_num TYPE REF TO i.
CREATE DATA lr_num.

lr_num->* = 2.
WRITE: / lr_num->*.

The output will be 2.

--------------------------------------------------------------------------------------------------------
NOTE:

◉ With ABAP 7.40, instead of CREATE DATA, the NEW operator can also be used to create an anonymous data object and assigns its reference to a data reference variable.
--------------------------------------------------------------------------------------------------------

DATA lr_num TYPE REF TO i.
lr_num = NEW #( ).

Assigning existing data object to data reference:

If you want to assign the reference of an existing data object to a data reference, you can use GET REFERENCE statement.

DATA: lv_num TYPE i VALUE 2.
DATA: lr_num TYPE REF TO i.

GET REFERENCE OF lv_num INTO lr_num.
lr_num->* = 4.
WRITE: / lv_num.

Here lv_num is an existing data object (not anonymous data object). The output would be 4.

---------------------------------------------------------------------------------------------------------
NOTE:

◉ With ABAP 7.40, instead of GET REFERENCE, the REF operator also can be used to assign the reference of an existing data object to a data reference.
---------------------------------------------------------------------------------------------------------

Working with structures:

DATA: lr_mara TYPE REF TO mara.

CREATE DATA lr_mara.
lr_mara->matnr = '1111'.
lr_mara->matkl = '03'.

Here individual components of the structure can be accessed with -> operator on data reference variable.

Working with internal tables:

While processing internal table row, we can use REFERENCE INTO statement to set references to table rows as shown below:

DATA: lr_mara TYPE REF TO mara.
DATA: lt_mara TYPE TABLE OF mara.

SELECT * FROM mara INTO TABLE lt_mara UP TO 10 ROWS.

LOOP AT lt_mara REFERENCE INTO lr_mara.
  WRITE: / lr_mara->matnr.
ENDLOOP.

2. Generic Data Reference:


Generic data reference can be declared as:

DATA: lr_num TYPE REF TO data.
CREATE DATA lr_num TYPE i.

Here first statement declares a generic data reference lr_num which can point to any data object. And second statement creates an anonymous data object of type “i” and assigns its reference to lr_num.

‘data’ in ABAP is a generic data type.

Now since lr_num is generic, lr_num->* cannot be directly used at operand position. Hence the below statement would not be allowed.

lr_num->* = 2.

So in case of generic data reference, it can only be dereferenced using a field symbol, and this field symbol can be used at any operand position to manipulate the value of data object as shown below:

DATA: lr_num TYPE REF TO data.
FIELD-SYMBOLS: <num> TYPE any.

CREATE DATA lr_num TYPE i.
ASSIGN lr_num->* TO <num>.

<num> = 3.

----------------------------------------------------------------------------------------------------------
NOTE:

After ASSIGN statement you should check sy-subrc If field symbol assignment is successful, sy-subrc will be 0 otherwise it will be 4.
----------------------------------------------------------------------------------------------------------

Working with structures:

DATA: lr_str TYPE REF TO data.
FIELD-SYMBOLS: <str> TYPE any.
FIELD-SYMBOLS: <data> TYPE any.
CREATE DATA lr_str TYPE mara.

ASSIGN lr_str->* TO <str>.
ASSIGN COMPONENT 'MATNR' OF STRUCTURE <str> TO <data>.
<data> = '112'.

Here CREATE DATA statement creates an anonymous data object (MARA structure) and assigns its reference to the generic data reference lr_str, which then can be dereferenced into a generic field symbol <str>. Now, to access individual component of MARA structure, ASSIGN COMPONENT statement can be used.

Dynamically create data objects:

Requirement: Selection screen parameter “Table Name” will take a table name as input and display the corresponding table entries as output.

Solution:

PARAMETERS: p_tname TYPE tabname.
DATA: lr_tab TYPE REF TO data.
FIELD-SYMBOLS: <tab> TYPE ANY TABLE.

CREATE DATA lr_tab TYPE TABLE OF (p_tname).
ASSIGN lr_tab->* TO <tab>.
IF sy-subrc EQ 0.
  SELECT * FROM (p_tname) INTO TABLE <tab> UP TO 10 ROWS.
  cl_demo_output=>display( <tab> ).
ENDIF.

Explanation:

Here lr_tab is a generic data reference and <tab> is a generic field symbol for internal table. In CREATE DATA statement, the type of data object is mentioned in parenthesis which means that the type will be determined at runtime based on the value of parameter p_tname. After that we have dereferenced the data reference lr_tab into a generic field symbol <tab>. Now this field symbol can be used to do any valid operation on the internal table.

Difference between data reference and object reference:

There are two types of reference variable:

◉ Data reference and
◉ Object reference

Data reference variable can store the reference to any data object (variable, structures, internal tables etc.) whereas Object reference variable can store the reference to any class object.

For data reference variables, either the generic data type or a completely specified data type can be specified. For object reference variables, either a class or an interface can be specified.

Credits: https://help.sap.com/http.svc/rc/abapdocu_751_index_htm/7.51/en-US/abendata_reference_type.htm

Follow us on Twitter: https://twitter.com/saponlineguides
Google+: https://plus.google.com/b/107454975947044053086/107454975947044053086
Facebook:  https://www.facebook.com/saponlineguides/

Wednesday, 6 September 2017

Dynamic Programming in ABAP: Part 1 - Introduction to Field Symbols

Field symbol is a placeholder for data object, which points to the value present at the memory address of a data object. It does not reserve any physical memory space when we declare them. It only points to a data object at run time. Field symbols are of two types:

SAP ABAP Certifications, SAP ABAP Development, SAP Guides, SAP All Modules, SAP Module, SAP Tutorials and Materials, SAP Learning

◉ Typed Field Symbol
◉ Generic Field Symbol

Typed Field Symbol:


Typed field symbol can be declared as:

DATA: var TYPE i VALUE 2.
FIELD-SYMBOLS: <fs_num> TYPE i.
ASSIGN var TO <fs_num>.
WRITE: / <fs_num>.
<fs_num> = 4.
WRITE: / var.

The output will be 2 and 4.

---------------------------------------------------------------------------------------------------------
NOTE:

◉ Typed field symbols can point to the data objects of specified type only.
◉ After assigning a data object to a field symbol, if we make any changes to the field symbol value, then the value of corresponding data object is also updated.
---------------------------------------------------------------------------------------------------------

Field symbol as a replacement of Work area:

Modifying internal table records – We can declare a field symbol of type any structure, which we can use while looping through an internal table.

DATA: lt_mara TYPE STANDARD TABLE OF mara.
FIELD-SYMBOLS: <fs_mara> TYPE mara.
SELECT * FROM mara INTO TABLE lt_mara UP TO 10 ROWS.
LOOP AT lt_mara ASSIGNING <fs_mara>.
  <fs_mara>-matkl = 'DEMO'.
ENDLOOP.


--------------------------------------------------------------------------------------------------------
NOTE:

◉ If we change any field of structure in field symbol, the corresponding field in internal will get updated. We don’t need to write the MODIFY statement which we would have written if we had used work area. This is because work area stores a copy of the internal table row, whereas field symbol directly references the internal table row.
◉ Hence processing of internal table with field symbol is faster than the processing of internal table with work area.
--------------------------------------------------------------------------------------------------------

Appending to internal table – Now suppose we want to append some values to one internal table, then we can use field symbol as below:

DATA: lt_mara TYPE STANDARD TABLE OF mara.
FIELD-SYMBOLS: <fs_mara> TYPE mara.

APPEND INITIAL LINE TO lt_mara ASSIGNING <fs_mara>.
IF <fs_mara> IS ASSIGNED.
  <fs_mara>-matnr = 'MAT1'.
  <fs_mara>-matkl = '001'.
  UNASSIGN <fs_mara>.
ENDIF.

APPEND INITIAL LINE TO lt_mara ASSIGNING <fs_mara>.
IF <fs_mara> IS ASSIGNED.
  <fs_mara>-matnr = 'MAT2'.
  <fs_mara>-matkl = '001'.
  UNASSIGN <fs_mara>.
ENDIF.

After executing this, the internal table will hold two rows.

--------------------------------------------------------------------------------------------------------
NOTE:

◉ Always perform a check on field symbol that if it is assigned before doing any operation to avoid short dump. Also after doing the operation, unassign the field symbol.
--------------------------------------------------------------------------------------------------------

Reading internal table – We can read a record of internal table using field symbol as below:

READ TABLE lt_mara ASSIGNING <fs_mara> WITH KEY matnr = 'MAT1'.

Generic Field Symbol:


Dynamic programming is actually implemented using generic field symbols. The most commonly used generic types are TYPE ANY and TYPE ANY TABLE.

FIELD-SYMBOLS: <fs_str> TYPE ANY.
FIELD-SYMBOLS: <fs_tab> TYPE ANY TABLE.

Here we can assign any data object to TYPE ANY field symbol whereas TYPE ANY TABLE field symbol is used for assigning any internal table.

TYPE ANY:

Let us assign a work area of type MARA to a TYPE ANY field symbol and then populate the work area using field symbol.

FIELD-SYMBOLS: <fs_str> TYPE ANY.
FIELD-SYMBOLS: <fs_data> TYPE ANY.
DATA: lw_mara TYPE mara.

ASSIGN lw_mara TO <fs_str>.
IF <fs_str> IS ASSIGNED.
  ASSIGN COMPONENT 'MATNR' OF STRUCTURE <fs_str> TO <fs_data>.
  IF <fs_data> IS ASSIGNED.
    <fs_data> = 'MAT001'.
    UNASSIGN <fs_data>.
  ENDIF.
  UNASSIGN <fs_str>.
ENDIF.

--------------------------------------------------------------------------------------------------------
NOTE:

◉ After assigning lw_mara to <fs_str>, we cannot directly use the ‘-‘ operator on field symbol to access the fields of MARA structure i.e. <fs_str>-matnr would produce syntax error. This is because the field symbol type is declared only at runtime not at compile time.
◉ So to access the matnr field with field symbol, first we need to assign that field component to a different field symbol and then use the new field symbol to update the matnr field as show in above code snippet.
◉ After execution of above code snippet, the value of lw_mara-matnr would be MAT001.
--------------------------------------------------------------------------------------------------------

TYPE ANY TABLE:

We can assign any internal table to this field symbol. Let us analyze the below code snippet to understand how we could use such field symbol.

FIELD-SYMBOLS: <fs_tab> TYPE ANY TABLE.
FIELD-SYMBOLS: <fs_str> TYPE any.
FIELD-SYMBOLS: <fs_data> TYPE any.
DATA: lt_mara TYPE STANDARD TABLE OF mara.
DATA: lw_mara TYPE mara.

ASSIGN lt_mara TO <fs_tab>.
SELECT * FROM mara INTO TABLE lt_mara UP TO 10 ROWS.

LOOP AT <fs_tab> ASSIGNING <fs_str>.
  IF <fs_str> IS ASSIGNED.
    ASSIGN COMPONENT 'MATKL' OF STRUCTURE <fs_str> TO <fs_data>.
    IF <fs_data> IS ASSIGNED.
      IF <fs_data> EQ '01'.
*********** Do some processing *********
      ENDIF.
      UNASSIGN <fs_data>.
    ENDIF.
  ENDIF.
ENDLOOP.

Reading internal table using generic field symbol:

FIELD-SYMBOLS: <fs_tab> TYPE ANY TABLE.
FIELD-SYMBOLS: <fs_str> TYPE any.
DATA: lt_mara TYPE STANDARD TABLE OF mara.

ASSIGN lt_mara TO <fs_tab>.
SELECT * FROM mara INTO TABLE lt_mara UP TO 10 ROWS.

READ TABLE <fs_tab> ASSIGNING <fs_str> WITH KEY ('MATNR') = 'MAT001'.


--------------------------------------------------------------------------------------------------------
NOTE:

◉ Since <fs_tab> is a generic field symbol, its type will be known only at runtime, hence we cannot directly write the fields of MARA structure after WITH KEY, instead we have to write the field name within parenthesis as shown above.
◉ In ABAP, this parenthesis indicates the compiler that the value of the operand will be decided at runtime, hence we don’t get any compilation error.
--------------------------------------------------------------------------------------------------------

Saturday, 22 October 2016

Connectivity News in AS ABAP 7.51

ABAP Channels


Multiplexer for WebSocket connections

In contrast to HTTP connection, which is short-lived and can be reused for multiple HTTP requests, the WebSocket connection is long-lived and cannot be reused for other WebSockets. That means that each WebSocket-enabled component requires its own WebSocket connection and the number of WebSockets connections grows over time. Besides this any web browser has its own WebSocket connections limitations and the ABAP application server might reach its connection limit as well.

ABAP Connectivity, ABAP Development, SAP NetWeaver Application Server for ABAP

To get over these problems you can now benefit from the multiplexer which virtualizes multiple WebSocket connections via the only one real WebSocket connection which is then used for exchanging messages. Each application (component) still establishes its own WebSocket connection but now this connection is virtual and doesn’t cause any physical load. Multiplexing is enabled by default for the WebSocket application in the AS ABAP via transaction SAPC and shipped on the client side with the PCP JavaScript library.

Enhanced support for large ABAP Channels messages

Now you can send large messages via ABAP Push Channel (APC) and ABAP Messaging Channel (AMC). The max. message length of messages for AMC was increased from 31 kB to approx. 1 MB and can be configured. The max. message length of messages for APC was increased from approx. 64 kB to approx. 100 MB and can be configured as well.

Create ABAP Push Channels applications in Eclipse

Now you can create ABAP Push Channels (APC) and specify APC applications (transaction SAPC) also in the ABAP Development Tools for Eclipse and so manage your APC applications without accessing a SAP GUI.

ABAP Development, ABAP Connectivity, SAP NetWeaver Application Server for ABAP

SAP Web Dispatcher / Internet Communication Manager


Network Edge Authentication

With Network Edge Authentication you get integrated, simple and secure Web access to backend systems of SAP solutions. SAP Web Dispatcher intercepts all incoming requests from the Internet and forwards only authenticated requests to backend systems in the internal network. Single sign-on and single log-off are provided for multiple independent backend systems including Fiori and SAP Enterprise Portal. A prerequisite for using Network Edge Authentication with SAP Web Dispatcher version 7.49 is a SAP Single Sign-On 3.0 SP1 installation. 

HTTP/2 Support

HTTP/2 (originally named HTTP/2.0) is a major revision of the HTTP protocol used by the World Wide Web.  HTTP/2 reuses the HTTP1.1 (methods, status codes, semantics etc.) but focuses on end-user perceived performance by optimizing network and server resource usage. Major goal is to use one single connection from browsers to a Web site.

The SAP ABAP application server as well as the SAP Web Dispatcher support HTTP/2 in the HTTP server role with release 7.51 and kernel version 7.49. The feature has to be enabled by setting the profile parameter icm/HTTP/support_http2=true. Please note: server push feature of HTTP/2 is not yet supported by the SAP ABAP application server.

RFC


RFC: New Fast Serialization

Now if you need a faster RFC connection, you benefit from new fast RFC serialization for RFC communication. The new fast RFC serialization is many times faster then xRFC/classic RFC or basXML, behaves uniformly for all data types and allowed extensions and is fully compatible with the existing RFC serialization types. You choose the fast RFC serialization in the transaction SM59 while defining RFC Destinations. It is only possible if both communication partners support the new serialization type. 

UCON: Managing HTTP(S) Whitelists

The UCON Framework offers you a new scenario within the transaction UCONCOCKPIT for whitelisting HTTP(S) calls based on a long-term logging. You can now maintain different whitelists for different context types. You are offered the comprehensive UI for all tasks and whitelists, where you can choose to maintain e.g. only one whitelist per context type and so that significantly reduce the number of whitelists. The number of context types itself was reduced from 10 to 3 by integrating similar context types into one new comprehensive context type.