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

[Report] 일괄 번역 편집기(MASS_TRANSLATE)

by name_text 2023. 11. 15.

일괄 번역 편집기

MASS_TRANSLATE

 

 

다국어 적용을 위해 ABAP Object(Program, Function, Class, Table 등) 이나 Roll에 다른 언어의 텍스트를 입력하고자 할 경우 SAP 표준 기능을 가지고 하기에는 상당히 번거롭고 작업 여부를 체크하기에도 편리하지 않습니다.

다국어 적용을 위해 많은 프로젝트에서 CBO로 프로그램을 만들어 Package내의 모든 항목을 일괄로 조회/변경하는 식으로 작업을 합니다.

 

CBO 프로그램에서 타 언어의 텍스트를 저장한 후 T-Code : SLXT 에서 Package별로 Workbench CTS를 생성하는 방식으로 사용하면 됩니다.

 

해당 소스코드에 사용된 공통 기능들은 블로그내의 아래 게시물 내용을 참고하면 됩니다.

ALV Common Include

2023.09.05 - [ABAP/소스코드] - [Include] ALV용 Common Include

 

Excel 파일 업로드 Function

2023.07.10 - [ABAP/소스코드] - [Function] ZCM_EXCEL_UPLOAD - 필드 점검 및 변환 엑셀 업로드

 

Internal Table Excel 다운로드 Class

2023.11.15 - [ABAP/소스코드] - [Class] Internal Table 엑셀 다운로드(XLSX 형식)

 

# 소스코드

REPORT zmass_translate.

*--------------------------------------------------------------------*
* TOP
*--------------------------------------------------------------------*
TYPE-POOLS : icon.
TABLES: sscrfields, lxe_attob, tadir, agr_define.

TYPES: BEGIN OF t_obj_lxe_map,
         lxe_objtype TYPE lxe_attob-obj_type,  "번역 오브젝트 유형
         ktext       TYPE lxe_attobt-ktext,
         object      TYPE tadir-object,        "오브젝트 유형
         object_t    TYPE as4text,
       END OF t_obj_lxe_map.

TYPES: BEGIN OF t_obj_f4,
         object   TYPE tadir-object,        "오브젝트 유형
         object_t TYPE as4text,
       END OF t_obj_f4.
TYPES: BEGIN OF t_lxe_f4,
         lxe_objtype TYPE lxe_attob-obj_type,
         ktext       TYPE lxe_attobt-ktext,
       END OF t_lxe_f4.

TYPES: BEGIN OF t_lxe_object,
         devclass    TYPE devclass,      "개발클래스
         object      TYPE tadir-object,   "오브젝트 유형
         obj_name    TYPE tadir-obj_name, "오브젝트
         obj_desc    TYPE as4text,         "오브젝트 내역
         lxe_objtype TYPE lxe_attob-obj_type,   "번역 오브젝트 유형
         lxe_ktext   TYPE as4text,     "번역 오브젝트 유형 내역
         lxe_objname TYPE lxeobjname,           "번역 오브젝트
         textkey     TYPE lxe_pcx_s1-textkey,   "번역 오브젝트 텍스트 키
         unitmlt     TYPE lxe_pcx_s1-unitmlt,
         m_lang      TYPE tadir-masterlang,         "Master Language
         s_lang      TYPE t002-spras,                    "Source Language
         s_text      TYPE lxe_pcx_s1-s_text,
         t_lang      TYPE t002-spras,    "Target Language
         t_text      TYPE lxe_pcx_s1-t_text,

       END OF t_lxe_object.

TYPES: BEGIN OF t_trans_text,
         s_text TYPE lxe_pcx_s1-s_text,
         t_text TYPE lxe_pcx_s1-t_text,
       END OF t_trans_text,
       tt_trans_text TYPE SORTED TABLE OF t_trans_text WITH UNIQUE KEY s_text.

TYPES: BEGIN OF t_disp.
         INCLUDE TYPE t_lxe_object.
TYPES:   lxe_collname TYPE lxecollnam,     "언어 컬렉션
         status       TYPE iconname,
         message      TYPE bapi_msg.
TYPES: info_field(4) TYPE c,
       excp_field    TYPE c,
       END OF t_disp.

DATA: gt_disp TYPE STANDARD TABLE OF t_disp WITH EMPTY KEY WITH NON-UNIQUE SORTED KEY excp COMPONENTS excp_field,
      gs_disp LIKE LINE OF gt_disp.

DATA: gt_obj_lxe_map TYPE SORTED TABLE OF t_obj_lxe_map WITH UNIQUE KEY object lxe_objtype,
      gt_f4_obj      TYPE STANDARD TABLE OF t_obj_f4,
      gt_f4_lxe      TYPE STANDARD TABLE OF t_lxe_f4.

DATA: gt_trans_text TYPE tt_trans_text.

DATA: gt_excel TYPE STANDARD TABLE OF t_lxe_object.

DATA: gr_object      TYPE RANGE OF tadir-object,
      gr_lxe_objtype TYPE RANGE OF lxe_attob-obj_type.

DATA: gv_slang TYPE lxeisolang,
      gv_tlang TYPE lxeisolang.

DATA: ok_code TYPE sy-ucomm.

DATA: gv_simple_view TYPE abap_bool.

CONSTANTS: BEGIN OF gc_langu,
             ko TYPE sy-langu VALUE '3',
             en TYPE sy-langu VALUE 'E',
           END OF gc_langu,
           BEGIN OF gc_alv_color,
             m_lang TYPE lvc_emphsz  VALUE 'C500',
             s_lang TYPE lvc_emphsz  VALUE 'C600',
             t_lang TYPE lvc_emphsz  VALUE 'C700',
           END OF gc_alv_color.

DATA: BEGIN OF gs_lang,
        input   TYPE t002-spras,
        output  TYPE t002-laiso,
        suffix  TYPE string,
        text    TYPE t002t-sptxt,
        text_en TYPE t002t-sptxt,
      END OF gs_lang.

DATA: go_grid TYPE REF TO cl_gui_alv_grid.
DATA: gt_field_cat TYPE lvc_t_fcat.
DATA: gv_grid_title TYPE lvc_title.

CONSTANTS: gc_handle_0100 TYPE slis_handl VALUE '0100'.

DEFINE _excp_field.
  &3 = COND #( WHEN &2 IS INITIAL THEN '1'
               WHEN &1 EQ &2 THEN '2'
               ELSE '3' ).
END-OF-DEFINITION.

*-----------------------------------------------------------------------
* SELECTION-SCREEN
*-----------------------------------------------------------------------
SELECTION-SCREEN FUNCTION KEY 1. "Function Key1 (SSCRFIELDS-FUNCTXT_01)

SELECTION-SCREEN BEGIN OF BLOCK bl1 WITH FRAME TITLE TEXT-bl1.
  PARAMETERS: p_obj RADIOBUTTON GROUP rb1 USER-COMMAND rb1,
              p_rol RADIOBUTTON GROUP rb1.

SELECTION-SCREEN END OF BLOCK bl1.

SELECTION-SCREEN BEGIN OF BLOCK bl2 WITH FRAME TITLE TEXT-bl2.
  SELECT-OPTIONS: s_devc FOR tadir-devclass     MODIF ID ob0,        " Package
                  s_obje FOR tadir-object       MODIF ID ob1,        " 오브젝트 유형
                  s_name FOR tadir-obj_name     MODIF ID ob1.        " 오브젝트
  PARAMETERS      p_obje TYPE tadir-object DEFAULT 'ACGR'      MODIF ID ro2.
  SELECT-OPTIONS: s_roll FOR agr_define-agr_name  MODIF ID ro1,      " ROLL
                  s_user FOR tadir-author,                           " 오브젝트 생성자
                  s_lobj FOR lxe_attob-obj_type MODIF ID ob1.        " 번역 오브젝트 유형
  PARAMETERS      p_lobj TYPE lxe_attob-obj_type DEFAULT 'ACGR'      MODIF ID ro2.

  SELECTION-SCREEN SKIP .
  PARAMETERS: p_slang TYPE t002-spras OBLIGATORY,     " Source Language
              p_tlang TYPE t002-spras OBLIGATORY.     " Target Language

  SELECTION-SCREEN SKIP .
  PARAMETERS: p_check AS CHECKBOX.
SELECTION-SCREEN END OF BLOCK bl2.

*--------------------------------------------------------------------*
* Class
*--------------------------------------------------------------------*
CLASS lcl_object DEFINITION.
  PUBLIC SECTION.
    TYPES: BEGIN OF t_objlist,
             devclass    TYPE devclass,
             object      TYPE tadir-object,        "오브젝트 유형
             obj_name    TYPE tadir-obj_name,      "오브젝트
             lxe_objname TYPE lxeobjname,          "번역 오브젝트
             m_lang      TYPE tadir-masterlang,    "Master Language
           END OF t_objlist,
           tt_objlist      TYPE STANDARD TABLE OF t_objlist WITH EMPTY KEY,
           tt_objlist_sort TYPE SORTED TABLE OF t_objlist WITH NON-UNIQUE KEY object.

    TYPES: BEGIN OF t_obj_desc,
             object   TYPE trobjtype,
             obj_name TYPE sobj_name,
             spras    TYPE spras,
             obj_desc TYPE repti,
           END OF t_obj_desc,
