Dynamically Download Data From Any SAP Table in ABAP-740 – Part 1

A few days ago, one of my SAP BI/BW friends requested a program that would accept any table as input and download it as a file to the local machine. In short, he needed a utility tool for the mass download of any SAP table. There may be numerous ways to achieve this goal, but creating an effective program to handle the result table structure is crucial. In “Dynamically Download Data From Any SAP Table in ABAP-740 – Part 1,” we will explore how to develop such a utility to streamline this process.

You might ponder, for what reason can they not simply use SE16, SE16N to download the information? I don’t have a persuading reply to that. Yet, I was glad to investigate this necessity and do some powerful table age.

How to give user option to Select Fields of Table?

I attempted and had the option to produce the program. Yet, I needed to give the client choices to pick the fields which they need to find in the last result record. Since I was being languid, I chose to ask our SAP Wire Gathering individuals. Brief came the answer from Ananias who gave his feedback. This program is the code piece given by Ananias.

Capability Modules ‘DD_TABL_GET’ and ‘DD_LIST_TABFIELDS’ would help.

How to handle .INCLUDE and .APPEND in the tables?

The field ROLLNAME would be clear for these metadata. We can securely erase them.

* .INCLUDE, .APPEND and other attributes should be deleted
* They have rollname as blank
  DELETE li_fld_copy WHERE rollname IS INITIAL.

Cautioning People…

In any case, however.. There is a grave issue. There are many fields in the tables where we don’t characterize the information component. We utilize the Predefined Types. Along these lines, we shouldn’t erase where ROLLNAME is clear.

So the protected method for eliminating the Adds and Incorporates is to search for PreDefined Information Type. They can’t be clear for any field.

* .INCLUDE, .APPEND and other attributes should be deleted
* They have INTTYPE as blank
  DELETE li_fld_copy WHERE inttype IS INITIAL.

How to remove fields not chosen?

We have included a field named MARK in our TYPE. We will use it for identifying the chosen fields.

* Remove what the user did not choose
  DELETE li_fld_copy WHERE mark IS INITIAL.

How to build the list of fields for the SELECT statement?

Simply put the fields in a string separated by SPACE.

*   Make the list of fields to be used in SELECT Statement
CONCATENATE ls_fields-fieldname gs_field_list INTO gs_field_list SEPARATED BY space.

How to get the Component Details?

ABAP_COMPONENTDESCR table type comes handy here.

data:   
gs_components  TYPE STANDARD TABLE OF abap_componentdescr
                       WITH KEY name, " Components
ls_components  LIKE LINE OF gs_components.

ls_components-name = ls_fields-fieldname.
ls_components-type ?= cl_abap_elemdescr=>describe_by_name( ls_fields-rollname ) .
APPEND ls_components TO gs_components.

How to Create the Dynamic Structure & Internal Table?

The standard class CL_ABAP_STRUCTDESC method CREATE would do the needful. Get P_COMPONENTS for the structure and P_LINE_TYPE for the internal table type.

lr_struct_result = cl_abap_structdescr=>create( p_components = gs_components ).
lr_table_result =  cl_abap_tabledescr=>create( p_line_type  = lr_struct_result ).

 

How to SELECT from Table Dynamically?

TYPE HANDLE and ASSIGN lrt_table->* TO dynamic table do the trick.

  
*&---------------------------------------------------------------------*
*&      Form  SUB_DYNAMIC_SELECT
*&---------------------------------------------------------------------*
*       Dynamically Select from Any Table
*----------------------------------------------------------------------*
FORM sub_dynamic_select  USING    lr_table_result  TYPE REF TO cl_abap_tabledescr
                                  lr_struct_result TYPE REF TO cl_abap_structdescr.

  DATA: lrt_table  TYPE REF TO data,
        lrs_struct TYPE REF TO data.

  FIELD-SYMBOLS:
         TYPE any.

  CREATE DATA: lrt_table  TYPE HANDLE lr_table_result.
*               lrs_struct TYPE HANDLE lr_struct_result.

  ASSIGN lrt_table->* TO .
*  ASSIGN lrs_struct->* TO .

  IF  IS  ASSIGNED.
*   This is the Dynamic Select
    SELECT (gs_field_list) FROM (p_tab) INTO CORRESPONDING FIELDS OF TABLE .
  ENDIF.
ENDFORM.
ENDIF.

Note: Keep the above code snippet as Template to create Dynamic Internal table and work area.

Let’s Check the Output

Choose the Fields for Output
Only the selected fields are displayed in the output

Can we download all the Fields?

Yes. Why not? Check the output below.

Give Table name, File Path and hit Execute
Click Select All and hit Copy
All the fields show up

Code Snippet

