Friday, May 15, 2009

ABAP Report: Upload file in an internal table

There is always a requirement of creating a program that uploads a file in an internal table for some reason or the other. I end up copying some old program and then modifying it to reflect the new structure. I thought it’s easier to make generic program that does the upload based on the structure definition using RTTS. The program needs the name of the structure, whether there is a header or not and field separator. Here is the template:

*&---------------------------------------------------------------------*
*& Report  ZUPLOAD
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT  zupload.
*----------------------------------------------------------------------*
*       CLASS lcl_report DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_report DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      open_file RETURNING value(r_file) TYPE string.
    METHODS:
      read_file IMPORTING i_file TYPE string,
      convert_file2struc IMPORTING i_header TYPE boolean
                                   i_separator TYPE c.
  PRIVATE SECTION.
    CONSTANTS:
      struc_name TYPE string VALUE 'ZST_TEST01'. " Put yours in here
    DATA:
      t_filecontent TYPE string_table,
      d_struc_content TYPE REF TO data.
ENDCLASS.                    "lcl_report DEFINITION
DATA:
  o_report TYPE REF TO lcl_report.
SELECTION-SCREEN BEGIN OF BLOCK file WITH FRAME TITLE text-001.
PARAMETERS:
  p_file TYPE string.
SELECTION-SCREEN END OF BLOCK file.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
  p_file = lcl_report=>open_file( ).
START-OF-SELECTION.
  CREATE OBJECT o_report.
  o_report->read_file( i_file = p_file ).
END-OF-SELECTION.
* The file will be loaded in the data object d_struc_content
  o_report->convert_file2struc( i_header    = ''
                                i_separator = '' )."cl_abap_char_utilities=>horizontal_tab ).
*----------------------------------------------------------------------*
*       CLASS lcl_report IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_report IMPLEMENTATION.
  METHOD open_file.
    DATA:
      l_t_file_table TYPE TABLE OF file_table,
      l_s_file_table TYPE file_table,
      l_rc TYPE i.
    CALL METHOD cl_gui_frontend_services=>file_open_dialog
      CHANGING
        file_table              = l_t_file_table
        rc                      = l_rc
      EXCEPTIONS
        file_open_dialog_failed = 1
        cntl_error              = 2
        error_no_gui            = 3
        not_supported_by_gui    = 4
        OTHERS                  = 5.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                 WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
    READ TABLE l_t_file_table INTO l_s_file_table INDEX 1.
    r_file = l_s_file_table-filename.
  ENDMETHOD.                    "open_file
  METHOD read_file.
    CALL METHOD cl_gui_frontend_services=>gui_upload
      EXPORTING
        filename                = i_file
*        has_field_separator     = 'X'
      CHANGING
        data_tab                = t_filecontent
      EXCEPTIONS
        file_open_error         = 1
        file_read_error         = 2
        no_batch                = 3
        gui_refuse_filetransfer = 4
        invalid_type            = 5
        no_authority            = 6
        unknown_error           = 7
        bad_data_format         = 8
        header_not_allowed      = 9
        separator_not_allowed   = 10
        header_too_long         = 11
        unknown_dp_error        = 12
        access_denied           = 13
        dp_out_of_memory        = 14
        disk_full               = 15
        dp_timeout              = 16
        not_supported_by_gui    = 17
        error_no_gui            = 18
        OTHERS                  = 19.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                 WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
  ENDMETHOD.                    "read_file
  METHOD convert_file2struc.
    DATA:
      l_struc TYPE REF TO data,
      l_o_datadescr TYPE REF TO cl_abap_datadescr,
      l_o_tabledescr TYPE REF TO cl_abap_tabledescr,
      l_t_fields TYPE string_table,
      l_s_fields TYPE string.
    FIELD-SYMBOLS:
      <l_filecontent> TYPE ANY,
      <l_field> TYPE ANY,
      <l_row> TYPE ANY,
      <l_struc_content> TYPE table.
* Create the structure
    l_o_datadescr ?= cl_abap_datadescr=>describe_by_name( struc_name ).
    CREATE DATA l_struc TYPE HANDLE l_o_datadescr.
    ASSIGN l_struc->* TO <l_row>.
* Create the table
    TRY.
        CALL METHOD cl_abap_tabledescr=>create
          EXPORTING
            p_line_type = l_o_datadescr
          RECEIVING
            p_result    = l_o_tabledescr.
      CATCH cx_sy_table_creation .
    ENDTRY.
    CREATE DATA d_struc_content TYPE HANDLE l_o_tabledescr.
    ASSIGN d_struc_content->* TO <l_struc_content>.
    IF i_header = abap_true.
      DELETE t_filecontent INDEX 1.
    ENDIF.
    LOOP AT t_filecontent ASSIGNING <l_filecontent>.
      IF i_separator IS INITIAL. " File is same as structure
        <l_row> = <l_filecontent>.
      ELSE.
*---split based on the separator
        SPLIT <l_filecontent> AT i_separator INTO TABLE l_t_fields.
        LOOP AT l_t_fields INTO l_s_fields.
          ASSIGN COMPONENT sy-tabix OF STRUCTURE <l_row> TO <l_field>.
          <l_field> = l_s_fields.
        ENDLOOP.
      ENDIF.
      APPEND <l_row> TO <l_struc_content>.
    ENDLOOP.
  ENDMETHOD.                    "convert_file2struc
ENDCLASS.                    "lcl_report IMPLEMENTATION

5 comments:

scrapy said...

can any one help me to solve the following issue:
Disabling the print button in PDF which is embedded in web dynpro abap.

Mike said...

Many thanks for the code.

Maybe I am missing something but shouldn't the 4th last line read as follows?:

APPEND {l_field} TO {l_struc_content}.

SAPDev said...

refers to column of . In the loop above gets updated one column at a time and then appended to .

Mike said...

Could you please repost your comment using different brackets? the page thinks they are html tags. Thanks

SAPDev said...

Ah...

{l_field} refers to column of . In the loop above {l_row} gets updated one column at a time and then appended to {l_struc_content}.