*    TT_OBJS TYPE SORTED TABLE OF T_OBJ_DESC WITH NON-UNIQUE KEY OBJECT,
           tt_obj_desc TYPE SORTED TABLE OF t_obj_desc WITH UNIQUE KEY object obj_name spras.

    TYPES: BEGIN OF t_stxftxt,
             lxe_objname TYPE stxftxt-formname,
             iname       TYPE stxftxt-iname,
             linenr      TYPE stxftxt-linenr,
             tdformat    TYPE stxftxt-tdformat,
             s_text      TYPE stxftxt-tdline,
             t_text      TYPE stxftxt-tdline,
           END OF t_stxftxt,
           tt_stxftxt TYPE STANDARD TABLE OF t_stxftxt WITH EMPTY KEY.

    CONSTANTS: BEGIN OF lc_object,
                 func TYPE tadir-object VALUE 'FUNC',
                 msag TYPE tadir-object VALUE 'MSAG',
                 mess TYPE tadir-object VALUE 'MESS',
                 tabl TYPE tadir-object VALUE 'TABL',
                 fugr TYPE tadir-object VALUE 'FUGR',
                 fugx TYPE tadir-object VALUE 'FUGX',
                 prog TYPE tadir-object VALUE 'PROG',
                 acgr TYPE tadir-object VALUE 'ACGR',
               END OF lc_object.
    CONSTANTS: BEGIN OF lc_pgmid,
                 r3tr TYPE tadir-pgmid VALUE 'R3TR',
               END OF lc_pgmid.

    CLASS-METHODS: get_object_list RETURNING VALUE(et_objlist) TYPE tt_objlist_sort,
      get_object_descript RETURNING VALUE(et_obj_desc) TYPE tt_obj_desc,
      get_smartform_text IMPORTING iv_formname       TYPE stxftxt-formname
                                   iv_slang          TYPE sy-langu
                                   iv_tlang          TYPE sy-langu
                         RETURNING VALUE(et_stxftxt) TYPE tt_stxftxt.
  PRIVATE SECTION.
    CLASS-DATA: lv_object      TYPE tadir-object,
                lv_lxe_objname TYPE lxeobjname,
                lv_char20      TYPE c LENGTH 20,
                lv_char30      TYPE c LENGTH 30,
                lv_char40      TYPE c LENGTH 40,
                es_objlist     TYPE t_objlist.

    CLASS-METHODS: get_tadir_main RETURNING VALUE(et_objlist) TYPE tt_objlist,    "일반 오브젝트
      get_tadir_func RETURNING VALUE(et_objlist) TYPE tt_objlist,    "펑션 모듈
      get_tadir_mess RETURNING VALUE(et_objlist) TYPE tt_objlist,    "메시지
      get_tadir_tadc RETURNING VALUE(et_objlist) TYPE tt_objlist,    "Tables (Customizing - Maintenance
      get_tadir_screen RETURNING VALUE(et_objlist) TYPE tt_objlist,    "Screen
      get_tadir_roll RETURNING VALUE(et_objlist) TYPE tt_objlist.    "Roll
ENDCLASS.
CLASS lcl_object IMPLEMENTATION.
  METHOD get_object_list.
    DATA lt_objlist TYPE tt_objlist.
    lt_objlist = get_tadir_main( ).
    IF lc_object-func IN gr_object.
      APPEND LINES OF get_tadir_func( ) TO lt_objlist.
    ENDIF.
    IF lc_object-mess IN gr_object.
      APPEND LINES OF get_tadir_mess( ) TO lt_objlist.
    ENDIF.
    IF lc_object-tabl IN gr_object.
      APPEND LINES OF get_tadir_tadc( ) TO lt_objlist.
    ENDIF.
    IF lc_object-fugr IN gr_object OR lc_object-fugx IN gr_object OR  lc_object-prog IN gr_object.
      APPEND LINES OF get_tadir_screen( ) TO lt_objlist.
    ENDIF.
    IF lc_object-acgr IN gr_object.
      APPEND LINES OF get_tadir_roll( ) TO lt_objlist.
    ENDIF.

    et_objlist = CORRESPONDING #( lt_objlist ).
  ENDMETHOD.

  METHOD get_tadir_main.
    SELECT
      a~devclass,
      a~object,
      a~obj_name,
      a~obj_name    AS lxe_objname,
      a~masterlang  AS m_lang
    FROM tadir AS a
    WHERE a~pgmid     EQ @lc_pgmid-r3tr
      AND a~object    IN @gr_object
      AND a~devclass  IN @s_devc
      AND a~obj_name  IN @s_name
      AND a~author    IN @s_user
      INTO CORRESPONDING FIELDS OF TABLE @et_objlist.
  ENDMETHOD.

  METHOD get_tadir_func.
    SELECT
      a~devclass,
      @lc_object-func AS object,
      a~obj_name,
      a~masterlang  AS m_lang,
      b~funcname
    FROM tadir AS a
      INNER JOIN tfdir AS b ON 'SAPL' && a~obj_name EQ b~pname
    WHERE a~pgmid     EQ @lc_pgmid-r3tr
      AND a~object    EQ @lc_object-fugr
      AND a~devclass  IN @s_devc
      AND b~funcname  IN @s_name
      AND a~author    IN @s_user
      AND ( b~funcname  LIKE 'Z%' OR b~funcname LIKE 'Y%' )
      INTO TABLE @DATA(lt_objlist).
    LOOP AT lt_objlist INTO DATA(ls_objlist).
      es_objlist = CORRESPONDING #( ls_objlist ).

      CONCATENATE ls_objlist-funcname es_objlist-obj_name INTO es_objlist-lxe_objname RESPECTING BLANKS.
      es_objlist-obj_name = ls_objlist-funcname.

      APPEND es_objlist TO et_objlist.
    ENDLOOP.
  ENDMETHOD.

  METHOD get_tadir_mess.
    SELECT
      a~devclass,
      @lc_object-mess AS object,
      a~obj_name,
      a~masterlang  AS m_lang,
      b~msgnr
    FROM tadir AS a
      INNER JOIN t100 AS b ON a~obj_name = b~arbgb AND b~sprsl = @p_slang
    WHERE a~pgmid     EQ @lc_pgmid-r3tr
      AND a~object    EQ @lc_object-msag
      AND a~devclass  IN @s_devc
      AND a~obj_name  IN @s_name
*      AND ( A~OBJ_NAME LIKE 'Z%' OR A~OBJ_NAME LIKE 'Y%' )
      AND a~author    IN @s_user
      INTO TABLE @DATA(lt_objlist).

    LOOP AT lt_objlist INTO DATA(ls_objlist).
      es_objlist = CORRESPONDING #( ls_objlist ).

      lv_char20 = es_objlist-obj_name.
      CONCATENATE lv_char20 ls_objlist-msgnr INTO es_objlist-lxe_objname RESPECTING BLANKS.

      APPEND es_objlist TO et_objlist.
    ENDLOOP.
  ENDMETHOD.

  METHOD get_tadir_tadc.
    SELECT
      a~devclass,
      a~object,
      a~obj_name,
      a~obj_name    AS lxe_objname,
      a~masterlang  AS m_lang
    FROM tadir AS a
    WHERE a~pgmid     EQ @lc_pgmid-r3tr
      AND a~object    EQ @lc_object-tabl
      AND a~devclass  IN @s_devc
      AND a~object    IN @s_obje
      AND a~obj_name  IN @s_name
*      AND ( A~OBJ_NAME  LIKE 'Z%' OR A~OBJ_NAME  LIKE 'Y%' )
      AND a~author    IN @s_user
    INTO TABLE @DATA(lt_objlist).

    LOOP AT lt_objlist INTO DATA(ls_objlist).
      es_objlist = CORRESPONDING #( ls_objlist ).
      lv_char30 = es_objlist-obj_name.
      CONCATENATE sy-mandt lv_char30 '+' INTO es_objlist-lxe_objname RESPECTING BLANKS.

      APPEND es_objlist TO et_objlist.
    ENDLOOP.
  ENDMETHOD.

  METHOD get_tadir_screen. " Screen
    SELECT
      a~devclass,
      a~object,
      a~obj_name,
      a~obj_name    AS lxe_objname,
      a~masterlang  AS m_lang,
      b~prog,
      b~dnum
    FROM tadir AS a
      INNER JOIN d020s AS b ON
        CASE WHEN a~object EQ @lc_object-fugr OR a~object EQ @lc_object-fugx THEN 'SAPL' && a~obj_name ELSE a~obj_name END EQ b~prog
    WHERE a~pgmid     EQ @lc_pgmid-r3tr
      AND a~object    IN @gr_object
      AND a~devclass  IN @s_devc
      AND a~obj_name  IN @s_name
