Quelquepart

Blog d'un développeur ABAP

Vous êtes ici : Accueil>Show code in Nugget

Show code in Nugget ZBACKUP.nugg

Table of content

Program ZBACKUP: Backup / Restore table content

Text Elements

Text symbols

Text symbolLanguageTextLength
M01EView can be downloaded but cannot be uploaded50
M02EChoose file132
M03ECSV File (*.csv)|*.csv132
M04EAre you sure you want to update the table data?100
M05EConfirmation50
M06ECancelled by user50
M07EAre you sure you want to drop table content and load file?100
T01EFlow50
T02ESAP Object50
T03EData File50

Selection texts

NameLanguageText
P_DOWNESAP -> File
P_DROPEDrop SAP content before import
P_FILEEFile Path+Name
P_SERVEFile on server (huge table)
P_TABLEEDDIC table name
P_UPEFile -> SAP
SO_WHEREEWhere clause

ABAP Code

*----------------------------------------------------------------------*
*  Program : ZBACKUP
*  Author  : S. Hermann
*  Date    : 20.04.2016
*  Version : 1.2
*----------------------------------------------------------------------*
*  This program allow you to download/upload SAP tables into file
*  File can be local for small tables or on SAP server for huge tables
*  (optimized to avoid memory issue)
*
*  Based on an idea from Steve Coupland
*----------------------------------------------------------------------*
* History
* 2016.04.20 v1.2  : Add where clause on selection screen
*                        Thanks to Cyril Raffin
*                    Fix warning on view upload
* 2015.08.27 v1.1  : Add option to drop sap table content before import
* 2014.11.30 v1.01 : Add Manage server available space shortage
* 2014.11.23 v1.0  : Initial release
*----------------------------------------------------------------------*
PROGRAM zbackup.

*######################################################################*
*
*                             DATA SECTION
*
*######################################################################*
DATA : w_tableclass TYPE dd02l-tabclass,                    "#EC NEEDED
       w_string(255) TYPE c.                                "#EC NEEDED
FIELD-SYMBOLS: <ft_data_table> TYPE STANDARD TABLE,         "#EC NEEDED
               <fs_data_line> TYPE any,                     "#EC NEEDED
               <fw_field> TYPE any.                         "#EC NEEDED
CONSTANTS : c_separator TYPE abap_char1
                        VALUE cl_abap_char_utilities=>horizontal_tab,
            c_msg_warning TYPE c VALUE 'W',
            c_msg_error TYPE c VALUE 'E',
            c_msg_success TYPE c VALUE 'S',
            c_tabclass_structure TYPE dd02l-tabclass VALUE 'INTTAB',
            c_tabclass_append TYPE dd02l-tabclass VALUE 'APPEND',
            c_tabclass_view TYPE dd02l-tabclass VALUE 'VIEW',
            c_packet_size TYPE i VALUE 10000.

*######################################################################*
*
*                             SELECTION SCREEN
*
*######################################################################*
SELECTION-SCREEN BEGIN OF BLOCK one WITH FRAME TITLE text-t01.
PARAMETERS p_down RADIOBUTTON GROUP b1 DEFAULT 'X'.
SELECTION-SCREEN BEGIN OF LINE.
PARAMETERS p_up RADIOBUTTON GROUP b1.
SELECTION-SCREEN COMMENT (32) FOR FIELD p_up.
PARAMETERS p_drop AS CHECKBOX.
SELECTION-SCREEN COMMENT (32) FOR FIELD p_drop.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN END OF BLOCK one.
SELECTION-SCREEN BEGIN OF BLOCK two WITH FRAME TITLE text-t02.
PARAMETERS p_table TYPE dd02l-tabname OBLIGATORY. "DEFAULT '/bic/azt_0scl00'.
SELECT-OPTIONS so_where FOR w_string NO INTERVALS VISIBLE LENGTH 120 LOWER CASE.
SELECTION-SCREEN END OF BLOCK two.
SELECTION-SCREEN BEGIN OF BLOCK tri WITH FRAME TITLE text-t03.
PARAMETERS p_file TYPE string LOWER CASE OBLIGATORY. "DEFAULT 'D:\guixt\file.txt'.
PARAMETERS p_serv AS CHECKBOX.
SELECTION-SCREEN END OF BLOCK tri.

