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

[Class] Internal Table/Structure 일괄 Conversion - ZCL_MASS_CONV_ALPHA

by name_text 2023. 11. 22.

일괄 Conversion Alpha

ZCL_MASS_CONV_ALPHA

 

 

# Conversion 규칙

Domain 설정된 Conversion Routine

Domain 설정된 소문자 사용 여부

숫자 필드의 경우 마이너스 기호를 앞으로 (OUTPUT 시)

금액필드의 경우 통화참조가 있을 경우 통화에 따른 변환 적용

날짜 시간의 경우 숫자를 제외한 모든 문자 제거 (INPUT 시)

 

# Input/Output 형식

Internal Table 전체 변환 : Standard Table

단일 레코드 변환 : Structure

단일 변수 변환 : Variant

 

 

# 사용예시

  TYPES: BEGIN OF T_BSIK,
    LIFNR     TYPE BSIK-LIFNR,
    GJAHR     TYPE BSIK-GJAHR,
    BELNR     TYPE BSIK-BELNR,
    BUZEI     TYPE BSIK-BUZEI,
    BUDAT     TYPE BSIK-BUDAT,
    WAERS     TYPE BSIK-WAERS,
    DMBTR     TYPE BSIK-DMBTR,
    WRBTR     TYPE BSIK-WRBTR,
    END OF T_BSIK.

  TYPES: BEGIN OF T_STRING,
    LIFNR     TYPE STRING,
    GJAHR(4)  TYPE C,
    BELNR(10) TYPE C,
    BUZEI(3)  TYPE C,
    BUDAT     TYPE STRING,
    WAERS     TYPE STRING,
    DMBTR     TYPE STRING,
    WRBTR     TYPE STRING,
    END OF T_STRING.


  DATA: LT_ABAPDDIC TYPE STANDARD TABLE OF BSIK,      "통화에 따른 금액변환을 하려면 DDIC를 사용해야 함
        LS_ABAPDDIC LIKE LINE OF LT_ABAPDDIC,
        LT_BSIK     TYPE STANDARD TABLE OF T_BSIK,
        LS_BSIK     LIKE LINE OF LT_BSIK,
        LT_BSIK2    TYPE STANDARD TABLE OF T_BSIK,
        LS_BSIK2    LIKE LINE OF LT_BSIK2,
        LT_STRING   TYPE STANDARD TABLE OF T_STRING,
        LS_STRING   LIKE LINE OF LT_STRING,
        LV_LIFNR    TYPE BSIK-LIFNR,
        LV_LIFNR2   TYPE BSIK-LIFNR,
        LV_STRING   TYPE STRING.

  SELECT
    *
  FROM BSIK
  INTO CORRESPONDING FIELDS OF TABLE @LT_BSIK
    UP TO 3 ROWS.

  LT_ABAPDDIC = CORRESPONDING #( LT_BSIK ).
  READ TABLE LT_ABAPDDIC INTO LS_ABAPDDIC INDEX 1.
  LV_LIFNR = LS_ABAPDDIC-LIFNR.


*1. Internal Table 일괄 변환
  "Convert output
  LT_BSIK = CORRESPONDING #( LT_ABAPDDIC ).
  ZCL_MASS_CONV_ALPHA=>OUTPUT( EXPORTING INPUT  = LT_ABAPDDIC
                                CHANGING OUTPUT = LT_STRING ).
  "Convert input
  ZCL_MASS_CONV_ALPHA=>INPUT( EXPORTING INPUT  = LT_STRING
                               CHANGING OUTPUT = LT_ABAPDDIC ).
  LT_BSIK2 = CORRESPONDING #( LT_ABAPDDIC ).

*2. Structure 일괄 변환
  "Convert output
  LS_BSIK = CORRESPONDING #( LS_ABAPDDIC ).
  ZCL_MASS_CONV_ALPHA=>OUTPUT( EXPORTING INPUT  = LS_ABAPDDIC
                                CHANGING OUTPUT = LS_STRING ).
  "Convert input
  ZCL_MASS_CONV_ALPHA=>INPUT( EXPORTING INPUT  = LS_STRING
                               CHANGING OUTPUT = LS_ABAPDDIC ).
  LS_BSIK2 = CORRESPONDING #( LS_ABAPDDIC ).