*      AND ( A~OBJ_NAME LIKE 'Z%' OR A~OBJ_NAME LIKE 'Y%' )
      AND a~author    IN @s_user
      AND b~type      NE 'S'
    INTO TABLE @DATA(lt_objlist).

    LOOP AT lt_objlist INTO DATA(ls_objlist).
      es_objlist = CORRESPONDING #( ls_objlist ).
      lv_char40  = es_objlist-obj_name.
      CONCATENATE lv_char40 ls_objlist-dnum INTO es_objlist-lxe_objname RESPECTING BLANKS.

      APPEND es_objlist TO et_objlist.
    ENDLOOP.
  ENDMETHOD.

  METHOD get_tadir_roll. " Role definition
    SELECT
      @lc_object-acgr    AS object,
      agr_name  AS obj_name
    FROM agr_define
    WHERE agr_name IN @s_roll
      AND agr_name LIKE 'Z%'
      AND ( create_usr IN @s_user OR change_usr IN @s_user )
    INTO TABLE @DATA(lt_objlist).
    LOOP AT lt_objlist INTO DATA(ls_objlist).
      es_objlist = CORRESPONDING #( ls_objlist ).
      CONCATENATE sy-mandt es_objlist-obj_name INTO es_objlist-lxe_objname.

      APPEND es_objlist TO et_objlist.
    ENDLOOP.
  ENDMETHOD.

  METHOD get_smartform_text.
    SELECT DISTINCT
      a~formname AS lxe_objname,
      a~iname,
      a~linenr,
      a~tdformat,
      coalesce( t1~tdline, @space ) AS s_text,
      coalesce( t2~tdline, @space ) AS t_text
    FROM  stxftxt AS a
      LEFT OUTER JOIN stxftxt AS t1 ON  a~txtype  EQ t1~txtype  AND a~formname  EQ t1~formname
                                    AND a~iname   EQ t1~iname   AND a~vari      EQ t1~vari
                                    AND a~linenr  EQ t1~linenr  AND t1~spras    EQ @iv_slang
      LEFT OUTER JOIN stxftxt AS t2 ON  a~txtype  EQ t2~txtype  AND a~formname  EQ t2~formname
                                    AND a~iname   EQ t2~iname   AND a~vari      EQ t2~vari
                                    AND a~linenr  EQ t2~linenr  AND t2~spras    EQ @iv_tlang
    WHERE a~formname EQ @iv_formname
      AND a~spras    IN ( @iv_slang, @iv_tlang )
      AND a~txtype   EQ 'F'
    INTO CORRESPONDING FIELDS OF TABLE @et_stxftxt.
  ENDMETHOD.

  METHOD get_object_descript.
    TYPES: BEGIN OF ts_obj,
             object   TYPE tadir-object,
             obj_name TYPE tadir-obj_name,
             spras    TYPE sy-langu,
           END OF ts_obj,
           tt_obj TYPE STANDARD TABLE OF ts_obj WITH EMPTY KEY.

    DATA(lt_obj_tmp) = CORRESPONDING tt_obj( gt_disp DISCARDING DUPLICATES
                                             EXCEPT spras ).
    SORT lt_obj_tmp BY object obj_name. DELETE ADJACENT DUPLICATES FROM lt_obj_tmp COMPARING ALL FIELDS.

    DATA(lt_obj) = VALUE tt_obj( ).
    DATA lr_langu TYPE RANGE OF sy-langu.
    lr_langu = VALUE #( sign = 'I' option = 'EQ'
                        ( low = sy-langu )
                        ( low = gc_langu-en )
                        ( low = gc_langu-ko ) ).
    SORT lr_langu BY low. DELETE ADJACENT DUPLICATES FROM lr_langu COMPARING ALL FIELDS.

    LOOP AT lr_langu INTO DATA(ls_langu).
      lt_obj = VALUE #( BASE lt_obj
                        FOR ls IN lt_obj_tmp
                        ( object = ls-object
                          obj_name = ls-obj_name
                          spras = ls_langu-low ) ).
    ENDLOOP.
    CLEAR lt_obj_tmp.

    WITH +t01 AS ( SELECT 'DEVC' AS object,
                     spras AS spras,
                     devclass AS obj_name,
                     ctext AS obj_desc
                   FROM tdevct AS a
                   WHERE spras IN @lr_langu ),
         +t02 AS ( SELECT 'PROG' AS object,
                     sprsl AS spras,
                     name AS obj_name,
                     text AS obj_desc
                   FROM trdirt AS a
                   WHERE sprsl IN @lr_langu ),
         +t03 AS ( SELECT 'FUGR' AS object,
                     spras,
                     area AS obj_name,
                     areat AS obj_desc
                   FROM tlibt
                   WHERE spras IN @lr_langu ),
         +t04 AS ( SELECT 'FUNC' AS object,
                     spras,
                     funcname AS obj_name,
                     stext AS obj_desc
                   FROM tftit
                   WHERE spras IN @lr_langu ),
         +t05 AS ( SELECT 'MSAG' AS object,
                     sprsl AS spras,
                     arbgb AS obj_name,
                     stext AS obj_desc
                   FROM t100t
                   WHERE sprsl IN @lr_langu ),
         +t06 AS ( SELECT 'MESS' AS object,
                     sprsl AS spras,
                     arbgb AS obj_name,
                     stext AS obj_desc
                   FROM t100t
                   WHERE sprsl IN @lr_langu ),
         +t07 AS ( SELECT 'TABL' AS object,
                     ddlanguage AS spras,
                     tabname AS obj_name,
                     ddtext AS obj_desc
                   FROM dd02t
                   WHERE ddlanguage IN @lr_langu
                     AND as4local   EQ 'A' ),
         +t08 AS ( SELECT 'DTEL' AS object,
                     ddlanguage AS spras,
                     rollname AS obj_name,
                     ddtext AS obj_desc
                   FROM dd04t
                   WHERE ddlanguage IN @lr_langu
                     AND as4local   EQ 'A' ),
         +t09 AS ( SELECT 'VIEW' AS object,
                     ddlanguage AS spras,
                     viewname AS obj_name,
                     ddtext AS obj_desc
                   FROM dd25t
                   WHERE ddlanguage IN @lr_langu
                     AND as4local   EQ 'A' ),
         +t10 AS ( SELECT 'SHLP' AS object,
                     ddlanguage AS spras,
                     shlpname AS obj_name,
                     ddtext AS obj_desc
                   FROM dd30t
                   WHERE ddlanguage IN @lr_langu
                     AND as4local   EQ 'A' ),
         +t11 AS ( SELECT 'DOMA' AS object,
                     ddlanguage AS spras,
                     domname AS obj_name,
                     ddtext AS obj_desc
                   FROM dd01t
                   WHERE ddlanguage IN @lr_langu
                     AND as4local   EQ 'A' ),
         +t12 AS ( SELECT 'ENQU' AS object,
                     ddlanguage AS spras,
                     viewname  AS obj_name,
                     ddtext   AS obj_desc
                   FROM dd25t
                   WHERE ddlanguage IN @lr_langu
                     AND as4local   EQ 'A' ),
         +t13 AS ( SELECT 'TTYP' AS object,
                     ddlanguage AS spras,
                     typename AS obj_name,
                     ddtext AS obj_desc
                   FROM dd40t
                   WHERE ddlanguage IN @lr_langu
                     AND as4local   EQ 'A' ),
         +t14 AS ( SELECT 'TRAN' AS object,
                     sprsl AS spras,
                     tcode AS obj_name,
                     ttext AS obj_desc
                   FROM tstct
                   WHERE sprsl IN @lr_langu ),
         +t15 AS ( SELECT 'CLAS' AS object,
                     langu AS spras,
                     clsname AS obj_name,
                     descript AS obj_desc
                   FROM seoclasstx
                   WHERE langu IN @lr_langu ),
         +t16 AS ( SELECT 'INTF' AS object,
                     langu AS spras,
                     clsname AS obj_name,
                     descript AS obj_desc
                   FROM seoclasstx
                   WHERE langu IN @lr_langu ),
         +t17 AS ( SELECT 'SSFO' AS object,
                     langu AS spras,
                     formname  AS obj_name,
                     caption   AS obj_desc
                   FROM stxfadmt
                   WHERE langu IN @lr_langu ),
         +t18 AS ( SELECT 'PARA' AS object,
                     sprache AS spras,
                     paramid   AS obj_name,
                     partext   AS obj_desc
                   FROM tparat
                   WHERE sprache IN @lr_langu ),
         +t19 AS ( SELECT 'SHI3' AS object,
                     b~spras,
                     a~tree_id AS obj_name,
                     b~text    AS obj_desc
                   FROM tmenu01 AS a
                     INNER JOIN tmenu01t AS b ON a~tree_id EQ b~tree_id
                                             AND a~extension EQ b~extension
                                             AND a~node_id EQ b~node_id
                                             AND a~ext_key EQ b~ext_key
                   WHERE a~parent_id EQ @space
                     AND b~spras IN @lr_langu ),
         +t20 AS ( SELECT 'ACGR' AS object,
                     spras AS spras,
                     agr_name AS obj_name,
                     text AS obj_desc
                   FROM agr_texts
                   WHERE spras IN @lr_langu
                     AND line EQ 0 ),
         +t21 AS ( SELECT 'DDLS' AS object,
                     @sy-langu AS spras,
                     strucobjn AS obj_name,
                     value     AS obj_desc
                   FROM ddheadanno
                   WHERE name EQ 'ENDUSERTEXT.LABEL' )
    SELECT
      a~object,
      a~obj_name,
      a~spras,
      coalesce( +t01~obj_desc,
                +t02~obj_desc,
                +t03~obj_desc,
                +t04~obj_desc,
                +t05~obj_desc,
                +t06~obj_desc,
                +t07~obj_desc,
                +t08~obj_desc,
                +t09~obj_desc,
                +t10~obj_desc,
                +t11~obj_desc,
                +t12~obj_desc,
                +t13~obj_desc,
                +t14~obj_desc,
                +t15~obj_desc,
                +t16~obj_desc,
                +t17~obj_desc,
                +t18~obj_desc,
                +t19~obj_desc,
                +t20~obj_desc,
                +t21~obj_desc ) AS obj_desc
    FROM @lt_obj AS a
      LEFT OUTER JOIN +t01 ON a~object EQ +t01~object AND a~obj_name EQ +t01~obj_name AND a~spras EQ +t01~spras
      LEFT OUTER JOIN +t02 ON a~object EQ +t02~object AND a~obj_name EQ +t02~obj_name AND a~spras EQ +t02~spras
      LEFT OUTER JOIN +t03 ON a~object EQ +t03~object AND a~obj_name EQ +t03~obj_name AND a~spras EQ +t03~spras
      LEFT OUTER JOIN +t04 ON a~object EQ +t04~object AND a~obj_name EQ +t04~obj_name AND a~spras EQ +t04~spras
      LEFT OUTER JOIN +t05 ON a~object EQ +t05~object AND a~obj_name EQ +t05~obj_name AND a~spras EQ +t05~spras
      LEFT OUTER JOIN +t06 ON a~object EQ +t06~object AND a~obj_name EQ +t06~obj_name AND a~spras EQ +t06~spras
      LEFT OUTER JOIN +t07 ON a~object EQ +t07~object AND a~obj_name EQ +t07~obj_name AND a~spras EQ +t07~spras
      LEFT OUTER JOIN +t08 ON a~object EQ +t08~object AND a~obj_name EQ +t08~obj_name AND a~spras EQ +t08~spras
      LEFT OUTER JOIN +t09 ON a~object EQ +t09~object AND a~obj_name EQ +t09~obj_name AND a~spras EQ +t09~spras
      LEFT OUTER JOIN +t10 ON a~object EQ +t10~object AND a~obj_name EQ +t10~obj_name AND a~spras EQ +t10~spras
      LEFT OUTER JOIN +t11 ON a~object EQ +t11~object AND a~obj_name EQ +t11~obj_name AND a~spras EQ +t11~spras
      LEFT OUTER JOIN +t12 ON a~object EQ +t12~object AND a~obj_name EQ +t12~obj_name AND a~spras EQ +t12~spras
      LEFT OUTER JOIN +t13 ON a~object EQ +t13~object AND a~obj_name EQ +t13~obj_name AND a~spras EQ +t13~spras
      LEFT OUTER JOIN +t14 ON a~object EQ +t14~object AND a~obj_name EQ +t14~obj_name AND a~spras EQ +t14~spras
      LEFT OUTER JOIN +t15 ON a~object EQ +t15~object AND a~obj_name EQ +t15~obj_name AND a~spras EQ +t15~spras
      LEFT OUTER JOIN +t16 ON a~object EQ +t16~object AND a~obj_name EQ +t16~obj_name AND a~spras EQ +t16~spras
      LEFT OUTER JOIN +t17 ON a~object EQ +t17~object AND a~obj_name EQ +t17~obj_name AND a~spras EQ +t17~spras
      LEFT OUTER JOIN +t18 ON a~object EQ +t18~object AND a~obj_name EQ +t18~obj_name AND a~spras EQ +t18~spras
      LEFT OUTER JOIN +t19 ON a~object EQ +t19~object AND a~obj_name EQ +t19~obj_name AND a~spras EQ +t19~spras
      LEFT OUTER JOIN +t20 ON a~object EQ +t20~object AND a~obj_name EQ +t20~obj_name AND a~spras EQ +t20~spras
      LEFT OUTER JOIN +t21 ON a~object EQ +t21~object AND a~obj_name EQ +t21~obj_name AND a~spras EQ +t21~spras
    INTO CORRESPONDING FIELDS OF TABLE @et_obj_desc.

  ENDMETHOD.
ENDCLASS.

CLASS lcl_progress DEFINITION.

  PUBLIC SECTION.

    METHODS initial
      IMPORTING
        VALUE(i_total) TYPE i .
    METHODS set_percent
      IMPORTING
        VALUE(i_text) TYPE any OPTIONAL .
    METHODS set_step
      IMPORTING
        VALUE(i_text) TYPE any OPTIONAL .
    METHODS constructor
      IMPORTING
        VALUE(i_total) TYPE i OPTIONAL .
  PROTECTED SECTION.
  PRIVATE SECTION.

    DATA g_progress_total TYPE i .
    DATA g_progress_curnt TYPE i .
    DATA g_percentage_prev TYPE i .