*---------------------------------------------------------------------*
* TYPES
*---------------------------------------------------------------------*
TYPES:
* Type for the table along with Marker Flag
  BEGIN OF t_fld.
      INCLUDE STRUCTURE dd03p AS dd03p.       " Dictonary Attributes
      TYPES:
          mark            LIKE rsdxx-mark,      " Entry marked
          type_icon       TYPE dd02d-datatype,  " Type Icon
*  fkexi(1),                             " Flag for existence
*  mod(1),                               " Modification Id
*  actf(1),                              " Active Flag
*  switch_id       TYPE sfw_switch_id,   " Id of a Switch in Switch Framework
  END OF t_fld,

* Type for the table header
  BEGIN OF ty_str_hdr,
    field_name TYPE char20,
  END OF ty_str_hdr.

*---------------------------------------------------------------------*
*  DATA                                                               *
*---------------------------------------------------------------------*
DATA:

  git_header_text    TYPE STANDARD TABLE OF ty_str_hdr, " Header Text
  gs_field_list      TYPE string, " SELECT Field List
  gref_struct_result TYPE REF TO cl_abap_structdescr, " Structure
  gref_table_result  TYPE REF TO cl_abap_tabledescr,  " Table
  gs_components      TYPE STANDARD TABLE OF abap_componentdescr
                     WITH KEY name. " Components
*---------------------------------------------------------------------*
*  FIELD-SYMBOLS                                                               *
*---------------------------------------------------------------------*
FIELD-SYMBOLS:  TYPE INDEX TABLE. " Final Table

*---------------------------------------------------------------------*
* SELECTION SCREEN                                                    *
*---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
PARAMETERS:
  p_tab  TYPE tabname   OBLIGATORY,
  p_file TYPE localfile OBLIGATORY.

SELECTION-SCREEN END OF BLOCK b1.
*---------------------------------------------------------------------*
* AT SELECTION-SCREEN ON VALUE-REQUEST.
*---------------------------------------------------------------------*
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
* F4 Help for File
  PERFORM sub_f4_for_file CHANGING p_file.

*---------------------------------------------------------------------*
* START-OF-SELECTION.                                                 *
*---------------------------------------------------------------------*
START-OF-SELECTION.
* Option to Select Which Field to download
  PERFORM sub_pop_up_to_select USING p_tab
                            CHANGING gref_table_result
                                     gref_struct_result.

*---------------------------------------------------------------------*
* END-OF-SELECTION.                                                   *
*---------------------------------------------------------------------*
END-OF-SELECTION.
* Do the Dynamic Select from Any Table
  PERFORM sub_dynamic_select USING    gref_table_result
                                      gref_struct_result.
* Download the Tab Delimited Text File to the Local Machine
  PERFORM sub_download_file USING p_file.

*---------------------------------------------------------------------*
* SUB ROUTINES                                                        *
*---------------------------------------------------------------------*

*&---------------------------------------------------------------------*
*&      Form  SUB_F4_FOR_FILE
*&---------------------------------------------------------------------*
*       F4 Help
*----------------------------------------------------------------------*
FORM sub_f4_for_file  CHANGING p_p_file TYPE localfile.
  CALL FUNCTION 'F4_FILENAME'
    EXPORTING
      field_name = 'p_file'
    IMPORTING
      file_name  = p_p_file.
ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  SUB_POP_UP_TO_SELECT
*&---------------------------------------------------------------------*
*       Select Fields for Output
*----------------------------------------------------------------------*
FORM sub_pop_up_to_select  USING    p_p_tab TYPE tabname
      CHANGING    lr_table_result  TYPE REF TO  cl_abap_tabledescr
                                  lr_struct_result TYPE REF TO cl_abap_structdescr..

  DATA:
    lv_get_state  TYPE dctablget,
    li_fld_copy   TYPE TABLE OF t_fld,
    li_dd03p      TYPE TABLE OF dd03p,
    ls_components LIKE LINE OF gs_components,
    ls_header     TYPE ty_str_hdr.

  lv_get_state-tabd = lv_get_state-tabt = 'A'.

* Get table metadata
  CALL FUNCTION 'DD_TABL_GET'
    EXPORTING
      get_state    = lv_get_state
      prid         = -2
      tabl_name    = p_p_tab
      withtext     = 'X'
      add_typeinfo = 'X'
    TABLES
      dd03p_tab_a  = li_dd03p
    EXCEPTIONS
      OTHERS       = 2.

* Adding extra fields
* Field MARK is used for now to idendify the selected field(s)
  li_fld_copy = li_dd03p.

  CALL FUNCTION 'DD_LIST_TABFIELDS'
    EXPORTING
      eutype       = 'V'
      p_with_type  = 'X'
    TABLES
      fieldtab     = li_fld_copy
    EXCEPTIONS
      not_executed = 1
      OTHERS       = 2.

* .INCLUDE, .APPEND and other attributes should be deleted
* They have INTTYPE as blank
  DELETE li_fld_copy WHERE inttype IS INITIAL.