*3. 단일 변수 변환
  ZCL_MASS_CONV_ALPHA=>OUTPUT( EXPORTING INPUT  = LV_LIFNR
                                CHANGING OUTPUT = LV_STRING ).
  "Convert input
  ZCL_MASS_CONV_ALPHA=>INPUT( EXPORTING INPUT  = LV_STRING
                               CHANGING OUTPUT = LV_LIFNR2 ).

cl_demo_output=>new(
       )->next_section( 'Internal Table 일괄 변환'
       )->write( LT_BSIK
       )->write( 'Conversion Output : LT_BSIK -> LT_STRING'
       )->write( LT_STRING
       )->write( 'Conversion intput : LT_STRING -> LT_BSIK2'
       )->write( LT_BSIK2
       )->next_section( 'Structure 일괄 변환'
       )->write( LS_BSIK
       )->write( 'Conversion Output : LS_BSIK -> LS_STRING'
       )->write( LS_STRING
       )->write( 'Conversion intput : LS_STRING -> LS_BSIK2'
       )->write( LS_BSIK2
       )->next_section( '단일 변수 변환'
       )->write( LV_LIFNR
       )->write( 'Conversion Output : LV_LIFNR -> LV_STRING'
       )->write( LV_STRING
       )->write( 'Conversion intput : LV_STRING -> LV_LIFNR2'
       )->write( LV_LIFNR2
       )->display( ).
ABAP

 

# 소스코드

class ZCL_MASS_CONV_ALPHA definition
  public
  final
  create public .

public section.

  class-methods INPUT
    importing
      !INPUT type ANY
    changing
      value(OUTPUT) type ANY .
  class-methods OUTPUT
    importing
      !INPUT type ANY
    changing
      value(OUTPUT) type ANY .
protected section.
private section.

  class-methods CONV
    importing
      !I_INPUT type ANY
      !I_TYPE type ANY
    changing
      value(C_OUTPUT) type ANY .
  class-methods CONV_FIELD
    importing
      !I_INPUT type ANY
      !I_TYPE type ANY
      !I_DDFIELDS type DFIES
      !I_CFIELD type ANY optional
    changing
      value(C_OUTPUT) type ANY .
  class-methods CONV_LINE
    importing
      !I_INPUT type ANY
      !I_TYPE type ANY
      !I_DDFIELDS type DDFIELDS
    changing
      value(C_OUTPUT) type ANY .
ENDCLASS.