ENDCLASS.

CLASS lcl_progress IMPLEMENTATION.
  METHOD constructor.
    initial( i_total ).
  ENDMETHOD.
  METHOD initial.
    CLEAR: g_progress_curnt, g_percentage_prev.
    g_progress_total = i_total.
  ENDMETHOD.
  METHOD set_percent.
    DATA: lv_progress_title TYPE string,
          lv_percentage     TYPE i,
          lv_per_text(10)   TYPE c,
          lv_text           TYPE string.

    MOVE i_text TO lv_text.
    ADD 1 TO g_progress_curnt.
    IF g_progress_total = 0.
      g_progress_total = 100.
    ENDIF.
    IF g_progress_curnt <> 0.
      lv_percentage = g_progress_curnt * 100 / g_progress_total.
    ENDIF.
    IF lv_percentage > 100.
      lv_percentage = 100.
    ENDIF.
    IF lv_percentage > g_percentage_prev.
      g_percentage_prev = lv_percentage.
      WRITE lv_percentage TO lv_per_text. CONDENSE lv_per_text.
      CONCATENATE '[' lv_per_text '%] ' ` ` lv_text INTO lv_progress_title.

      CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
        EXPORTING
          percentage = lv_percentage
          text       = lv_progress_title.
    ENDIF.
  ENDMETHOD.
  METHOD set_step.
    DATA: lv_progress_title TYPE string,
          lv_percentage     TYPE i,
          lv_cur_text(10)   TYPE c,
          lv_tot_text(10)   TYPE c,
          lv_text           TYPE string.
    CLEAR : lv_cur_text, lv_tot_text.

    MOVE i_text TO lv_text.
    ADD 1 TO g_progress_curnt.
    WRITE g_progress_curnt TO lv_cur_text. CONDENSE lv_cur_text.
    IF g_progress_total = 0.
      g_progress_total = 100.
    ELSE.
      WRITE g_progress_total TO lv_tot_text. CONDENSE lv_tot_text.
    ENDIF.
    IF g_progress_curnt <> 0.
      lv_percentage = g_progress_curnt * 100 / g_progress_total.
    ENDIF.
    IF lv_percentage > 100.
      lv_percentage = 100.
    ENDIF.

    IF lv_tot_text IS INITIAL.
      CONCATENATE '[' lv_cur_text '] ' ` ` lv_text INTO lv_progress_title.
    ELSE.
      CONCATENATE '[' lv_cur_text 'of' lv_tot_text '] ' ` ` lv_text INTO lv_progress_title.
    ENDIF.

    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        percentage = lv_percentage
        text       = lv_progress_title.
  ENDMETHOD.
ENDCLASS.

CLASS lcl_excel DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS conv_to_excel
      IMPORTING
        VALUE(it_itab)   TYPE STANDARD TABLE
        it_fieldcat      TYPE lvc_t_fcat OPTIONAL
        iv_without_mandt TYPE abap_bool DEFAULT abap_false
      EXPORTING
        ev_xstring       TYPE xstring
        ev_size          TYPE i
        ev_bintab        TYPE solix_tab .

    CLASS-METHODS download
      IMPORTING
        VALUE(it_itab)       TYPE STANDARD TABLE
        iv_directory         TYPE csequence OPTIONAL
        iv_filename          TYPE csequence OPTIONAL
        it_fieldcat          TYPE lvc_t_fcat OPTIONAL
        iv_without_mandt     TYPE abap_bool DEFAULT abap_false
        iv_auto_open         TYPE abap_bool DEFAULT abap_false
      EXPORTING
        ev_download_filename TYPE csequence
        ev_download_path     TYPE csequence.
ENDCLASS.

