Wednesday 13 May 2020

Display standard text using CDS in ALV with IDA

Overview


This blogs mainly cover the topic to display standard text(T-code: SO10) is abap list viewer(ALV) with IDA which uses CDS as data source.

Standard Text


Standard text is a long text  and are not stored in SAP tables directly instead it is compressed & stored in the long raw data format in the table STXH and STXL. In ABAP programming, mainly Function Module READ_TEXT is used to retrieve these text.

Recently I had requirement to display standard text in abap list veiw(alv) with IDA (Integrated Data Access) which use CDS as data source. All the queries / with respect to different ALV columns(beside one) were available in the different table/CDS , however it was not possible to query one field which needs to display standard text.

To display the standard, I used the concept calculated field.

What is calculated field in ALV with IDA ?


IDA framework has a provision to provide the extra field handler. This is called as calculated field.

Calculated field helps to add new column in the ALV dynamically at the runtime, which are not part of CDS projection list. The value in these columns can be populated at runtime by implementing API interface IF_SALV_IDA_CALC_FIELD_HANDLER method calculate_line.

Lets see what are method available in the inteface:

SAP HANA Study Materials, SAP HANA Exam Prep, SAP HANA Certification, SAP HANA Guides, SAP HANA CDS

◉ Method GET_CALC_FIELD_STRUCTURE: This method is used provide the information of new fields which will be added in the alv at runtime. Create a type with all required additional fields.

◉ Method GET_REQUESTED_FIELDS: This method is use to supply the fields information which are required to determine the value for new column/fields.

◉ Method CALCULATE_LINE: This method used to populate/calculate of new field in the result based on the requested fields.Pass the calculated fields back to the entire row.

◉ Method START_PAGE: This method provides the access to the data for the current page. If the data is not required, processing can be cancelled.

◉ Method END_PAGE – This method trigger at the page end. It can be used for data refresh.

Restrictions:


◉ The new field added using API method name should not match with any of the CDS project list fields (or ALIAS) name.If new field name matches with any of existing CDS fields, an exception CX_SALV_IDA_CONTRACT_VIOLATION raised (short dump).
◉ Method calculate cannot be used to modify data of fields, which are part of CDS projection list.
◉ Cell has maximum limit of length 128 characters.

Using the concept of calculated field, standard text can be displayed in ALV with IDA, which uses CDS/table as the data source using calculated fields.

Lets implement the solution…


In the below example, I will retrieve & display Purchase Order Item text which is stored as standard text in the ALV output. The text will fetched using Function Module READ_TEXT inside the inteface method.

Example tested on below systems:


ABAP : AS ABAP 750 or above.

Database: Oracle or HDB

Create CDS


This CDS query purchase document, item, material, quantity and unit.

CDS Source Code

@AbapCatalog.sqlViewName: 'ZPOITEXT'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@VDM.viewType: #BASIC
@EndUserText.label: 'Purchase Order Item Standard Text in CDS'
define view ZPOITEMTEXT as select from ekko 
 inner join ekpo on ekko.ebeln = ekpo.ebeln
                 and ekko.bstyp = 'F'           --purchase order
                 and matnr <> ' '               --Must have material
                 and ekko.loekz = ' '           --PO not marked for deletion
                 and ekpo.loekz = ' '           --Item not marked for deletion
{

key ekpo.ebeln as PurchaseOrder,
key ekpo.ebelp as PurchaseOrderItem,
    matnr as Material,
    menge as Quantity,
    meins as Unit,
    ekko.aedat as PuchaseDocument

}
where ekko.aedat between '20200101' and '20200430';

Create Report program


CDS can be directly consumed in ALV by calling method cl_salv_gui_table_ida=>create_for_cds_view. This method contains import parameter where object of class implementing calculated field inteface: if_salv_ida_calc_field_handler can be passed.

In my example local class lc_salv_ida_standard_text  implements the interface. The method of the class contains the logic to read standard text.

Source Code

REPORT zsalv_ida_standard_text.
*&---------------------------------------------------------------------*
*& Report ZSALV_IDA_STANDARD_TEXT
*&---------------------------------------------------------------------*

CLASS lc_salv_ida_standard_text DEFINITION.

  PUBLIC SECTION.
    CLASS-METHODS:
      "! Main method to call IDA
      main.
    INTERFACES: if_salv_ida_calc_field_handler .       "IDA API: Handler for Calculated Fields
    METHODS:
      "! Set coulmn header for new field
      set_column_header_texts
        IMPORTING io_field_catalog TYPE REF TO if_salv_gui_field_catalog_ida.
  PRIVATE SECTION.
    TYPES:
      "! the additional field item_text will be added to structure in ALV at runtime
      BEGIN OF lty_calc_field,
        item_text TYPE c LENGTH 255,
      END OF lty_calc_field .
    DATA:
      "! internal table for calculated fields
       lt_calc_field_name TYPE if_salv_ida_types=>yts_field_name.