INITIALIZATION.
  PERFORM restrict_so_where.

* Check that table exists and is not a structure
AT SELECTION-SCREEN ON p_table.
  SELECT SINGLE tabname tabclass INTO (p_table, w_tableclass)
         FROM dd02l
         WHERE tabname = p_table
         AND as4local = 'A'.                                "#EC WARNOK
  IF sy-subrc NE 0.
    MESSAGE e007(e2) WITH p_table.
  ELSEIF w_tableclass = c_tabclass_structure
      OR w_tableclass = c_tabclass_append.
    MESSAGE e403(mo) WITH p_table.
  ENDIF.

* Alert if table is a view
AT SELECTION-SCREEN.
  IF w_tableclass = c_tabclass_view.
    IF p_up NE space.
      p_up = space.
      p_down = abap_true.
      MESSAGE 'View can be downloaded but cannot be uploaded'(m01)
              TYPE c_msg_warning.
    ENDIF.
  ENDIF.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
  PERFORM prompt_for_file CHANGING p_file.

*######################################################################*
*
*                             MAIN PROGRAM
*
*######################################################################*
START-OF-SELECTION.
  IF p_down = abap_true.
    IF p_serv = space.
      PERFORM download_table_to_file USING p_table p_file.
    ELSE.
      PERFORM download_table_to_file_serv USING p_table p_file.
    ENDIF.
  ELSEIF w_tableclass NE 'VIEW'.
    IF p_serv = space.
      PERFORM upload_file_to_table USING p_file p_table.
    ELSE.
      PERFORM upload_file_to_table_serv USING p_file p_table.
    ENDIF.
  ENDIF.

*######################################################################*
*
*                             SUBROUTINES
*
*######################################################################*

*&---------------------------------------------------------------------*
*&      Form  prompt_for_file
*&---------------------------------------------------------------------*
*       Searchhelp for input file
*----------------------------------------------------------------------*
*      <--FP_FILENAME   Returning path+filename
*----------------------------------------------------------------------*
FORM prompt_for_file CHANGING fw_filename TYPE string.

  DATA : lw_dyname TYPE d020s-prog,
         lw_dynumb TYPE d020s-dnum,
         lt_dynpread TYPE STANDARD TABLE OF dynpread,
         ls_dynpread LIKE LINE OF lt_dynpread.
  DATA : lt_file_f4 TYPE filetable,
         ls_file_f4 LIKE LINE OF lt_file_f4,
         lw_rc TYPE i,
         lw_filter TYPE string,
         lw_title TYPE string.

  lw_dyname = sy-repid.
  lw_dynumb = sy-dynnr.

* Get actual value of parameter p_serv
  CLEAR ls_dynpread.
  ls_dynpread-fieldname = 'P_SERV'.
  APPEND ls_dynpread TO lt_dynpread.
  CALL FUNCTION 'DYNP_VALUES_READ'
    EXPORTING
      dyname     = lw_dyname
      dynumb     = lw_dynumb
    TABLES
      dynpfields = lt_dynpread
    EXCEPTIONS
      OTHERS     = 4.
  IF sy-subrc = 0.
    READ TABLE lt_dynpread INTO ls_dynpread INDEX 1.
    p_serv = ls_dynpread-fieldvalue.
  ENDIF.

  lw_filter = 'CSV File (*.csv)|*.csv'(m03).

* Server File
  IF p_serv NE space.
    CALL FUNCTION '/SAPDMC/LSM_F4_SERVER_FILE'
      EXPORTING
        filemask   = lw_filter
      IMPORTING
        serverfile = fw_filename.

* Local file
  ELSE.
    lw_title = 'Choose file'(m02).
    CALL METHOD cl_gui_frontend_services=>file_open_dialog
      EXPORTING
        window_title = lw_title
        file_filter  = lw_filter
      CHANGING
        file_table   = lt_file_f4
        rc           = lw_rc
      EXCEPTIONS
        OTHERS       = 0.
    READ TABLE lt_file_f4 INTO ls_file_f4 INDEX 1.
    IF sy-subrc = 0.
      fw_filename = ls_file_f4.
    ENDIF.
  ENDIF.
ENDFORM.                    " PROMPT_FOR_FILE

