본문 바로가기

ABAP

Internal Table 속성에 맞게 Field Catalog 설정하기

반응형

ABAP 프로그램 만들다 보면 필드카탈로그 일일이 설정하기 귀찮을 때가 있죠..

그럴 때 유용한 클래스 입니다.

 

일단 클래스로 만들 것이기 때문에 Class Builder로 GoGo 

이름은 대충 지어주고 생성 버튼 클릭 ▼

T-CODE : SE24

 

내역 대충 써주고 넘어가죠 ▼

 

방법을 두개 입력

GET_FCAT_FOR_ITAB / Static Method / Public

GET_ELEMENTS / Static Method / Private

 

각 방법에 매개변수를 설정하기 GET_FCAT_FOR_ITAB 먼저 클릭하고 매개변수 클릭 ▼

 

 

IT_TABLE / Importing / TABLE

RT_FCAT / Exporting / LVC_T_FCAT

다 입력하였으면 방법 눌러서 다시 뒤로 ▼

 

이번엔 GET_ELEMENTS 매개변수 설정하러 가시죠 ▼

 

I_COMP_T / Importing / CL_ABAP_STRUCTDESCR=>COMPONENT_TABLE

R_COMP_T / Returning / CL_ABAP_STRUCTDESCR=>COMPONENT_TABLE

다 입력하였으면 방법 눌러서 다시 뒤로 ▼

 

이제 각 방법의 소스를 작성하러 갑시다~!

소스를 작성할 방법 선택하고 버튼 누르거나 해당 방법 더블클릭

먼저 GET_FCAT_FOR_ITAB 작성하죠 ▼

 

 

아래의 코드를 긁어줍시다. 


GET_FCAT_FOR_ITAB 소스코드

 

 

    FIELD-SYMBOLS<WA> TYPE ANY,
                   <CP> TYPE ANY.

    DATALV_SREF TYPE REF TO DATA,
          LV_CREF TYPE REF TO DATA.

    DATALC_STRU_REF  TYPE REF TO CL_ABAP_STRUCTDESCR,
          LC_CLSS_REF  TYPE REF TO CL_ABAP_CLASSDESCR,
          LC_ELEM_REF  TYPE REF TO CL_ABAP_ELEMDESCR,
          LC_TAB_REF   TYPE REF TO CL_ABAP_TABLEDESCR,
          LT_COMP      TYPE CL_ABAP_STRUCTDESCR=>COMPONENT_TABLE,
          LT_COMP_     LIKE LT_COMP,
          LS_COMP      LIKE LINE OF LT_COMP,
          LV_SIZE      TYPE I,
          LV_INDEX     TYPE I,
          LV_HLPID     TYPE STRING,
          LV_SNAME     TYPE STRING,
          LS_FCAT      TYPE LVC_S_FCAT,
          LS_DFIES     TYPE DFIES,
          LT_TAB       TYPE TABLE OF STRING,
          LV_REFSTRUCT TYPE SWCONTDEF-REFSTRUCT,
          LV_REFFIELD  TYPE SWCONTDEF-REFFIELD,
          LS_DD04V     TYPE DD04V,
          LV_LEN       TYPE I.


    LC_TAB_REF  ?= CL_ABAP_TYPEDESCR=>DESCRIBE_BY_DATAIT_TABLE ).
    LC_STRU_REF ?= LC_TAB_REF->GET_TABLE_LINE_TYPE).

*-- Check Reference
    LC_CLSS_REF ?= CL_ABAP_TYPEDESCR=>DESCRIBE_BY_OBJECT_REFLC_STRU_REF ).
    IF LC_CLSS_REF->GET_RELATIVE_NAME<> 'CL_ABAP_STRUCTDESCR'.
*      RAISE not_a_structure.
    ENDIF.

*-- Recursive Search for Include.
    LT_COMP_ LC_STRU_REF->GET_COMPONENTS).
* Table Type 제거
    LOOP AT LT_COMP_ INTO LS_COMP.
      LC_CLSS_REF ?= CL_ABAP_TYPEDESCR=>DESCRIBE_BY_OBJECT_REFLS_COMP-TYPE ).
      IF LC_CLSS_REF->GET_RELATIVE_NAME'CL_ABAP_TABLEDESCR'.
        DELETE LT_COMP_.
      ENDIF.
    ENDLOOP.


    LT_COMP  GET_ELEMENTSLT_COMP_ ).
    LV_SIZE  LINESLT_COMP ).
    LV_SNAME LC_STRU_REF->ABSOLUTE_NAME."get_relative_name( ).

*-- get memebers
    CREATE DATA LV_SREF TYPE (LV_SNAME).
    ASSIGN LV_SREF->TO <WA>.

    LOOP AT LT_COMP INTO LS_COMP.
      ASSIGN COMPONENT LS_COMP-NAME OF STRUCTURE <WA> TO <CP>.
      DESCRIBE FIELD <CP> HELP-ID LV_HLPID.