CLASS lcl_excel IMPLEMENTATION.
  METHOD conv_to_excel.
    DATA: lt_fieldcat     TYPE lvc_t_fcat.
    FIELD-SYMBOLS <lfs_tab>   TYPE ANY TABLE.

    CLEAR : ev_xstring, ev_size.

    DATA(lt_data) = REF #( it_itab ).

    IF it_fieldcat[] IS INITIAL.
      ASSIGN lt_data->* TO <lfs_tab>.
      TRY .
          cl_salv_table=>factory(
            EXPORTING
              list_display = abap_false
            IMPORTING
              r_salv_table = DATA(lo_salv_table)
            CHANGING
              t_table      = <lfs_tab> ).
        CATCH cx_salv_msg.

      ENDTRY.
      IF lo_salv_table IS NOT INITIAL.
        lt_fieldcat = cl_salv_controller_metadata=>get_lvc_fieldcatalog( r_columns      = lo_salv_table->get_columns( )
                                                                         r_aggregations = lo_salv_table->get_aggregations( ) ).
      ENDIF.
    ELSE.
      lt_fieldcat[] = it_fieldcat[].
    ENDIF.

    IF iv_without_mandt EQ abap_true.
      DELETE lt_fieldcat WHERE datatype EQ 'CLNT'.
    ENDIF.

    DATA(lo_result_data) = cl_salv_ex_util=>factory_result_data_table( r_data         = lt_data
                                                                       t_fieldcatalog = lt_fieldcat ).

    cl_salv_bs_tt_util=>if_salv_bs_tt_util~transform(
      EXPORTING
        xml_type      = if_salv_bs_xml=>c_type_xlsx
        xml_version   = cl_salv_bs_a_xml_base=>get_version( )
        r_result_data = lo_result_data
        xml_flavour   = if_salv_bs_c_tt=>c_tt_xml_flavour_export
        gui_type      = if_salv_bs_xml=>c_gui_type_gui
      IMPORTING
        xml           = ev_xstring ).

    IF ev_bintab IS SUPPLIED.
      ev_size = xstrlen( ev_xstring ).
      ev_bintab = cl_bcs_convert=>xstring_to_solix( ev_xstring ).
    ENDIF.
  ENDMETHOD.

  METHOD download.
    DATA: lv_extension_mask TYPE string,
          lv_filename       TYPE string.
    DATA: lt_bintab  TYPE solix_tab,
          lv_xstring TYPE xstring,
          lv_size    TYPE i.
    DATA: lv_action      TYPE i,                "ACTION
          lv_path        TYPE string,
          lv_file_path   TYPE string,
          lv_de_filename TYPE string.

    CLEAR ev_download_filename.

    conv_to_excel( EXPORTING  it_itab     = it_itab
                              it_fieldcat = it_fieldcat
                              iv_without_mandt = iv_without_mandt
                   IMPORTING  ev_xstring  = lv_xstring
                              ev_size     = lv_size
                              ev_bintab   = lt_bintab ).

    DATA lv_is_its TYPE c.
    CALL FUNCTION 'GUI_IS_ITS'
      IMPORTING
        return = lv_is_its.

    MOVE iv_filename TO lv_filename.
    IF iv_filename IS NOT INITIAL AND to_upper( lv_filename ) NP '*.XLSX'.
      lv_filename = |{ lv_filename }.xlsx|.
    ENDIF.
    IF iv_directory IS NOT INITIAL AND iv_filename IS NOT INITIAL.
      MOVE iv_directory TO lv_path.

      CONCATENATE lv_path lv_filename INTO lv_file_path.
    ELSEIF lv_is_its IS NOT INITIAL AND iv_filename IS NOT INITIAL.
      lv_file_path = |{ replace( val = CONV string( lv_filename ) regex = '[/|:|*|?|"|<|>]' with = space occ = 0 ) }|.
    ELSE.
      MOVE iv_filename TO lv_de_filename.

      "확장자
      CLEAR lv_extension_mask.
      IF sy-langu EQ '3'.
        CONCATENATE lv_extension_mask 'Excel 통합문서 (*.XLSX)|*.XLSX|' INTO lv_extension_mask.
      ELSE.
        CONCATENATE lv_extension_mask 'Excel Workbook (*.XLSX)|*.XLSX|' INTO lv_extension_mask.
      ENDIF.

      cl_gui_frontend_services=>file_save_dialog(
        EXPORTING
*         WINDOW_TITLE              =
*         DEFAULT_EXTENSION         =
          default_file_name         = lv_de_filename
*         WITH_ENCODING             =
          file_filter               = lv_extension_mask "CL_GUI_FRONTEND_SERVICES=>FILETYPE_EXCEL
          initial_directory         = CONV #( iv_directory )
*         PROMPT_ON_OVERWRITE       = 'X'
        CHANGING
          filename                  = lv_filename
          path                      = lv_path
          fullpath                  = lv_file_path
          user_action               = lv_action
*         FILE_ENCODING             =
        EXCEPTIONS
          cntl_error                = 1
          error_no_gui              = 2
          not_supported_by_gui      = 3
          invalid_default_file_name = 4
          OTHERS                    = 5 ).
      IF sy-subrc <> 0 OR lv_action = cl_gui_frontend_services=>action_cancel.
        RETURN.
      ENDIF.
    ENDIF.


    "다운로드
    cl_gui_frontend_services=>gui_download(
      EXPORTING
        bin_filesize            = lv_size
        filename                = lv_file_path
        filetype                = 'BIN'
      CHANGING
        data_tab                = lt_bintab
      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 NE 0.
      RETURN.
    ENDIF.

    IF iv_auto_open EQ abap_true.
      cl_gui_frontend_services=>execute(
        EXPORTING
          document               = lv_file_path
        EXCEPTIONS
          cntl_error             = 1
          error_no_gui           = 2
          bad_parameter          = 3
          file_not_found         = 4
          path_not_found         = 5
          file_extension_unknown = 6
          error_execute_failed   = 7
          synchronous_failed     = 8
          not_supported_by_gui   = 9
          OTHERS                 = 10 ).
      IF sy-subrc <> 0.
        RETURN.
      ENDIF.
    ENDIF.

    ev_download_filename = lv_filename.
    ev_download_path     = lv_path.
  ENDMETHOD.
ENDCLASS.

*-----------------------------------------------------------------------
* ALV Event Receiver Class
*-----------------------------------------------------------------------
CLASS lcl_alv_event DEFINITION.
  PUBLIC SECTION .
    DATA alv_id TYPE slis_handl.
    CLASS-METHODS
      get_fieldcatalog_from_itab IMPORTING itab                TYPE any
                                 RETURNING VALUE(fieldcatalog) TYPE lvc_t_fcat.
    METHODS
      constructor IMPORTING i_alv_id TYPE slis_handl OPTIONAL.      "ALV Event Receiver 초기화시 각 ALV 구분을 위한 값
    METHODS:  "ALV Event
      handle_toolbar          FOR EVENT toolbar        OF cl_gui_alv_grid  IMPORTING sender
                                                                                     e_object
                                                                                     e_interactive,
      handle_user_command     FOR EVENT user_command   OF cl_gui_alv_grid  IMPORTING sender
                                                                                     e_ucomm,
      handle_onf4             FOR EVENT onf4           OF cl_gui_alv_grid  IMPORTING sender
                                                                                     e_fieldname
                                                                                     e_fieldvalue
                                                                                     es_row_no
                                                                                     er_event_data
                                                                                     et_bad_cells
                                                                                     e_display.
ENDCLASS.

CLASS lcl_alv_event IMPLEMENTATION.
  METHOD constructor.
    CALL METHOD super->constructor.
    alv_id = i_alv_id.
  ENDMETHOD.
  METHOD get_fieldcatalog_from_itab.
    DATA: ls_fieldcat TYPE lvc_s_fcat.
    DATA: lo_type   TYPE REF TO cl_abap_typedescr,
          lo_struct TYPE REF TO cl_abap_structdescr,
          lo_table  TYPE REF TO cl_abap_tabledescr.
    DATA: ld_line TYPE REF TO data.

    lo_type = cl_abap_typedescr=>describe_by_data( itab ).

    IF lo_type->kind EQ cl_abap_typedescr=>kind_struct.
      lo_struct ?= lo_type.
    ELSEIF lo_type->kind EQ cl_abap_typedescr=>kind_table.
      lo_table ?= lo_type.
      lo_struct ?= lo_table->get_table_line_type( ).
    ELSE.
      RETURN.
    ENDIF.

    CREATE DATA ld_line TYPE HANDLE lo_struct.

    DATA(lt_components) = cl_salv_data_descr=>read_structdescr( lo_struct ).

    LOOP AT cl_salv_ddic=>get_by_typedescr( lo_type ) INTO DATA(ls_dfies).
      ls_dfies-fieldname = VALUE #( lt_components[ sy-tabix ]-fieldname DEFAULT ls_dfies-fieldname ).

      IF ls_dfies-lfieldname IS NOT INITIAL.  "STRUCTURE
        ls_fieldcat = CORRESPONDING #( ls_dfies
                                       MAPPING key       = keyflag
                                               ref_table = precfield
                                               ref_field = lfieldname
                                               intlen    = leng
                                        EXCEPT rollname tabname ).
      ELSE.
        ls_fieldcat = CORRESPONDING #( ls_dfies
                                       MAPPING key       = keyflag
                                               ref_table = reftable
                                               ref_field = reffield
                                               intlen    = leng
                                       EXCEPT  tabname ).
      ENDIF.

      ls_fieldcat-col_pos = sy-tabix.
      IF ls_fieldcat-datatype EQ 'CLNT'.
        ls_fieldcat-tech = 'X'.
      ENDIF.

      IF ls_fieldcat-inttype EQ cl_abap_typedescr=>typekind_char OR ls_fieldcat-inttype EQ cl_abap_typedescr=>typekind_num.
        ls_fieldcat-intlen = ls_fieldcat-outputlen.
      ENDIF.

      IF ls_fieldcat-ref_table IS INITIAL." AND ls_fieldcat-f4availabl EQ abap_true.
        ASSIGN COMPONENT ls_fieldcat-fieldname OF STRUCTURE ld_line->* TO FIELD-SYMBOL(<lfv>).
        DESCRIBE FIELD <lfv> HELP-ID DATA(lv_helpid).
        IF lv_helpid CS '-'.
          CLEAR ls_fieldcat-rollname.
          SPLIT lv_helpid AT '-' INTO ls_fieldcat-ref_table DATA(lv_ref_field).
          IF ls_fieldcat-fieldname NE lv_ref_field.
            ls_fieldcat-ref_field = lv_ref_field.
          ENDIF.
        ELSE.
          CLEAR ls_fieldcat-f4availabl.
        ENDIF.
      ENDIF.

      IF ls_dfies-reftable EQ ls_dfies-precfield AND ls_dfies-reffield IS NOT INITIAL.
        CASE ls_fieldcat-datatype.
          WHEN 'CURR'.
            ls_fieldcat-cfieldname = ls_dfies-reffield.
          WHEN 'QUAN'.
            ls_fieldcat-qfieldname = ls_dfies-reffield.
        ENDCASE.
      ENDIF.
      IF ls_fieldcat-coltext IS INITIAL AND ls_fieldcat-reptext IS INITIAL AND ls_fieldcat-scrtext_l IS INITIAL AND ls_fieldcat-scrtext_m IS INITIAL AND ls_fieldcat-scrtext_s IS INITIAL.
        ls_fieldcat-coltext = ls_dfies-fieldtext.
      ENDIF.

      APPEND ls_fieldcat TO fieldcatalog.
    ENDLOOP.
  ENDMETHOD.
  METHOD handle_toolbar.
    CASE alv_id.
      WHEN gc_handle_0100.
        APPEND VALUE #( butn_type = 0
                        function  = 'EXCEL'
                        icon      = icon_xls
                        quickinfo = SWITCH #( sy-langu WHEN '3' THEN '엑셀' ELSE 'Excel' )
                        text      = SWITCH #( sy-langu WHEN '3' THEN '엑셀 다운로드' ELSE 'Download Excel' ) ) TO e_object->mt_toolbar.
        APPEND VALUE #( butn_type = 3 ) TO e_object->mt_toolbar.
        APPEND VALUE #( butn_type = 0                     "0 : 버튼, 3 : Separator
                        function  = 'CP_TEXT'             "ALV User-Command 의 E_UCOMM 값
                        icon      = icon_system_copy      "버튼에 표시할 아이콤
                        quickinfo = SWITCH #( sy-langu WHEN '3' THEN '텍스트 복사' ELSE 'Text Copy' )                "툴팁
                        text      = SWITCH #( sy-langu WHEN '3' THEN '선택 텍스트 복사' ELSE 'Copy selected text' ) ) TO e_object->mt_toolbar.

        APPEND VALUE #( butn_type = 0
                        function  = 'SAVE'
                        icon      = icon_system_save
                        quickinfo = SWITCH #( sy-langu WHEN '3' THEN '저장' ELSE 'Save' )
                        text      = SWITCH #( sy-langu WHEN '3' THEN '선택 항목 저장' ELSE 'Save selected rows' ) ) TO e_object->mt_toolbar.
        APPEND VALUE #( butn_type = 3 ) TO e_object->mt_toolbar.
        APPEND VALUE #( butn_type = 0
                        function  = 'REFRESH'
                        icon      = icon_refresh
                        quickinfo = SWITCH #( sy-langu WHEN '3' THEN '새로고침' ELSE 'Refresh' )
                        text      = SWITCH #( sy-langu WHEN '3' THEN '새로고침' ELSE 'Refresh' ) ) TO e_object->mt_toolbar.
    ENDCASE.
  ENDMETHOD.
  METHOD handle_user_command.
    CASE alv_id.
      WHEN gc_handle_0100.
        sender->check_changed_data( ).
        sender->get_selected_rows( IMPORTING et_index_rows = DATA(lt_rows) ).
        DELETE lt_rows WHERE rowtype IS NOT INITIAL.

        DATA: ls_rows LIKE LINE OF lt_rows.
        FIELD-SYMBOLS <lfs_disp> LIKE LINE OF gt_disp.

        CASE e_ucomm.
          WHEN 'CP_TEXT'.
            IF lt_rows[] IS INITIAL.
              MESSAGE s006(0k) DISPLAY LIKE 'E'.
              EXIT.
            ENDIF.

            LOOP AT lt_rows INTO ls_rows.
              READ TABLE gt_disp ASSIGNING <lfs_disp> INDEX ls_rows-index.
              IF sy-subrc NE 0.
                CONTINUE.
              ENDIF.
              <lfs_disp>-t_text = <lfs_disp>-s_text.
            ENDLOOP.

          WHEN 'SAVE'.
            IF lt_rows[] IS INITIAL.
              MESSAGE s006(0k) DISPLAY LIKE 'E'.
              EXIT.
            ENDIF.

            PERFORM save_translate USING lt_rows.
          WHEN 'EXCEL'.
            gt_excel = CORRESPONDING #( gt_disp ).
            "엑셀 다운로드
            lcl_excel=>download( it_itab              = gt_excel
                                 it_fieldcat          = gt_field_cat
                                 iv_auto_open         = abap_true ).
            EXIT.

          WHEN 'REFRESH'.
            CLEAR lt_rows.
            PERFORM get_data.
            go_grid->set_gridtitle( gv_grid_title ).
        ENDCASE.

        go_grid->refresh_table_display( EXPORTING is_stable      = VALUE lvc_s_stbl( row = 'X' col = 'X' )
                                        EXCEPTIONS finished      = 1
                                                   OTHERS        = 2 ).

        IF lt_rows[] IS NOT INITIAL.
          sender->set_selected_rows( EXPORTING it_index_rows = lt_rows ).
        ENDIF.
    ENDCASE.
  ENDMETHOD.
  METHOD handle_onf4.
    DATA: lt_return TYPE STANDARD TABLE OF ddshretval,
          ls_return LIKE LINE OF lt_return.
    FIELD-SYMBOLS : <lft> TYPE lvc_t_modi.

    "Event was Handled 속성
    er_event_data->m_event_handled = 'X'.

    CASE alv_id.
      WHEN gc_handle_0100.
        CASE e_fieldname.
          WHEN 'OBJECT'.
            CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
              EXPORTING
                retfield        = 'OBJECT'
                value_org       = 'S'
              TABLES
                value_tab       = gt_f4_obj
                return_tab      = lt_return
              EXCEPTIONS
                parameter_error = 1
                no_values_found = 2
                OTHERS          = 3.
            IF sy-subrc <> 0.
              EXIT.
            ENDIF.
          WHEN 'LXE_OBJTYPE'.
            CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
              EXPORTING
                retfield        = 'LXE_OBJTYPE'
                value_org       = 'S'
              TABLES
                value_tab       = gt_f4_lxe
                return_tab      = lt_return
              EXCEPTIONS
                parameter_error = 1
                no_values_found = 2
                OTHERS          = 3.
            IF sy-subrc <> 0.
              EXIT.
            ENDIF.
        ENDCASE.
    ENDCASE.

    IF e_display NE 'X'.
      READ TABLE lt_return INTO ls_return INDEX 1.
      "탐색도움말에서 선택한 값으로 화면 업데이트
      ASSIGN er_event_data->m_data->* TO <lft>.
      IF <lft> IS ASSIGNED.
        APPEND VALUE #( row_id    = es_row_no-row_id
                        fieldname = e_fieldname
                        value     = ls_return-fieldval ) TO <lft>.
      ENDIF.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

*--------------------------------------------------------------------*
* Sub Routine
*--------------------------------------------------------------------*
FORM initialization .
  sscrfields-functxt_01 = |{ icon_transport }Translation Export|.