*&---------------------------------------------------------------------*
*&      Form  CREATE_DATA_RECEIVER
*&---------------------------------------------------------------------*
*       Create structured table & working area
*       Assign <ft_data_table> and <fs_data_line>
*----------------------------------------------------------------------*
*      -->FW_TABLE   Reference ddic table for data
*----------------------------------------------------------------------*
FORM create_data_receiver USING fw_table TYPE c.
  DATA : lo_table  TYPE REF TO data,
         lo_table_line TYPE REF TO data.

  CREATE DATA lo_table_line TYPE (fw_table).
  ASSIGN lo_table_line->* TO <fs_data_line>.
  CREATE DATA lo_table LIKE STANDARD TABLE OF <fs_data_line>
                      WITH DEFAULT KEY.
  ASSIGN lo_table->* TO <ft_data_table>.
ENDFORM.                    " CREATE_DATA_RECEIVER

*&---------------------------------------------------------------------*
*&      Form  DOWNLOAD_TABLE_TO_FILE
*&---------------------------------------------------------------------*
*       Download SAP table to local file
*----------------------------------------------------------------------*
*      -->FW_TABLE     SAP Table
*      -->FW_FILENAME  Path+filename
*----------------------------------------------------------------------*
FORM download_table_to_file USING fw_table TYPE c
                                  fw_filename TYPE string.
  DATA lw_where TYPE string.

* Create data receiver
  PERFORM create_data_receiver USING fw_table.

  LOOP AT so_where.
    CONCATENATE lw_where so_where-low
                INTO lw_where SEPARATED BY space.
  ENDLOOP.

  SELECT * INTO TABLE <ft_data_table>
         FROM (fw_table)
         WHERE (lw_where).

* Download
  CALL METHOD cl_gui_frontend_services=>gui_download
    EXPORTING
      filename              = fw_filename
      write_field_separator = abap_true
    CHANGING
      data_tab              = <ft_data_table>
    EXCEPTIONS
      OTHERS                = 0.
  MESSAGE s111(sr) WITH fw_filename. "Download complete
ENDFORM.                    " DOWNLOAD_TABLE_TO_FILE

*&---------------------------------------------------------------------*
*&      Form  UPLOAD_FILE_TO_TABLE
*&---------------------------------------------------------------------*
*       Upload file to SAP table
*----------------------------------------------------------------------*
*      -->FW_FILENAME Path+filename
*      -->FW_TABLE    SAP Table
*----------------------------------------------------------------------*
FORM upload_file_to_table USING fw_filename TYPE string
                                fw_table TYPE c.
  DATA: lt_data TYPE TABLE OF string,
        lw_data TYPE string,
        lt_fields TYPE TABLE OF string,
        lw_field TYPE string,
        lw_answer TYPE c.

* Confirm action
  IF p_drop = space.
    lw_data = 'Are you sure you want to update the table data?'(m04).
  ELSE.
    lw_data = 'Are you sure you want to drop table content and load file?'(m07).
  ENDIF.
  CALL FUNCTION 'POPUP_TO_CONFIRM'
    EXPORTING
      text_question = lw_data
      titlebar      = 'Confirmation'(m05)
    IMPORTING
      answer        = lw_answer
    EXCEPTIONS
      OTHERS        = 0.
  IF lw_answer NE '1'.
    MESSAGE 'Cancelled by user'(m06) TYPE c_msg_success
            DISPLAY LIKE c_msg_error.
    RETURN.
  ENDIF.

* Drop actual table content if applicable
  IF p_drop NE space.
    PERFORM drop_table USING fw_table.
  ENDIF.

* Create data receiver
  PERFORM create_data_receiver USING fw_table.

* Upload
  CALL METHOD cl_gui_frontend_services=>gui_upload
    EXPORTING
      filename = fw_filename
    CHANGING
      data_tab = lt_data
    EXCEPTIONS
      OTHERS   = 0.

* Cast data into structured data
  LOOP AT lt_data INTO lw_data.
    CLEAR <fs_data_line>.
    SPLIT lw_data AT c_separator INTO TABLE lt_fields.
    LOOP AT lt_fields INTO lw_field.
      ASSIGN COMPONENT sy-tabix OF STRUCTURE <fs_data_line> TO <fw_field>.
      IF sy-subrc NE 0.
        EXIT.
      ENDIF.
      <fw_field> = lw_field.
    ENDLOOP.
    APPEND <fs_data_line> TO <ft_data_table>.
  ENDLOOP.

