본문 바로가기
ABAP/소스코드

[Report] 소스코드 작성하여 바로 실행(YDIRECT_EXEC)

by name_text 2024. 10. 24.

소스코드 작성하여 바로 실행

GENERATE SUBROUTINE POOL

 

 

간단한 소스코드를 작성하여 바로 실행(Execute)할 수 있는 리포트 프로그램입니다.

메모리상에 서브루틴을 만들어 바로 실행하는 방식으로 운영 환경에서 긴급으로 무언가를 하려할때 아주 요긴하게 사용됩니다.

# 소스코드

REPORT YDIRECT_EXEC LINE-SIZE 270  NO STANDARD PAGE HEADING.

TYPES: BEGIN OF t_source,
         line(256),
       END OF t_source.

DATA: gt_source         TYPE STANDARD TABLE OF t_source,
      gt_program        TYPE STANDARD TABLE OF t_source,
      gv_cursor(50)     TYPE c,
      gv_editor_visible TYPE abap_bool,
      go_editor         TYPE REF TO cl_gui_abapedit,
      go_source         TYPE REF TO cl_wb_source,
      go_wbeditor       TYPE REF TO cl_wb_editor.
DATA: gt_functionkeys    TYPE STANDARD TABLE OF  rsmpe_keys,
      gt_menu_tree       TYPE STANDARD TABLE OF rsmpe_tree,
      gt_ecomm           TYPE STANDARD TABLE OF sy-ucomm,
      gt_ecomm_only_show TYPE STANDARD TABLE OF sy-ucomm.

CONSTANTS: gc_formname(20) TYPE c VALUE 'EXEC_FORM'.

CONSTANTS: BEGIN OF gc_status_bar,
             program TYPE trdir-name VALUE 'SAPLS38E',
             status  TYPE gui_status VALUE 'WB_WITH_TOOL_PC',
             title   TYPE gui_title VALUE 'WB_TITLE',
           END OF gc_status_bar.

INITIALIZATION.
  CALL FUNCTION 'RS_CUA_GET_STATUS'
    EXPORTING
      program           = gc_status_bar-program
      status            = gc_status_bar-status
    TABLES
      menutree          = gt_menu_tree
      functionkeys      = gt_functionkeys
    EXCEPTIONS
      not_found_program = 1
      not_found_status  = 2
      recursive_menues  = 3
      empty_list        = 4
      not_found_menu    = 5
      OTHERS            = 6.
  IF sy-subrc <> 0.
*Implement suitable error handling here
  ENDIF.

  gt_ecomm = VALUE #( FOR <lfs> IN gt_functionkeys
                      WHERE ( code NE 'WB_BACK'
                              AND code NE 'WB_END'
                              AND code NE 'WB_EXEC'
                              AND code NE 'ED_PRETTY_PRINT' )
                    ( <lfs>-code ) ).

  gt_ecomm = VALUE #( BASE gt_ecomm
                      FOR <lfs2> IN gt_menu_tree
                      WHERE ( code NE 'WB_BACK'
                              AND code NE 'WB_END'
                              AND code NE 'WB_EXEC'
                              AND code NE 'ED_PRETTY_PRINT' )
                    ( <lfs2>-code ) ).

  gt_ecomm_only_show = VALUE #( FOR <lfs> IN gt_functionkeys
                                WHERE ( code NE 'WB_BACK'
                                        AND code NE 'WB_END'
                                        AND code NE 'WB_CANCEL' )
                    ( <lfs>-code ) ).

  gt_ecomm_only_show = VALUE #( BASE gt_ecomm_only_show
                                FOR <lfs2> IN gt_menu_tree
                                WHERE ( code NE 'WB_BACK'
                                        AND code NE 'WB_END'
                                        AND code NE 'WB_CANCEL' )
                    ( <lfs2>-code ) ).

AT USER-COMMAND.
  CASE sy-ucomm.
    WHEN 'WB_BACK' OR 'WB_CANCEL'.
      IF go_editor IS BOUND AND gv_editor_visible EQ abap_false.
        PERFORM editor_call.
        RETURN.
      ENDIF.
      LEAVE TO SCREEN 0.
    WHEN 'WB_END'.
      LEAVE PROGRAM.
    WHEN 'WB_EXEC'.
      go_editor->get_text(
*        exporting
*          NAME                   =     " document name
        IMPORTING
          table                  = gt_source
          is_modified            = DATA(lv_modified)
        EXCEPTIONS
          error_dp               = 1
          error_cntl_call_method = 2
          OTHERS                 = 3
      ).
      IF sy-subrc <> 0.
        MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                   WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
      ENDIF.

      PERFORM write_source_code.
      PERFORM execute.
    WHEN 'ED_PRETTY_PRINT'.
      go_editor->get_text(
        IMPORTING
          table                  = gt_source
        EXCEPTIONS
          error_dp               = 1
          error_cntl_call_method = 2
          OTHERS                 = 3
      ).
      IF sy-subrc NE 0.
        RETURN.
      ENDIF.
      IF go_wbeditor IS NOT BOUND.
        go_wbeditor = NEW #( ).
        go_wbeditor->create_source_object( IMPORTING source_object = go_source ).
      ENDIF.
      go_source->set_source_tab( source = gt_source ).
      go_wbeditor->execute_function( CHANGING fcode = sy-ucomm ).
      go_source->get_source_tab( IMPORTING source = gt_source ).
      go_editor->set_text(
        EXPORTING
          table           = gt_source
        EXCEPTIONS
          error_dp        = 1
          error_dp_create = 2
          error_code_page = 3
          OTHERS          = 4 ).
  ENDCASE.