*  p_slang = sy-langu.
*  p_tlang = SWITCH #( sy-langu WHEN gc_langu-ko THEN gc_langu-en ELSE gc_langu-ko ).

  p_slang = gc_langu-ko.
  p_tlang = gc_langu-en.
  p_obj = abap_true.

  gv_simple_view = xsdbool( sy-tcode EQ 'ZMASS_TRANSLATE' ).

  "사용 가능 오브젝트
  "일반 사용자의 경우 최소한의 오브젝트만
  gt_obj_lxe_map = VALUE #(
                        ( lxe_objtype = 'ACGR' object = 'ACGR' )  " Roles
                        ( lxe_objtype = 'DTEL' object = 'DTEL' )  " Data Elements
                        ( lxe_objtype = 'MESS' object = 'MESS' )  " Messages
                        ( lxe_objtype = 'MSAG' object = 'MSAG' )  " Message Classes
                        ( lxe_objtype = 'CA1'  object = 'FUGR' )  " Interface Texts (FUGR)
                        ( lxe_objtype = 'CA3'  object = 'FUGX' )  " Interface Texts (FUGX)
                        ( lxe_objtype = 'CA4'  object = 'PROG' )  " Interface Texts (PROG)
                        ( lxe_objtype = 'RPT1' object = 'FUGR' )  " Text Elements (FUGR)
                        ( lxe_objtype = 'RPT3' object = 'FUGX' )  " Text Elements (FUGX)
                        ( lxe_objtype = 'RPT4' object = 'PROG' )  " Text Elements (PROG)
                        ( lxe_objtype = 'RPT8' object = 'CLAS' )  " Text Elements (CLAS)
                        ( lxe_objtype = 'SRT1' object = 'FUGR' )  " Screen Painter Texts (FUGR)
                        ( lxe_objtype = 'SRT3' object = 'FUGX' )  " Screen Painter Texts (FUGX)
                        ( lxe_objtype = 'SRT4' object = 'PROG' )  " Screen Painter Texts (PROG)
                        ( lxe_objtype = 'SRT8' object = 'CLAS' )  " Screen Painter Texts (CLAS)
                        ( lxe_objtype = 'SHI3' object = 'SHI3' )  " Area Menu
                        ( lxe_objtype = 'SHLP' object = 'SHLP' )  " Search Helps
*                        ( LXE_OBJTYPE = 'SOTR'  OBJECT = 'SOTR' ) " Web Dynpr(OTR Short Texts)
                        ( lxe_objtype = 'TABT' object = 'TABL' )  " Table Descriptions
                        ( lxe_objtype = 'TADC' object = 'TABL' )  " Tables 값, 언어키별 테이블 값
                        ( lxe_objtype = 'TRAN' object = 'TRAN' )  " Transaction
                        ( lxe_objtype = 'VALU' object = 'DOMA' )  " Fixed Values for Domains
                        ( lxe_objtype = 'SSF'  object = 'SSFO' )  " Smartform
  ).

  IF gv_simple_view NE abap_true.  "개발자의 경우 추가 오브젝트까지 사용
    gt_obj_lxe_map = VALUE #( BASE gt_obj_lxe_map
                          ( lxe_objtype = 'CLAS' object = 'CLAS' ) " Classes
                          ( lxe_objtype = 'INTF' object = 'INTF' ) " Class Interfaces
                          ( lxe_objtype = 'DEVC' object = 'DEVC' ) " Packages
                          ( lxe_objtype = 'ENQU' object = 'ENQU' ) " Lock Objects
                          ( lxe_objtype = 'DOMA' object = 'DOMA' ) " Domains
                          ( lxe_objtype = 'CAD1' object = 'FUGR' ) " Developer Interface Docu (FUGR)
                          ( lxe_objtype = 'CAD4' object = 'PROG' ) " Developer Interface Docu (PROG)
                          ( lxe_objtype = 'SRH1' object = 'FUGR' ) " Screen Painter Headers (FUGR)
                          ( lxe_objtype = 'SRH3' object = 'FUGX' ) " Screen Painter Headers (FUGX)
                          ( lxe_objtype = 'SRH4' object = 'PROG' ) " Screen Painter Headers (PROG)
                          ( lxe_objtype = 'SRH8' object = 'CLAS' ) " Screen Painter Headers (CLAS)
                          ( lxe_objtype = 'SCT1' object = 'FUGR' ) " Screen Control (FUGR)
                          ( lxe_objtype = 'SCT4' object = 'PROG' ) " Screen Control (PROG)
                          ( lxe_objtype = 'SGPA' object = 'PARA' ) " SET/GET Parameters
                          ( lxe_objtype = 'FNC1' object = 'FUNC' ) " Function
                          ( lxe_objtype = 'TTYP' object = 'TTYP' ) " Table Types
                          ( lxe_objtype = 'VIEW' object = 'VIEW' ) " View
                          ( lxe_objtype = 'DDLS' object = 'DDLS' )  " CDS View
    ).
  ENDIF.


  DATA lt_object_text TYPE TABLE OF ko100.
  CALL FUNCTION 'TR_OBJECT_TABLE'
    TABLES
      wt_object_text = lt_object_text.
  .
  SORT lt_object_text BY object.

  SELECT obj_type, ktext FROM lxe_attobt WHERE lang EQ @sy-langu INTO TABLE @DATA(lt_lxe_attobt).
  SORT lt_lxe_attobt BY obj_type.

  LOOP AT gt_obj_lxe_map ASSIGNING FIELD-SYMBOL(<lfs>).
    READ TABLE lt_object_text INTO DATA(ls_object_text) WITH KEY object = <lfs>-object BINARY SEARCH.
    IF sy-subrc EQ 0.
      <lfs>-object_t = ls_object_text-text.
    ENDIF.
    READ TABLE lt_lxe_attobt INTO DATA(ls_lxe_attobt) WITH KEY obj_type = <lfs>-lxe_objtype BINARY SEARCH.
    IF sy-subrc EQ 0.
      <lfs>-ktext = ls_lxe_attobt-ktext.
    ENDIF.
  ENDLOOP.

  gt_f4_obj = CORRESPONDING #( gt_obj_lxe_map ).
  SORT gt_f4_obj. DELETE ADJACENT DUPLICATES FROM gt_f4_obj COMPARING ALL FIELDS.
  gt_f4_lxe = CORRESPONDING #( gt_obj_lxe_map ).
  SORT gt_f4_lxe. DELETE ADJACENT DUPLICATES FROM gt_f4_lxe COMPARING ALL FIELDS.
ENDFORM.

FORM at_selection_screen_output .
  LOOP AT SCREEN.

    CHECK screen-group1 IS NOT INITIAL.
    IF screen-group1 EQ 'OB0'.
      screen-required = '2'.
    ENDIF.
    IF screen-group1 EQ 'RO2'.
      screen-input = '0'.
    ENDIF.

    CASE screen-group1.
      WHEN 'OB0' OR 'OB1'.
        screen-active = SWITCH #( p_obj WHEN 'X' THEN 1 ELSE 0 ).
      WHEN 'RO1' OR 'RO2'.
        screen-active = SWITCH #( p_rol WHEN 'X' THEN 1 ELSE 0 ).
    ENDCASE.


    MODIFY SCREEN.
  ENDLOOP.
ENDFORM.

FORM at_selection_screen .
  CASE sscrfields-ucomm.
    WHEN 'FC01'.
      CALL TRANSACTION 'SLXT'.
  ENDCASE.
ENDFORM.