* Insert into SAP table
  MODIFY (fw_table) FROM TABLE <ft_data_table>.

  MESSAGE s429(ds). "Upload complete
ENDFORM.                    " UPLOAD_FILE_TO_TABLE

*&---------------------------------------------------------------------*
*&      Form  DOWNLOAD_TABLE_TO_FILE_SERV
*&---------------------------------------------------------------------*
*       Download SAP table to server file
*       Manage huge sap table
*----------------------------------------------------------------------*
*      -->FW_TABLE     SAP Table
*      -->FW_FILENAME  Path+filename
*----------------------------------------------------------------------*
FORM download_table_to_file_serv USING fw_table TYPE c
                                       fw_filename TYPE string.
  DATA : lw_cursor TYPE cursor,
         lw_line TYPE string,
         lw_field TYPE string,
         lo_error TYPE REF TO cx_sy_file_io,
         lw_message TYPE string,
         lw_where type string.

* Create data receiver
  PERFORM create_data_receiver USING fw_table.

* Open file connexion with output file (create the file)
  OPEN DATASET fw_filename FOR OUTPUT IN TEXT MODE ENCODING DEFAULT.
  IF sy-subrc NE 0.
    MESSAGE s207(xt) WITH fw_filename
            DISPLAY LIKE c_msg_error. "Could not create file
    RETURN.
  ENDIF.

  LOOP AT so_where.
    CONCATENATE lw_where so_where-low
                INTO lw_where SEPARATED BY space.
  ENDLOOP.

* Open SQL connexion with table to read
  OPEN CURSOR lw_cursor
       FOR SELECT * FROM (fw_table)
       WHERE (lw_where).
  IF sy-subrc NE 0.
    CLOSE DATASET fw_filename.
    MESSAGE s703(b1) WITH fw_table
            DISPLAY LIKE c_msg_error. "Error when reading table
    RETURN.
  ENDIF.

* Process line by line
  DO.
* Read a packet from DB
    FETCH NEXT CURSOR lw_cursor INTO TABLE <ft_data_table>
          PACKAGE SIZE c_packet_size.
    IF sy-subrc <> 0.
      EXIT.
    ENDIF.

    LOOP AT <ft_data_table> INTO <fs_data_line>.
      CLEAR lw_line.
* Append field by field into output string
      DO.
        ASSIGN COMPONENT sy-index OF STRUCTURE <fs_data_line> TO <fw_field>.
        IF sy-subrc NE 0.
          EXIT. "exit do.
        ENDIF.
        IF sy-index = 1.
          lw_line = <fw_field>.
        ELSE.
          lw_field = <fw_field>.
          CONCATENATE lw_line lw_field INTO lw_line
                          SEPARATED BY c_separator.
        ENDIF.
      ENDDO.
* Append the output string into file
      TRY.
          TRANSFER lw_line TO fw_filename.
        CATCH cx_sy_file_io INTO lo_error.
* If no space left on server, stop process
          lw_message = lo_error->get_text( ).
          CLOSE CURSOR lw_cursor.
          MESSAGE lw_message TYPE c_msg_error.
      ENDTRY.
    ENDLOOP.

  ENDDO.

* Close connexions
  CLOSE CURSOR lw_cursor.
  CLOSE DATASET fw_filename.

  MESSAGE s111(sr) WITH fw_filename. "Download complete
ENDFORM.                    " DOWNLOAD_TABLE_TO_FILE_SERV

*&---------------------------------------------------------------------*
*&      Form  UPLOAD_FILE_TO_TABLE_SERV
*&---------------------------------------------------------------------*
*       Upload server file to SAP table
*       Manage huge files
*----------------------------------------------------------------------*
*      -->FW_FILENAME Path+filename
*      -->FW_TABLE    SAP Table
*----------------------------------------------------------------------*
FORM upload_file_to_table_serv USING fw_filename TYPE string
                                     fw_table TYPE c.

  DATA: lt_fields TYPE TABLE OF string,
        lw_field TYPE string,
        lw_line TYPE string,
        lw_answer TYPE c.