START-OF-SELECTION.
  IMPORT gt_source FROM MEMORY ID 'DIRECT_EXEC'.
  PERFORM editor_call.

END-OF-SELECTION.

*&---------------------------------------------------------------------*
*&      FORM  EDITOR_CALL
*&---------------------------------------------------------------------*
FORM editor_call.
  DATA lv_is_its TYPE c.
  CALL FUNCTION 'GUI_IS_ITS'
    IMPORTING
      return = lv_is_its.

  IF lv_is_its IS NOT INITIAL.
    MESSAGE i001(00) WITH 'WEB GUI에서는 사용 불가합니다' DISPLAY LIKE 'E'.
    RETURN.
  ELSE.
    SKIP.

    SET PF-STATUS gc_status_bar-status OF PROGRAM gc_status_bar-program EXCLUDING gt_ecomm.
    SET TITLEBAR gc_status_bar-title OF PROGRAM gc_status_bar-program WITH 'Direct Execution'.

    gv_editor_visible = abap_true.
    IF go_editor IS NOT BOUND.
      go_editor = NEW #( parent = cl_gui_container=>default_screen ).
    ELSE.
      go_editor->set_visible( '1' ).
    ENDIF.

    go_editor->set_text(
      EXPORTING
        table           = gt_source
      EXCEPTIONS
        error_dp        = 1
        error_dp_create = 2
        error_code_page = 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.
  ENDIF.
ENDFORM.                    " EDITOR_CALL
*&---------------------------------------------------------------------*
*&      FORM  EXECUTE
*&---------------------------------------------------------------------*
FORM execute.
  DATA: lv_pool_name LIKE sy-repid.
  DATA: BEGIN OF syn_msg,
          l1(72),
          l2(72),
          l3(72),
        END OF syn_msg.
  DATA: syn_lin     TYPE i, syn_wrd(30).

  CHECK gt_program[] IS NOT INITIAL.

  GENERATE SUBROUTINE POOL gt_program NAME lv_pool_name
                           MESSAGE syn_msg LINE syn_lin WORD syn_wrd.
  IF sy-subrc EQ 0.
    DATA lv_answer TYPE c.
    CLEAR lv_answer.

    CALL FUNCTION 'POPUP_CONTINUE_YES_NO'
      EXPORTING
        defaultoption = 'Y'
        textline1     = 'Run the current source code?'
        titel         = 'Question'
      IMPORTING
        answer        = lv_answer.
    IF lv_answer EQ 'J'.
      PERFORM editor_invisible.
      PERFORM (gc_formname) IN PROGRAM (lv_pool_name).

      MESSAGE i001(00) WITH 'OK'.
      PERFORM editor_call.
    ENDIF.
  ELSE.
    syn_lin = syn_lin - 2.

    MESSAGE syn_msg TYPE 'S' DISPLAY LIKE 'E'.

    go_editor->select_lines(
      EXPORTING
        from_line              = CONV #( syn_lin )
        to_line                = CONV #( syn_lin )
      EXCEPTIONS
        error_cntl_call_method = 1                " Error while selecting lines within SourceEdit control!
        OTHERS                 = 2
    ).
  ENDIF.
ENDFORM.                    " EXECUTE
*&---------------------------------------------------------------------*
*&      Form  WRITE_SOURCE_CODE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM write_source_code .
  CLEAR gt_program.

  EXPORT gt_source TO MEMORY ID 'DIRECT_EXEC'.
  CHECK gt_source[] IS NOT INITIAL.

  APPEND |REPORT { sy-repid } NO STANDARD PAGE HEADING.| TO gt_program.
  APPEND |FORM { gc_formname }.| TO gt_program.
  APPEND LINES OF gt_source TO gt_program.
  APPEND 'ENDFORM.' TO gt_program.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form editor_invisible
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM editor_invisible .
  gv_editor_visible = abap_false.
  go_editor->set_visible( '0' ).
  SET PF-STATUS gc_status_bar-status OF PROGRAM gc_status_bar-program EXCLUDING gt_ecomm_only_show.
ENDFORM.

댓글