FORM get_data .
  DATA: lt_pcx_s1  TYPE TABLE OF lxe_pcx_s1,
        lv_collnam TYPE lxecollnam,
        lv_pstatus TYPE lxestatprc.

  CLEAR: gt_disp, gv_slang, gv_tlang.
  CLEAR: gr_object, gr_lxe_objtype.


  "오브젝트 유형, 번역 오브젝트 유형 제한
  IF p_obj IS NOT INITIAL.  "ABAP OBJECT
    gr_object = VALUE #( FOR ls IN gt_obj_lxe_map
                         WHERE ( object IN s_obje AND lxe_objtype IN s_lobj AND object NE p_obje AND lxe_objtype NE p_lobj )
                       ( sign = 'I' option = 'EQ'
                         low  = ls-object ) ).
    SORT gr_object. DELETE ADJACENT DUPLICATES FROM gr_object COMPARING ALL FIELDS.

    gr_lxe_objtype = VALUE #( FOR ls IN gt_obj_lxe_map
                              WHERE ( object IN s_obje AND lxe_objtype IN s_lobj AND object NE p_obje AND lxe_objtype NE p_lobj )
                            ( sign = 'I' option = 'EQ'
                              low  = ls-lxe_objtype ) ).
    SORT gr_lxe_objtype. DELETE ADJACENT DUPLICATES FROM gr_lxe_objtype COMPARING ALL FIELDS.
  ELSE. "ROLL
    gr_object = VALUE #( ( sign = 'I' option = 'EQ' low = p_obje ) ).
    gr_lxe_objtype = VALUE #( ( sign = 'I' option = 'EQ' low = p_lobj ) ).
  ENDIF.

  IF gr_object[] IS INITIAL OR gr_lxe_objtype[] IS INITIAL.
    EXIT.
  ENDIF.

  "Languages in the Translation Environment
  SELECT
    r3_lang,
    language
  FROM lxe_t002x
  WHERE r3_lang IN ( @p_slang, @p_tlang )
    AND is_r3_lang EQ @abap_true
  INTO TABLE @DATA(lt_lxe_t002x).
  IF sy-subrc EQ 0.
    TRY.
        gv_slang = lt_lxe_t002x[ r3_lang = p_slang ]-language.
        gv_tlang = lt_lxe_t002x[ r3_lang = p_tlang ]-language.
      CATCH cx_sy_itab_line_not_found INTO DATA(lv_cx).
        MESSAGE s000(0k) WITH TEXT-e02 DISPLAY LIKE 'E'.
        LEAVE LIST-PROCESSING .
    ENDTRY.
  ENDIF.

  DATA(lo_progress) = NEW lcl_progress( 100 ).
  lo_progress->set_percent( 'Object Text Read' ).

  "번역 오브젝트별로 개별 오브젝트 조회
  DATA(lt_tadir) = lcl_object=>get_object_list( ).

  "번역 오브젝트 리스트
  LOOP AT gt_obj_lxe_map INTO DATA(ls_obj_lxe_map) WHERE lxe_objtype IN gr_lxe_objtype AND object IN gr_object.
    LOOP AT lt_tadir INTO DATA(ls_tadir) WHERE object EQ ls_obj_lxe_map-object.

      "번역 오브젝트
      IF ls_obj_lxe_map-lxe_objtype NE 'SSF'.   "번역 오브젝트 유형이 스마트폼이 아닌 경우
        CLEAR: lt_pcx_s1, lv_collnam, lv_pstatus.

        " Source language -> Target language
        CALL FUNCTION 'LXE_OBJ_TEXT_PAIR_READ'
          EXPORTING
            t_lang    = gv_tlang
            s_lang    = gv_slang
            custmnr   = '999999'
            objtype   = ls_obj_lxe_map-lxe_objtype
            objname   = ls_tadir-lxe_objname
            read_only = 'X'
          IMPORTING
            collnam   = lv_collnam
            pstatus   = lv_pstatus
          TABLES
            lt_pcx_s1 = lt_pcx_s1.
        LOOP AT lt_pcx_s1 INTO DATA(ls_pcx_s1).
          gs_disp = CORRESPONDING #( ls_tadir ).
          MOVE-CORRESPONDING ls_pcx_s1 TO gs_disp.
          gs_disp-lxe_objtype = ls_obj_lxe_map-lxe_objtype.
          gs_disp-lxe_ktext   = ls_obj_lxe_map-ktext.

          gs_disp-lxe_collname = lv_collnam.

          " Web dynpro ## SOTR object# Alias# Textkey# ##
          gs_disp-textkey = COND #( WHEN ls_obj_lxe_map-lxe_objtype EQ 'SOTR' THEN ls_tadir-obj_name ELSE gs_disp-textkey ).


          "상태 표시
          _excp_field gs_disp-s_text gs_disp-t_text gs_disp-excp_field.
          APPEND gs_disp TO gt_disp.
        ENDLOOP.
      ELSE.   "스마트폼일 경우
        LOOP AT lcl_object=>get_smartform_text( iv_formname = CONV #( ls_tadir-obj_name )
                                                iv_slang    = p_slang
                                                iv_tlang    = p_tlang ) INTO DATA(ls_stxftxt).
          gs_disp = CORRESPONDING #( ls_tadir ).
          gs_disp-lxe_objtype = ls_obj_lxe_map-lxe_objtype.
          gs_disp-lxe_ktext   = ls_obj_lxe_map-ktext.
          gs_disp-s_text      = ls_stxftxt-s_text.
          gs_disp-t_text      = ls_stxftxt-t_text.
          gs_disp-lxe_objname = ls_stxftxt-lxe_objname.

          CONCATENATE ls_stxftxt-iname ls_stxftxt-linenr ls_stxftxt-tdformat
                 INTO gs_disp-textkey SEPARATED BY space.

          "상태 표시
          _excp_field gs_disp-s_text gs_disp-t_text gs_disp-excp_field.
          APPEND gs_disp TO gt_disp.
        ENDLOOP.
      ENDIF.
    ENDLOOP.
  ENDLOOP.

  "기 번역항목 제어
  IF p_check IS NOT INITIAL.
    DELETE gt_disp WHERE excp_field EQ '3'
                      OR excp_field EQ '2'.
  ENDIF.

  "건수 표시
  DATA: lv_cnt_r TYPE i VALUE IS INITIAL,
        lv_cnt_y TYPE i VALUE IS INITIAL,
        lv_cnt_g TYPE i VALUE IS INITIAL.

  lo_progress->initial( 1 ).
  lo_progress->set_percent( 'Object Description Read' ).

  "오브젝트 내역
  DATA(lt_obj_desc) = lcl_object=>get_object_descript( ).
  LOOP AT gt_disp ASSIGNING FIELD-SYMBOL(<lfs_disp>).
    lv_cnt_r = lv_cnt_r + SWITCH #( <lfs_disp>-excp_field WHEN '1' THEN 1 ELSE 0 ).
    lv_cnt_y = lv_cnt_y + SWITCH #( <lfs_disp>-excp_field WHEN '2' THEN 1 ELSE 0 ).
    lv_cnt_g = lv_cnt_g + SWITCH #( <lfs_disp>-excp_field WHEN '3' THEN 1 ELSE 0 ).

    READ TABLE lt_obj_desc INTO DATA(ls_obj_desc) WITH TABLE KEY object   = <lfs_disp>-object
                                                                 obj_name = <lfs_disp>-obj_name
                                                                 spras    = sy-langu.
    IF sy-subrc NE 0 OR ls_obj_desc-obj_desc IS INITIAL.
      READ TABLE lt_obj_desc INTO ls_obj_desc WITH TABLE KEY object   = <lfs_disp>-object
                                                             obj_name = <lfs_disp>-obj_name
                                                             spras    = gc_langu-ko.
      IF sy-subrc NE 0 OR ls_obj_desc-obj_desc IS INITIAL.
        READ TABLE lt_obj_desc INTO ls_obj_desc WITH TABLE KEY object   = <lfs_disp>-object
                                                               obj_name = <lfs_disp>-obj_name
                                                               spras    = gc_langu-en.
      ENDIF.
    ENDIF.
    IF sy-subrc EQ 0.
      <lfs_disp>-obj_desc = ls_obj_desc-obj_desc.
    ENDIF.
    <lfs_disp>-s_lang = p_slang.
    <lfs_disp>-t_lang = p_tlang.
  ENDLOOP.

  SORT gt_disp BY devclass object obj_name lxe_objtype lxe_objname textkey.

  MESSAGE s000(0k) WITH |Total: { lines( gt_disp ) NUMBER = USER }, |
                    |Green: { lv_cnt_g NUMBER = USER }, |
                    |Yellow: { lv_cnt_y NUMBER = USER }, |
                    |Red: { lv_cnt_r NUMBER = USER }| INTO gv_grid_title.
ENDFORM.

FORM f4_object .
  CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
    EXPORTING
      retfield        = 'OBJECT'
      dynpprog        = sy-repid
      dynpnr          = sy-dynnr
      dynprofield     = 'S_OBJE'
      value_org       = 'S'
    TABLES
      value_tab       = gt_f4_obj
    EXCEPTIONS
      parameter_error = 1
      no_values_found = 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.
ENDFORM.

FORM f4_lxe_objtype .
  CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
    EXPORTING
      retfield        = 'LXE_OBJTYPE'
      dynpprog        = sy-repid
      dynpnr          = sy-dynnr
      dynprofield     = 'S_LOBJ'
      value_org       = 'S'
    TABLES
      value_tab       = gt_f4_lxe
    EXCEPTIONS
      parameter_error = 1
      no_values_found = 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.
ENDFORM.

FORM save_translate USING pt_rows TYPE lvc_t_row.
  DATA: ls_stxftxt TYPE stxftxt,
        ls_lxe_log TYPE lxe_log.
  DATA: lv_lxestatprc TYPE lxestatprc,
        lt_lxe_pcx_s1 TYPE STANDARD TABLE OF lxe_pcx_s1.
  DATA: lv_cnt_e TYPE i,
        lv_cnt_s TYPE i.

  CONSTANTS: BEGIN OF lc_smartform_table,
               txt TYPE tabname16 VALUE 'STXFTXT',
               log TYPE tabname16 VALUE 'LXE_LOG',
             END OF lc_smartform_table.

  IF NOT zcl_cmz_util=>popup_continue_yes_no( iv_title         = TEXT-q02
                                              iv_textline1     = TEXT-q01 ).
    EXIT.
  ENDIF.


  CLEAR: lv_cnt_e, lv_cnt_s.

  DATA(lo_progress) = NEW lcl_progress( lines( pt_rows ) ).

  LOOP AT pt_rows INTO DATA(ls_rows).
    lo_progress->set_percent( TEXT-t01 ).
    READ TABLE gt_disp ASSIGNING FIELD-SYMBOL(<lfs_disp>) INDEX ls_rows-index.
    IF sy-subrc NE 0.
      CONTINUE.
    ENDIF.

    CLEAR <lfs_disp>-message.

    IF <lfs_disp>-lxe_objtype EQ 'SSF'. "SMARTFORM
      ls_stxftxt = VALUE #( spras    = <lfs_disp>-t_lang
                            txtype   = 'F'
                            formname = <lfs_disp>-lxe_objname
                            tdline   = <lfs_disp>-t_text ).

      SPLIT <lfs_disp>-textkey AT space INTO  ls_stxftxt-iname
                                          ls_stxftxt-linenr
                                          ls_stxftxt-tdformat
                                    IN CHARACTER MODE.

      ls_lxe_log = VALUE #( custmnr = '999999'
                            targlng = gv_tlang
                            objtype = <lfs_disp>-lxe_objtype
                            objname = <lfs_disp>-lxe_objname
                            uname   = sy-uname
                            udate   = sy-datlo
                            utime   = sy-timlo ).

      MODIFY (lc_smartform_table-txt) FROM ls_stxftxt.
      IF sy-subrc NE 0.
        ROLLBACK WORK.
        <lfs_disp>-status = icon_message_error.
      ELSE.
        MODIFY (lc_smartform_table-log) FROM ls_lxe_log.
        IF sy-subrc NE 0.
          ROLLBACK WORK.
          <lfs_disp>-status = icon_message_error.
        ELSE.
          COMMIT WORK AND WAIT.
          <lfs_disp>-status = icon_system_okay.
        ENDIF.
      ENDIF.
    ELSE.
      CLEAR: lt_lxe_pcx_s1.

      IF <lfs_disp>-unitmlt IS NOT INITIAL AND <lfs_disp>-unitmlt < strlen( <lfs_disp>-t_text ).
        <lfs_disp>-status = icon_message_error.
        <lfs_disp>-message = |{ TEXT-f04 }{ replace( val = TEXT-e03 sub = '&2' with = |{ <lfs_disp>-unitmlt }| occ = 1 ) }|.
      ELSE.
        CALL FUNCTION 'LXE_OBJ_TEXT_PAIR_READ'
          EXPORTING
            t_lang    = gv_tlang
            s_lang    = gv_slang
            custmnr   = '999999'
            objtype   = <lfs_disp>-lxe_objtype
            objname   = <lfs_disp>-lxe_objname
            read_only = ''
          IMPORTING
            pstatus   = lv_lxestatprc
          TABLES
            lt_pcx_s1 = lt_lxe_pcx_s1.

        SORT lt_lxe_pcx_s1 BY textkey.
        READ TABLE lt_lxe_pcx_s1 ASSIGNING FIELD-SYMBOL(<lfs_pcx>) WITH KEY textkey = <lfs_disp>-textkey BINARY SEARCH.
        IF sy-subrc EQ 0.
          <lfs_pcx>-t_text = <lfs_disp>-t_text.
        ENDIF.
        CALL FUNCTION 'LXE_OBJ_TEXT_PAIR_WRITE'
          EXPORTING
            t_lang    = gv_tlang
            s_lang    = gv_slang
            custmnr   = '999999'
            objtype   = <lfs_disp>-lxe_objtype
            objname   = <lfs_disp>-lxe_objname
          IMPORTING
            pstatus   = lv_lxestatprc
          TABLES
            lt_pcx_s1 = lt_lxe_pcx_s1.

        IF lv_lxestatprc EQ  'S'.
          <lfs_disp>-status = icon_system_okay.
        ELSE.
          <lfs_disp>-status = icon_message_error.
        ENDIF.
      ENDIF.
    ENDIF.

    IF <lfs_disp>-status EQ icon_system_okay.
      ADD 1 TO lv_cnt_s.

      _excp_field <lfs_disp>-s_text <lfs_disp>-t_text <lfs_disp>-excp_field.
    ELSE.
      ADD 1 TO lv_cnt_e.
    ENDIF.

    IF <lfs_disp>-message IS INITIAL.
      <lfs_disp>-message = COND #( WHEN <lfs_disp>-status EQ icon_system_okay THEN 'OK' ELSE 'ERROR' ).
    ENDIF.
  ENDLOOP.

  DATA(lv_msgty) = COND sy-msgty( WHEN lv_cnt_s > 0 AND lv_cnt_e > 0 THEN 'W'
                                  WHEN lv_cnt_e = 0 THEN 'S'
                                  ELSE 'E' ).
  MESSAGE i000(0k) WITH |{ lv_cnt_e + lv_cnt_s NUMBER = USER } 건의 데이터가 처리 되었습니다(성공 : { lv_cnt_s NUMBER = USER }, 실패 : { lv_cnt_e NUMBER = USER })|
    DISPLAY LIKE lv_msgty.