CLASS ZCL_MASS_CONV_ALPHA IMPLEMENTATION.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_MASS_CONV_ALPHA=>CONV
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_INPUT                        TYPE        ANY
* | [--->] I_TYPE                         TYPE        ANY
* | [<-->] C_OUTPUT                       TYPE        ANY
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method CONV.
    DATA: LV_FTYPE    TYPE C,
          LV_COMPS    TYPE I,
          LT_DDFIELDS TYPE DDFIELDS.

    DATA: LD_OUTPUT         TYPE REF TO DATA.
    FIELD-SYMBOLS: <LFT_INPUT>  TYPE ANY TABLE,
                   <LFT_OUTPUT> TYPE STANDARD TABLE,
                   <LFS_INPUT>  TYPE ANY,
                   <LFS_OUTPUT> TYPE ANY.

    CLEAR LT_DDFIELDS.

    CASE I_TYPE.
      WHEN 'INPUT'.
        TRY.
          CALL METHOD CL_SALV_DDIC=>GET_BY_DATA
            EXPORTING
              DATA    = C_OUTPUT
            RECEIVING
              T_DFIES = LT_DDFIELDS
              .
          "변수의 타입
          DESCRIBE FIELD C_OUTPUT TYPE LV_FTYPE COMPONENTS LV_COMPS.
        CATCH CX_ROOT INTO DATA(LO_CX_INPUT).
          EXIT.
        ENDTRY.
      WHEN 'OUTPUT'.
        TRY.
          CALL METHOD CL_SALV_DDIC=>GET_BY_DATA
            EXPORTING
              DATA    = I_INPUT
            RECEIVING
              T_DFIES = LT_DDFIELDS
              .
          "변수의 타입
          DESCRIBE FIELD I_INPUT TYPE LV_FTYPE COMPONENTS LV_COMPS.
        CATCH CX_ROOT INTO DATA(LO_CX_OUTPUT).
          EXIT.
        ENDTRY.
    ENDCASE.

    IF LT_DDFIELDS[] IS INITIAL.
      EXIT.
    ENDIF.

    CASE LV_FTYPE.
      WHEN CL_ABAP_TYPEDESCR=>TYPEKIND_TABLE.     "Internal Type h (Internal Table)
        ASSIGN I_INPUT TO <LFT_INPUT>.
        ASSIGN C_OUTPUT TO <LFT_OUTPUT>.

        IF <LFT_INPUT> IS NOT ASSIGNED OR <LFT_OUTPUT> IS NOT ASSIGNED.
          EXIT.
        ENDIF.

        CREATE DATA LD_OUTPUT LIKE LINE OF <LFT_OUTPUT>.
        ASSIGN LD_OUTPUT->* TO <LFS_OUTPUT>.
        CLEAR <LFT_OUTPUT>[].

        LOOP AT <LFT_INPUT> ASSIGNING <LFS_INPUT>.
          CLEAR <LFS_OUTPUT>.
          CONV_LINE( EXPORTING I_INPUT     = <LFS_INPUT>
                               I_TYPE      = I_TYPE
                               I_DDFIELDS  = LT_DDFIELDS
                      CHANGING C_OUTPUT    = <LFS_OUTPUT> ).
          APPEND <LFS_OUTPUT> TO <LFT_OUTPUT>.
        ENDLOOP.

      WHEN CL_ABAP_TYPEDESCR=>TYPEKIND_STRUCT1.   "Internal type u (flat structure)
        ASSIGN I_INPUT TO <LFS_INPUT>.
        ASSIGN C_OUTPUT TO <LFS_OUTPUT>.

        IF <LFS_INPUT> IS NOT ASSIGNED OR <LFS_OUTPUT> IS NOT ASSIGNED.
          EXIT.
        ENDIF.

        CONV_LINE( EXPORTING I_INPUT     = <LFS_INPUT>
                             I_TYPE      = I_TYPE
                             I_DDFIELDS  = LT_DDFIELDS
                    CHANGING C_OUTPUT    = <LFS_OUTPUT> ).

      WHEN OTHERS.  "Variant
        READ TABLE LT_DDFIELDS INTO DATA(LS_DDFIELDS) INDEX 1.
        CONV_FIELD( EXPORTING I_INPUT     = I_INPUT
                              I_TYPE      = I_TYPE
                              I_DDFIELDS  = LS_DDFIELDS
                     CHANGING C_OUTPUT    = C_OUTPUT ).

    ENDCASE.
  endmethod.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_MASS_CONV_ALPHA=>CONV_FIELD
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_INPUT                        TYPE        ANY
* | [--->] I_TYPE                         TYPE        ANY
* | [--->] I_DDFIELDS                     TYPE        DFIES
* | [--->] I_CFIELD                       TYPE        ANY(optional)
* | [<-->] C_OUTPUT                       TYPE        ANY
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method CONV_FIELD.
    DATA: LV_FTYPE    TYPE C,
          LV_COMPS    TYPE I.
    DATA: LV_TMP      TYPE STRING,
          LV_FUNCNAME TYPE RS38L_FNAM,
          LV_CFIELD_CONV_FUNC TYPE RS38L_FNAM.
    DATA: LV_AMOUNT_INPUT   TYPE BAPICURR-BAPICURR,
          LV_AMOUNT_OUTPUT  TYPE BAPICURR-BAPICURR,
          LV_CURRENCY TYPE TCURC-WAERS,
          LV_CHAR(1024) TYPE C,
          LV_TUMLS_DATE TYPE TUMLS_DATE.

    CLEAR C_OUTPUT.
    MOVE I_INPUT TO LV_TMP.

    CASE I_DDFIELDS-INTTYPE.
      WHEN CL_ABAP_TYPEDESCR=>TYPEKIND_DATE OR
           CL_ABAP_TYPEDESCR=>TYPEKIND_TIME.
        CHECK LV_TMP IS NOT INITIAL.
        IF I_TYPE EQ 'INPUT'.
          IF I_DDFIELDS-INTTYPE EQ CL_ABAP_TYPEDESCR=>TYPEKIND_DATE.
            MOVE LV_TMP TO LV_TUMLS_DATE.
            "date format YYYY/MM/DD
            FIND REGEX '^\d{4}[/|-]\d{1,2}[/|-]\d{1,2}$' IN LV_TUMLS_DATE.
            IF sy-subrc = 0.
              CALL FUNCTION '/SAPDMC/LSM_DATE_CONVERT'
                EXPORTING
                  date_in             = LV_TUMLS_DATE
                  date_format_in      = 'DYMD'
                  to_output_format    = ' '
                  to_internal_format  = 'X'
                IMPORTING
                  date_out            = LV_TUMLS_DATE
                EXCEPTIONS
                  illegal_date        = 1
                  illegal_date_format = 2
                  no_user_date_format = 3
                  OTHERS              = 4.
            ELSE.
              " date format DD/MM/YYYY
              FIND REGEX '^\d{1,2}[/|-]\d{1,2}[/|-]\d{4}$' IN LV_TUMLS_DATE.
              IF sy-subrc = 0.
                CALL FUNCTION '/SAPDMC/LSM_DATE_CONVERT'
                  EXPORTING
                    date_in             = LV_TUMLS_DATE
                    date_format_in      = 'DDMY'
                    to_output_format    = ' '
                    to_internal_format  = 'X'
                  IMPORTING
                    date_out            = LV_TUMLS_DATE
                  EXCEPTIONS
                    illegal_date        = 1
                    illegal_date_format = 2
                    no_user_date_format = 3
                    OTHERS              = 4.
              ENDIF.
            ENDIF.
            IF SY-SUBRC EQ 0.
              MOVE LV_TUMLS_DATE TO LV_TMP.
            ENDIF.
          ENDIF.

          REPLACE ALL OCCURRENCES OF REGEX '[^[:digit:]]' IN LV_TMP WITH SPACE.
        ENDIF.
        MOVE LV_TMP TO C_OUTPUT.
      WHEN CL_ABAP_TYPEDESCR=>TYPEKIND_PACKED OR
           CL_ABAP_TYPEDESCR=>TYPEKIND_NUM    OR
           CL_ABAP_TYPEDESCR=>TYPEKIND_INT    OR
           CL_ABAP_TYPEDESCR=>TYPEKIND_FLOAT.
        DESCRIBE FIELD C_OUTPUT TYPE LV_FTYPE COMPONENTS LV_COMPS.

        IF I_TYPE EQ 'INPUT'.
          REPLACE ALL OCCURRENCES OF REGEX '[^[:digit:]|.|-]' IN LV_TMP WITH SPACE.
        ENDIF.

        "금액의 통화 변환
        IF I_CFIELD IS NOT INITIAL AND LV_TMP IS NOT INITIAL.
          MOVE I_CFIELD TO LV_CURRENCY.
          IF I_TYPE EQ 'INPUT'.
            MOVE LV_TMP TO LV_AMOUNT_INPUT.
            CALL FUNCTION 'CURRENCY_AMOUNT_BAPI_TO_SAP'
              EXPORTING
                CURRENCY                    = LV_CURRENCY
                BAPI_AMOUNT                 = LV_AMOUNT_INPUT
              IMPORTING
                SAP_AMOUNT                  = LV_AMOUNT_OUTPUT
              EXCEPTIONS
                BAPI_AMOUNT_INCORRECT       = 1
                OTHERS                      = 2
                      .
            IF SY-SUBRC <> 0.
