Michael's profileAt world's endBlogGuestbookNetwork Tools Help

Blog


    March 28

    Get SAP data and mail mail merge it to a MS word document

    ************************************************************************
    *   Description :  This demo program will work for version 4.6 onward. *
    *                  It will get SAP data and mail merge it to a MS word *
    *                  document.                                           *
    *======================================================================*
    *            M O D I F I C A T I O N   H I S T O R Y                   *
    *======================================================================*
    *
    ************************************************************************
    report zzjf_word_46up no standard page heading
                     message-id zh
                     line-count 65
                     line-size 132.
    tables: pernr.
    infotypes: 0000, 0001, 0002.
    *----------------------------------------------------------------------*
    * parameters and selection options.
    *----------------------------------------------------------------------*
    selection-screen begin of block blk0 with frame title text-l02.
    parameters: p_year(2) type n default '15'.
    selection-screen end of block blk0.
    type-pools: abap.
    data: begin of empinfo occurs 0,
            first_name(30) type c,
            last_name(30) type c,
            years(2) type c,
          end of empinfo.
    data: ee_selected(1) type c.
    ********************* OLE Defines **********************************
    include ole2incl.
    data: h_word  type ole2_object,
          wordapp type ole2_object,
          worddoc type ole2_object,
          wordobj type ole2_object.
    data: txt_work_file like rlgrap-filename value
             'C:\Program Files\SAP\SAP_DATA_FILE.txt'.
    data: doc_work_file like rlgrap-filename value
             'C:\Program Files\SAP\MS_WORD_DOC.doc'.
    data: begin of fieldnames occurs 5,
            field(60) type c,
          end of fieldnames.
    ********************* end OLE Defines *****************************
    *----------------------------------------------------------------------*
    initialization.
    *----------------------------------------------------------------------*
      perform init_parameters.
    *----------------------------------------------------------------------*
    start-of-selection.
    *----------------------------------------------------------------------*
    *----------------------------------------------------------------------*
    get pernr.
    *----------------------------------------------------------------------*
      clear: empinfo, ee_selected.
      perform gather_infotype_data.
      check ee_selected ne space.
      append empinfo.
    *----------------------------------------------------------------------*
    end-of-selection.
    *----------------------------------------------------------------------*
      if not empinfo[] is initial.
        perform mail_merge_data_to_ms_word.
      else.
        write: / 'NO DATA AVAILABLE FOR THIS SELECTION!'.
      endif.
    *----------------------------------------------------------------------*
    top-of-page.
    *----------------------------------------------------------------------*
      perform print_report_header.
    *&---------------------------------------------------------------------*
    *&      Form  GATHER_INFOTYPE_DATA
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    form gather_infotype_data.
      data: begin of phifi occurs 5.
              include structure phifi.
      data: end of phifi.
      data: hire_date type d.
      data: fire_date type d.
      data: cutoff_date type d.
      data: years(2) type n.
      call function 'RP_HIRE_FIRE'
        exporting
          beg       = '18000101'
          end       = '99991231'
        importing
          hire_date = hire_date
          fire_date = fire_date
        tables
          pp0000    = p0000          "input
          pp0001    = p0001          "input
          pphifi    = phifi.         "output
      check fire_date eq '99991231'.
      cutoff_date = sy-datum.
      check not hire_date is initial.
      check hire_date < cutoff_date.
      call function 'COMPUTE_YEARS_BETWEEN_DATES'
        exporting
          first_date          = hire_date
          second_date         = cutoff_date
        importing
          years_between_dates = years.
      check years >= p_year.
      write years to empinfo-years no-zero.
      rp-provide-from-last p0002 space pn-begda pn-endda.
      if pnp-sw-found eq '1'.
        empinfo-last_name = p0002-nachn.
        empinfo-first_name = p0002-vorna.
      endif.
      ee_selected = 'X'.
    endform.                               " GATHER_INFOTYPE_DATA
    *&---------------------------------------------------------------------*
    *&      Form  INIT_PARAMETERS
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    form init_parameters.
      pnptimed = 'D'.                      "set to today radio button
    endform.                               " INIT_PARAMETERS
    *&---------------------------------------------------------------------*
    *&      Form  PRINT_REPORT_HEADER
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    form print_report_header.
    endform.                               " PRINT_REPORT_HEADER
    *&---------------------------------------------------------------------*
    *&      Form  MAIL_MERGE_DATA_TO_MS_WORD
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    form mail_merge_data_to_ms_word .
      perform clear_existing_data_file.
      perform download_employee_data_to_pc.
      perform start_ms_word.
      perform fill_ms_word_with_data.
    endform.                    " MAIL_MERGE_DATA_TO_MS_WORD
    *&---------------------------------------------------------------------*
    *&      Form  CLEAR_EXISTING_DATA_FILE
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    form clear_existing_data_file .
      data: file_name type string.
      data: result type abap_bool.
      data: rc type i.
      file_name = txt_work_file.
      call method cl_gui_frontend_services=>file_exist
        exporting
          file            = file_name
        receiving
          result          = result
        exceptions
          cntl_error      = 1
          error_no_gui    = 2
          wrong_parameter = 3
          others          = 4.
      call method cl_gui_cfw=>flush.
      if result eq abap_true.
        call method cl_gui_frontend_services=>file_delete
          exporting
            filename = file_name
          changing
            rc       = rc
          exceptions
            others   = 0.
    * flush to execute the deletion
        call method cl_gui_cfw=>flush.
      endif.
    endform.                    " CLEAR_EXISTING_DATA_FILE
    *&---------------------------------------------------------------------*
    *&      Form  DOWNLAOD_EMPLOYEE_DATA_TO_PC
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    form download_employee_data_to_pc.
      data: file_name type string.
      data: cnt type i.
      data: lt_download type standard table of string,
            lv_download type string,
            lv_hstr(1024) type c.
      class cl_abap_char_utilities definition load.
      constants: lc_tab type string
                        value cl_abap_char_utilities=>horizontal_tab.
      field-symbols: <field> type any,
                     <data_tab_wa> type any.
      perform get_all_field_names.
      clear lv_download.
      loop at fieldnames.
        write fieldnames to lv_hstr left-justified.
        if sy-tabix > 1.
          concatenate lv_download lc_tab lv_hstr
                      into lv_download.
        else.
          concatenate lv_download lv_hstr
                      into lv_download.
        endif.
      endloop.
      append lv_download to lt_download.
    * then the data table
      loop at empinfo
           assigning <data_tab_wa>.
        cnt = 0.
        clear lv_download.
        sy-subrc = 0.
        while sy-subrc = 0.
          cnt = cnt + 1.
          assign component cnt of structure <data_tab_wa> to <field>.
          check sy-subrc = 0.
          write <field> to lv_hstr left-justified.
          if cnt > 1.
            concatenate lv_download lc_tab lv_hstr
                        into lv_download.
          else.
            concatenate lv_download lv_hstr
                        into lv_download.
          endif.
        endwhile.
        append lv_download to lt_download.
      endloop.
      file_name = txt_work_file.
      call function 'GUI_DOWNLOAD'
        exporting
    *     BIN_FILESIZE                  =
          filename                      = file_name
    *     FILETYPE                      = 'ASC'
    *     APPEND                        = ' '
          write_field_separator         = 'X'
    *     HEADER                        = '00'
          trunc_trailing_blanks         = 'X'
    *      col_select                    =
    *      col_select_mask               =
    *   IMPORTING
    *     FILELENGTH                    =
        tables
          data_tab                      = lt_download
       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
         others                        = 22.
      if sy-subrc <> 0.
        case sy-subrc.
          when 1.
            raise file_write_error.
          when 2.
            raise no_batch.
          when 3.
            raise gui_refuse_filetransfer.
          when 4.
            raise invalid_type .
          when 5.
            raise no_authority.
          when 6.
            raise unknown_error.
          when 7.
            raise header_not_allowed.
          when 8.
            raise separator_not_allowed.
          when 9.
            raise filesize_not_allowed.
          when 10.
            raise header_too_long.
          when 11.
            raise dp_error_create.
          when 12.
            raise dp_error_send.
          when 13.
            raise dp_error_write.
          when 14.
            raise unknown_dp_error.
          when 15.
            raise access_denied.
          when 16.
            raise dp_out_of_memory.
          when 17.
            raise disk_full.
          when 18.
            raise dp_timeout.
          when 19.
            raise file_not_found.
          when 20.
            raise dataprovider_exception.
          when 21.
            raise control_flush_error.
          when others.
            raise unknown_error.
        endcase.
      endif.
    endform.                               " DOWNLAOD_EMPLOYEE_DATA_TO_PC
    *&---------------------------------------------------------------------*
    *&      Form  GET_ALL_FIELD_NAMES
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    form get_all_field_names.
      type-pools: sydes.
      type-pools slis.
      data:  td type sydes_desc.
      data: name_header type sydes_nameinfo.
      data: name like name_header.
      data: types_header type sydes_typeinfo.
      data: type like types_header.
      data: prev_tabix like sy-tabix.
      data: continue_field(1) type c.
      data: search_str(40) type c.
      data: s_length(5) type p.
      data: begin of stru_tab occurs 0,
              name(30) type c,
              fldname(30) type c,
              index    like sy-tabix,
              length(3) type n,
              type(1)   type c,
              decimals(2) type n,
            end of stru_tab.
      clear: td.
      describe field empinfo into td.
      clear: stru_tab[], stru_tab.
      do 1000 times.
        read table td-types into types_header index sy-index.
        if sy-subrc ne 0.
          exit.
        endif.
        type = types_header.
        stru_tab-index = type-idx_name.
        stru_tab-type  = type-type.
        stru_tab-length = type-length.
        stru_tab-decimals = type-decimals.
        check stru_tab-index ne 0.
        append stru_tab.
      enddo.
      do 1000 times.
        read table td-names into name_header index sy-index.
        if sy-subrc ne 0.
          exit.
        endif.
        name = name_header.
        if continue_field ne space.
          read table stru_tab index prev_tabix.
          if sy-subrc eq 0.
            concatenate stru_tab-fldname name-name into stru_tab-fldname.
            modify stru_tab index prev_tabix.
            clear: prev_tabix, continue_field.
          endif.
        else.
          loop at stru_tab where index eq sy-index.
            stru_tab-fldname = name-name.
            prev_tabix = sy-tabix.
            modify stru_tab.
          endloop.
        endif.
        if name-continue eq '*'.
          continue_field = 'X'.
        else.
          continue_field = space.
        endif.
      enddo.
    * now build fieldnames
      loop at stru_tab.
        fieldnames-field   = stru_tab-fldname.
        append fieldnames.
      endloop.
    endform.                               " GET_ALL_FIELD_NAMES
    *&---------------------------------------------------------------------*
    *&      Form  OPEN_MS_WORD
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    form start_ms_word .
      data: xcode   like sy-xcode,
            ok_code like sy-xcode,
            rc type i,
            platform type i,
            registry_entry(255) type c,
            reg_value type string,
            temp_dir type string.
      data: version_str(80) type c,
            word_version type i.
      data: documents type ole2_object.
    * Start with OLE automation
      call method cl_gui_frontend_services=>registry_get_value
        exporting
          root                = cl_gui_frontend_services=>hkey_classes_root
          key                 = 'Word.Basic\CurVer'
          value               = ''
        importing
          reg_value           = reg_value
        exceptions
          get_regvalue_failed = 1
          cntl_error          = 2
          error_no_gui        = 3
          others              = 4.
      if sy-subrc <> 0.
        raise download_problem.
      endif.
      call method cl_gui_cfw=>flush.
      version_str = reg_value.
      shift version_str left by 11 places.
      move version_str to word_version.
      if word_version < 8.
        create object wordobj 'Word.Basic'.
      else.
        create object worddoc 'Word.Document'.
        get property of worddoc 'Application' = wordapp.
        set property of wordapp 'Visible' = 1.
        get property of wordapp 'WordBasic' = wordobj.
        call method of wordobj 'FileClose'.
      endif.
      call method of wordobj 'AppShow'.
    * Serienbriefdatei Жffnen
      if word_version > 8.
        get property of wordapp 'Documents' = documents.
        call method of documents 'Open'
          exporting
            #01 = doc_work_file  "file name
            #02 = 0.              "confirm conversion
    *        #03 = 1              "ReadOnly
    *        #04 = 1              "AddToRecentFile
    *        #05 = ''             "PasswordDocument
    *        #06 = ''             "PasswordTemplat
    *        #07 = 0              "Revert
    *        #08 = ''             "WritePasswordDocume
    *        #09 = ''.            "WritePasswordTemplate
    *        #10 = 4.             "Format 4=plain text
    *                        #11 = 1255.   "Encoding: e.g. hebrew=1255
      else.
        call method of wordobj 'FileOpen'
          exporting
            #01 = doc_work_file
            #02 = 0.
      endif.
    endform.                    " OPEN_MS_WORD
    *&---------------------------------------------------------------------*
    *&      Form  FILL_MS_WORD_WITH_DATA
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    form fill_ms_word_with_data .
      data: passwort(15).
      call method of wordobj 'MailMergeMainDocumentType'
        exporting
          #01 = 0.
      call method of wordobj 'MailMergeOpenDataSource'
        exporting
          #01 = txt_work_file
          #02 = 0
          #03 = 1
          #04 = 0
          #05 = 0
          #06 = passwort.
      call method of wordobj 'MailMergeEditMainDocument' .
      call method of wordobj 'MailMergeToDoc'.
    endform.                    " FILL_MS_WORD_WITH_DATA

    March 11

    Buttons to display First, Prev. Next, Last records

    Code:

    REPORT z_alv_grid_ctrl_refresh_2.
    ***********************************************************************
    * ALV Grid Control                                                    *
    * This report reads and displays data from table MARA,  using         *
    * the Method set_table_for_first_display of CL_GUI_ALV_GRID           *
    * Button 'NEXT_PAGE'  : displays the next N records                   *
    * Button 'PREV_PAGE'  : displays the previous N records               *
    * Button 'FIRST_PAGE' : displays the first page                       *
    * Button 'LAST_PAGE'  : displays the last page                        *
    * When the buttons Sort up, sort down, Filter, Delete Filter are      *
    * pressed, N record are still displayed                               *
    *---------------------------------------------------------------------*
    * Steps :                                                             *
    * - Create the report Z_ALV_GRID_CTRL_REFRESH_2                       *
    * - Create the Dynpro 0100 (size 27x120)                              *
    * - Add OKCODE (type OK) in the element list                          *
    * - Modify the flow logic of dynpro 0100 :                            *
    *   * PROCESS BEFORE OUTPUT.                                          *
    *       MODULE pbo_0100.                                              *
    *   * PROCESS AFTER INPUT.                                            *
    *       MODULE user_command_0100.                                     *
    * - Create a status named 'MAIN'                                      *
    *   with the buttons : REFRESH BACK EXIT                              *
    *   and the buttons : FIRST_PAGE PREV_PAGE NEXT_PAGE LAST_PAGE        *
    *---------------------------------------------------------------------*
    * Author : Michel PIOUD                                               *
    * Email : mpioud@yahoo.fr  HomePage : http://www.geocities.com/mpioud *
    ***********************************************************************
    CONSTANTS:
      c_first_page TYPE syucomm VALUE 'FIRST_PAGE',
      c_next_page  TYPE syucomm VALUE 'NEXT_PAGE',
      c_prev_page  TYPE syucomm VALUE 'PREV_PAGE',
      c_last_page  TYPE syucomm VALUE 'LAST_PAGE'.
    TYPES:
      BEGIN OF ty_s_mara,
        ernam LIKE mara-ernam,
        matnr LIKE mara-matnr,
        ersda LIKE mara-ersda,
        brgew LIKE mara-brgew,
      END OF ty_s_mara.
    CLASS lcl_event_alv DEFINITION DEFERRED.
    DATA:
      gt_mara TYPE STANDARD TABLE OF ty_s_mara,
      go_container TYPE REF TO cl_gui_docking_container,
      go_alv_grid  TYPE REF TO cl_gui_alv_grid,
      go_events    TYPE REF TO lcl_event_alv,
      gt_mara_ftr TYPE STANDARD TABLE OF ty_s_mara,   " Data filtered
      gt_mara_all TYPE STANDARD TABLE OF ty_s_mara,   " Data readfrom DB
      okcode    TYPE syucomm,
      gv_okcode TYPE syucomm.
    *---------------------------------------------------------------------*
    *       CLASS lcl_event_alv DEFINITION
    *---------------------------------------------------------------------*
    CLASS lcl_event_alv DEFINITION.
      PUBLIC SECTION.
        METHODS:
          h_user_command FOR EVENT after_user_command OF cl_gui_alv_grid
                         IMPORTING e_ucomm
                                   sender.
    ENDCLASS.                              " LCL_EVENT_ALV DEFINITION
    *---------------------------------------------------------------------*
    *        Class (Implementation)  lcl_event_alv
    *---------------------------------------------------------------------*
    CLASS lcl_event_alv IMPLEMENTATION.
      METHOD h_user_command.
        CASE e_ucomm.
          WHEN '&SORT_ASC' OR '&SORT_DSC'. " Sort
            PERFORM f_sort_big_table.
            PERFORM f_read_data USING c_first_page.
            PERFORM f_refresh_table.
          WHEN '&FILTER'.                  " Filter
            PERFORM f_filter_data.
            PERFORM f_read_data USING c_first_page.
            PERFORM f_refresh_table.
          WHEN '&DELETE_FILTER'.           " Delete filter
            gt_mara_ftr[] = gt_mara_all[].
            PERFORM f_read_data USING c_first_page.
            PERFORM f_refresh_table.
        ENDCASE.
      ENDMETHOD.                           " user_command
    ENDCLASS.                              " LCL_EVENT_ALV
    *---------------------------------------------------------------------*
    SELECTION-SCREEN :
    BEGIN OF LINE,COMMENT 10(20) v_1 FOR FIELD p_max.           "#EC NEEDED
    PARAMETERS p_max(2) TYPE n DEFAULT '30' OBLIGATORY.
    SELECTION-SCREEN END OF LINE.
    *---------------------------------------------------------------------*
    INITIALIZATION.
      v_1 = 'Lines per page'.
    *---------------------------------------------------------------------*
    START-OF-SELECTION.
      SELECT matnr ernam ersda brgew
        INTO TABLE gt_mara_all
        FROM mara.
      gt_mara_ftr[] = gt_mara_all[].
      PERFORM f_read_data USING c_first_page.
      CALL SCREEN 100.
    *---------------------------------------------------------------------*
    *       Module  pbo_0100  OUTPUT
    *---------------------------------------------------------------------*
    MODULE pbo_0100 OUTPUT.
      SET PF-STATUS 'MAIN'.
      PERFORM create_and_init_alv.
    ENDMODULE.                             " PBO_0100  OUTPUT
    *---------------------------------------------------------------------*
    *       Module  user_command_0100  INPUT
    *---------------------------------------------------------------------*
    MODULE user_command_0100 INPUT.
      gv_okcode = okcode.
      CLEAR okcode.
      CASE gv_okcode.
        WHEN 'BACK'.
          SET SCREEN 0.
        WHEN 'EXIT'.
          LEAVE PROGRAM.
        WHEN c_first_page OR c_next_page OR c_last_page OR c_prev_page.
          PERFORM f_read_data USING gv_okcode.            " Update gt_mara
          PERFORM f_refresh_table.
      ENDCASE.
    ENDMODULE.                             " USER_COMMAND_0100  INPUT
    *---------------------------------------------------------------------*
    *      Form  f_read_data
    *---------------------------------------------------------------------*
    FORM f_read_data USING u_ucomm TYPE syucomm.
      STATICS :
        l_1   TYPE sytabix,
        l_2   TYPE sytabix.
      DATA l_max TYPE sytabix.             " Internal table size
      DESCRIBE TABLE gt_mara_ftr LINES l_max.
      CASE u_ucomm.
        WHEN c_first_page.                 " 1st page
          l_1 = 1.
        WHEN c_prev_page.                  " Previous page
          SUBTRACT p_max FROM l_1.
          IF l_1 < 1.
            l_1 = 1.
          ENDIF.
        WHEN c_next_page.                  " Next page
          IF l_1 IS INITIAL.
            l_1 = 1.
          ELSE.
            ADD p_max TO l_1.
          ENDIF.
          IF l_1 > l_max.
            l_1 = l_max.
          ENDIF.
        WHEN c_last_page.                  " Last page
          l_1 = l_max - p_max + 1.
          IF l_1 < 1.
            l_1 = 1.
          ENDIF.
      ENDCASE.
      l_2 = l_1 + p_max - 1.
      IF l_2 > l_max.
        l_2 = l_max.
      ENDIF.
      REFRESH gt_mara.
      IF l_max > 0.
        APPEND LINES OF gt_mara_ftr FROM l_1
                                      TO l_2
                                      TO gt_mara.
      ENDIF.
    ENDFORM.                               " F_READ_DATA
    *---------------------------------------------------------------------*
    *       Form  create_and_init_alv
    *---------------------------------------------------------------------*
    FORM create_and_init_alv.
    * Macro definition
      DEFINE m_fieldcat.
        add 1 to ls_alv_cat-col_pos.
        ls_alv_cat-fieldname = &1.
        ls_alv_cat-ref_table = 'MARA'.
        append ls_alv_cat to lt_alv_cat.
      END-OF-DEFINITION.
      DATA:
        ls_variant      TYPE disvariant,
        lt_alv_cat      TYPE lvc_t_fcat,
        ls_alv_cat      TYPE lvc_s_fcat,
        ls_alv_lay      TYPE lvc_s_layo,
        l_offline       TYPE char1.
      CHECK go_container IS INITIAL.
      CALL METHOD cl_gui_alv_grid=>offline
        RECEIVING e_offline = l_offline.
      IF l_offline EQ 0.
        CREATE OBJECT go_container
            EXPORTING
                extension = 2000
            EXCEPTIONS
                cntl_error = 1
                cntl_system_error = 2
                create_error = 3
                lifetime_error = 4
                lifetime_dynpro_dynpro_link = 5
                others                      = 6.
        IF sy-subrc NE 0.
          MESSAGE e208(00) WITH 'The control could not be created'.
        ENDIF.
      ENDIF.
    * Create an instance of alv control
      CREATE OBJECT go_alv_grid
          EXPORTING i_parent = go_container.
      CREATE OBJECT go_events.
      SET HANDLER go_events->h_user_command FOR go_alv_grid.
    * Build field catalog
      m_fieldcat 'ERNAM'.
      m_fieldcat 'MATNR'.
      m_fieldcat 'ERSDA'.
      m_fieldcat 'BRGEW'.
    * Layout
      CLEAR ls_alv_lay.
      ls_alv_lay-zebra      = 'X'.
      ls_alv_lay-cwidth_opt = 'X'.
      ls_variant-report = sy-cprog.
    * Display
      CALL METHOD go_alv_grid->set_table_for_first_display
        EXPORTING
          is_variant      = ls_variant
          is_layout       = ls_alv_lay
          i_save          = 'A'
        CHANGING
          it_outtab       = gt_mara
          it_fieldcatalog = lt_alv_cat.
    ENDFORM.                               " CREATE_AND_INIT_ALV
    *---------------------------------------------------------------------*
    *      Form  F_REFRESH_TABLE
    *---------------------------------------------------------------------*
    FORM f_refresh_table.
      DATA: ls_layout TYPE lvc_s_layo.
      CALL METHOD go_alv_grid->get_frontend_layout
        IMPORTING es_layout = ls_layout.
      ls_layout-cwidth_opt = 'X'.
      CALL METHOD go_alv_grid->set_frontend_layout
        EXPORTING is_layout = ls_layout.
      CALL METHOD go_alv_grid->refresh_table_display.
    ENDFORM.                               " F_REFRESH_TABLE
    *---------------------------------------------------------------------*
    *       Form  F_SORT_BIG_TABLE
    *---------------------------------------------------------------------*
    FORM f_sort_big_table.
      DATA:
        lt_sort_kkblo TYPE kkblo_t_sortinfo,
        lt_sort       TYPE lvc_t_sort.
      CALL METHOD go_alv_grid->get_sort_criteria
        IMPORTING et_sort = lt_sort.
      CHECK NOT lt_sort[] IS INITIAL.
    * Format LVC --> KKBLO
      CALL FUNCTION 'LVC_TRANSFER_TO_KKBLO'
           EXPORTING
                it_sort_lvc   = lt_sort
           IMPORTING
                et_sort_kkblo = lt_sort_kkblo.
    * The big tables must be sorted like the small one
      PERFORM fb_outtab_sort(saplkkbl) TABLES gt_mara_ftr
                                              lt_sort_kkblo
                                        USING 'X'
                                              'X'.
      PERFORM fb_outtab_sort(saplkkbl) TABLES gt_mara_all
                                              lt_sort_kkblo
                                        USING 'X'
                                              'X'.
    ENDFORM.                               " F_SORT_BIG_TABLE
    *---------------------------------------------------------------------*
    *      Form  f_filter_data
    *---------------------------------------------------------------------*
    FORM f_filter_data.
      DATA:
        lt_filter_lvc   TYPE lvc_t_filt,
        lt_filter_index TYPE lvc_t_fidx WITH HEADER LINE.
      CALL METHOD go_alv_grid->get_filter_criteria
        IMPORTING et_filter = lt_filter_lvc.
    * Find data to filter
      CALL FUNCTION 'LVC_FILTER_APPLY'
           EXPORTING
                it_filter       = lt_filter_lvc
           IMPORTING
                et_filter_index = lt_filter_index[]
           TABLES
                it_data         = gt_mara_all.
      gt_mara_ftr[] = gt_mara_all[].
      SORT lt_filter_index DESCENDING.
      LOOP AT lt_filter_index.
        DELETE gt_mara_ftr INDEX lt_filter_index.
      ENDLOOP.
    ENDFORM.                               " F_FILTER_DATA
    ********* END OF PROGRAM Z_ALV_GRID_CTRL_REFRESH_2 ********************

    Displaying ALV Grid in Background Job

    Displaying ALV Grid in Background Job
    Author: Prashant Patil
    Original: https: //www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/5898
    Many a times there is a requirement to display ALV Grid (not ALV List) in the background Job. I have checked the SDN Forum for the same and it has been mentioned that ALV Grid cannot be displayed in Background, but the list output of ALV is possible. So user won’t have the actual Grid interface but the List interface.
    There is a workaround to display ALV Grid in Background Job. The only restriction is you can’t schedule the job through SM36. You need to execute the transaction of the report program, fill in the selection screen data and hit Execute.
    The job would be executed in background. User will be able to see the Job Log and Job Status after executing the program. User doesn’t have to go to SM37 to view the job status/log. Once the Job Status is changed to “COMPLETED”, user can click on “DISPLAY SPOOL” to view the ALV Grid.
    Limitations:
    1. Can’t schedulea background job
    2. The session should be active until the background job is completed. If the session is closed, then user won’t be able to check the output in ALV Grid. User would be able to check the output through spool or SM37
    Advantages:
    1. If the spool width is greater than 255 characters, then the entire width could be seen in the output because the output is directed to an ALV Grid and not to spool
    2. Interface of ALV Grid is available instead of ALV List even though it’s a background job.
    3. Program won’t give the TIME OUT error
    Steps Required:
    1. Once you execute the program, the following screen would be displayed

    2. Click “Display Job Status” to check the Status of the Background Job

    3. Click on “Display the Job Log” to check the Log

    4. Click on “Display Job Status” to check the Job Status

    5. Click on “DISPLAY SPOOL” to check the spool content once the Job Status is changed to “COMPLETED”. Output is displayed in ALV Grid

    Programs:
    1. Two different programs needs to be created
    ZPROGRAM_ONE: This is the 1st program, where the selection screen and all the data validations would be done. Error handling for invalid data should be done in this program.
    Once the data validation is done, this program would call the 2nd program ZPROGEAM_TWO. Build the logic to display ALV Grid in this program. The logic will only display ALV in foreground and it won’t be reflected in the spool.
    ZPROGRAM_TWO: This program would fetch all the data and do all the processing. If you want the spool output along with ALV Grid output, then build the logic in this program to display ALV Grid.

    Code:

    *&---------------------------------------------------------------------*
    *& Report  ZPROGRAM_ONE                                                *
    *&                                                                     *
    *&---------------------------------------------------------------------*
    *&                                                                     *
    *&                                                                     *
    *&---------------------------------------------------------------------*
    REPORT  zprogram_one                            .
    * PRASHANT PATIL
    TABLES : mara,
             tsp01.
    type-pools:slis.
    TYPES : BEGIN OF t_mara,
              matnr   TYPE mara-matnr,
              ersda   TYPE mara-ersda,
              ernam   TYPE mara-ernam,
              laeda   TYPE mara-laeda,
            END OF t_mara.
    DATA : i_mara       TYPE STANDARD TABLE OF t_mara,
           wa_mara      TYPE t_mara,
           wa_index     TYPE indx,        " For Index details
           wa_index_key TYPE indx-srtfd VALUE 'PRG_ONE',
           i_jobsteplist     TYPE STANDARD TABLE OF tbtcstep, " For spool number
           wa_params         TYPE pri_params,  " To Get Print Parameters
           wa_jobhead        TYPE tbtcjob,     " To know the status of job
           wa_jobsteplist    TYPE tbtcstep,    " To know the spool
           w_jobname         TYPE tbtco-jobname,  " Job name for bckgrnd job
           w_jobcount        TYPE tbtco-jobcount, " Unique id for bckgrd job
           w_path            TYPE string,         " Upload path
           w_lsind           TYPE sy-lsind,       " Index
           wa_seltab         TYPE rsparams,
           i_seltab          TYPE STANDARD TABLE OF rsparams,
           wa_index1         TYPE indx,        " For Index details
           wa_index_key1     TYPE indx-srtfd VALUE 'PRG_TWO',
           i_fieldcat        TYPE slis_t_fieldcat_alv,
           wa_fieldcat       LIKE LINE OF i_fieldcat.
    *----------------------------------------------------------------------*
    *         CONSTANTS DECLARATION                                        *
    *----------------------------------------------------------------------*
    CONSTANTS :
             c_a(1) TYPE c VALUE 'A',
             c_m(1) TYPE c VALUE 'M',
             c_l(1) TYPE c VALUE 'L',
             c_c(1) TYPE c VALUE 'C',
             c_zfdr(4) TYPE c VALUE 'ZFDR',
             c_x(1)    TYPE c VALUE 'X',
             c_locl(4) TYPE c VALUE 'LOCL', " Destination is LOCAL
             c_f(1)    TYPE c VALUE 'F',   " Job Status - Failed
             c_s(1)    TYPE c VALUE 'S',
             c_p(1)    TYPE c VALUE 'P'.
    *----------------------------
    * SELECTION SCREEN PARAMETERS
    *----------------------------
    SELECT-OPTIONS : s_matnr FOR mara-matnr.
    START-OF-SELECTION.
    *-------------------------------------------------------
    * Before the export, fill the data fields before CLUSTR
    *-------------------------------------------------------
      wa_index-aedat = sy-datum.
      wa_index-usera = sy-uname.
      EXPORT s_matnr
           TO DATABASE indx(st) FROM wa_index ID wa_index_key.
    *-----------------------------------------------
    * To Open the Job for background processing
    *-----------------------------------------------
      PERFORM open_job.
    *-----------------------------------------------
    * To get the print parameters
    *-----------------------------------------------
      PERFORM get_print_parameters.
    *------------------------------
    * Submit the job in background
    *------------------------------
      PERFORM job_submit.
    *---------------------------
    * Close the background job
    *---------------------------
      PERFORM job_close.
    ***************************************************************
    *****  This is the output screen with the buttons ********
    ***************************************************************
    * Create 3 buttons DISPLAY SPOOL, STATUS, JOBLOG
      SET PF-STATUS 'ZS001'.
      WRITE: / 'The program is submitted in Background'.
      WRITE: / 'Press DISPLAY SPOOL to see the spool'.
      WRITE: / 'Press STATUS to see the status of the background'.
    AT USER-COMMAND.
    *-------------------------------------
    * If user presses the 'BACK' button
    *-------------------------------------
      IF sy-ucomm = 'BAK'.
        IF  wa_jobhead-status = c_f OR
            wa_jobhead-status = c_a.
          LEAVE TO SCREEN 0.
        ENDIF.
      ENDIF.
    *-------------------------------------------------
    * If the user presses the 'DISPLAY SPOOL' Button
    *-------------------------------------------------
      IF sy-ucomm = 'DISPLAY'.
        PERFORM display_spool.
      ENDIF.
    *-----------------------------------------------
    * If the user presses the 'JOB STATUS' Button
    *-----------------------------------------------
      IF sy-ucomm = 'STATUS'.
        PERFORM display_status.
      ENDIF.
    *----------------------------------------------
    * If the user presses the 'JOB LOG' Button
    *----------------------------------------------
      IF sy-ucomm = 'JOBLOG'.
        PERFORM display_job_log.
      ENDIF.
    *&---------------------------------------------------------------------*
    *&      Form  open_job
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM open_job .
    *-----------------------------------------------------------------------
    * This is to Create a new job which is to be submitted in background to
    * process sales order/delivery/invoice
    * Here we would get a unique id ( Jobcount ) which identifies our job
    * along with the job name which we have assigned to our job
    *-----------------------------------------------------------------------
      CONCATENATE sy-uname
                  sy-datum
                  sy-uzeit
                          INTO w_jobname .  " Assign unique jobname
      CALL FUNCTION 'JOB_OPEN'
       EXPORTING
    *   DELANFREP              = ' '
    *   JOBGROUP               = ' '
        jobname                = w_jobname
    *   SDLSTRTDT              = NO_DATE
    *   SDLSTRTTM              = NO_TIME
    *   JOBCLASS               =
      IMPORTING
       jobcount                = w_jobcount
    * CHANGING
    *   RET                    =
    EXCEPTIONS
       cant_create_job        = 1
       invalid_job_data       = 2
       jobname_missing        = 3
       OTHERS                 = 4
                .
      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.                    " open_job
    *&---------------------------------------------------------------------*
    *&      Form  get_print_parameters
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM get_print_parameters .
      DATA : l_valid TYPE c.
    *-----------------------------------------------------------------
    * This is to get the Print Parameters for the job which is to be
    * submitted in background to process sales order/delivery/invoice
    *-----------------------------------------------------------------
      CALL FUNCTION 'GET_PRINT_PARAMETERS'
       EXPORTING
    *   ARCHIVE_ID                   = C_CHAR_UNKNOWN
    *   ARCHIVE_INFO                 = C_CHAR_UNKNOWN
    *   ARCHIVE_MODE                 = C_CHAR_UNKNOWN
    *   ARCHIVE_TEXT                 = C_CHAR_UNKNOWN
    *   AR_OBJECT                    = C_CHAR_UNKNOWN
    *   ARCHIVE_REPORT               = C_CHAR_UNKNOWN
    *   AUTHORITY                    = C_CHAR_UNKNOWN
    *   COPIES                       = C_NUM3_UNKNOWN
    *   COVER_PAGE                   = C_CHAR_UNKNOWN
    *   DATA_SET                     = C_CHAR_UNKNOWN
    *   DEPARTMENT                   = C_CHAR_UNKNOWN
          destination                  = c_locl " LOCL
    *   EXPIRATION                   = C_NUM1_UNKNOWN
          immediately                  = space
    *   IN_ARCHIVE_PARAMETERS        = ' '
    *   IN_PARAMETERS                = ' '
    *   LAYOUT                       = C_CHAR_UNKNOWN
    *   LINE_COUNT                   = C_INT_UNKNOWN
    *   LINE_SIZE                    = C_INT_UNKNOWN
    *   LIST_NAME                    = C_CHAR_UNKNOWN
    *   LIST_TEXT                    = C_CHAR_UNKNOWN
    *   MODE                         = ' '
          new_list_id                  = c_x
    *   PROTECT_LIST                 = C_CHAR_UNKNOWN
          no_dialog                    = c_x
    *   RECEIVER                     = C_CHAR_UNKNOWN
    *   RELEASE                      = C_CHAR_UNKNOWN
    *   REPORT                       = C_CHAR_UNKNOWN
    *   SAP_COVER_PAGE               = C_CHAR_UNKNOWN
    *   HOST_COVER_PAGE              = C_CHAR_UNKNOWN
    *   PRIORITY                     = C_NUM1_UNKNOWN
    *   SAP_OBJECT                   = C_CHAR_UNKNOWN
    *   TYPE                         = C_CHAR_UNKNOWN
          user                         = sy-uname
    *   USE_OLD_LAYOUT               = ' '
    *   UC_DISPLAY_MODE              = C_CHAR_UNKNOWN
    *   DRAFT                        = C_CHAR_UNKNOWN
    *   ABAP_LIST                    = ' '
    *   USE_ARCHIVENAME_DEF          = ' '
    *   DEFAULT_SPOOL_SIZE           = C_CHAR_UNKNOWN
    *   PO_FAX_STORE                 = ' '
    *   NO_FRAMES                    = C_CHAR_UNKNOWN
       IMPORTING
    *   OUT_ARCHIVE_PARAMETERS       =
          out_parameters               = wa_params
       valid                        = l_valid
       EXCEPTIONS
         archive_info_not_found       = 1
         invalid_print_params         = 2
         invalid_archive_params       = 3
         OTHERS                       = 4
                .
      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.                    " get_print_parameters
    *&---------------------------------------------------------------------*
    *&      Form  job_submit
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM job_submit .
    *-----------------------------------------------------------------------
    * The job which we have created & the unique id ( jobcount ) which we
    * have got identifies our job. Hence those parameters are passed along
    * with the name of the background program "ZPROGRAM_TWO"
    * The job is submitted in background.
    *-----------------------------------------------------------------------
      CALL FUNCTION 'JOB_SUBMIT'
        EXPORTING
    *   ARCPARAMS                         =
        authcknam                         = sy-uname
    *   COMMANDNAME                       = ' '
    *   OPERATINGSYSTEM                   = ' '
    *   EXTPGM_NAME                       = ' '
    *   EXTPGM_PARAM                      = ' '
    *   EXTPGM_SET_TRACE_ON               = ' '
    *   EXTPGM_STDERR_IN_JOBLOG           = 'X'
    *   EXTPGM_STDOUT_IN_JOBLOG           = 'X'
    *   EXTPGM_SYSTEM                     = ' '
    *   EXTPGM_RFCDEST                    = ' '
    *   EXTPGM_WAIT_FOR_TERMINATION       = 'X'
        jobcount                          = w_jobcount
        jobname                           = w_jobname
    *   LANGUAGE                          = SY-LANGU
        priparams                         = wa_params
        report                            = 'ZPROGRAM_TWO'
    *   VARIANT                           = ' '
    * IMPORTING
    *   STEP_NUMBER                       =
       EXCEPTIONS
         bad_priparams                     = 1
         bad_xpgflags                      = 2
         invalid_jobdata                   = 3
         jobname_missing                   = 4
         job_notex                         = 5
         job_submit_failed                 = 6
         lock_failed                       = 7
         program_missing                   = 8
         prog_abap_and_extpg_set           = 9
         OTHERS                            = 10
                .
      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.                    " job_submit
    *&---------------------------------------------------------------------*
    *&      Form  job_close
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM job_close .
    *-----------------------------------------------------------------
    * Once the job is submitted in background then the job is closed
    *-----------------------------------------------------------------
      CALL FUNCTION 'JOB_CLOSE'
        EXPORTING
    *   AT_OPMODE                         = ' '
    *   AT_OPMODE_PERIODIC                = ' '
    *   CALENDAR_ID                       = ' '
    *   EVENT_ID                          = ' '
    *   EVENT_PARAM                       = ' '
    *   EVENT_PERIODIC                    = ' '
        jobcount                          = w_jobcount
        jobname                           = w_jobname
    *   LASTSTRTDT                        = NO_DATE
    *   LASTSTRTTM                        = NO_TIME
    *   PRDDAYS                           = 0
    *   PRDHOURS                          = 0
    *   PRDMINS                           = 0
    *   PRDMONTHS                         = 0
    *   PRDWEEKS                          = 0
    *   PREDJOB_CHECKSTAT                 = ' '
    *   PRED_JOBCOUNT                     = ' '
    *   PRED_JOBNAME                      = ' '
    *   SDLSTRTDT                         = NO_DATE
    *   SDLSTRTTM                         = NO_TIME
    *   STARTDATE_RESTRICTION             = BTC_PROCESS_ALWAYS
        strtimmed                         = c_x
    *   TARGETSYSTEM                      = ' '
    *   START_ON_WORKDAY_NOT_BEFORE       = SY-DATUM
    *   START_ON_WORKDAY_NR               = 0
    *   WORKDAY_COUNT_DIRECTION           = 0
    *   RECIPIENT_OBJ                     =
    *   TARGETSERVER                      = ' '
    *   DONT_RELEASE                      = ' '
    *   TARGETGROUP                       = ' '
    *   DIRECT_START                      =
    * IMPORTING
    *   JOB_WAS_RELEASED                  =
    * CHANGING
    *   RET                               =
       EXCEPTIONS
         cant_start_immediate              = 1
         invalid_startdate                 = 2
         jobname_missing                   = 3
         job_close_failed                  = 4
         job_nosteps                       = 5
         job_notex                         = 6
         lock_failed                       = 7
         invalid_target                    = 8
         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.                    " job_close
    *&---------------------------------------------------------------------*
    *&      Form  display_spool
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM display_spool .
    *-------------------------------------------
    * To Read the Job to get the spool details
    *-------------------------------------------
      DATA : l_rqident TYPE tsp01-rqident, " Spool Number
             l_spoolno TYPE tsp01_sp0r-rqid_char.
      CLEAR : l_rqident,
              w_lsind,
              wa_jobsteplist.
      REFRESH : i_jobsteplist.
      SET PF-STATUS 'ZAR02'.
    *--------------------------------
    * Get the Spool Number
    *--------------------------------
      CALL FUNCTION 'BP_JOB_READ'
        EXPORTING
          job_read_jobcount           = w_jobcount
          job_read_jobname            = w_jobname
          job_read_opcode             = '20'
    *     JOB_STEP_NUMBER             =
       IMPORTING
         job_read_jobhead            = wa_jobhead
       TABLES
         job_read_steplist           = i_jobsteplist
    * CHANGING
    *    RET                         =
       EXCEPTIONS
         invalid_opcode              = 1
         job_doesnt_exist            = 2
         job_doesnt_have_steps       = 3
         OTHERS                      = 4
                .
      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 the Job Step list to get the spool number
    *------------------------------------------------
      READ TABLE i_jobsteplist INTO wa_jobsteplist INDEX 1.
      CHECK wa_jobsteplist-listident <> space.
    *-----------------
    * Spool Number
    *-----------------
      l_rqident = wa_jobsteplist-listident.
      MOVE l_rqident TO l_spoolno.
    *---------------------------
    * Check the spool in TSP01
    *---------------------------
      SELECT SINGLE * FROM tsp01 WHERE rqident = l_rqident.
      IF  sy-subrc = 0.
        LEAVE TO LIST-PROCESSING.
        CALL FUNCTION 'RSPO_R_RDELETE_SPOOLREQ'
          EXPORTING
            spoolid       = l_spoolno
    *     IMPORTING
    *       RC            =
    *       STATUS        =
                  .
        PERFORM show_alv.
      ENDIF.
      w_lsind = sy-lsind.
      IF sy-lsind GE 19.
        sy-lsind = 1.
      ENDIF.
    ENDFORM.                    " display_spool
    *&---------------------------------------------------------------------*
    *&      Form  show_alv
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM show_alv .
    *---------------------------------------------------------
    * Before the import, fill the data fields before CLUSTR.
    *---------------------------------------------------------
      wa_index1-aedat = sy-datum.
      wa_index1-usera = sy-uname.
    *----------------------------------------------------------
    * To Import the selection screen data from Calling Program
    *----------------------------------------------------------
      IMPORT i_mara
      FROM DATABASE indx(st) ID wa_index_key1 TO wa_index1.
      FREE MEMORY ID wa_index_key1.
    * This prepares the field-catalog for ALV.
      PERFORM prepare_fieldcatalog.
    * This displays the output in  ALV format .
      PERFORM display_alv.
    ENDFORM.                    " show_alv
    *&---------------------------------------------------------------------*
    *&      Form  display_status
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM display_status .
    *------------------------------------------------------------------
    * To Display the STATUS of the JOB which is exectued in background
    *------------------------------------------------------------------
      CLEAR : wa_jobsteplist.
      REFRESH : i_jobsteplist.
      WRITE:/ 'DISPLAYING JOB STATUS'.
      CALL FUNCTION 'BP_JOB_READ'
        EXPORTING
          job_read_jobcount           = w_jobcount
          job_read_jobname            = w_jobname
          job_read_opcode             = '20'
    *     JOB_STEP_NUMBER             =
       IMPORTING
         job_read_jobhead            = wa_jobhead
       TABLES
         job_read_steplist           = i_jobsteplist
    * CHANGING
    *    RET                         =
       EXCEPTIONS
         invalid_opcode              = 1
         job_doesnt_exist            = 2
         job_doesnt_have_steps       = 3
         OTHERS                      = 4
                .
      IF sy-subrc <> 0.
        MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
      ENDIF.
    *----------------------------------------------------
    * To Display the status text as per the status type
    *----------------------------------------------------
      CASE wa_jobhead-status.
        WHEN 'S'. WRITE: / 'Scheduled'.
        WHEN 'R'. WRITE: / 'Released'.
        WHEN 'F'. WRITE: / 'Completed'.
        WHEN 'A'. WRITE: / 'Cancelled'.
        WHEN OTHERS.
      ENDCASE.
      IF sy-lsind GE 19.
        sy-lsind = 1.
      ENDIF.
    ENDFORM.                    " display_status
    *&---------------------------------------------------------------------*
    *&      Form  display_job_log
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM display_job_log .
    *-----------------------------------------------
    * To display the log of the background program
    *-----------------------------------------------
      LEAVE TO LIST-PROCESSING.
      CALL FUNCTION 'BP_JOBLOG_SHOW_SM37B'
        EXPORTING
          client                    = sy-mandt
          jobcount                  = w_jobcount
          joblogid                  = ' '
          jobname                   = w_jobname
        EXCEPTIONS
          error_reading_jobdata     = 1
          error_reading_joblog_data = 2
          jobcount_missing          = 3
          joblog_does_not_exist     = 4
          joblog_is_empty           = 5
          joblog_show_canceled      = 6
          jobname_missing           = 7
          job_does_not_exist        = 8
          no_joblog_there_yet       = 9
          no_show_privilege_given   = 10
          OTHERS                    = 11.
      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.                    " display_job_log
    *&---------------------------------------------------------------------*
    *&      Form  prepare_fieldcatalog
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM prepare_fieldcatalog .
      CLEAR wa_fieldcat.
      wa_fieldcat-fieldname    = 'MATNR'.
      wa_fieldcat-tabname      = 'I_MARA'.
      wa_fieldcat-reptext_ddic = 'Material no.'.
      wa_fieldcat-outputlen    = '18'.
      APPEND wa_fieldcat TO i_fieldcat.
      CLEAR wa_fieldcat.
      wa_fieldcat-fieldname    = 'ERSDA'.
      wa_fieldcat-tabname      = 'I_MARA'.
      wa_fieldcat-reptext_ddic = 'Creation date'.
      wa_fieldcat-outputlen    = '10'.
      APPEND  wa_fieldcat TO i_fieldcat.
      CLEAR wa_fieldcat.
      wa_fieldcat-fieldname    = 'ERNAM'.
      wa_fieldcat-tabname      = 'I_MARA'.
      wa_fieldcat-reptext_ddic = 'Name of Person'.
      wa_fieldcat-outputlen    = '10'.
      APPEND wa_fieldcat TO i_fieldcat.
      CLEAR wa_fieldcat.
      wa_fieldcat-fieldname    = 'LAEDA'.
      wa_fieldcat-tabname      = 'I_MARA'.
      wa_fieldcat-reptext_ddic = ' Last Change'.
      wa_fieldcat-outputlen    = '10'.
      APPEND  wa_fieldcat TO i_fieldcat.
    ENDFORM.                    " prepare_fieldcatalog
    *&---------------------------------------------------------------------*
    *&      Form  display_alv
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM display_alv .
    * Call ABAP List Viewer (ALV)
      call function 'REUSE_ALV_GRID_DISPLAY'
        exporting
          it_fieldcat  = i_fieldcat
        tables
          t_outtab     = i_mara.
    ENDFORM.                    " display_alv
    •   ZPROGRAM_TWO: This is the 2nd program which would be called from program ZPROGRAM_ONE.
    *&---------------------------------------------------------------------*
    *& Report  ZPROGRAM_TWO                                                *
    *&                                                                     *
    *&---------------------------------------------------------------------*
    *&                                                                     *
    *&                                                                     *
    *&---------------------------------------------------------------------*
    REPORT  zprogram_two                            .
    * PRASHANT PATIL
    TABLES : mara.
    TYPE-POOLS:slis.
    TYPES : BEGIN OF t_mara,
              matnr   TYPE mara-matnr,
              ersda   TYPE mara-ersda,
              ernam   TYPE mara-ernam,
              laeda   TYPE mara-laeda,
            END OF t_mara.
    DATA : i_mara        TYPE STANDARD TABLE OF t_mara,
           wa_mara       TYPE t_mara,
           wa_index      TYPE indx,        " For Index details
           wa_index_key  TYPE indx-srtfd VALUE 'PRG_ONE',
           wa_index1     TYPE indx,        " For Index details
           wa_index_key1 TYPE indx-srtfd VALUE 'PRG_TWO',
           i_fieldcat        TYPE slis_t_fieldcat_alv,
           wa_fieldcat       LIKE LINE OF i_fieldcat.
    SELECT-OPTIONS : s_matnr FOR mara-matnr.
    *---------------------------------------------------------
    * Before the import, fill the data fields before CLUSTR.
    *---------------------------------------------------------
    wa_index-aedat = sy-datum.
    wa_index-usera = sy-uname.
    *----------------------------------------------------------
    * To Import the selection screen data from Calling Program
    *----------------------------------------------------------
    IMPORT s_matnr
    FROM DATABASE indx(st) ID wa_index_key TO wa_index.
    FREE MEMORY ID wa_index_key.
    SELECT matnr
           ersda
           ernam
           laeda
           FROM mara
           INTO TABLE i_mara
           WHERE matnr IN s_matnr.
    PERFORM prepare_fieldcatalog.
    PERFORM display_alv.
    *-------------------------------------------------------
    * Before the export, fill the data fields before CLUSTR
    *-------------------------------------------------------
    wa_index1-aedat = sy-datum.
    wa_index1-usera = sy-uname.
    EXPORT i_mara
    TO DATABASE indx(st) FROM wa_index1 ID wa_index_key1.
    *&---------------------------------------------------------------------*
    *&      Form  prepare_fieldcatalog
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM prepare_fieldcatalog .
      CLEAR wa_fieldcat.
      wa_fieldcat-fieldname    = 'MATNR'.
      wa_fieldcat-tabname      = 'I_MARA'.
      wa_fieldcat-outputlen    = '18'.
      APPEND wa_fieldcat TO i_fieldcat.
      CLEAR wa_fieldcat.
      wa_fieldcat-fieldname    = 'ERSDA'.
      wa_fieldcat-tabname      = 'I_MARA'.
      wa_fieldcat-outputlen    = '10'.
      APPEND  wa_fieldcat TO i_fieldcat.
      CLEAR wa_fieldcat.
      wa_fieldcat-fieldname    = 'ERNAM'.
      wa_fieldcat-tabname      = 'I_MARA'.
      wa_fieldcat-outputlen    = '10'.
      APPEND wa_fieldcat TO i_fieldcat.
      CLEAR wa_fieldcat.
      wa_fieldcat-fieldname    = 'LAEDA'.
      wa_fieldcat-tabname      = 'I_MARA'.
      wa_fieldcat-outputlen    = '10'.
      APPEND  wa_fieldcat TO i_fieldcat.
    ENDFORM.                    " prepare_fieldcatalog
    *&---------------------------------------------------------------------*
    *&      Form  display_alv
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM display_alv .
    * Call ABAP List Viewer (ALV)
      CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
        EXPORTING
          it_fieldcat = i_fieldcat
        TABLES
          t_outtab    = i_mara.
    ENDFORM.                    " display_alv

    A new approach to ALV Programming

    A new approach to ALV Programming
    Author: Poornanand Mandalika
    ALV Programming has undergone a major change over the last couple of years. First we had the function module approach - where the data to be displayed is passed to a function module like REUSE_ALV_LIST_DISPLAY. Then with the introduction of the OO concepts in 46C we had classes like CL_GUI_ALV_GRID and CL_GUI_ALV_TREE which changed ALV Programming quite a bit. Most (almost all ?) ABAPers today use these classes to program their ALV.
    If you were asked to name one improvement to this approach based on classes, what would that be? I would say that it is still a bit painful to create a screen and put a custom control container and then place this ALV Grid in that , all by myself. Especially when I want to create some test programs to answer the questions in the ABAP Forum Smile! Wouldn't it be great if I could worry less about these and concentrate more on imporving the functionality of my ALV Grid?
    This is precisely what you can do from Basis 640. You can now program an ALV in various modes (Fullscreen, Regular and List Mode), all using a single class (and without even having to create a screen ! ).
    So without further ado, let me introduce you what's called the ALV Object Model. Now, what's that ?
    ALV Object Model is an object-oriented encapsulation of the existing tools, presenting a simplified unified and object-oriented API to the application developer.
    It makes migration of applications to the Web Dynpro easier.
    ALV tools with the same data model can be used via the same API -
    List Based ALV, Fullscreen ALV, ALV Grid using simple tables can now be programmed using the same OM class CL_SALV_TABLE.
    Hierarchical ALV can be programmed using the OM class CL_SALV_HIERSEQ_TABLE.
    Tree ALV can be programmed using the OM class CL_SALV_TREE.
    Here's a small example program which illustrates the simplicity of this new approach - Here are the Data Declarations for this program-

    Code:

    REPORT  ZALV_OBJECTMODEL_TEST.
    DATA : dyntab    TYPE STANDARD TABLE OF dntab,
           wa_dyntab TYPE dntab,
           dref      TYPE REF TO data,
           i_fcat    TYPE  lvc_t_fcat,
           wa_fcat   TYPE lvc_s_fcat,
           tab_name TYPE ddobjname VALUE 'SPFLI',
           gr_table TYPE REF TO cl_salv_table.
    FIELD-SYMBOLS : <newtab> TYPE table.

    We shall first create an internal table dynamically (this technique has already been discussed in some of the earlier weblogs) and populate it with the data from the table SPFLI.

    Code:

    START-OF-SELECTION.
      CALL FUNCTION 'NAMETAB_GET'
        EXPORTING
          langu   = sy-langu
          tabname = tab_name
        TABLES
          nametab = dyntab. "dyntab now contains the field names
    * FILLING THE CATALOG OF NEW DYNAMIC INTERNAL TABLE
      LOOP AT dyntab INTO wa_dyntab.
        wa_fcat-fieldname = wa_dyntab-fieldname.
        wa_fcat-ref_field = wa_dyntab-fieldname.
        wa_fcat-ref_table = wa_dyntab-tabname.
        APPEND wa_fcat TO i_fcat .
      ENDLOOP.
    * CREATING A POINTER (FIELD SYMBOL) TO THE INTERNAL TABLE
      CALL METHOD cl_alv_table_create=>create_dynamic_table
        EXPORTING
          it_fieldcatalog = i_fcat
        IMPORTING
          ep_table        = dref.
      ASSIGN  dref->* TO <newtab>.
    * SELECT the data from the table SPFLI. If you want a
    * different table, then just use a different value
    * than SPFLI in the data declarations part. Or better
    * still, use a PARAMETERS to take the name of the
    * table name as input from the selection-screen.
      SELECT *
        FROM (tab_name)
        INTO TABLE <newtab>
       UP TO 25 ROWS.

    Now all you have to do is to call a method of the class CL_SALV_TABLE to display your grid.

    Code:

    * Instead of if_salv_c_bool_sap=>false, you can pass the
    * value if_salv_c_bool_sap=>true to this method to
    * see your ALV as a list.
      TRY.
          CALL METHOD cl_salv_table=>factory
            EXPORTING
              list_display   = if_salv_c_bool_sap=>false
            IMPORTING
              r_salv_table   = gr_table
            CHANGING
              t_table        = <newtab>.
        CATCH cx_salv_msg.
      ENDTRY.
      gr_table->display( ).

    Further information about the ALV Object Model is available on the SAP Online Documentation

    Back to top

    View user's profile Send private message

    ALV Grid List with page break

    REPORT z_demo_alv_sort_2.
    *---------------------------------------------------------------------*
    * This program lists orders (VBAK) with sort for 'Sales organization' *
    * (VKORG), 'sold-to-party' (KUNNR) and 'Document number' (VBELN)      *
    *---------------------------------------------------------------------*
    * Author : Michel                                          *
    *---------------------------------------------------------------------*
    TYPES :
      BEGIN OF ty_vbak,
        vkorg TYPE vbak-vkorg,             " Sales organization
        kunnr TYPE vbak-kunnr,             " Sold-to party
        vbeln TYPE vbak-vbeln,             " Sales document
        audat TYPE vbak-audat,             " Document date
      END OF ty_vbak.
    DATA :
      vbak    TYPE vbak,
      gt_vbak TYPE TABLE OF ty_vbak.
    SELECT-OPTIONS :
      s_vkorg FOR vbak-vkorg,              " Sales organization
      s_kunnr FOR vbak-kunnr,              " Sold-to party
      s_vbeln FOR vbak-vbeln.              " Sales document
    SELECTION-SCREEN SKIP.
    SELECTION-SCREEN : BEGIN OF LINE, COMMENT 1(35) v_1 FOR FIELD p_page.
    PARAMETERS p_page RADIOBUTTON GROUP optn.
    SELECTION-SCREEN END OF LINE.
    SELECTION-SCREEN : BEGIN OF LINE, COMMENT 1(35) v_2 FOR FIELD p_ligne.
    PARAMETERS p_ligne RADIOBUTTON GROUP optn.
    SELECTION-SCREEN END OF LINE.
    SELECTION-SCREEN : BEGIN OF LINE, COMMENT 1(35) v_3 FOR FIELD p_nthng.
    PARAMETERS p_nthng RADIOBUTTON GROUP optn.
    SELECTION-SCREEN END OF LINE.
    SELECTION-SCREEN :
      SKIP, BEGIN OF LINE,COMMENT 5(27) v_4 FOR FIELD p_max.
    PARAMETERS p_max(2) TYPE n DEFAULT '20' OBLIGATORY.
    SELECTION-SCREEN END OF LINE.
    *---------------------------------------------------------------------*
    INITIALIZATION.
      v_1 = 'New page at ''Sales Org.'' break'.
      v_2 = 'Underline at ''Sales Org.'' break'.
      v_3 = 'Nothing'.
      v_4 = 'Maximum of records to read'.
    *---------------------------------------------------------------------*
    START-OF-SELECTION.
      PERFORM f_read_data.
      PERFORM f_display_data.
    *---------------------------------------------------------------------*
    *      Form  f_read_data
    *---------------------------------------------------------------------*
    FORM f_read_data.
      SELECT vkorg kunnr vbeln audat
          UP TO p_max ROWS
        INTO TABLE gt_vbak
        FROM vbak
       WHERE kunnr IN s_kunnr
         AND vbeln IN s_vbeln
         AND vkorg IN s_vkorg.
    ENDFORM.                               " F_READ_DATA
    *---------------------------------------------------------------------*
    *      Form  f_display_data
    *---------------------------------------------------------------------*
    FORM f_display_data.
      TYPE-POOLS: slis.                    " ALV Global types
    * Macro definition
      DEFINE m_fieldcat.
        add 1 to ls_fieldcat-col_pos.
        ls_fieldcat-fieldname   = &1.
        ls_fieldcat-ref_tabname = 'VBAK'.
        append ls_fieldcat to lt_fieldcat.
      END-OF-DEFINITION.
      DEFINE m_sort.
        add 1 to ls_sort-spos.
        ls_sort-fieldname = &1.
        ls_sort-up        = 'X'.
        ls_sort-group     = &2.
        append ls_sort to lt_sort.
      END-OF-DEFINITION.
      DATA:
        ls_fieldcat TYPE slis_fieldcat_alv,
        lt_fieldcat TYPE slis_t_fieldcat_alv,
        lt_sort     TYPE slis_t_sortinfo_alv,
        ls_sort     TYPE slis_sortinfo_alv,
        ls_layout   TYPE slis_layout_alv,
        ls_grid_settings TYPE lvc_s_glay.
    *
      ls_grid_settings-top_p_only = 'X'.
      m_fieldcat 'VKORG'.
      m_fieldcat 'KUNNR'.
      m_fieldcat 'VBELN'.
      m_fieldcat 'AUDAT'.
      IF p_page = 'X'.
        m_sort 'VKORG' '*'.                " Sort by vkorg + Page break
      ELSEIF p_ligne = 'X'.
        m_sort 'VKORG' 'UL'.               " Sort by vkorg + Underline
      ELSE.
        m_sort 'VKORG' ' '.                " Sort by vkorg
      ENDIF.
      m_sort 'KUNNR' ' '.                  " Sort by kunnr
      m_sort 'VBELN' ' '.                  " Sort by vbeln
      ls_layout-colwidth_optimize = 'X'.
      ls_layout-zebra             = 'X'.
      ls_layout-cell_merge        = 'X'.
      CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
           EXPORTING
                i_callback_program     = sy-cprog
                i_callback_top_of_page = 'TOP_OF_PAGE'
                is_layout              = ls_layout
                i_grid_settings        = ls_grid_settings
                it_fieldcat            = lt_fieldcat
                it_sort                = lt_sort
           TABLES
                t_outtab               = gt_vbak.
    ENDFORM.                               " F_DISPLAY_DATA
    *---------------------------------------------------------------------*
    *       FORM top_of_page                                              *
    *---------------------------------------------------------------------*
    FORM top_of_page.                                           "#EC CALLED
      ULINE.
      WRITE : sy-title(65) CENTERED, 'Page :' , sy-pagno .
      ULINE.
    ENDFORM.
    **************** END OF PROGRAM Z_DEMO_ALV_SORT_2 *********************

    Docking container with Text Editor and Grid

    You may be able to use a text editor container directly above the ALV grid. Implement this program which I just developed, and run it. See how the text is in a text editor control above the ALV. Maybe you could use this. I have implemented in a docking container, so that you have a working(cut/paste) solution. You could easily modify to implement this in a dynpro container.

    Code:

    report zrich_0001 .
    data: it001w type table of t001w with header line.
    parameters: p_check type c.
    start-of-selection.
    at selection-screen output.
    data: itext type table of tline-tdline,
    xtext like line of itext.
    data: docking_left type ref to cl_gui_docking_container,
    alv_bottom type ref to cl_gui_alv_grid,
    splitter type ref to cl_gui_splitter_container,
    dock_sub_cont1 type ref to cl_gui_container,
    dock_sub_cont2 type ref to cl_gui_container,
    text_editor_top type ref to cl_gui_textedit,
    repid type syrepid.
    repid = sy-repid.
    select * into corresponding fields of table it001w
    from t001w.
    if docking_left is initial.
    Create the docking and splitter containers
    create object:
    docking_left
    exporting repid = repid
    dynnr = sy-dynnr
    side = docking_left->dock_at_left
    extension = 1000,
    splitter
    exporting parent = docking_left
    rows = 2
    columns = 1.
    call method:
    splitter->set_border
    exporting border = space,
    splitter->get_container
    exporting row = 1
    column = 1
    receiving container = dock_sub_cont1,
    splitter->set_row_height
    exporting id = 1
    height = '30',
    splitter->get_container
    exporting row = 2
    column = 1
    receiving container = dock_sub_cont2.
    create object text_editor_top
    exporting
    parent = dock_sub_cont1.
    xtext = 'This is a test for aRs'.
    append xtext to itext.
    xtext = 'Good Luck!!'.
    append xtext to itext.
    call method text_editor_top->Set_text_as_r3table
    eXporting
    table = itext
    exceptions
    others = 1.
    create object alv_bottom
    exporting i_parent = dock_sub_cont2.
    call method alv_bottom->set_table_for_first_display
    exporting
    i_structure_name = 'T001W'
    changing
    it_outtab = it001w[].
    endif.

    A Form that gets and sets user parameters.

    *----------------------------------------------------------------------*
    * FORM GET_USER_PARAM
    *----------------------------------------------------------------------*
    * Gets a user parameter
    *----------------------------------------------------------------------*
    FORM get_user_param CHANGING p_value TYPE c.
    
      DATA: lv_param_value TYPE xuvalue.
    
      CALL FUNCTION 'G_GET_USER_PARAMETER'
        EXPORTING
          parameter_id    = 'NDR'
        IMPORTING
          parameter_value = lv_param_value.
    
      MOVE lv_param_value TO p_value.
    
    ENDFORM.                    "get_print_param
    
    
    
    *----------------------------------------------------------------------*
    * FORM SET_USER_PARAM
    *----------------------------------------------------------------------*
    * Sets the value of a user parameter
    *----------------------------------------------------------------------*
    FORM set_user_param USING p_value TYPE c.
    
      DATA: lv_param_value TYPE xuvalue.
    
      CLEAR lv_param_value.
    
      MOVE p_value TO lv_param_value.
    
      CALL FUNCTION 'G_SET_USER_PARAMETER'
        EXPORTING
          parameter_id    = 'NDR'
          parameter_value = lv_param_value.
    
    ENDFORM.                    "set_print_param

    Removes the confirmation flag from a transfer order and all its items.

    *----------------------------------------------------------------------
    * Program Name: Z_TRANSFER_ORDER_UNCONFIRM
    * Author      : Michael 
    * Description : Removes the confirmation flag from a transfer order
    *               and all its items
    *----------------------------------------------------------------------
    REPORT Z_TRANSFER_ORDER_UNCONFIRM.
    
    PARAMETERS: p_order TYPE LTAP-TANUM.
    
    TABLES LTAP.
    TABLES LTAK.
    
    *items
    SELECT * FROM LTAP WHERE TANUM = p_order.
      LTAP-PQUIT = SPACE.
      MODIFY LTAP.
    ENDSELECT.
    
    *order
    SELECT * FROM LTAK WHERE TANUM = p_order.
      LTAK-KQUIT = SPACE.
      MODIFY LTAK.
    ENDSELECT.
    
    Write: 'Done'.

    Generates a dynamic program that allows you to download data from a table, with specified download and selection fields.

    ***********************************************************************************************************
    * Program:      Z_TABLE_DATA_DOWNLOAD
    * Restrictions: -Should be run in the background, for large tables
    *               -If run in production, should be run after business hours, as it could cause system
    *                performance issues
    * Description:  Given the name of a database table, a program is generated that allows the user to enter
    *               values for each field in the table. When the generated report is run, the contents of the
    *               table are downloaded to a unix file.
    *
    *               The user is prompt to choose the fields to appear on the selection screen of the program
    *               (up to 40 fields) and the fields to write to the downloaded file.
    *
    *               The generated program can be run in the background, via the Program menu on the selection
    *               screen of the generated program.
    ***********************************************************************************************************
    
    REPORT z_table_data_download MESSAGE-ID zbc_o.
    
    
    
    ***********************************************************************************************************
    * VARIABLES
    ***********************************************************************************************************
    
    *** Data
    DATA:
      v_report_name(30)  TYPE c VALUE 'ZBC_O_TABLE_DATA_DOWNLOAD_GEN',
      v_back_to_start(1) TYPE c,
      v_ok_code          TYPE sy-ucomm. "ok code from the screens
    
    
    *** Screen
    CONTROLS:
      i_popup_table TYPE TABLEVIEW USING SCREEN 2000.
    
    
    *** Internal Tables
    TYPES:
      BEGIN OF t_fields,
        fieldname    TYPE dd03l-fieldname,
        position     TYPE dd03l-position,
        screen(1)    TYPE c, " show on the selection screen
        download(1)  TYPE c, " download to the file
      END OF t_fields.
    
    DATA:
      i_fields TYPE STANDARD TABLE OF t_fields,
      v_fields TYPE t_fields.
    
    DATA:
      i_source TYPE STANDARD TABLE OF char72.
    
    
    
    * CHECK FOR AUTHORIZATION
    INCLUDE: zbc_o_modify_sap_table_check.
    
    
    
    ***********************************************************************************************************
    * SELECTION SCREEN
    ***********************************************************************************************************
    PARAMETERS:
      p_table TYPE dd02l-tabname   OBLIGATORY MEMORY ID tbl,    "#EC EXISTS
      p_file  TYPE rlgrap-filename OBLIGATORY DEFAULT '/usr/sap/OSD/local/downloads/table.txt'.
    
    
    
    ***********************************************************************************************************
    * START-OF-SELECTION
    ***********************************************************************************************************
    START-OF-SELECTION.
    
      CLEAR:
        v_back_to_start.
    
      PERFORM get_table_fields.
    
    
      IF i_fields IS INITIAL.
        MESSAGE e037.
      ELSE.
    
        PERFORM select_table_fields.
    
        IF v_back_to_start = 'X'.
          CLEAR:
            v_back_to_start.
        ELSE.
          PERFORM generate_selection_program.
        ENDIF.
    
      ENDIF.
    
    
    
    ***********************************************************************************************************
    * FORM GET_TABLE_FIELDS
    ***********************************************************************************************************
    * [+] Checks that the table exists, and is the correct type of table (transparent, cluster, or pool)
    * [+] Gets the fields of the table
    ***********************************************************************************************************
    FORM get_table_fields.
    
      TABLES:
        dd02l.                                                  "#EC NEEDED
    
      CLEAR:
        i_fields.
    
      REFRESH:
        i_fields.
    
    * check that the table type is legit.
      SELECT *
      FROM dd02l
      WHERE tabname = p_table
      AND
      ( tabclass = 'TRANSP' OR
        tabclass = 'CLUSTER' OR
        tabclass = 'POOL' ) .
    
        EXIT.
    
      ENDSELECT.
    
      IF sy-subrc <> 0.
        EXIT.
      ENDIF.
    
    * now get the fields
      SELECT fieldname position
      FROM dd03l
      INTO CORRESPONDING FIELDS OF TABLE i_fields
      WHERE tabname = p_table.
    
    
      SORT i_fields BY position.
    
    * Deletes any .INCLUDE and similar statements
      DELETE i_fields WHERE fieldname+0(1) = '.'.
    
    
    ENDFORM.                    "get_table_fields
    
    
    
    
    ***********************************************************************************************************
    * FORMM SELECT_TABLE_FIELDS
    ***********************************************************************************************************
    * [+] Asks the user to select the fields for the selection screen and the download file
    ***********************************************************************************************************
    FORM select_table_fields.
    
      CALL SCREEN 2000 STARTING AT 1 1.
    
    ENDFORM.                    "select_table_fields
    
    
    
    ***********************************************************************************************************
    * FORM GENERATE_SELECTION_PROGRAM
    ***********************************************************************************************************
    * [+] Generates the program that performs the downloading and selection from the database
    ***********************************************************************************************************
    FORM generate_selection_program.
    
      DATA:
        lv_line(72)  TYPE c,
        lv_index(3)  TYPE c,
        lv_table(31) TYPE c,
        lv_selscr_key(8) TYPE c,
        lv_more_than_one(1) TYPE c.
    
      DATA:
        lv_textpool TYPE textpool,
        li_textpool TYPE STANDARD TABLE OF textpool.
    
      CLEAR:
        lv_table,
        li_textpool.
    
    
      WRITE p_table TO lv_table+1.
    
    
    * Setting up the variables
      PERFORM build_selection_program USING: 'REPORT temp.'.
    
      PERFORM build_selection_program USING: 'DATA: li_select_table LIKE STANDARD TABLE OF'.
      CLEAR: lv_line.
      CONCATENATE lv_table '.' INTO lv_line.
      PERFORM build_selection_program USING: lv_line.
    
      PERFORM build_selection_program USING: 'DATA: lv_select_table LIKE'.
      CLEAR: lv_line.
      CONCATENATE lv_table '.' INTO lv_line.
      PERFORM build_selection_program USING: lv_line.
    
      PERFORM build_selection_program USING: 'DATA: lv_field_char(1000) TYPE c.'.
      PERFORM build_selection_program USING: 'DATA: lv_offset TYPE i.'.
    
      PERFORM build_selection_program USING: 'CONSTANTS: c_linebreak(1) TYPE x VALUE ''0D''.'.
      PERFORM build_selection_program USING: 'CONSTANTS: c_tab(1)       TYPE x VALUE ''09''.'.
    
    
      CLEAR: lv_line.
      CONCATENATE 'TABLES: ' lv_table '.' INTO lv_line.
      PERFORM build_selection_program USING: lv_line.
    
    * Creating the select-options
      LOOP AT i_fields INTO v_fields WHERE screen = 'X'.
        CLEAR:
          lv_line,
          lv_index,
          lv_selscr_key.
    
        WRITE sy-tabix TO lv_index LEFT-JUSTIFIED.
    
        CONCATENATE 'SELECT-OPTIONS: s_fld' lv_index ' FOR ' lv_table '-' v_fields-fieldname '.' INTO lv_line.
        PERFORM build_selection_program USING: lv_line.
    
        CONCATENATE 's_fld' lv_index INTO lv_selscr_key.
    
    *   Adds the name for the select-option into the text elements
        lv_textpool-id = 'S'.
        lv_textpool-key = lv_selscr_key.
        lv_textpool-entry = 'D'.                                     "means to get the name from the dictionary
        TRANSLATE lv_textpool-key TO UPPER CASE.              "#EC SYNTCHAR
        APPEND lv_textpool TO li_textpool.
    
      ENDLOOP.
    
    
    
      DATA:
        lv_file(130) TYPE c.
    
      CONCATENATE '''' p_file '''' INTO lv_file.
    
    
    * Open the file
      PERFORM build_selection_program USING: 'OPEN DATASET ', lv_file, ' FOR OUTPUT IN BINARY MODE.'.
    
    * insert the row headers
      CLEAR:
        lv_more_than_one.
    
      LOOP AT i_fields INTO v_fields WHERE download = 'X'.
        CLEAR:
          lv_line,
          lv_index.
    
        WRITE sy-tabix TO lv_index LEFT-JUSTIFIED.
    
        IF lv_more_than_one = 'X'.
          PERFORM build_selection_program USING: 'TRANSFER c_tab TO ', lv_file, '.'.
        ENDIF.
    
        CONCATENATE 'TRANSFER ''' v_fields-fieldname ''' TO ' INTO lv_line.
        PERFORM build_selection_program USING: lv_line, lv_file, '.'.
    
        lv_more_than_one = 'X'.
      ENDLOOP.
    
      PERFORM build_selection_program USING: 'TRANSFER c_linebreak TO ', lv_file, '.'.
    
    
    
    
    * Create the SELECT statement
      CLEAR: lv_line.
      CONCATENATE 'SELECT * FROM ' lv_table INTO lv_line.
      PERFORM build_selection_program USING: lv_line.
    
    
      READ TABLE i_fields INTO v_fields WITH KEY fieldname = 'MANDT' screen = 'X'.
      IF sy-subrc = 0.
    *   mandt is specified - the user will specify the system mandt to use
        PERFORM build_selection_program USING: 'CLIENT SPECIFIED INTO TABLE li_select_table PACKAGE SIZE 1000 WHERE'.
      ELSE.
    *   mandt is not specified - so use the system mandt
        PERFORM build_selection_program USING: 'INTO TABLE li_select_table PACKAGE SIZE 1000 WHERE'.
      ENDIF.
    
    
    * insert the select-options into the SELECT statement
      CLEAR:
        lv_more_than_one.
    
      LOOP AT i_fields INTO v_fields WHERE screen = 'X'.
        CLEAR:
          lv_line,
          lv_index.
    
        WRITE sy-tabix TO lv_index LEFT-JUSTIFIED.
    
        IF lv_more_than_one = 'X'.
          PERFORM build_selection_program USING: 'AND'.
        ENDIF.
    
        PERFORM build_selection_program USING: v_fields-fieldname.
        CONCATENATE 'IN s_fld' lv_index INTO lv_line.
        PERFORM build_selection_program USING: lv_line.
    
        lv_more_than_one = 'X'.
      ENDLOOP.
    
      PERFORM build_selection_program USING: '.'.  "dot at the end of the SELECT
    
    
    
    
    * loop over the data, appending to the file.
      PERFORM build_selection_program USING: 'LOOP AT li_select_table INTO lv_select_table.'.
    
    
    * insert the select-options into the output loop
      CLEAR:
        lv_more_than_one.
    
      LOOP AT i_fields INTO v_fields WHERE download = 'X'.
        CLEAR:
          lv_line,
          lv_index.
    
        WRITE sy-tabix TO lv_index LEFT-JUSTIFIED.
    
        IF lv_more_than_one = 'X'.
          PERFORM build_selection_program USING: 'TRANSFER c_tab TO ', lv_file, '.'.
        ENDIF.
    
        CONCATENATE 'WRITE: lv_select_table-' v_fields-fieldname INTO lv_line.
        PERFORM build_selection_program USING: lv_line, 'TO lv_field_char LEFT-JUSTIFIED.'.
        PERFORM build_selection_program USING: 'lv_offset = STRLEN( lv_field_char ).'.
        PERFORM build_selection_program USING: 'TRANSFER lv_field_char TO ', lv_file, ' LENGTH lv_offset.'.
    
        lv_more_than_one = 'X'.
      ENDLOOP.
    
      PERFORM build_selection_program USING: 'TRANSFER c_linebreak TO ', lv_file, '.'.
    
      PERFORM build_selection_program USING: 'ENDLOOP.'.
    
    
    * ENDSELECT because PACKAGE SIZZE was specified, creating a loop.
      PERFORM build_selection_program USING: 'ENDSELECT.'.
    
    
    
    * close the file
      PERFORM build_selection_program USING: 'CLOSE DATASET ', lv_file, '.'.
    
      PERFORM build_selection_program USING: 'WRITE: / ''Download has completed.''.'.
    
    
    
    
    * Save the report
      DELETE REPORT v_report_name.
      INSERT REPORT v_report_name FROM i_source.
    
      GENERATE REPORT v_report_name.
    
    * Save the text elements
      INSERT textpool v_report_name FROM li_textpool LANGUAGE sy-langu.
    
    * Run the report
      SUBMIT (v_report_name) VIA SELECTION-SCREEN AND RETURN.
    
    ENDFORM.                    "generate_selection_program
    
    
    
    ***********************************************************************************************************
    * FORM BUILD_SELECTION_PROGRAM
    ***********************************************************************************************************
    * [+] Adds the p_code text to the source code of the generated program
    ***********************************************************************************************************
    FORM build_selection_program
      USING
        p_code TYPE c.
    
      APPEND p_code TO i_source.
    
    ENDFORM.                    "build_selection_program
    
    
    
    ***********************************************************************************************************
    * FORM SELECT_ALL_SCREEN
    ***********************************************************************************************************
    * [+] Selects all the 'screen' checkboxes on the popup
    ***********************************************************************************************************
    FORM select_all_screen.
    
      LOOP AT i_fields INTO v_fields.
        v_fields-screen = 'X'.
        MODIFY i_fields FROM v_fields.
      ENDLOOP.
    
    ENDFORM.                    "select_all_screen
    
    
    
    ***********************************************************************************************************
    * FORM SELECT_ALL_DOWNLOAD
    ***********************************************************************************************************
    * [+] Selects all the 'download' checkboxes on the popup
    ***********************************************************************************************************
    FORM select_all_download.
    
      LOOP AT i_fields INTO v_fields.
        v_fields-download = 'X'.
        MODIFY i_fields FROM v_fields.
      ENDLOOP.
    
    ENDFORM.                    "select_all_download
    
    
    
    ***********************************************************************************************************
    * FORM SELECT_NONE_SCREEN
    ***********************************************************************************************************
    * [+] Deselects all the 'screen' checkboxes on the popup
    ***********************************************************************************************************
    FORM select_none_screen.
    
      LOOP AT i_fields INTO v_fields.
        v_fields-screen = ' '.
        MODIFY i_fields FROM v_fields.
      ENDLOOP.
    
    ENDFORM.                    "select_none_screen
    
    
    
    ***********************************************************************************************************
    * FORM SELECT_NONE_DOWNLOAD
    ***********************************************************************************************************
    * [+] Deselects all the 'download' checkboxes on the popup
    ***********************************************************************************************************
    FORM select_none_download.
    
      LOOP AT i_fields INTO v_fields.
        v_fields-download = ' '.
        MODIFY i_fields FROM v_fields.
      ENDLOOP.
    
    ENDFORM.                    "select_none_download
    
    
    
    ***********************************************************************************************************
    * MODULE SET_FIELDS_2000
    ***********************************************************************************************************
    * [+] Sets the field values on the popup
    ***********************************************************************************************************
    MODULE set_fields_2000 OUTPUT.                              "#EC NEEDED
    
    ENDMODULE.                 " set_fields_2000  OUTPUT
    
    
    
    ***********************************************************************************************************
    * MODULE SET_STATUS_2000
    ***********************************************************************************************************
    * [+] Sets the status of the popup, to alllow for function codes
    ***********************************************************************************************************
    MODULE set_status_2000 OUTPUT.
    
      SET PF-STATUS 'POPUP'.
    
    ENDMODULE.                 " set_status_2000  OUTPUT
    
    
    
    ***********************************************************************************************************
    * MODULE UPDATE_CHECKBOXES_2000
    ***********************************************************************************************************
    * [+] Saves the selected checkboxes from the popup back to the source table
    ***********************************************************************************************************
    MODULE update_checkboxes_2000 INPUT.
    
      DATA:
        lv_temp_fields LIKE v_fields.                           "#EC NEEDED
    
      IF v_ok_code = 'OK' OR v_ok_code = space.
    
        READ TABLE i_fields
              INTO lv_temp_fields
          WITH KEY fieldname = v_fields-fieldname.
    
        IF sy-subrc = 0.
          MODIFY i_fields FROM v_fields INDEX sy-tabix.
        ENDIF.
    
      ENDIF.
    
    ENDMODULE.                 " update_checkboxes_2000  INPUT
    
    
    
    ***********************************************************************************************************
    * MODULE PROCESS_BUTTONS_2000
    ***********************************************************************************************************
    * [+] Processes the function codes from the popup
    ***********************************************************************************************************
    MODULE process_buttons_2000 INPUT.
    
      DATA:
        lv_num_screen TYPE i,
        lv_ok_code LIKE v_ok_code.
    
      CLEAR:
        lv_num_screen.
    
      lv_ok_code = v_ok_code.
    
    
      IF NOT lv_ok_code IS INITIAL.
        CLEAR:
          v_ok_code.
    
        IF lv_ok_code = 'ALL_S'.
          PERFORM select_all_screen.
        ELSEIF lv_ok_code = 'ALL_D'.
          PERFORM select_all_download.
        ELSEIF lv_ok_code = 'NONE_S'.
          PERFORM select_none_screen.
        ELSEIF lv_ok_code = 'NONE_D'.
          PERFORM select_none_download.
        ELSEIF lv_ok_code = 'CLOSE'.
          v_back_to_start = 'X'.
          LEAVE TO SCREEN 0.
        ELSE.
    
    *   check not more than 40 SCREEN items selected
          LOOP AT i_fields INTO v_fields WHERE screen = 'X'.
            ADD 1 TO lv_num_screen.
          ENDLOOP.
    
          IF lv_num_screen > 40.
    *     popup - only allowed to have < 40.
            MESSAGE e034.
            EXIT.
          ELSEIF lv_num_screen = 0.
    *     popup - no screen items selected
            MESSAGE e036.
            EXIT.
          ENDIF.
    
          READ TABLE i_fields INTO v_fields WITH KEY download = 'X'.
          IF sy-subrc <> 0.
    *     popup - no download items selected
            MESSAGE e035.
            EXIT.
          ENDIF.
    
          LEAVE TO SCREEN 0.
    
        ENDIF.
    
      ENDIF.
    
    ENDMODULE.                 " process_buttons_2000  INPUT

    Runs the syntax checker on a number of programs in one go.

    *----------------------------------------------------------------------
    * Program Name: Z_SYNTAX_CHECKER
    * Author      : Michael 
    * Description : Performs a syntax check on the given objects, listing
    *               those with errors.
    *----------------------------------------------------------------------
    REPORT  Z_SYNTAX_CHECKER.
    
    tables: tdevc, tadir, trdir.
    
    select-options s_devc for tdevc-devclass.
    select-options s_prog for sy-cprog.
    
    data:
          lv_trdir like trdir.
    *--------------------------------------------------------*
    start-of-selection.
    
    perform syntax_check.
    
    form syntax_check.
      data:
         check_include like sy-repid,
         check_index   like sy-tabix,
         check_message(80) type c,
         check_offs    like sy-tabix,
         check_subrc like sy-subrc.
    
      data: fugr_name(8) type c value 'SAPLxxxx'.
    
      data: begin of content occurs 0,
            line(500) type c,
            end of content.
      data: wasanerror(1).
    
      wasanerror = '0'.
    
        select * from tadir where devclass in s_devc and
                                  obj_name in s_prog and
                                  ( object   eq 'PROG' or
                                    object   eq 'FUGR' )
                                    order by primary key.
          if tadir-object = 'FUGR'.
            move tadir-obj_name to fugr_name+4(4).
            move fugr_name      to tadir-obj_name.
          endif.
    
          select single * from trdir into lv_trdir where name eq tadir-obj_name.
    
          check sy-subrc eq 0.
          check lv_trdir-subc ne 'I'.         "Include??
          refresh content.
          read report lv_trdir-name into content.
          if sy-subrc = 0.
    
          call function 'EDITOR_SYNTAX_CHECK'
               exporting
                    i_global_check   = ' '
                    i_global_program = ' '
                    i_program        = lv_trdir-name
               importing
                    o_error_include  = check_include
                    o_error_line     = check_index
                    o_error_message  = check_message
                    o_error_offset   = check_offs
                    o_error_subrc    = check_subrc
               tables
                    i_source         = content.
    
          if check_subrc eq 0.
    *      no code
          else.
           write: lv_trdir-name, ',Error: ', check_message.
          endif.
    
         else.
           write: 'Program: ', lv_trdir-name, 'Error: ', check_message.
         endif.
    
        endselect.
    
    endform.

    A template program that runs a SmartForm and prints the output.

    REPORT z_smartform_template_print.
    
    DATA:
      v_control_params TYPE ssfctrlop,
      v_output_options TYPE ssfcompop,
      v_output_info    TYPE ssfcrescl.
    
    
    
    *---------------------------------------------------------------------*
    *       START-OF-SELECTION
    *---------------------------------------------------------------------*
    START-OF-SELECTION.
    
      CLEAR:
        v_output_info.
    
    
      PERFORM setup_smartform_for_print USING 'LOPC'.
    
      PERFORM run_smartform
        USING 'MYSMARTFORM'
          v_control_params
          v_output_options
        CHANGING
          v_output_info.
    
    
    
    *---------------------------------------------------------------------*
    *       FORM setup_smartform_for_print
    *---------------------------------------------------------------------*
    * [+] Sets the parameters for PDF conversions
    *---------------------------------------------------------------------*
    FORM setup_smartform_for_print
      USING
        p_printr TYPE rspopname.
    
      CLEAR:
        v_control_params,
        v_output_options.
    
      v_output_options-tddest     = p_printr.
      v_output_options-tdprinter  = 'SAPWIN'.
      v_output_options-tdnewid    = 'X'.
      v_output_options-tdimmed    = 'X'.
      v_output_options-tddelete   = 'X'.
      v_output_options-tdlifetime = 1.
      v_output_options-tdfinal    = 'X'.
    
      v_control_params-device     = 'PRINTER'.
    
    ENDFORM.                    "setup_smartform_for_print
    
    
    
    *---------------------------------------------------------------------*
    *       FORM run_smartform
    *---------------------------------------------------------------------*
    * [+] Runs the SmartForm of the given name
    *---------------------------------------------------------------------*
    FORM run_smartform
      USING
        p_form_name TYPE c
        p_control_params TYPE ssfctrlop
        p_output_options TYPE ssfcompop
      CHANGING
        p_output_info TYPE ssfcrescl.
    
      DATA:
        lv_function_name TYPE rs38l_fnam.
    
    * Find the SmartForm function module name
      CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
        EXPORTING
          formname           = p_form_name
        IMPORTING
          fm_name            = lv_function_name
        EXCEPTIONS
          no_form            = 1
          no_function_module = 2
          OTHERS             = 99.
    
      IF sy-subrc <> 0.
        EXIT.
      ENDIF.
    
    * Run the SmartForm function module
      CALL FUNCTION p_form_name
        EXPORTING
          control_parameters = p_control_params
          output_options     = p_output_options
          user_settings      = ' '
        IMPORTING
          job_output_info    = p_output_info
        EXCEPTIONS
          formatting_error   = 1
          internal_error     = 2
          send_error         = 3
          user_canceled      = 4
          OTHERS             = 99.
    
    ENDFORM.                    "run_smartform

    SmartForm PDF Generator

    REPORT z_smartform_template_pdf.
    
    DATA:
      v_control_params TYPE ssfctrlop,
      v_output_options TYPE ssfcompop,
      v_output_info    TYPE ssfcrescl.
    
    DATA:
      i_pdf_data TYPE tline_t.
    
    DATA:
      v_spool_id  TYPE rspoid,
      v_num_bytes TYPE i,
      v_filename  TYPE string  VALUE 'filename.pdf'.
    
    
    *---------------------------------------------------------------------*
    *       START-OF-SELECTION
    *---------------------------------------------------------------------*
    START-OF-SELECTION.
    
      CLEAR:
        v_output_info,
        i_pdf_data.
    
      REFRESH:
        i_pdf_data.
    
    
      PERFORM setup_smartform_for_pdf.
    
      PERFORM run_smartform
        USING 'MYSMARTFORM'
          v_control_params
          v_output_options
        CHANGING
          v_output_info.
    
      LOOP AT v_output_info-spoolids INTO v_spool_id.
    
    *     Convert the spool to a PDF document
        PERFORM convert_otf_spool_to_pdf
          USING
            v_spool_id
          CHANGING
            v_num_bytes
            i_pdf_data.
    
    
    *     Downloading the PDF document to the local PC
        PERFORM download_pdf_to_file
          USING
            v_num_bytes
            v_filename
            i_pdf_data.
    
      ENDLOOP.
    
    
    
    *---------------------------------------------------------------------*
    *       FORM setup_smartform_for_pdf
    *---------------------------------------------------------------------*
    * [+] Sets the parameters for PDF conversions
    *---------------------------------------------------------------------*
    FORM setup_smartform_for_pdf.
    
      CLEAR:
        v_control_params,
        v_output_options.
    
      v_output_options-tddest     = 'LOCP'.
      v_output_options-tdprinter  = 'SAPWIN'.
      v_output_options-tdnewid    = 'X'.
      v_output_options-tdimmed    = space.
      v_output_options-tddelete   = 'X'.
      v_output_options-tdlifetime = 1.
      v_output_options-tdfinal    = 'X'.
    
      v_control_params-no_dialog  = 'X'.
      v_control_params-device     = 'PRINTER'.
    
    ENDFORM.                    "setup_smartform_for_pdf
    
    
    *---------------------------------------------------------------------*
    *       FORM run_smartform
    *---------------------------------------------------------------------*
    * [+] Runs the SmartForm of the given name
    *---------------------------------------------------------------------*
    FORM run_smartform
      USING
        p_form_name TYPE c
        p_control_params TYPE ssfctrlop
        p_output_options TYPE ssfcompop
      CHANGING
        p_output_info TYPE ssfcrescl.
    
      DATA:
        lv_function_name TYPE rs38l_fnam.
    
    * Find the SmartForm function module name
      CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
        EXPORTING
          formname           = p_form_name
        IMPORTING
          fm_name            = lv_function_name
        EXCEPTIONS
          no_form            = 1
          no_function_module = 2
          OTHERS             = 99.
    
      IF sy-subrc <> 0.
        EXIT.
      ENDIF.
    
    * Run the SmartForm function module
      CALL FUNCTION p_form_name
        EXPORTING
          control_parameters = p_control_params
          output_options     = p_output_options
          user_settings      = ' '
        IMPORTING
          job_output_info    = p_output_info
        EXCEPTIONS
          formatting_error   = 1
          internal_error     = 2
          send_error         = 3
          user_canceled      = 4
          OTHERS             = 99.
    
    ENDFORM.                    "run_smartform
    
    
    
    *----------------------------------------------------------------------*
    *       FORM convert_otf_spool_to_pdf
    *----------------------------------------------------------------------*
    * [+] Converts a OTF spool document to a PDF data stream
    *----------------------------------------------------------------------*
    FORM convert_otf_spool_to_pdf
      USING
        p_spool_id  TYPE rspoid                   " spool id number
      CHANGING
        p_num_bytes TYPE i                        " no. of bytes in output
        p_pdf       TYPE tline_t. " the output
    
    * Write the spooled report to a PDF file
      CALL FUNCTION 'CONVERT_OTFSPOOLJOB_2_PDF'
        EXPORTING
          src_spoolid   = p_spool_id
          no_dialog     = ' '
        IMPORTING
          pdf_bytecount = p_num_bytes
        TABLES
          pdf           = p_pdf
        EXCEPTIONS
          OTHERS        = 99.
    
    ENDFORM.                    "convert_otf_spool_to_pdf
    
    
    
    *----------------------------------------------------------------------*
    *       FORM download_pdf_to_file
    *----------------------------------------------------------------------*
    * [+] Downloads PDF data (TLINE) to a local file
    *----------------------------------------------------------------------*
    FORM download_pdf_to_file
      USING
        p_num_bytes TYPE i
        p_filename  TYPE string
        p_data      TYPE tline_t.
    
      DATA:
        lv_append TYPE xfeld.
    
    * Download the PDF data to a file on the users' computer
      CALL METHOD cl_gui_frontend_services=>gui_download
        EXPORTING
          bin_filesize = p_num_bytes
          filename     = p_filename
          filetype     = 'BIN'
          append       = lv_append
        CHANGING
          data_tab     = p_data
        EXCEPTIONS
          OTHERS       = 99.
    
    ENDFORM.                    "download_pdf_to_file

    SmartForm Displaying/Previewing

     

    “A template program for running a SmartForm and previewing it. The previewing is done separate to the standard previewing, so “that you can have control over the pages separately. Includes the following functionality...
    Generate a SmartForm output
    Display and navigate between pages
    Can do your own manipulation of the output prior to display

    REPORT z_smartform_template_display.
    
    DATA:
      v_control_params TYPE ssfctrlop,
      v_output_options TYPE ssfcompop,
      v_output_info    TYPE ssfcrescl.
    
    
    * OTF Data for previewing
    DATA:
      i_otf TYPE tsfotf,
      v_otf LIKE LINE OF i_otf.
    
    * A single page
    DATA:
      v_preview_page TYPE itcoo,
      i_preview_page TYPE STANDARD TABLE OF itcoo.
    
    DATA:
      BEGIN OF i_gui_preview OCCURS 0.
            INCLUDE STRUCTURE itcoo.
    DATA:
      END OF i_gui_preview.
    
    * Bitmaps used in the preview
    TYPES:
      BEGIN OF t_bitmaps,
        bm_index      LIKE sy-tabix, " Index in Table OTF
        bm_doc_id(42) TYPE c,        " DOC-ID of the Bitmap
      END OF t_bitmaps.
    
    DATA:
      v_bitmaps TYPE t_bitmaps,
      i_bitmaps TYPE STANDARD TABLE OF t_bitmaps.
    
    
    * details about the preview
    TYPES:
      BEGIN OF t_preview_info,
        curr_pag LIKE ssfpp-tdpages, " Page Number
        op_index LIKE sy-tabix,      " Index in Table OTF
      END OF t_preview_info.
    
    DATA:
      v_preview_info TYPE t_preview_info,
      i_preview_info TYPE STANDARD TABLE OF t_preview_info.
    
    
    *---------------------------------------------------------------------*
    *       START-OF-SELECTION
    *---------------------------------------------------------------------*
    START-OF-SELECTION.
    
      CLEAR:
        v_output_info.
    
    
      PERFORM setup_smartform_for_display.
    
      PERFORM run_smartform
        USING 'MYSMARTFORM'
          v_control_params
          v_output_options
        CHANGING
          v_output_info.
    
    *   Retrieve the generated output
      i_otf = v_output_info-otfdata.
    
    *   prepare the data for previewing.
      PERFORM load_preview_bitmaps.
      PERFORM get_preview_page_count.
    
    *   Loads page 1 of the preview
      PERFORM show_preview_page
        USING
          1.
    
    
    
    *---------------------------------------------------------------------*
    *       FORM setup_smartform_for_display
    *---------------------------------------------------------------------*
    * [+] Sets the parameters for PDF conversions
    *---------------------------------------------------------------------*
    FORM setup_smartform_for_display.
    
      CLEAR:
        v_control_params,
        v_output_options.
    
      v_output_options-tddest     = 'LOCP'.
      v_output_options-tdprinter  = 'SAPWIN'.
      v_output_options-tdnewid    = 'X'.
      v_output_options-tdimmed    = space.
      v_output_options-tddelete   = 'X'.
      v_output_options-tdlifetime = 1.
      v_output_options-tdfinal    = 'X'.
    
      v_control_params-no_dialog  = 'X'.
      v_control_params-device     = 'PRINTER'.
      v_control_params-preview    = 'X'.
      v_control_params-getotf     = 'X'.
    
    ENDFORM.                    "setup_smartform_for_display
    
    
    *---------------------------------------------------------------------*
    *       FORM run_smartform
    *---------------------------------------------------------------------*
    * [+] Runs the SmartForm of the given name
    *---------------------------------------------------------------------*
    FORM run_smartform
      USING
        p_form_name TYPE c
        p_control_params TYPE ssfctrlop
        p_output_options TYPE ssfcompop
      CHANGING
        p_output_info TYPE ssfcrescl.
    
      DATA:
        lv_function_name TYPE rs38l_fnam.
    
    * Find the SmartForm function module name
      CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
        EXPORTING
          formname           = p_form_name
        IMPORTING
          fm_name            = lv_function_name
        EXCEPTIONS
          no_form            = 1
          no_function_module = 2
          OTHERS             = 99.
    
      IF sy-subrc <> 0.
        EXIT.
      ENDIF.
    
    * Run the SmartForm function module
      CALL FUNCTION p_form_name
        EXPORTING
          control_parameters = p_control_params
          output_options     = p_output_options
          user_settings      = ' '
        IMPORTING
          job_output_info    = p_output_info
        EXCEPTIONS
          formatting_error   = 1
          internal_error     = 2
          send_error         = 3
          user_canceled      = 4
          OTHERS             = 99.
    
    ENDFORM.                    "run_smartform
    
    
    
    *----------------------------------------------------------------------
    *       FORM load_preview_bitmaps
    *----------------------------------------------------------------------
    * [+] Prepares the bitmap images used in the print preview
    *----------------------------------------------------------------------
    FORM load_preview_bitmaps.
    
      CLEAR:
        v_bitmaps,
        i_bitmaps.
    
      LOOP AT i_otf
         INTO v_otf
        WHERE tdprintcom = 'BM'.
    
        IF v_otf-tdprintpar+11(1) = 'D'.
          v_bitmaps-bm_index  = sy-tabix.
          v_bitmaps-bm_doc_id = v_otf-tdprintpar+16(42).
          APPEND v_bitmaps TO i_bitmaps.
        ENDIF.
    
      ENDLOOP.
    
    ENDFORM.                    "load_preview_bitmaps
    
    
    *----------------------------------------------------------------------
    *       FORM get_preview_page_count
    *----------------------------------------------------------------------
    * [+] Gets the number of pages in this preview.
    * [+] Sets up the i_preview_info
    *----------------------------------------------------------------------
    FORM get_preview_page_count.
    
    * Internal variables
      DATA:
        lv_pages LIKE ssfpp-tdpages.
    
    * Clear variables
      CLEAR:
        lv_pages,
        v_preview_info,
        i_preview_info.
    
      REFRESH:
        i_preview_info.
    
      LOOP AT i_otf
         INTO v_otf
        WHERE tdprintcom = 'OP'. "Open Page
    
        v_preview_info-op_index = sy-tabix.
        ADD 1 TO lv_pages.
        v_preview_info-curr_pag = lv_pages.
    
        APPEND v_preview_info TO i_preview_info.
    
      ENDLOOP.
    
      CLEAR:
        v_preview_info.
    
    ENDFORM.                    "get_preview_page_count
    
    
    
    *----------------------------------------------------------------------
    *       FORM show_preview_page
    *----------------------------------------------------------------------
    * [+] Loads the given page number in the preview
    *----------------------------------------------------------------------
    FORM show_preview_page
      USING
        p_page_number TYPE txpagenr.
    
    * Internal variables
      DATA:
        lv_current_index LIKE sy-tabix.
    
    * Clear variables
      CLEAR:
        v_preview_page,
        i_preview_page.
    
      REFRESH
        i_preview_page.
    
    
    
      CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
        EXPORTING
          percentage = 25
          text       = 'Please wait...'.
    
    
    
    * already on the correct page
      CHECK v_preview_info-curr_pag <> p_page_number.
    
    
      READ TABLE i_preview_info
            INTO v_preview_info
           INDEX p_page_number.
    
      CHECK sy-subrc = 0.
    
    * preview header data
      v_preview_page-tdprintcom = '//'.
      APPEND v_preview_page TO i_preview_page.
    
    * preview page data
      lv_current_index = v_preview_info-op_index.
    
      DO.
        READ TABLE i_otf
              INTO v_otf
             INDEX lv_current_index.
    
        IF sy-subrc <> 0.
          EXIT.
        ENDIF.
    
        v_preview_page = v_otf.
    
        CASE v_preview_page-tdprintcom.
          WHEN 'RD'. "Raw Data
            APPEND v_preview_page TO i_preview_page.
          WHEN 'EP'. "Close Page
            APPEND v_preview_page TO i_preview_page.
            EXIT.
          WHEN OTHERS.
            APPEND v_preview_page TO i_preview_page.
        ENDCASE.
    
        ADD 1 TO lv_current_index.
      ENDDO.
    
    ENDFORM.                    "show_preview_page
    
    
    *----------------------------------------------------------------------
    *       FORM show_next_page
    *----------------------------------------------------------------------
    * [+] Shows the next page
    *----------------------------------------------------------------------
    FORM show_next_page.
      DATA: lv_page_number TYPE txpagenr,
            lv_last_page   TYPE i.
    
      lv_page_number = v_preview_info-curr_pag.
      ADD 1 TO lv_page_number.
    
      DESCRIBE TABLE i_preview_info LINES lv_last_page.
    
      IF lv_page_number > lv_last_page.
        lv_page_number = lv_last_page.
      ENDIF.
    
    
      IF lv_page_number <> v_preview_info-curr_pag.
    
        PERFORM show_preview_page
          USING
            lv_page_number.
    
      ENDIF.
    
    ENDFORM.                    "show_next_page
    
    
    
    *----------------------------------------------------------------------
    *       FORM show_previous_page
    *----------------------------------------------------------------------
    * [+] Shows the previous page
    *----------------------------------------------------------------------
    FORM show_previous_page.
      DATA: lv_page_number TYPE txpagenr.
    
      lv_page_number = v_preview_info-curr_pag.
      SUBTRACT 1 FROM lv_page_number.
    
      IF lv_page_number <= 0.
        lv_page_number = 1.
      ENDIF.
    
      IF lv_page_number <> v_preview_info-curr_pag.
    
        PERFORM show_preview_page
          USING
            lv_page_number.
    
      ENDIF.
    
    ENDFORM.                    "show_previous_page
    
    
    
    *----------------------------------------------------------------------
    *       FORM show_first_page
    *----------------------------------------------------------------------
    * [+] Shows the first page
    *----------------------------------------------------------------------
    FORM show_first_page.
      DATA: lv_page_number TYPE txpagenr.
    
      lv_page_number = 1.
    
      IF lv_page_number <> v_preview_info-curr_pag.
    
        PERFORM show_preview_page
          USING
            lv_page_number.
    
      ENDIF.
    
    ENDFORM.                    "show_first_page
    
    
    
    *----------------------------------------------------------------------
    *       FORM show_last_page
    *----------------------------------------------------------------------
    * [+] Shows the first page
    *----------------------------------------------------------------------
    FORM show_last_page.
      DATA: lv_page_number TYPE txpagenr.
    
      DESCRIBE TABLE i_preview_info LINES lv_page_number.
    
      IF lv_page_number <> v_preview_info-curr_pag.
    
        PERFORM show_preview_page
          USING
            lv_page_number.
    
      ENDIF.
    
    ENDFORM.                    "show_last_page
    
    
    *----------------------------------------------------------------------
    *       MODULE display_preview
    *----------------------------------------------------------------------
    * [+] Prepares the print preview for being displayed
    *
    *   THIS SHOULD BE PUT IN THE "PROCESS BEFORE OUTPUT" OF THE SCREEN
    *
    *----------------------------------------------------------------------
    MODULE display_preview OUTPUT.
    
      CALL FUNCTION 'PREPARE_OTF_FOR_GUI_PREVIEWER'
        EXPORTING
          otf_raw         = i_preview_page[]
          defined_bitmaps = i_bitmaps[]
        IMPORTING
          otf_preview     = i_gui_preview[]
        TABLES
          otf             = i_otf[]
        EXCEPTIONS
          OTHERS          = 0.
    
    * show the preview
      CALL 'C_TRADR'  ID 'OUTTAB' FIELD i_gui_preview[]
                      ID 'APPL'   FIELD 'SCRIPT'.
    
    ENDMODULE.                    "display_preview OUTPUT

    Sets the range for a select-option

    *----------------------------------------------------------------------*
    *       FORM set_range
    *----------------------------------------------------------------------*
    * [+] Sets the range for a select-option
    *----------------------------------------------------------------------*
    FORM set_range
      USING
        p_high TYPE RSDSSELOP_
        p_low TYPE RSDSSELOP_
      CHANGING
        p_selopt TYPE RSELOPTION.
    
      DATA:
        lv_single_opt LIKE LINE OF p_selopt.
    
      CLEAR:
        lv_single_opt,
         p_selopt.
    
      REFRESH:
         p_selopt.
    
      lv_single_opt-high = p_high.
      lv_single_opt-low  = p_low.
    
      APPEND lv_single_opt TO  p_selopt.
    
    ENDFORM.

    A Form that sends a email with a message and attachments.

    *----------------------------------------------------------------------*
    * Data and types for send_email
    *----------------------------------------------------------------------*
    * raw data for attachment
    TYPES:
      BEGIN OF t_data,
        lifnr TYPE elifn,
        name1 TYPE name1_gp,
      END OF t_data.
    
    DATA:
      i_data TYPE STANDARD TABLE OF t_data,
      v_data TYPE t_data.
    
    * attachment details and formatted data
    TYPES:
      BEGIN OF t_attach_file,
        file_name TYPE so_obj_des,
        file_ext  TYPE so_obj_tp,
        attach    TYPE soli_tab,
      END OF t_attach_file,
    
      ti_attach_file TYPE STANDARD TABLE OF t_attach_file.
    
    * receivers table
    TYPES:
      BEGIN OF t_email_address,
        address TYPE ad_smtpadr,
      END OF t_email_address,
    
      ti_email_address TYPE STANDARD TABLE OF t_email_address.
    
    
    
    *----------------------------------------------------------------------*
    *       FORM send_email
    *----------------------------------------------------------------------*
    * [+] Sends an email with a message and attachment
    *----------------------------------------------------------------------*
    FORM send_email
      USING
        p_email TYPE ad_smtpadr.
    
    
      CONSTANTS:
        c_subject TYPE so_obj_des VALUE 'Email Subject',
        c_tab(1)       TYPE x VALUE '09',
        c_linebreak(2) TYPE x VALUE '0D0A',
        c_filename(50) TYPE c VALUE 'file_attachment_01',
        c_txt(3)       TYPE c VALUE 'txt'.
    
      DATA:
        li_message_body    TYPE STANDARD TABLE OF soli,
        lv_message_body    LIKE LINE OF li_message_body,
        li_attachment_data TYPE STANDARD TABLE OF soli,
        lv_attachment_data LIKE LINE OF li_attachment_data,
    
        lv_email_data    TYPE t_attach_file,
        li_email_data    TYPE ti_attach_file,
        li_email_address TYPE ti_email_address.
    
    
    
    * Build the email body message
      CLEAR: lv_message_body.
      MOVE 'This is line 1'
        TO lv_message_body.
      APPEND lv_message_body TO li_message_body.
    
      CLEAR: lv_message_body.
      CONCATENATE
          'This Is'
          'Line 2'
        INTO
          lv_message_body SEPARATED BY space.
      APPEND lv_message_body TO li_message_body.
    
      CLEAR: lv_message_body.
      MOVE 'This is line 3'
        TO lv_message_body.
      APPEND lv_message_body TO li_message_body.
    
    
    
    * setting up attachment name
      MOVE:
        c_filename TO lv_email_data-file_name,
        c_txt      TO lv_email_data-file_ext.
    
    
    
    * Build the attachment (text file)
    
    * Column headings as first row
      CLEAR: lv_attachment_data.
      CONCATENATE
          'Vendor'
          'Name'
        INTO
          lv_attachment_data SEPARATED BY c_tab.
      APPEND lv_attachment_data TO li_attachment_data.
    
    * Extracting table data into remaining rows
      LOOP AT i_data INTO v_data.
        CLEAR: lv_attachment_data.
        CONCATENATE
            v_data-lifnr
            v_data-name1
          INTO
            lv_attachment_data SEPARATED BY c_tab.
    *   add the line break
        CONCATENATE
            c_linebreak
            lv_attachment_data
          INTO
            lv_attachment_data.
        APPEND lv_attachment_data TO li_attachment_data.
      ENDLOOP.
    
      MOVE li_attachment_data TO lv_email_data-attach.
      APPEND lv_email_data TO li_email_data.
      CLEAR: lv_email_data.
    
    
    * build email address table
      APPEND p_email TO li_email_address.
    
    
    * Send the email
      PERFORM send_mail_api
        USING
          li_message_body
          c_subject
          li_email_address
          li_email_data.
    
    ENDFORM.
    
    
    
    *----------------------------------------------------------------------*
    *       FORM send_mail_api
    *----------------------------------------------------------------------*
    * [+] Generic email sending
    *----------------------------------------------------------------------*
    FORM send_mail_api
      USING
        p_message_body    TYPE soli_tab
        p_message_subject TYPE sood1-objdes
        p_recipient_email TYPE ti_email_address
        p_attachment      TYPE ti_attach_file.
    
    
    *** CONSTANTS ***
      CONSTANTS:
        c_rt_internet TYPE soos1-recesc VALUE 'U'. "internet mail
    
    *** DATA ***
      DATA:
        lv_tab_lines  TYPE sy-tabix,
        lv_obj_descr  TYPE sodocchgi1-obj_descr,
        lv_head_start TYPE sytabix,
        lv_body_start TYPE sytabix.
    
    *** STRUCTURES ***
      DATA:
        lv_objpack         TYPE sopcklsti1,
        lv_objhead         TYPE solisti1,
        lv_objbin          TYPE solisti1,
        lv_objtxt          TYPE solisti1,
        lv_reclist         TYPE somlreci1,
        lv_recipients      TYPE somlreci1,
        lv_doc_chng        TYPE sodocchgi1,
        lv_attachment      TYPE t_attach_file,
        lv_recipient_email TYPE t_email_address.
    
    *** INTERNAL TABLES ***
      DATA:
        li_objpack TYPE TABLE OF sopcklsti1,
        li_objhead TYPE TABLE OF solisti1,
        li_objbin  TYPE TABLE OF solisti1,
        li_objtxt  TYPE TABLE OF solisti1,
        li_objhex  TYPE TABLE OF solix,
        li_reclist TYPE TABLE OF somlreci1.
    
    
    *** Build the message body
      MOVE p_message_body TO li_objtxt.
    
      DESCRIBE TABLE li_objtxt LINES lv_tab_lines.
      READ TABLE li_objtxt INTO lv_objtxt INDEX lv_tab_lines.
      lv_doc_chng-doc_size = ( lv_tab_lines - 1 ) * 255
                             + STRLEN( lv_objtxt ).
    
    
      MOVE p_message_subject TO lv_doc_chng-obj_descr.
      CONDENSE lv_doc_chng-obj_descr.
    
    * creation of the message
      CLEAR lv_objpack-transf_bin.
    
      lv_objpack-head_start = 1.
      lv_objpack-head_num = 0.
      lv_objpack-body_start = 1.
      lv_objpack-doc_type = 'RAW'.
    
      DESCRIBE TABLE li_objtxt LINES lv_objpack-body_num.
    
      APPEND lv_objpack TO li_objpack.
      CLEAR lv_objpack.
    
    
    *** Build the attachments
      LOOP AT p_attachment INTO lv_attachment.
    
        DESCRIBE TABLE lv_attachment-attach LINES lv_tab_lines.
        DESCRIBE TABLE li_objhex            LINES lv_body_start.
        DESCRIBE TABLE li_objhead           LINES lv_head_start.
    
        ADD 1 TO lv_head_start.
        ADD 1 TO lv_body_start.
    
        lv_objpack-transf_bin = 'X'.
        lv_objpack-head_start = lv_head_start.
        lv_objpack-head_num   = 1.
        lv_objpack-body_start = lv_body_start.
        lv_objpack-body_num   = lv_tab_lines.
        lv_objpack-doc_type   = lv_attachment-file_ext.
        lv_objpack-obj_name   = lv_attachment-file_ext.
    
        CONCATENATE
            lv_attachment-file_name
            '.'
            lv_attachment-file_ext
          INTO
            lv_obj_descr.
    
        lv_objpack-obj_descr = lv_obj_descr.
        lv_objpack-doc_size  = lv_tab_lines * 255.
    
        APPEND lv_objpack TO li_objpack.
        CLEAR  lv_objpack.
    
    *   creation of the document attachment
        APPEND LINES OF lv_attachment-attach TO li_objhex.
    
    *   build file information into header
        MOVE lv_obj_descr TO lv_objhead.
        APPEND lv_objhead TO li_objhead.
    
        CLEAR: lv_objhead.
        CLEAR: lv_tab_lines.
    
      ENDLOOP.
    
    
    *** Build recipients
      IF p_recipient_email IS INITIAL.
        EXIT.
      ENDIF.
    
    
    * build recipients table
      LOOP AT p_recipient_email INTO lv_recipient_email.
        CLEAR lv_reclist.
    
        lv_reclist-rec_type = c_rt_internet.
        lv_reclist-receiver = lv_recipient_email-address.
    
        APPEND lv_reclist TO li_reclist .
      ENDLOOP.
    
    
    *** Send the email
      CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
           EXPORTING
                document_data              = lv_doc_chng
                put_in_outbox              = 'X'
           TABLES
                packing_list               = li_objpack
                object_header              = li_objhead
                contents_bin               = li_objbin
                contents_txt               = li_objtxt
                contents_hex               = li_objhex
                receivers                  = li_reclist
           EXCEPTIONS
                OTHERS                     = 99.
    
    ENDFORM.

    Sends a regular email (ie. no attachments, only a message)

    *----------------------------------------------------------------------*
    *       FORM send_basic_email
    *----------------------------------------------------------------------*
    * [+] Sends a regular email (ie. no attachments, only a message)
    *----------------------------------------------------------------------*
    FORM send_basic_email
      USING
        p_email   TYPE ad_smtpadr
        p_message TYPE STANDARD TABLE OF char255.
    
      DATA:
        lv_pack_list     TYPE sopcklsti1,
        li_pack_list     TYPE STANDARD TABLE OF sopcklsti1,
        lv_receivers     TYPE somlreci1,
        li_receivers     TYPE STANDARD TABLE OF somlreci1,
        lv_email_details TYPE sodocchgi1.
    
      CLEAR:
        lv_pack_list,
        li_pack_list,
        lv_receivers,
        li_receivers,
        lv_email_details.
    
      REFRESH:
        li_pack_list,
        li_receivers.
    
    
    * Setup the email details
      lv_email_details-obj_name  = 'My Email'.
      lv_email_details-obj_descr = 'My really cool email'.
      lv_email_details-obj_langu = 'E'.
    
    * Describe the email contents
      DESCRIBE TABLE p_message LINES lv_pack_list-body_num.
    
      lv_pack_list-head_start = 1.
      lv_pack_list-head_num   = 0.
      lv_pack_list-body_start = 1.
      lv_pack_list-doc_type   = 'RAW'.
      APPEND lv_pack_list TO li_pack_list.
    
    * Create receiver list
      lv_receivers-receiver = p_email.
      lv_receivers-rec_type = 'U'.
      lv_receivers-com_type = 'INT'.
      APPEND lv_receivers TO li_receivers.
    
    
    * Send the email
      CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
        EXPORTING
          document_data              = lv_email_details
          put_in_outbox              = 'X'
        TABLES
          packing_list               = li_pack_list
          contents_txt               = p_message
          receivers                  = li_receivers
        EXCEPTIONS
          OTHERS                     = 99.
    
      IF sy-subrc <> 0.
        EXIT.
      ENDIF.
    
    ENDFORM.

    CONVERT_SECONDS_TO_TIMESTAMP

    *---------------------------------------------------------------------*
    *       FORM CONVERT_SECONDS_TO_TIMESTAMP
    *---------------------------------------------------------------------*
    * [+] Converts a number of seconds into a timestamp HH:MM:SS
    *---------------------------------------------------------------------*
    FORM convert_seconds_to_timestamp
      USING
        value(p_number) TYPE i
      CHANGING
        p_time TYPE c.
    
    
      DATA:
        lv_hours(2)   TYPE n,
        lv_minutes(2) TYPE n,
        lv_seconds(2) TYPE n.
    
    
      lv_hours = p_number DIV 3600.
      lv_minutes = ( p_number - ( lv_hours * 3600 ) ) DIV 60.
      lv_seconds = p_number - ( lv_hours * 3600 ) - ( lv_minutes * 60 ).
    
      CONCATENATE lv_hours ':' lv_minutes ':' lv_seconds INTO p_time.
    
    ENDFORM.                    "convert_seconds_to_timestamp

    Right-aligns the text in the character field

    *----------------------------------------------------------------------*
    *       FORM RIGHT_ALIGN
    *----------------------------------------------------------------------*
    * [+] Right-aligns the text in the character field
    *----------------------------------------------------------------------*
    FORM right_align
      USING
        p_padding_char TYPE c
      CHANGING
        p_text TYPE c.
    
      DATA:
        lv_text_length  TYPE i,
        lv_field_length TYPE i,
        lv_remaining    TYPE i.
    
      lv_text_length = strlen( p_text ).
      DESCRIBE FIELD p_text LENGTH lv_field_length.
    
      lv_remaining = lv_field_length - lv_text_length.
      if lv_remaining = 0.
        exit.
      endif.
    
      WRITE p_text TO p_text+lv_remaining.
    
      SUBTRACT 1 FROM lv_remaining.
    
      WHILE lv_remaining >= 0.
        WRITE p_padding_char TO p_text+lv_remaining(1).
        SUBTRACT 1 FROM lv_remaining.
      ENDWHILE.
    
    ENDFORM.

    Removes the zeros from the left of the field

    *----------------------------------------------------------------------*
    *       FORM REMOVE_ZEROS
    *----------------------------------------------------------------------*
    * [+] Removes the zeros from the left of the field
    *----------------------------------------------------------------------*
    FORM remove_zeros
      CHANGING
        p_text TYPE c.
    
      DATA:
        lv_field_length TYPE i,
        lv_copy_length  TYPE i.
    
      DESCRIBE FIELD p_text LENGTH lv_field_length.
    
      lv_copy_length = lv_field_length - 1.
    
      WHILE p_text(1) = '0'.
        WRITE p_text+1(lv_copy_length) TO p_text+0(lv_field_length).
      ENDWHILE.
    
    ENDFORM.

    Removes the editor locks for the given objects

    *----------------------------------------------------------------------
    * Program Name: Z_REMOVE_EDITOR_LOCK
    * Author      : Michael 
    * Description : Removes the editor locks for the given objects
    *----------------------------------------------------------------------
    REPORT  Z_REMOVE_EDITOR_LOCK.
    
    TABLES: trdir.
    
    SELECT-OPTIONS: PROG FOR trdir-NAME.
    
    UPDATE PROGDIR SET EDTX = SPACE
           WHERE NAME IN PROG.
    
    WRITE: 'Reset ok when number 0 appears ->', SYST-SUBRC.