ENDCLASS.

CLASS lc_salv_ida_standard_text IMPLEMENTATION.

  METHOD if_salv_ida_calc_field_handler~get_calc_field_structure.
*--define additional fields by returning the structure description
    DATA ls_calc_field TYPE lty_calc_field.
    ro_calc_field_structure ?= cl_abap_structdescr=>describe_by_data( ls_calc_field ).
  ENDMETHOD.

  METHOD if_salv_ida_calc_field_handler~get_requested_fields.
*--for additional ITEM_TEXT the CDS fields PURCHASEORDER and PURCHASEORDERITEM are required
    IF line_exists( its_calc_field_name[ table_line = |ITEM_TEXT| ] ).
      rts_db_field_name = VALUE #( ( |PURCHASEORDER| )
                                   ( |PURCHASEORDERITEM| ) ).
    ENDIF.
  ENDMETHOD.
  METHOD if_salv_ida_calc_field_handler~start_page.
*--buffer which of the calculated fields are displayed
*--later calculate values only for these fields to save performance
    lt_calc_field_name = its_calc_field_name.
  ENDMETHOD.
  METHOD if_salv_ida_calc_field_handler~calculate_line.

    DATA: lt_lines      TYPE STANDARD TABLE OF tline,
          ls_calc_field TYPE lty_calc_field.
    REFRESH lt_lines.
    TRY.
*--read CDS fields
        DATA(ls_po_item) = CORRESPONDING zpoitemtext( is_data_base_line ).
        IF line_exists( lt_calc_field_name[ table_line = |ITEM_TEXT| ] ).
*--prepare Item text name
          DATA(lv_name) = CONV tdobname( ls_po_item-purchaseorder && ls_po_item-purchaseorderitem ).
          CALL FUNCTION 'READ_TEXT'
            EXPORTING
              client                  = sy-mandt
              id                      = 'F01'
              language                = sy-langu
              name                    = lv_name
              object                  = 'EKPO'
            TABLES
              lines                   = lt_lines
            EXCEPTIONS
              id                      = 1
              language                = 2
              name                    = 3
              not_found               = 4
              object                  = 5
              reference_check         = 6
              wrong_access_to_archive = 7
              OTHERS                  = 8.
          IF sy-subrc IS INITIAL.
            LOOP AT lt_lines ASSIGNING FIELD-SYMBOL(<ls_lines>).
*--concatenate text lines
              ls_calc_field-item_text = ls_calc_field-item_text && <ls_lines>-tdline.
            ENDLOOP.
          ENDIF.
        ENDIF.
*--return values in added structure
        es_calculated_fields = ls_calc_field.
      CATCH cx_root INTO DATA(lo_err).
        DATA(lv_msg) = lo_err->get_text(  ).
    ENDTRY.
  ENDMETHOD.
  METHOD if_salv_ida_calc_field_handler~end_page.
    "   do nothing.
  ENDMETHOD.
  METHOD set_column_header_texts.
*--set column header for additional field ITEM_TEXT
    io_field_catalog->set_field_header_texts( iv_field_name   = 'ITEM_TEXT'
                                              iv_header_text  = 'PO Item text'
                                              iv_tooltip_text = 'PO Item text' ).

  ENDMETHOD.
  METHOD main.
*--create object
    DATA(lo_calc_field_handler) = NEW lc_salv_ida_standard_text( ).
*--call ALV using CDS as data source
    DATA(lo_alv_display) = cl_salv_gui_table_ida=>create_for_cds_view(  iv_cds_view_name      = |ZPOITEMTEXT|
                                                 io_calc_field_handler = lo_calc_field_handler )."
*--set field catalogue
    lo_calc_field_handler->set_column_header_texts( lo_alv_display->field_catalog( ) ).
*--display full screen alv in GUI
    lo_alv_display->fullscreen( )->display( ).
  ENDMETHOD.
ENDCLASS.

END-OF-SELECTION.
*--start processing
  lc_salv_ida_standard_text=>main( ).

Execute report (T-code: SA38)

SAP HANA Study Materials, SAP HANA Exam Prep, SAP HANA Certification, SAP HANA Guides, SAP HANA CDS

ALV Output


New column with PO Item text and value is added.

SAP HANA Study Materials, SAP HANA Exam Prep, SAP HANA Certification, SAP HANA Guides, SAP HANA CDS

Lets verify text in Purchase Oder Item(T-code ME23N)

SAP HANA Study Materials, SAP HANA Exam Prep, SAP HANA Certification, SAP HANA Guides, SAP HANA CDS

SAP HANA Study Materials, SAP HANA Exam Prep, SAP HANA Certification, SAP HANA Guides, SAP HANA CDS

No comments:

Post a Comment