* Remove what the user did not choose
  DELETE li_fld_copy WHERE mark IS INITIAL.

  LOOP AT li_fld_copy INTO DATA(ls_fields).

*   Make the list of fields to be used in SELECT Statement
    CONCATENATE ls_fields-fieldname gs_field_list INTO gs_field_list SEPARATED BY space.

**   Header Line (Medium Text) for the Spreadsheet
*    CONCATENATE ls_fields-scrtext_m gs_header_text INTO gs_header_text SEPARATED BY cl_abap_char_utilities=>horizontal_tab.

    ls_components-name = ls_fields-fieldname.
    ls_components-type ?= cl_abap_elemdescr=>describe_by_name( ls_fields-rollname ) .
    APPEND ls_components TO gs_components.

    APPEND ls_fields-scrtext_m TO git_header_text.

  ENDLOOP.

  TRY .
      lr_struct_result = cl_abap_structdescr=>create( p_components = gs_components ).
      lr_table_result =  cl_abap_tabledescr=>create( p_line_type  = lr_struct_result ).
    CATCH cx_sy_struct_creation.    "
    CATCH cx_sy_table_creation.

  ENDTRY.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  SUB_DYNAMIC_SELECT
*&---------------------------------------------------------------------*
*       Dynamically Select from Any Table
*----------------------------------------------------------------------*
FORM sub_dynamic_select  USING    lr_table_result  TYPE REF TO cl_abap_tabledescr
                                  lr_struct_result TYPE REF TO cl_abap_structdescr.

  DATA: lrt_table  TYPE REF TO data,
        lrs_struct TYPE REF TO data.

  FIELD-SYMBOLS:
         TYPE any.

  CREATE DATA: lrt_table  TYPE HANDLE lr_table_result.
*               lrs_struct TYPE HANDLE lr_struct_result.

  ASSIGN lrt_table->* TO .
*  ASSIGN lrs_struct->* TO .

  IF  IS  ASSIGNED.
*   This is the Dynamic Select
    SELECT (gs_field_list) FROM (p_tab) INTO CORRESPONDING FIELDS OF TABLE .
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  SUB_DOWNLOAD_FILE
*&---------------------------------------------------------------------*
*       Download File
*----------------------------------------------------------------------*
FORM sub_download_file  USING    p_p_file type localfile.

  DATA:
        lv_file      TYPE string.

* Moving to a type compatible variable
  lv_file = p_p_file.

  CALL METHOD cl_gui_frontend_services=>gui_download
    EXPORTING
      filename                = lv_file
      filetype                = 'ASC'
      write_field_separator   = 'X'
      fieldnames              = git_header_text
    CHANGING
      data_tab                = 
    EXCEPTIONS
      file_write_error        = 1
      no_batch                = 2
      gui_refuse_filetransfer = 3
      invalid_type            = 4
      no_authority            = 5
      unknown_error           = 6
      header_not_allowed      = 7
      separator_not_allowed   = 8
      filesize_not_allowed    = 9
      header_too_long         = 10
      dp_error_create         = 11
      dp_error_send           = 12
      dp_error_write          = 13
      unknown_dp_error        = 14
      access_denied           = 15
      dp_out_of_memory        = 16
      disk_full               = 17
      dp_timeout              = 18
      file_not_found          = 19
      dataprovider_exception  = 20
      control_flush_error     = 21
      not_supported_by_gui    = 22
      error_no_gui            = 23
      OTHERS                  = 24.
  IF sy-subrc = 0.
    WRITE:/ 'File downloaded successfully' COLOR COL_POSITIVE.
  ENDIF.
ENDFORM.

This is an example program to progressively download any table. There are dependably various ways to arrive at a similar objective. Likewise, there would be other better ways of accomplishing this usefulness. Be that as it may, you can securely utilize this code scrap to begin your utility program. You might upgrade it better and can likewise put one more screen to add fields in the choice screen progressively to choose just those values recorded in the determination screen input.

There are some issues with the above method.

1. Data Element should not be used for creation of dynamic structures.

Reason being – Some tables are created with fields without data elements.

2. Error Handling not done

In the above code scrap, a few special cases are not dealt with. Thus, now and again, it could dump.

In the following article, we will demonstrate how Stephan developed another program in ABAP 751 (NW7.51) using the new syntax features such as DECREASE, VALUE, INIT, COND, FOR, etc., and how these features helped overcome the challenges associated with this program. Additionally, we will explore Dynamically Download Data From Any SAP Table in ABAP-740 – Part 1,” which provides a practical utility for downloading SAP table data.

 

YOU MAY BE INTERESTED IN

Steampunk Chronicles: Navigating the Cloud with SAP BTP ABAP Environment

SAP ABAP HANA: Revolutionizing Enterprise Application

Chart of accounts in SAP

 

WhatsApp WhatsApp us