본문 바로가기
카테고리 없음

ABAP New Syntax #14 - 응용1

by SAPortal 2024. 3. 7.

목차

    1. 응용하기

    이번장에서는 지금까지 배웠던 NEW ABAP 구문들이 실제 어떻게 사용되는지 예제를 통해 알아보겠습니다.

    옛날 구문의 소스를 NEW ABAP으로 단계별로 수정하며 진행하겠습니다.

     

    2. ABAP 7.40 이전소스와 이후소스 비교

    CLASS LCL_CONVERT DEFINITION.
      PUBLIC SECTION.
        METHODS CONVERT_LOCAL_CURRENCY IMPORTING PRICE              TYPE S_PRICE
                                                 FCURR              TYPE S_CURRCODE
                                                 LCURR              TYPE S_CURRCODE
                                       RETURNING VALUE(LOCAL_PRICE) TYPE S_PRICE.
    ENDCLASS.
    
    CLASS LCL_CONVERT IMPLEMENTATION.
      METHOD CONVERT_LOCAL_CURRENCY.
        CALL FUNCTION 'CONVERT_TO_LOCAL_CURRENCY'
          EXPORTING
            DATE             = SY-DATUM
            FOREIGN_AMOUNT   = PRICE
            FOREIGN_CURRENCY = FCURR
            LOCAL_CURRENCY   = LCURR
          IMPORTING
            LOCAL_AMOUNT     = LOCAL_PRICE.
      ENDMETHOD.
    ENDCLASS.
    
    START-OF-SELECTION.
    
      DATA : BEGIN OF GS_ITAB,
               ICON         LIKE ICON-ID,
               CARRID       LIKE SFLIGHT-CARRID,
               CARRNAME(30),
               CONNID       LIKE SFLIGHT-CONNID,
               FLDATE       LIKE SFLIGHT-FLDATE,
               PRICE        LIKE SFLIGHT-PRICE,
               CURRENCY     LIKE SFLIGHT-CURRENCY,
               BOOKCNT      TYPE I,
             END OF GS_ITAB.
      DATA : GT_ITAB LIKE TABLE OF GS_ITAB.
    
      DATA : LT_SFLIGHT TYPE TABLE OF SFLIGHT,
             LT_SCARR   TYPE TABLE OF SCARR,
             LT_SBOOK   TYPE TABLE OF SBOOK.
    
      SELECT *
        INTO TABLE @LT_SFLIGHT
        FROM SFLIGHT.
    
      SELECT *
        INTO TABLE @LT_SCARR
        FROM SCARR
       ORDER BY CARRID.
    
      SELECT *
        INTO TABLE @LT_SBOOK
        FROM SBOOK.

    이부분은 예제를 위한 DATA선언 및 초기화 시키는 부분입니다.

     

      LOOP AT LT_SFLIGHT INTO DATA(LS_SFLIGHT).
        MOVE-CORRESPONDING LS_SFLIGHT TO GS_ITAB.
    
        IF LS_SFLIGHT-PRICE > 1000.
          GS_ITAB-ICON = ICON_LED_RED.
        ELSEIF LS_SFLIGHT-PRICE > 500.
          GS_ITAB-ICON = ICON_LED_YELLOW.
        ELSE.
          GS_ITAB-ICON = ICON_LED_GREEN.
        ENDIF.
    
        READ TABLE LT_SCARR INTO DATA(LS_SCARR) WITH KEY CARRID = LS_SFLIGHT-CARRID
                                                BINARY SEARCH.
        IF SY-SUBRC = 0.
          CONCATENATE '항공사이름:' LS_SCARR-CARRNAME INTO GS_ITAB-CARRNAME SEPARATED BY SPACE.
        ENDIF.
    
        LOOP AT LT_SBOOK INTO DATA(LS_SBOOK) WHERE CARRID = LS_SFLIGHT-CARRID
                                               AND CONNID = LS_SFLIGHT-CONNID
                                               AND FLDATE = LS_SFLIGHT-FLDATE.
          GS_ITAB-BOOKCNT = GS_ITAB-BOOKCNT + 1.
        ENDLOOP.
    
        CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
          EXPORTING
            INPUT  = GS_ITAB-CARRID
          IMPORTING
            OUTPUT = GS_ITAB-CARRID.
    
        DATA : LV_LOCAL_AMOUNT LIKE SFLIGHT-PRICE.
        IF GS_ITAB-CURRENCY <> 'KRW'.
          CALL FUNCTION 'CONVERT_TO_LOCAL_CURRENCY'
            EXPORTING
              DATE             = SY-DATUM
              FOREIGN_AMOUNT   = GS_ITAB-PRICE
              FOREIGN_CURRENCY = GS_ITAB-CURRENCY
              LOCAL_CURRENCY   = 'KRW'
            IMPORTING
              LOCAL_AMOUNT     = LV_LOCAL_AMOUNT.
          IF SY-SUBRC = 0.
            GS_ITAB-PRICE = LV_LOCAL_AMOUNT.
          ENDIF.
        ENDIF.
    
        APPEND GS_ITAB TO GT_ITAB.
      ENDLOOP.

    위에는 ABAP 7.40 이전 문법으로만 사용한 예제입니다.

    아래는 위 예제소스를 NEW ABAP을 사용하여 구현한 예제입니다.

     

    GT_ITAB =  VALUE #( LET LO_CONVERT = NEW LCL_CONVERT( ) IN
                        FOR LS_SFLIGHT IN LT_SFLIGHT (
                        VALUE #( BASE CORRESPONDING #( LS_SFLIGHT )
                                 ICON = COND #( WHEN LS_SFLIGHT-PRICE > 1000 THEN ICON_LED_RED
                                                WHEN LS_SFLIGHT-PRICE > 500  THEN ICON_LED_YELLOW
                                                ELSE ICON_LED_GREEN )
                                 CARRNAME = |항공사이름: { VALUE #( LT_SCARR[ CARRID = LS_SFLIGHT-CARRID ]-CARRNAME ) }|
                                 BOOKCNT = REDUCE I( INIT CNT = 0 FOR WA IN LT_SBOOK WHERE ( CARRID = LS_SFLIGHT-CARRID AND
                                                                                             CONNID = LS_SFLIGHT-CONNID AND
                                                                                             FLDATE = LS_SFLIGHT-FLDATE )
                                           NEXT CNT = CNT + 1 )
                                 CARRID = |{ GS_ITAB-CARRID ALPHA = OUT } |
                                 PRICE = COND #( WHEN GS_ITAB-CURRENCY <> 'KRW'
                                                 THEN LO_CONVERT->CONVERT_LOCAL_CURRENCY( EXPORTING PRICE = GS_ITAB-PRICE
                                                                                                    FCURR = GS_ITAB-CURRENCY
                                                                                                    LCURR = 'KRW' ) ) ) )
                       ).

    어떠신가요? 소스기 많이 간결해 진게 느껴지시나요?

    처음에는 어색해서 가독성이 떨어져 보이지만 익숙해지면 소스가 간결해진 만큼 가독성 또한 높아지는걸 느낄수 있습니다.

    처음부터 모든로직을 위 예제처럼 한번에 코딩하기는 힘듭니다.

    어려워 마시고 쉬운 구문부터 하나씩 바꿔나가면 됩니다.

    아래 예제에서 단계별로 로직을 바꿔나가는 방법을 같이 보겠습니다.

     

    3. 소스변환 - 1단계

    [OLD]
        MOVE-CORRESPONDING LS_SFLIGHT TO GS_ITAB.
        
    [NEW]
        GS_ITAB = CORRESPONDING #( LS_SFLIGHT ).

    MOVE-CORRESPONDING구분을 CORRESPONDING 연산자를 사용하여 수정하였습니다.

    기본적인 CORRESPONDING 연산자 구문이기 때문에 어려운건 없습니다.

     

    [OLD]
        IF LS_SFLIGHT-PRICE > 1000.
          GS_ITAB-ICON = ICON_LED_RED.
        ELSEIF LS_SFLIGHT-PRICE > 500.
          GS_ITAB-ICON = ICON_LED_YELLOW.
        ELSE.
          GS_ITAB-ICON = ICON_LED_GREEN.
        ENDIF.
        
    [NEW]
        GS_ITAB-ICON = COND #( WHEN LS_SFLIGHT-PRICE > 1000 THEN ICON_LED_RED
                               WHEN LS_SFLIGHT-PRICE > 500  THEN ICON_LED_YELLOW
                               ELSE ICON_LED_GREEN ).

    이 부분도 마찬가지로 IF조건문을 COND 연산자를 사용하여 수정하였습니다. 어려운건 없습니다.

     

    [OLD]
        READ TABLE LT_SCARR INTO DATA(LS_SCARR) WITH KEY CARRID = LS_SFLIGHT-CARRID
                                                BINARY SEARCH.
        IF SY-SUBRC = 0.
          CONCATENATE '항공사이름:' LS_SCARR-CARRNAME INTO GS_ITAB-CARRNAME SEPARATED BY SPACE.
        ENDIF.
        
    [NEW]
        DATA(LV_CARRNAME) = VALUE #( LT_SCARR[ CARRID = LS_SFLIGHT-CARRID ]-CARRNAME OPTIONAL ).
        GS_ITAB-CARRNAME = |항공사이름: { LV_CARRNAME }|.

    READ TABLE구문을 TABLE EXPRESSION 구문으로 바꿔사용하였습니다.

    조건에 맞는 값을 LV_CARRNAME에 담아서 새로운 CONCATENATE 구문을 사용하여 GS_ITAB-CARRNAME에 담았습니다.

     

    [OLD]
        LOOP AT LT_SBOOK INTO DATA(LS_SBOOK) WHERE CARRID = LS_SFLIGHT-CARRID
                                               AND CONNID = LS_SFLIGHT-CONNID
                                               AND FLDATE = LS_SFLIGHT-FLDATE.
          GS_ITAB-BOOKCNT = GS_ITAB-BOOKCNT + 1.
        ENDLOOP.
        
    [NEW]
        GS_ITAB-BOOKCNT = REDUCE I( INIT CNT = 0 FOR WA IN LT_SBOOK WHERE ( CARRID = LS_SFLIGHT-CARRID AND
                                                                            CONNID = LS_SFLIGHT-CONNID AND
                                                                            FLDATE = LS_SFLIGHT-FLDATE )
                                    NEXT CNT = CNT + 1 ).

    조건에 맞는 SBOOK정보의 카운트를 구하는 로직입니다.

    LOOP을 돌면서 카운트를 했던 로직을 REDUCE 연산자를 사용하여 카운트 하도록 수정했습니다.

     

    [OLD]
        CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
          EXPORTING
            INPUT  = GS_ITAB-CARRID
          IMPORTING
            OUTPUT = GS_ITAB-CARRID.
            
    [NEW]
        GS_ITAB-CARRID = |{ GS_ITAB-CARRID ALPHA = OUT } |.

    ALPHA CONVERSION도 함수를 쓰지 않고 STRING 관련 기능중에 ALPHA = OUT으로 처리하였습니다.

     

    [OLD]
        DATA : LV_LOCAL_AMOUNT LIKE SFLIGHT-PRICE.
        IF GS_ITAB-CURRENCY <> 'KRW'.
          CALL FUNCTION 'CONVERT_TO_LOCAL_CURRENCY'
            EXPORTING
              DATE             = SY-DATUM
              FOREIGN_AMOUNT   = GS_ITAB-PRICE
              FOREIGN_CURRENCY = GS_ITAB-CURRENCY
              LOCAL_CURRENCY   = 'KRW'
            IMPORTING
              LOCAL_AMOUNT     = LV_LOCAL_AMOUNT.
          IF SY-SUBRC = 0.
            GS_ITAB-PRICE = LV_LOCAL_AMOUNT.
          ENDIF.
        ENDIF.
    
    [NEW]
        DATA(LO_CONVERT) = NEW LCL_CONVERT( ).
        GS_ITAB-PRICE = COND #( WHEN GS_ITAB-CURRENCY <> 'KRW'
                                THEN LO_CONVERT->CONVERT_LOCAL_CURRENCY( EXPORTING PRICE = GS_ITAB-PRICE
                                                                                   FCURR = GS_ITAB-CURRENCY
                                                                                   LCURR = 'KRW' ) ).

    금액 CONVERT하는 펑션을 CLASS로 감싸서 COND문에서 사용할수 있도록 수정하였습니다.

    새로운 구문에서는 FUNCTION을 직접사용하지 못하기 때문에 CLASS를 활용하면 간결하게 코딩을 할 수 있습니다.

     

    자 그러면 1차로 변환된 전체소스를 보도록 하겠습니다.

      LOOP AT LT_SFLIGHT INTO DATA(LS_SFLIGHT).
        GS_ITAB = CORRESPONDING #( LS_SFLIGHT ).
    
        GS_ITAB-ICON = COND #( WHEN LS_SFLIGHT-PRICE > 1000 THEN ICON_LED_RED
                               WHEN LS_SFLIGHT-PRICE > 500  THEN ICON_LED_YELLOW
                               ELSE ICON_LED_GREEN ).
    
        DATA(LV_CARRNAME) = VALUE #( LT_SCARR[ CARRID = LS_SFLIGHT-CARRID ]-CARRNAME OPTIONAL ).
    
        GS_ITAB-CARRNAME = |항공사이름: { LV_CARRNAME }|.
    
        GS_ITAB-BOOKCNT = REDUCE I( INIT CNT = 0 FOR WA IN LT_SBOOK WHERE ( CARRID = LS_SFLIGHT-CARRID AND
                                                                            CONNID = LS_SFLIGHT-CONNID AND
                                                                            FLDATE = LS_SFLIGHT-FLDATE )
                                    NEXT CNT = CNT + 1 ).
    
        GS_ITAB-CARRID = |{ GS_ITAB-CARRID ALPHA = OUT } |.
    
        DATA(LO_CONVERT) = NEW LCL_CONVERT( ).
        GS_ITAB-PRICE = COND #( WHEN GS_ITAB-CURRENCY <> 'KRW'
                                THEN LO_CONVERT->CONVERT_LOCAL_CURRENCY( EXPORTING PRICE = GS_ITAB-PRICE
                                                                                   FCURR = GS_ITAB-CURRENCY
                                                                                   LCURR = 'KRW' ) ).
    
        APPEND GS_ITAB TO GT_ITAB.
      ENDLOOP.

    가장 기본적은 부분만 NEW ABAP으로 수정한 소스입니다.

    처음 소스에 비해 간결해진걸 볼수 있습니다.

    다음장에서 현재 소스를 바탕으로 좀더 진행해 보겠습니다.