ENDFORM.

FORM create_object_alv_0100 .
  CHECK go_grid IS NOT BOUND.

  go_grid = NEW #( COND #( WHEN cl_gui_alv_grid=>offline( ) IS INITIAL
                           THEN NEW cl_gui_docking_container( extension = 2500 side = cl_gui_docking_container=>dock_at_top )
                           ELSE VALUE #( ) ) ).

  DATA(lt_f4) = VALUE lvc_t_f4( ( fieldname = 'OBJECT'      register = 'X' )
                                ( fieldname = 'LXE_OBJTYPE' register = 'X' ) ).
  go_grid->register_f4_for_fields( lt_f4 ).

  gt_field_cat = lcl_alv_event=>get_fieldcatalog_from_itab( gt_disp ).
  LOOP AT gt_field_cat ASSIGNING FIELD-SYMBOL(<lfs>).
    <lfs>-f4availabl = xsdbool( <lfs>-f4availabl EQ abap_true OR line_exists( lt_f4[ fieldname = <lfs>-fieldname ] ) ).

    CASE <lfs>-fieldname.
      WHEN 'LXE_COLLNAME'.
        <lfs>-tech = 'X'.
      WHEN 'M_LANG'.
        <lfs>-coltext = TEXT-f00.
        <lfs>-emphasize = gc_alv_color-m_lang.
      WHEN 'S_LANG'.
        <lfs>-coltext = TEXT-f01.
        <lfs>-emphasize = gc_alv_color-s_lang.
      WHEN 'S_TEXT'.
        <lfs>-coltext = TEXT-f02.
      WHEN 'T_LANG'.
        <lfs>-coltext = TEXT-f03.
        <lfs>-emphasize = gc_alv_color-t_lang.
        <lfs>-no_convext = abap_true.
        <lfs>-icon = abap_false.
      WHEN 'T_TEXT'.
        <lfs>-coltext = TEXT-f04.
        <lfs>-edit = 'X'.
        <lfs>-no_convext = abap_true.
        <lfs>-icon = abap_false.
      WHEN 'STATUS'.
        <lfs>-coltext = TEXT-f05.
        <lfs>-just = 'C'.
      WHEN 'UNITMLT'.
        <lfs>-no_zero = abap_true.
    ENDCASE.
  ENDLOOP.

  DATA(lo_event) = NEW lcl_alv_event( gc_handle_0100 ).
  SET HANDLER lo_event->handle_toolbar FOR go_grid.
  SET HANDLER lo_event->handle_user_command FOR go_grid.
  SET HANDLER lo_event->handle_onf4 FOR go_grid.

  DATA(lt_sort) = VALUE lvc_t_sort( up = 'X'
                                    ( spos = 1  fieldname = 'DEVCLASS' )
                                    ( spos = 2  fieldname = 'OBJECT' )
                                    ( spos = 3  fieldname = 'OBJ_NAME' ) ).

  go_grid->set_table_for_first_display(
    EXPORTING
      is_variant                    = VALUE #( report    = sy-repid
                                               handle    = gc_handle_0100
                                               username  = sy-uname )
      i_save                        = 'A'
      i_default                     = 'X'
      is_layout                     = VALUE #( zebra      = ' '
                                               sel_mode   = 'A'
                                               cwidth_opt = 'X'
                                               smalltitle = 'X'
                                               grid_title = gv_grid_title
                                               info_fname = 'INFO_FIELD'
                                               excp_fname = 'EXCP_FIELD' )
      it_toolbar_excluding          =  VALUE #( ( cl_gui_alv_grid=>mc_fc_loc_copy_row )
                                                ( cl_gui_alv_grid=>mc_fc_loc_delete_row )
                                                ( cl_gui_alv_grid=>mc_fc_loc_append_row )
                                                ( cl_gui_alv_grid=>mc_fc_loc_insert_row )
                                                ( cl_gui_alv_grid=>mc_fc_loc_move_row )
                                                ( cl_gui_alv_grid=>mc_fc_loc_paste_new_row )
                                                ( cl_gui_alv_grid=>mc_fc_loc_paste )
                                                ( cl_gui_alv_grid=>mc_fc_loc_undo )
                                                ( cl_gui_alv_grid=>mc_fc_loc_copy )
                                                ( cl_gui_alv_grid=>mc_fc_loc_cut )
                                                ( cl_gui_alv_grid=>mc_fc_refresh )
                                                ( cl_gui_alv_grid=>mc_fc_info )
                                                ( cl_gui_alv_grid=>mc_fc_graph ) )
    CHANGING
      it_outtab                     = gt_disp
      it_fieldcatalog               = gt_field_cat
      it_sort                       = lt_sort
    EXCEPTIONS
      invalid_parameter_combination = 1
      program_error                 = 2
      too_many_lines                = 3
      OTHERS                        = 4
  ).

ENDFORM.

*--------------------------------------------------------------------*
* PBO
*--------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
  SET PF-STATUS '100'.
  SET TITLEBAR '100'.
ENDMODULE.

MODULE create_object_alv_0100 OUTPUT.
  PERFORM create_object_alv_0100.
ENDMODULE.

*--------------------------------------------------------------------*
* PAI
*--------------------------------------------------------------------*
MODULE user_command_0100_exit INPUT.
  ok_code = sy-ucomm.
  CLEAR sy-ucomm.
  CASE ok_code.
    WHEN 'BACK' OR 'CANC'.
      LEAVE TO SCREEN 0.
    WHEN 'EXIT'.
      LEAVE PROGRAM.
  ENDCASE.
  CLEAR ok_code.
ENDMODULE.

MODULE user_command_0100 INPUT.
  ok_code = sy-ucomm.
  CLEAR sy-ucomm.
ENDMODULE.

*--------------------------------------------------------------------*
* Event
*--------------------------------------------------------------------*
INITIALIZATION.
  PERFORM initialization.

AT SELECTION-SCREEN OUTPUT.
  PERFORM at_selection_screen_output.

AT SELECTION-SCREEN.
  PERFORM at_selection_screen.

AT SELECTION-SCREEN ON s_obje.
  IF s_obje-low IS NOT INITIAL AND NOT line_exists( gt_f4_obj[ object = s_obje-low ] ).
    MESSAGE e002(00).
  ENDIF.
  IF s_obje-high IS NOT INITIAL AND NOT line_exists( gt_f4_obj[ object = s_obje-high ] ).
    MESSAGE e002(00).
  ENDIF.

AT SELECTION-SCREEN ON s_lobj.
  IF s_lobj-low IS NOT INITIAL AND NOT line_exists( gt_f4_lxe[ lxe_objtype = s_lobj-low ] ).
    MESSAGE e002(00).
  ENDIF.
  IF s_lobj-high IS NOT INITIAL AND NOT line_exists( gt_f4_lxe[ lxe_objtype = s_lobj-high ] ).
    MESSAGE e002(00).
  ENDIF.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR s_obje-low .
  PERFORM f4_object.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR s_obje-high .
  PERFORM f4_object.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR s_lobj-low.
  PERFORM f4_lxe_objtype.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR s_lobj-high.
  PERFORM f4_lxe_objtype.

START-OF-SELECTION.
  IF p_obj IS NOT INITIAL AND s_devc[] IS INITIAL.
    MESSAGE s055(00) DISPLAY LIKE 'E'.
    EXIT.
  ENDIF.

  PERFORM get_data .

  IF gt_disp[] IS INITIAL.
    RETURN.
  ELSE.
    IF go_grid IS BOUND.
      go_grid->refresh_table_display( EXPORTING is_stable      = VALUE lvc_s_stbl( row = 'X' col = 'X' )
                                      EXCEPTIONS finished      = 1
                                                 OTHERS        = 2 ).
    ENDIF.
    CALL SCREEN 100.
  ENDIF.

 

*GUI Texts
*----------------------------------------------------------
* 100 --> Mass Translation Editor
* 100 --> Mass Translation Editor

*Text elements
*----------------------------------------------------------
* BL1 선택조건
* BL2 조회조건
* E01 선택#가능한#오브젝트#타입이#없습니다
* E02 입력한 언어가 올바르지 않습니다
* F01 원어
* F02 원본 언어 텍스트
* F03 대어
* F04 대상 언어 텍스트
* F05 처리상태
* Q01 선택한 항목의 텍스트를 적용 하시겠습니까?
* Q02 질문
* T01 오브젝트 언어 업데이트


*Selection texts
*----------------------------------------------------------
* P_CHECK         기 번역항목 제거
* P_OBJ         ABAP Object
* P_ROL         Roll
* P_SLANG         원본 언어
* P_TLANG         대상 언어
* S_NAME         오브젝트이름
* P_FILEN D       .
* P_LOBJ D       .
* P_OBJE D       .
* S_DEVC D       .
* S_LOBJ D       .
* S_OBJE D       .
* S_ROLL D       .
* S_USER D       .


*Messages
*----------------------------------------------------------
*
* Message class: 00
*055   모든 필수 입력 필드에 값을 입력하십시오.
*
* Message class: YISPIMS01
*000   &1 &2 &3 &4
*004   입력값이 유효하지 않습니다
*005   데이터가 존재하지 않습니다
*006   선택한 항목이 없습니다
*007   Total: &1 , Green: &2 , Yellow: &3 , Red: &4
*008   &1 건의 데이터가 처리되었습니다(성공 : &2, 실패 : &3)

 

댓글