* Implement suitable error handling here
            ENDIF.
            MOVE LV_AMOUNT_OUTPUT TO C_OUTPUT.
          ELSE.
            "OUTPUT 필드 형식에 따라 CONV 펑션 결정
            CASE LV_FTYPE.
              WHEN CL_ABAP_TYPEDESCR=>TYPEKIND_CHAR OR CL_ABAP_TYPEDESCR=>TYPEKIND_STRING OR CL_ABAP_TYPEDESCR=>TYPEKIND_W.
                "CHAR 형식 => CURRENCY_AMOUNT_SAP_TO_IDOC
                CALL FUNCTION 'CURRENCY_AMOUNT_SAP_TO_IDOC'
                  EXPORTING
                    CURRENCY          = LV_CURRENCY
                    SAP_AMOUNT        = I_INPUT
                  IMPORTING
                    IDOC_AMOUNT       = LV_CHAR
                          .
                CONDENSE LV_CHAR.
                MOVE LV_CHAR TO C_OUTPUT.
              WHEN OTHERS.
                MOVE I_INPUT TO LV_AMOUNT_INPUT.
                CALL FUNCTION 'CURRENCY_AMOUNT_SAP_TO_BAPI'
                  EXPORTING
                    CURRENCY          = LV_CURRENCY
                    SAP_AMOUNT        = LV_AMOUNT_INPUT
                  IMPORTING
                    BAPI_AMOUNT       = LV_AMOUNT_OUTPUT
                          .
                MOVE LV_AMOUNT_OUTPUT TO C_OUTPUT.
            ENDCASE.
          ENDIF.
        ELSE.
          MOVE LV_TMP TO C_OUTPUT.
        ENDIF.
        IF I_TYPE EQ 'OUTPUT'.
          CASE LV_FTYPE.
            WHEN CL_ABAP_TYPEDESCR=>TYPEKIND_CHAR OR CL_ABAP_TYPEDESCR=>TYPEKIND_STRING OR CL_ABAP_TYPEDESCR=>TYPEKIND_W.
              CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT'
                CHANGING
                  VALUE         = C_OUTPUT.
          ENDCASE.
        ENDIF.
      WHEN OTHERS.
        CHECK LV_TMP IS NOT INITIAL.
        MOVE LV_TMP TO C_OUTPUT.

        IF I_DDFIELDS-LOWERCASE NE 'X' AND I_TYPE EQ 'INPUT' AND I_DDFIELDS-INTTYPE EQ 'C'.
          TRANSLATE C_OUTPUT TO UPPER CASE.
        ENDIF.
        IF I_DDFIELDS-CONVEXIT IS NOT INITIAL.
          LV_FUNCNAME = |CONVERSION_EXIT_{ I_DDFIELDS-CONVEXIT }_{ I_TYPE }|.
          TRY.
            CASE I_TYPE.
              WHEN 'INPUT'.
                MOVE C_OUTPUT TO LV_CHAR.
                CALL FUNCTION LV_FUNCNAME
                  EXPORTING
                    INPUT   = LV_CHAR
                  IMPORTING
                    OUTPUT  = C_OUTPUT
                  EXCEPTIONS
                    OTHERS  = 1.
              WHEN 'OUTPUT'.
                CALL FUNCTION LV_FUNCNAME
                  EXPORTING
                    INPUT   = I_INPUT
                  IMPORTING
                    OUTPUT  = LV_CHAR
                  EXCEPTIONS
                    OTHERS  = 1.
                MOVE LV_CHAR TO C_OUTPUT.
            ENDCASE.

          CATCH CX_ROOT INTO DATA(LO_CX_ALPHA).
          ENDTRY.
        ENDIF.
    ENDCASE.
  endmethod.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_MASS_CONV_ALPHA=>CONV_LINE
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_INPUT                        TYPE        ANY
* | [--->] I_TYPE                         TYPE        ANY
* | [--->] I_DDFIELDS                     TYPE        DDFIELDS
* | [<-->] C_OUTPUT                       TYPE        ANY
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method CONV_LINE.
    DATA: LV_FIELD_I(255)   TYPE C,
          LV_FIELD_O(255)   TYPE C,
          LV_FIELD_C(255)   TYPE C.

    FIELD-SYMBOLS: <LFV_INPUT>  TYPE ANY,
                   <LFV_OUTPUT> TYPE ANY,
                   <LFV_CFIELD> TYPE ANY.

    LOOP AT I_DDFIELDS INTO DATA(LS_DDFIELDS).
      IF <LFV_INPUT> IS ASSIGNED.
        UNASSIGN <LFV_INPUT>.
      ENDIF.
      IF <LFV_OUTPUT> IS ASSIGNED.
        UNASSIGN <LFV_OUTPUT>.
      ENDIF.
      IF <LFV_CFIELD> IS ASSIGNED.
        UNASSIGN <LFV_CFIELD>.
      ENDIF.
      LV_FIELD_I = |I_INPUT-{ LS_DDFIELDS-FIELDNAME }|.
      LV_FIELD_O = |C_OUTPUT-{ LS_DDFIELDS-FIELDNAME }|.
      IF LS_DDFIELDS-REFTABLE EQ LS_DDFIELDS-PRECFIELD AND LS_DDFIELDS-REFFIELD IS NOT INITIAL
        AND LS_DDFIELDS-DATATYPE EQ 'CURR'. "금액 환산용 통화키
        LV_FIELD_C = |I_INPUT-{ LS_DDFIELDS-REFFIELD }|.
        ASSIGN (LV_FIELD_C) TO <LFV_CFIELD>.
      ENDIF.

      ASSIGN (LV_FIELD_I) TO <LFV_INPUT>.
      ASSIGN (LV_FIELD_O) TO <LFV_OUTPUT>.

      IF <LFV_INPUT> IS ASSIGNED AND <LFV_OUTPUT> IS ASSIGNED.
        IF <LFV_CFIELD> IS ASSIGNED.
          CONV_FIELD( EXPORTING I_INPUT     = <LFV_INPUT>
                                I_TYPE      = I_TYPE
                                I_DDFIELDS  = LS_DDFIELDS
                                I_CFIELD    = <LFV_CFIELD>
                       CHANGING C_OUTPUT    = <LFV_OUTPUT> ).
        ELSE.
          CONV_FIELD( EXPORTING I_INPUT     = <LFV_INPUT>
                                I_TYPE      = I_TYPE
                                I_DDFIELDS  = LS_DDFIELDS
                       CHANGING C_OUTPUT    = <LFV_OUTPUT> ).
        ENDIF.
      ENDIF.
    ENDLOOP.
  endmethod.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_MASS_CONV_ALPHA=>INPUT
* +-------------------------------------------------------------------------------------------------+
* | [--->] INPUT                          TYPE        ANY
* | [<-->] OUTPUT                         TYPE        ANY
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method INPUT.
    CONV( EXPORTING I_INPUT   = INPUT
                    I_TYPE    = 'INPUT'
          CHANGING  C_OUTPUT  = OUTPUT ).
  endmethod.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_MASS_CONV_ALPHA=>OUTPUT
* +-------------------------------------------------------------------------------------------------+
* | [--->] INPUT                          TYPE        ANY
* | [<-->] OUTPUT                         TYPE        ANY
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method OUTPUT.
    CONV( EXPORTING I_INPUT   = INPUT
                    I_TYPE    = 'OUTPUT'
          CHANGING  C_OUTPUT  = OUTPUT ).
  endmethod.
ENDCLASS.
ABAP

댓글