**    DO lv_size TIMES.
**      lv_index = lv_index + 1.
**
**      UNASSIGN <cp>.
**      ASSIGN COMPONENT lv_index OF STRUCTURE <wa> TO <cp>.
**      clear lv_hlpid.
**      DESCRIBE FIELD <cp> HELP-ID lv_hlpid.

      " XXX-VVV, VVV, SPACE
      CLEAR LT_TABLT_TAB[].
      SPLIT LV_HLPID AT '-' INTO TABLE LT_TAB.
      LV_LEN LINESLT_TAB ).
      READ TABLE LT_COMP INTO LS_COMP INDEX LV_INDEX.

      IF LV_LEN 2.     "struct + field
        READ TABLE LT_TAB INTO LV_REFSTRUCT INDEX 1.
        READ TABLE LT_TAB INTO LV_REFFIELD  INDEX 2.

        CALL FUNCTION 'SWP_DDIC_FIELD_INFO_GET'
          EXPORTING
            REFSTRUCT            LV_REFSTRUCT
            REFFIELD             LV_REFFIELD
            LANGUAGE             SY-LANGU
          IMPORTING
            FIELD_ATTRIBUTES     LS_DFIES
          EXCEPTIONS
            FIELD_INFO_NOT_FOUND 1
            OTHERS               9.

        IF SY-SUBRC 0.
          MOVE-CORRESPONDING LS_DFIES TO LS_FCAT.
*       Data Type 에 따라서
*       Currency, Quanitity 참조 Field 가 있는지 확인 한다
*       없는경우 삭제 한다
          CASE LS_DFIES-DATATYPE.
            WHEN 'CURR' OR 'QUAN'.
              READ TABLE LT_COMP WITH KEY NAME LS_DFIES-REFFIELD
                   TRANSPORTING NO FIELDS.
              IF SY-SUBRC 0.
                CASE LS_DFIES-DATATYPE.
                  WHEN 'CURR' .
                    LS_FCAT-CFIELDNAME LS_DFIES-REFFIELD.
                  WHEN 'QUAN'.
                    LS_FCAT-QFIELDNAME LS_DFIES-REFFIELD.
                ENDCASE.
              ENDIF.
          ENDCASE.

          LS_FCAT-REF_TABLE LV_REFSTRUCT.
          LS_FCAT-REF_FIELD LV_REFFIELD.
          LS_FCAT-TABNAME   ''.
          "[Add]
          LS_FCAT-REPTEXT   LS_FCAT-COLTEXT LS_FCAT-SCRTEXT_L.
          LS_FCAT-FIELDNAME LS_COMP-NAME.

          IF LS_FCAT-COL_POS IS INITIAL."ADD
            LS_FCAT-COL_POS LV_INDEX"ADD
          ENDIF.                        "ADD
          APPEND LS_FCAT TO RT_FCAT.
        ELSE.
**          RAISE no_ddic.
        ENDIF.

      ELSEIF LV_LEN 1.   "DataElement
        READ TABLE LT_TAB INTO LV_REFFIELD INDEX 1.

        CALL FUNCTION 'DDIF_DTEL_GET'
          EXPORTING
            NAME          LV_REFFIELD
            LANGU         SY-LANGU
          IMPORTING
            DD04V_WA      LS_DD04V
          EXCEPTIONS
            ILLEGAL_INPUT 1
            OTHERS        2.

        IF SY-SUBRC 0.
          MOVE-CORRESPONDING LS_DD04V TO LS_FCAT.

          LS_FCAT-REF_TABLE ''.
          LS_FCAT-TABNAME   ''.

          "[Add]
          LS_FCAT-REPTEXT LS_FCAT-COLTEXT LS_FCAT-SCRTEXT_L.

          IF LV_REFFIELD <> LS_COMP-NAME.
            LS_FCAT-REF_FIELD LV_REFFIELD.
          ENDIF.

          LS_FCAT-FIELDNAME LS_COMP-NAME.
          IF LS_FCAT-COL_POS IS INITIAL.
            LS_FCAT-COL_POS LV_INDEX.
          ENDIF.
          APPEND LS_FCAT TO RT_FCAT.
        ELSE.
*          RAISE no_ddic.
        ENDIF.

      ELSEIF LV_LEN 0.     "AND iv_cfield = 'X'.    "Custom Field

*
*        lc_elem_ref ?= ls_comp-type.
*        ls_fcat-fieldname = ls_comp-name.
*        ls_fcat-inttype   = lc_elem_ref->type_kind.
*        ls_fcat-intlen    = lc_elem_ref->length.
*        ls_fcat-decimals  = ls_fcat-decimals_o = lc_elem_ref->decimals.
*        ls_fcat-outputlen = lc_elem_ref->output_length.
*
*        IF ls_fcat-COL_POS IS INITIAL.
*          ls_fcat-COL_POS = lv_index.
*        ENDIF.
*
*        APPEND ls_fcat TO rt_fcat.


        DATA:   lv_relative_Name TYPE STRING.


        LC_CLSS_REF    ?= CL_ABAP_TYPEDESCR=>DESCRIBE_BY_OBJECT_REFLS_COMP-TYPE ).
        lv_relative_Name LC_CLSS_REF->GET_RELATIVE_NAME.

        IF lv_relative_Name 'CL_ABAP_STRUCTDESCR' .  "다음에...