* Confirm action
  IF p_drop = space.
    lw_line = 'Are you sure you want to update the table data?'(m04).
  ELSE.
    lw_line = 'Are you sure you want to drop table content and load file?'(m07).
  ENDIF.
  CALL FUNCTION 'POPUP_TO_CONFIRM'
    EXPORTING
      text_question = lw_line
      titlebar      = 'Confirmation'(m05)
    IMPORTING
      answer        = lw_answer
    EXCEPTIONS
      OTHERS        = 0.
  IF lw_answer NE '1'.
    MESSAGE 'Cancelled by user'(m06) TYPE c_msg_success
            DISPLAY LIKE c_msg_error.
    RETURN.
  ENDIF.

* Drop actual table content if applicable
  IF p_drop NE space.
    PERFORM drop_table USING fw_table.
  ENDIF.

* Create data receiver
  PERFORM create_data_receiver USING fw_table.

* Open file connexion with output file
  OPEN DATASET fw_filename FOR INPUT IN TEXT MODE ENCODING DEFAULT.
  IF sy-subrc NE 0.
    MESSAGE s375(e0) WITH fw_filename
            DISPLAY LIKE c_msg_error. "Error when read file
    RETURN.
  ENDIF.

* Process line by line
  DO.
* Read a line in the file
    READ DATASET p_file INTO lw_line.
    IF sy-subrc NE 0.
      EXIT. "exit do
    ENDIF.

* Cast data into structured data
    SPLIT lw_line AT c_separator INTO TABLE lt_fields.
    LOOP AT lt_fields INTO lw_field.
      ASSIGN COMPONENT sy-tabix OF STRUCTURE <fs_data_line> TO <fw_field>.
      IF sy-subrc NE 0.
        EXIT. "exit do
      ENDIF.
      <fw_field> = lw_field.
    ENDLOOP.

* Build the data packet
    APPEND <fs_data_line> TO <ft_data_table>.

* If packet is ready, save into DB
    IF sy-tabix GE c_packet_size.
      MODIFY (fw_table) FROM TABLE <ft_data_table>.
      REFRESH <ft_data_table>.
      COMMIT WORK AND WAIT.
    ENDIF.
  ENDDO.

* Save last packet into DB
  IF NOT <ft_data_table> IS INITIAL.
    MODIFY (fw_table) FROM TABLE <ft_data_table>.
    REFRESH <ft_data_table>.
    COMMIT WORK AND WAIT.
  ENDIF.

* Close the file connexion
  CLOSE DATASET fw_filename.

  MESSAGE s429(ds). "Upload complete
ENDFORM.                    " UPLOAD_FILE_TO_TABLE_SERV

*&---------------------------------------------------------------------*
*&      Form  DROP_TABLE
*&---------------------------------------------------------------------*
*       Drop table content
*----------------------------------------------------------------------*
*      -->FW_TABLE  Table to drop
*----------------------------------------------------------------------*
FORM drop_table USING fw_table TYPE c.

  DELETE FROM (fw_table).
  COMMIT WORK AND WAIT.

ENDFORM.                    " DROP_TABLE

*&---------------------------------------------------------------------*
*&      Form  RESTRICT_SO_WHERE
*&---------------------------------------------------------------------*
*       Restrict select option so_where
*----------------------------------------------------------------------*
FORM restrict_so_where .
  DATA : ls_restrict TYPE sscr_restrict,
         ls_opt_list LIKE LINE OF ls_restrict-opt_list_tab,
         ls_ass LIKE LINE OF ls_restrict-ass_tab.

  ls_opt_list-name = 'WHERE'.
  ls_opt_list-options-eq = 'X'.
  APPEND ls_opt_list TO ls_restrict-opt_list_tab.

  ls_ass-kind = 'S'.
  ls_ass-name = 'SO_WHERE'.
  ls_ass-sg_main = 'I'.
  ls_ass-sg_addy = space.
  ls_ass-op_main = 'WHERE'.
  APPEND ls_ass TO ls_restrict-ass_tab.

  CALL FUNCTION 'SELECT_OPTIONS_RESTRICT'
    EXPORTING
      restriction = ls_restrict
    EXCEPTIONS
      OTHERS      = 9.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
ENDFORM.                    " RESTRICT_SO_WHERE