*      -- Recursive Search for Include.
*          DATA: lt_comp1_  TYPE cl_abap_structdescr=>component_table.
*data:     lc_stru_ref_1  TYPE REF TO cl_abap_structdescr,
*          lc_clss_ref_1  TYPE REF TO cl_abap_classdescr,
*          lc_elem_ref_1  TYPE REF TO cl_abap_elemdescr,
*          lc_tab_ref_1   TYPE REF TO cl_abap_tabledescr.
*
*          lc_tab_ref_1  ?= cl_abap_typedescr=>describe_by_data( ls_comp-type->COMPONENT ).
*          lc_stru_ref_1 ?= lc_tab_ref->get_table_line_type( ).

*                lt_comp1_ = ls_comp-type->COMPONENTS.
*          CASE ls_comp-type->kind.
*            WHEN cl_abap_structdescr=>kind_struct    "S
*              OR cl_abap_structdescr=>kind_table.    "T
*              CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
*                EXPORTING
*                  i_structure_name       = lv_structure_name
*                  i_bypassing_buffer     = 'X'
*                CHANGING
*                  ct_fieldcat            = lt_fieldcat
*                EXCEPTIONS
*                  inconsistent_interface = 1
*                  program_error          = 2.
*
*          ENDCASE.
        ELSE.
          LC_ELEM_REF ?= LS_COMP-TYPE.
          LS_FCAT-FIELDNAME LS_COMP-NAME.
          LS_FCAT-INTTYPE   LC_ELEM_REF->TYPE_KIND.
          LS_FCAT-INTLEN    LC_ELEM_REF->LENGTH.
          LS_FCAT-DECIMALS  LS_FCAT-DECIMALS_O LC_ELEM_REF->DECIMALS.
          LS_FCAT-OUTPUTLEN LC_ELEM_REF->OUTPUT_LENGTH.

          IF LS_FCAT-COL_POS IS INITIAL.
            LS_FCAT-COL_POS LV_INDEX.
          ENDIF.
          APPEND LS_FCAT TO RT_FCAT.

        ENDIF.
      ENDIF.

      CLEARLS_FCATLS_COMPLV_REFFIELDLV_REFSTRUCTLS_DD04VLS_DFIESLC_ELEM_REFLT_TAB[].
    ENDLOOP.


이번엔 GET_ELEMENTS ▼


GET_ELEMENTS 소스코드

 

 

    DATALC_CLSS_REF TYPE REF TO CL_ABAP_CLASSDESCR,
          LT_COMP     TYPE CL_ABAP_STRUCTDESCR=>COMPONENT_TABLE,
          LS_COMP     LIKE LINE OF LT_COMP,
          LT_COMP_D   LIKE LT_COMP,
          LT_COMP_R   LIKE LT_COMP,
          LS_COMP_D   LIKE LS_COMP,
          LV_STRU_REF TYPE REF TO CL_ABAP_STRUCTDESCR,
          LV_INDEX    TYPE SY-INDEX.

    LT_COMP[] I_COMP_T[].

    LOOP AT LT_COMP INTO LS_COMP WHERE AS_INCLUDE 'X'.
      LV_INDEX SY-TABIX.

      DELETE LT_COMP.
      LV_STRU_REF ?= LS_COMP-TYPE.
      LT_COMP_D LV_STRU_REF->GET_COMPONENTS)."Recursive Point

      IF LS_COMP-SUFFIX IS NOT INITIAL.
        LOOP AT LT_COMP_D INTO LS_COMP_D WHERE AS_INCLUDE SPACE.
          CONCATENATE LS_COMP_D-NAME LS_COMP-SUFFIX INTO LS_COMP_D-NAME.
          MODIFY LT_COMP_D FROM LS_COMP_D.
        ENDLOOP.
      ENDIF.

      LT_COMP_R GET_ELEMENTSLT_COMP_D ).

      LOOP AT LT_COMP_R INTO LS_COMP_D.
        INSERT LS_COMP_D INTO LT_COMP INDEX LV_INDEX.
        LV_INDEX LV_INDEX + 1.
        CLEAR LS_COMP_D.
      ENDLOOP.
      CLEAR LS_COMPLT_COMP_R[].

    ENDLOOP.

    R_COMP_T LT_COMP.


저장하고 활성화시켜주면 클래스 작성 끝 ▼

 

프로그램에 아래와 같이 삽입하면 해당 프로그램의 필드 카탈로그가 인터널 테이블(GT_LIST)의 속성에 맞게 자동 변환 됩니다.

 

 

 GET_FCAT_FOR_ITAB 의 소스코드는 그대로 사용하셔도 되지만 자기 상황에 맞게 수정하시면 됩니다.


끝.

반응형